Pages: [1]   Go Down
Author Topic: Algorithmic symphonies  (Read 646 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Inspired by http://countercomplex.blogspot.com/2011/10/algorithmic-symphonies-from-one-line-of.html I decided, hey my Arduino can do that. I have been playing with syntheses on the Arduino for a few months it looked like the perfect little project for a Saturday morning.

I decided easiest is best. Use Fast PWM and throw a lowpass filter on the PWM output to produce the sound. That way I don't have to deal with DACs or R2R ladders and all those pesky little wires. I have used the PWM/lowpass approach for sound generation with a great deal of success in the past.

I sourced the design for the low pass filter from http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/. I did not have the exact values for the inductors but that does not appear to make much of a difference. You could also use a simple RC filter to filter and smooth out the output. RC filters are slightly simpler and if you don't have a couple inductors lying around will produce similar results.

So with out further bloviation here is the source code.

Code:
static char out = 255;
static int t = 255;
static int i = 0;
int count = 0;

ISR(TIMER1_OVF_vect){
 
  //The timer overflows at 62.5 KHz.
  //Algorithmic symphonies calls for 8khz
  // Throw a counter in there to slow things down.
  // It is also fun to play with the counter :-)
  //http://countercomplex.blogspot.com/2011/10/algorithmic-symphonies-from-one-line-of.html
  if(count < 7){
    count++;
    return;
  }else{
    count = 0;
  }

  /** The best so far */
  out = (char)(((t>>6|t|t>>(t>>3))*10+((t>>11)&7))|(t)*(t>>14)|(t)*(t>>9))
              ^(63*(t/16) |(t%13) | (t%15))
              ^(16*(t/8));
 
  OCR1A = out;
  t++;
 
}


// Configures TIMER1 to fast PWM non inverted mode.
// Prescaler set to 1, which means that timer overflows
// every 16MHz/256 = 62.5KHz
void initPWM(void)
{

pinMode(9, OUTPUT);
// 8-bit Fast PWM - non inverted PWM
TCCR1A= _BV(COM1A1) | _BV(WGM10);

// Start timer without prescaler
TCCR1B = _BV(CS10) | _BV(WGM12);

// Enable overflow interrupt for OCR1A
TIMSK1 = _BV(TOIE1);

}

void setup(void){
  initPWM();
}

void loop(){
//Nothing to see here
}


I have attached a sound sample produced by the source code and a low pass filter schematic taken from the above mentioned URL.

I hope you find this as inspiring as I did.

Enjoy,
Will




* BitBashing.mp3 (800.74 KB - downloaded 11 times.)

* dds_lowpass1251-360x89.jpg (8.98 KB, 360x89 - viewed 15 times.)
Logged

Pages: [1]   Go Up
Jump to: