USBMIDI sampled pipe organ uses real pipe organ samples to produce a realistic sound with 16 note polyphony. A serial output will drive external TPIC6A596 shift registers that could be used to drive pipe organ magnets (Solenoid valves)

Dependencies:   TextLCD USBDevice mbed

Revision:
17:7f27f4921305
Parent:
16:d2694fb530c3
Child:
18:472954b6b711
--- a/main.cpp	Thu Nov 12 21:54:14 2015 +0000
+++ b/main.cpp	Thu Nov 12 22:48:31 2015 +0000
@@ -8,13 +8,13 @@
 */
 #include "mbed.h"
 
-//#include "Rohrflute.h"
-//#include "Dubbelflojt.h"
-//#include "Principal.h"
-//#include "Bourdon.h"
-//#include "Bourdon_32.h"
-//#include "Bourdon_44.h"                                                                                 //This is the best sample 44.1Khz
-#include "Montre_44.h" 
+#include "Bourdon_44.h"                                                                                 //This is the best sample 44.1Khz
+#include "Montre_44.h"
+const float sample1_rate = 0.00002268;       //44.1KHz
+const float freqtab[] = {
+//For Organ Sample played at sample speed       
+1,  1.0596, 1.1227, 1.1893, 1.2599, 1.3348, 1.4144, 1.4985, 1.5872, 1.6819, 1.782,  1.888,  2   };  
+
 
 #include "USBMIDI.h"
 
@@ -103,6 +103,7 @@
 int oldstops=1;
 
 //Sound generator variables
+int sampleset=0;
 int tempidx=0;
 int freqidx=45;
 float synth[16];
@@ -137,42 +138,83 @@
 //    diag=1;                                                                                             //Pulse DIAG Pin for Scoping purposes IE pin high
 //    redled=0;                                                                                           //Pulse Red LED to indicate Ticker working
     audio_out=0;                                                                                        //Clear Audio Accumulator
-
-    for (i =0; i<16; i++) {                                                                             //Do 16 channels
-        switch (synthstat[i]) {
-            case 1:     //Sustain phase
-                if (synth[i]>sample_loop_end[synthoctave[i]]) {                                         //Got to end of buffer?
-                    synth[i]=sample_loop_start[synthoctave[i]];                                         //Wrap around back to start
-                }
-                break;
-            case 2:     //Note off demand state
-                if (synth[i]>=sample_attack[synthoctave[i]]) {                                          //Delay decay phase if not past end of attack
+    if (sampleset==0) {
+        for (i =0; i<16; i++) {                                                                             //Do 16 channels
+            switch (synthstat[i]) {
+                case 1:     //Sustain phase
+                    if (synth[i]>sample1_loop_end[synthoctave[i]]) {                                         //Got to end of buffer?
+                        synth[i]=sample1_loop_start[synthoctave[i]];                                         //Wrap around back to start
+                    }
+                    break;
+                case 2:     //Note off demand state
+                    if (synth[i]>=sample1_attack[synthoctave[i]]) {                                          //Delay decay phase if not past end of attack
 //Check if the waveform is close to zero crossing this helps eliminate clicks looks for rising edge approaching 0x80
-                    tempidx=synth[i];
-                    if (sample[synthoctave[i]][tempidx]<128 & sample[synthoctave[i]][tempidx]>120) {
-                        if (sample[synthoctave[i]][tempidx]>synth_old[i]) {
-                            synth[i]=sample_loop_off[synthoctave[i]];                                   //Jump to start of decay
-                            synthstat[i]=3;                                                             //Say note in decay
+                        tempidx=synth[i];
+                        if (sample1[synthoctave[i]][tempidx]<128 & sample1[synthoctave[i]][tempidx]>120) {
+                            if (sample1[synthoctave[i]][tempidx]>synth_old[i]) {
+                                synth[i]=sample1_loop_off[synthoctave[i]];                                   //Jump to start of decay
+                                synthstat[i]=3;                                                             //Say note in decay
+                            }
                         }
                     }
-                }
-                break;
-            case 3:    //Check if decay has completed
-                if (synth[i]>=sample_len[synthoctave[i]]) {                                             //End of decay?
-                    synthstat[i]=0;                                                                     //say channel free
-                    synth[i]=0;                                                                         //Set sample pointer to 0
-                    synthidx[i]=0;                                                                      //Set sample index to 0
-                    synthtab[i]=255;                                                                    //Set to invalid
-                }
-                break ;
-        }
+                    break;
+                case 3:    //Check if decay has completed
+                    if (synth[i]>=sample1_len[synthoctave[i]]) {                                             //End of decay?
+                        synthstat[i]=0;                                                                     //say channel free
+                        synth[i]=0;                                                                         //Set sample pointer to 0
+                        synthidx[i]=0;                                                                      //Set sample index to 0
+                        synthtab[i]=255;                                                                    //Set to invalid
+                    }
+                    break ;
+            }
 
 //get sample and add to Audio Accumulator
-        synth_old[i]=sample[synthoctave[i]][(int)(synth[i])];                                           //Get and save old sample
-        audio_out=audio_out+synth_old[i];                                                               //add sample to audio out accumulator
-        synth[i]=synth[i]+synthidx[i];                                                                  //Get next sample pointer
+            synth_old[i]=sample1[synthoctave[i]][(int)(synth[i])];                                           //Get and save old sample
+            audio_out=audio_out+synth_old[i];                                                               //add sample to audio out accumulator
+            synth[i]=synth[i]+synthidx[i];                                                                  //Get next sample pointer
+
+        }                                                                                                   //Next Note
+    } else {
+
+//Sample Set 2
 
-    }                                                                                                   //Next Note
+        for (i =0; i<16; i++) {                                                                             //Do 16 channels
+            switch (synthstat[i]) {
+                case 1:     //Sustain phase
+                    if (synth[i]>sample2_loop_end[synthoctave[i]]) {                                         //Got to end of buffer?
+                        synth[i]=sample2_loop_start[synthoctave[i]];                                         //Wrap around back to start
+                    }
+                    break;
+                case 2:     //Note off demand state
+                    if (synth[i]>=sample2_attack[synthoctave[i]]) {                                          //Delay decay phase if not past end of attack
+//Check if the waveform is close to zero crossing this helps eliminate clicks looks for rising edge approaching 0x80
+                        tempidx=synth[i];
+                        if (sample2[synthoctave[i]][tempidx]<128 & sample2[synthoctave[i]][tempidx]>120) {
+                            if (sample2[synthoctave[i]][tempidx]>synth_old[i]) {
+                                synth[i]=sample1_loop_off[synthoctave[i]];                                   //Jump to start of decay
+                                synthstat[i]=3;                                                             //Say note in decay
+                            }
+                        }
+                    }
+                    break;
+                case 3:    //Check if decay has completed
+                    if (synth[i]>=sample2_len[synthoctave[i]]) {                                             //End of decay?
+                        synthstat[i]=0;                                                                     //say channel free
+                        synth[i]=0;                                                                         //Set sample pointer to 0
+                        synthidx[i]=0;                                                                      //Set sample index to 0
+                        synthtab[i]=255;                                                                    //Set to invalid
+                    }
+                    break ;
+            }
+
+//get sample and add to Audio Accumulator
+            synth_old[i]=sample2[synthoctave[i]][(int)(synth[i])];                                           //Get and save old sample
+            audio_out=audio_out+synth_old[i];                                                               //add sample to audio out accumulator
+            synth[i]=synth[i]+synthidx[i];                                                                  //Get next sample pointer
+
+        }                                                                                                   //Next Note
+    }
+
 
 //Output to DAC
     Aout.write_u16(audio_out*16);
@@ -257,7 +299,7 @@
     p4.mode(PullUp);
     p5.mode(PullUp);
 
-    output_ticker.attach(&aout, sample_rate);                                                           //Set Sample frequency
+    output_ticker.attach(&aout, sample1_rate);                                                           //Set Sample frequency
 
     lcd.cls();
     wait(0.1);
@@ -395,9 +437,6 @@
         }
         sw3_count--;
 
-
-
-
         if (sw1_phase==2 | sw3_phase==2) {
             blueled=0;
         } else {
@@ -405,17 +444,23 @@
         }
 
 
-//Button 1 will clear all playing notes
+//Button 1 will clear all playing notes & switch sampleset
         if (sw1_phase != sw1_old) {
             if(sw1_phase==2) {
                 for (cl=0; cl<108; cl++) {
-                    keybuf[cl]=0;                                                                        //Clear Keybuf
+                    keybuf[cl]=0;                                                                       //Clear Keybuf
+                }
+                sampleset++;
+                oldstops=255;                                                                           //Force a display refresh
+                if (sampleset>1) {
+                    sampleset=0;
                 }
             }
         }
-
+        sw1_old=sw1_phase; 
+               
 //Check for display mode button being presed
-        if (sw3_phase != sw3_old) {                                                                      //Mode Switch pressed
+        if (sw3_phase != sw3_old) {                                                                     //Mode Switch pressed
             if(sw3_phase==2) {
                 lcdmode++;
                 if (lcdmode>4) {
@@ -560,13 +605,16 @@
 
             pos=stops[0] + stops[1]+stops[2]+stops[3]+stops[4];
             if (oldstops != pos) {
-            oldstops=pos;
+                oldstops=pos;
                 lcd.cls();
                 for (pos=0; pos<16; pos++) {
                     lcd.locate(pos,0);
-                    lcd.putc(stopname[pos]);
+                    if (sampleset==0) {
+                        lcd.putc(stopname1[pos]);
+                    } else {
+                        lcd.putc(stopname2[pos]);
+                    }
                 }
-
                 lcd.locate(0,1);
                 if (stops[0]==0) {
                     lcd.printf("16 ");