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

Files at this revision

API Documentation at this revision

Comitter:
djbottrill
Date:
Fri Nov 20 23:01:29 2015 +0000
Parent:
29:acabf551aa0e
Commit message:
Further tidy up of comments

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Fri Nov 20 13:48:26 2015 +0000
+++ b/main.cpp	Fri Nov 20 23:01:29 2015 +0000
@@ -8,6 +8,7 @@
 Pressing sw1 switches between two sound samples Bourdon and Montre only one rank is availble at any one time.
 This program is currently only compatible with the K64F as it's one of the few MBED boards that has sufficient speed, Flash ROM storage 
 and of course a DAC.
+The sounds samples are derived from the Jeux D'Orgue 2 sample set http://www.jeuxdorgues.com and are used with permission.
 */
 #include "mbed.h"
 
@@ -68,7 +69,7 @@
 unsigned char oldkeybuf[128]= {};                                                                       //Last note buffer        
 int keyidx=0;                                                                                           //Key index
 
-//Recieved MIDI note variables
+//Received MIDI note variables
 int key=0;                                                                          
 int velocity=0;
 int chan=0;
@@ -129,17 +130,19 @@
 
 /*
 Ticker routine to calculate and output the audio signal.
-As the DAC is 12 bit this allows for 16 concurrennt 8 bit samples running with no additional loss of precision.
+As the DAC is 12 bit this allows for 16 concurrent 8 bit samples running with no additional loss of precision.
 The samples should be normalised to maximise the 8 bit range as only one sample is used there is no need to generate sounds with different amplitude.
 Sound Generation is in 4 states stored in synthstat:
 0 = Synth Channel idle
 1 = Attack / Sustain phase note running and looping if necessary
-2 = Signal to start release this may be delayed until the sound is paat the initial attack point typically 100-200 mS
+2 = Signal to start release this may be delayed until the sound is paat the initial attack/decay point typically 100-200 mS
 3 = Sample is in the release phase.
 
 */
 void aout()
 {
+//The lines below are commented out and actually add to much time to the ticker routine each command adds around  1 uS which is significant
+//when the whole routine only takes around 16uS and is repeated every 23mS    
 //    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
@@ -229,8 +232,16 @@
 }
 
 /*
-Interrupt routine to receive MIDI on/off message and set LED status accordingly
-MIDI note on/off events directly start/stop the synth channels and store the note status in keytab.
+Interrupt routine to receive MIDI on/off message
+MIDI note on/off events are stored in the note status buffer keytab.
+the lower 5 bits of keytab represent a note being on or off
+Bit 0 = 16'
+Bit 1 = 8'
+Bit 2 = 4'
+Bit 3 = 2 2/3' (12th)
+Bit 4 = 2' (15th)
+Thus if keytab >0 then the note should be played
+Currently MIDI note on/off messages are accepted on any channel
 */
 void get_message(MIDIMessage msg)
 {
@@ -319,7 +330,10 @@
     lcd.setCursor(TextLCD::CurOff_BlkOff);
     lcd.cls();
     lcd.printf("MIDI Pipe Organ Waiting for USB");
-
+/*
+I couldn't figure out which interrupt is used for the ticker so I lowered the USB interrupt priority so that it didn't
+interfere with the smooth operation of the sound generation ticker
+*/
     NVIC_SetPriority(USB0_IRQn, 99);                                                                    //Reduce Interrupt priority of USB
 
     USBMIDI midi;                                                                                       //Start up MIDI
@@ -330,7 +344,6 @@
     wait(1);
     lcd.cls();
     lcd.printf("On Chan Note Vel");
-
     key=0;
     velocity=0;
     chan=0;
@@ -341,9 +354,9 @@
 
 
 //Process notes off
-        for (ii=0; ii<16; ii++) {
-            if (synthstat[ii]==1 & keybuf[synthtab[ii]]==0) {                                           //Note currently playing
-                synthstat[ii]=2;                                                                        //Set Start decay
+        for (ii=0; ii<16; ii++) {                                                                       //Scan through 16 channels
+            if (synthstat[ii]==1 & keybuf[synthtab[ii]]==0) {                                           //Note currently playing but should be off
+                synthstat[ii]=2;                                                                        //Set Start release
             }
         }
 //Process keys on
@@ -388,12 +401,11 @@
             }
             if (sucess==1) {
                 oldkeybuf[keyidx]=keybuf[keyidx];                                                       //Store old value if note sucessfull
-            }
+            }                                                                                           //If not sucessfull try on the next scan    
         }
- //       wait_ms(1);
 
 
-//Output to Shift register
+//Output to Shift register pallet magnet driver board
         for (keyidx=107; keyidx>11; keyidx--) {
             if (keybuf[keyidx]>0) {
                 SER1=1;
@@ -419,13 +431,13 @@
         sw[4]=p5;
         sw[6]=sw1;
         sw[7]=sw3;
-
-//Additional code to de-bounce the K64F onboard and eterna switches using multiple loops to de-bounce; has 3 states:
-//0 - Button not pressed
-//1 - Button pressed waiting for de-bounce count of 5 loops
-//2 - Button press stable, this status can be read as the de-bounced status indicating the button press is clean
-
-// De-bounce Switches
+/*
+code to de-bounce the K64F onboard and external switches using multiple loops to de-bounce; has 3 states:
+0 - Button not pressed
+1 - Button pressed waiting for de-bounce count of 5 loops
+2 - Button press stable, this status can be read as the de-bounced status indicating the button press is clean
+sw_status is toggled by each sucessive key press 0 / 1
+*/
         pressed=0;
         for (swi=0; swi<8; swi++) {                                                                     //Process 8 push switches
             if (sw_phase[swi]==0 & sw[swi]==0) {                                                        //Button just been pressed