Commits

Anonymous committed 6253af1 Draft

working example of karplus_string_synthesis

Comments (0)

Files changed (1)

karplus_string_synthesis/karplus_string_synthesis.pde

 
 http://en.wikipedia.org/wiki/Karplus%E2%80%93Strong_string_synthesis
 
-Karplus-Strong string synthesis is a method of physical modelling synthesis that
-loops a short waveform through a filtered delay line to simulate the sound of a
-hammered or plucked string or some types of percussion. Although it is useful to
-view this as a subtractive synthesis technique based on a feedback loop similar
-to that of a comb filter for z-transform analysis, it is better viewed as the
-simplest of a class of wavetable-modification algorithms now known as digital
-waveguide synthesis, as the delay line acts to store one period of the signal.
-Alexander Strong invented the algorithm, and Kevin Karplus did the first analysis
-of how it worked. Together they developed software and hardware implementations
-of the algorithm, including a custom VLSI chip. They named the algorithm
-"Digitar" synthesis, as an abbreviation for "digital guitar".
+  Karplus-Strong string synthesis is a method of physical modelling synthesis that
+  loops a short waveform through a filtered delay line to simulate the sound of a
+  hammered or plucked string or some types of percussion. Although it is useful to
+  view this as a subtractive synthesis technique based on a feedback loop similar
+  to that of a comb filter for z-transform analysis, it is better viewed as the
+  simplest of a class of wavetable-modification algorithms now known as digital
+  waveguide synthesis, as the delay line acts to store one period of the signal.
+  Alexander Strong invented the algorithm, and Kevin Karplus did the first analysis
+  of how it worked. Together they developed software and hardware implementations
+  of the algorithm, including a custom VLSI chip. They named the algorithm
+  "Digitar" synthesis, as an abbreviation for "digital guitar".
 
 */
 
 // must be done before #includes
 // see readme file in libraries folder for explanations
 #define SAMPLE_RATE 44 // 44.1Khz
-#define ADCS 1 // no ADCs are being used
+#define ADCS 1 // this is checked in AudioCodec_Maple.h, to determine how ADCs are being used
 
 // include necessary libraries
-#include <Wire.h>
-#include <SPI.h>
-#include <AudioCodec.h>
+// #include <Wire.h>
+// #include <SPI.h>
+#include <AudioCodec_Maple.h>
 
 // create data variables for audio transfer
-int left_in = 0x0000;
-int left_out = 0x0000;
-int right_in = 0x0000;
-int right_out = 0x0000;
-int last_value = 0x0000;
-int curr_value = 0x0000;
+int16 left_in = 0x0000;
+int16 left_out = 0x0000;
+int16 right_in = 0x0000;
+int16 right_out = 0x0000;
+int16 last_value = 0x0000;
+int16 curr_value = 0x0000;
 unsigned int decay = 0x0000;
 #define DECAY 65000
-unsigned int mod0_value =0;
+
+uint16 mod0_value =0;
 
 // create a delay buffer in memory
-#define SIZE 800 // buffer size is limited by microcontroller SRAM size
-int delaymem[SIZE]; // 800 positions x 2 bytes = 1600 bytes of SRAM
-unsigned int location = 0; // buffer location to read/write from
-unsigned int boundary = SIZE;
+#define SIZE 1600 // buffer size is limited by microcontroller SRAM size
+int16 delaymem[SIZE]; // 800 positions x 2 bytes = 1600 bytes of SRAM
+uint16 location = 0; // buffer location to read/write from
+uint16 boundary = SIZE; 
 
-void setup() {
-  
+
+void seed_delayline()
+{
   for (int i = 0; i < SIZE; i++) {
     delaymem[i] = random(65535);
   }
-  
+
+}
+
+void setup() {
+  SerialUSB.end();  
+  seed_delayline();
   AudioCodec_init(); // setup codec registers
   // call this last if setting up other parts
 }
 }
 
 // timer1 interrupt routine - all data processed here
-ISR(TIMER1_COMPA_vect, ISR_NAKED) { // dont store any registers
+// ISR(TIMER1_COMPA_vect, ISR_NAKED) { // dont store any registers
+void AudioCodec_interrupt()
+{
 
   // &'s are necessary on data_in variables
   AudioCodec_data(&left_in, &right_in, left_out, right_out);
   
-   // & is required before adc variable
+  // & is required before adc variable
   AudioCodec_ADC(&mod0_value);
   
   if (decay++ < DECAY) {
     curr_value = delaymem[location];
     left_out = (last_value>>1) + (curr_value>>1);
     last_value = curr_value;
-    }
+  }
   else {
     for (int i = 0; i < SIZE; i++) {
       delaymem[i] = random(65535);
     decay = 0;
     
     unsigned int scale = SIZE;
-    MultiU16X16toH16(boundary, mod0_value, scale);
+
+    // I suspect this is originally from Arduino specialized 16bit x 16bit multiplication
+    // which returns a 16 bit number
+    // MultiU16X16toH16(boundary, mod0_value, scale);
+    boundary = (mod0_value * scale) >> 16;
   }
   // dont forget to return from interrupt
   // may not need this on maple