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
Diff: main.cpp
- 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 ");