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

Committer:
djbottrill
Date:
Sun Nov 08 10:58:44 2015 +0000
Revision:
11:a27a71f7c149
Parent:
10:fa2dee836ceb
Child:
12:74b52900cddb
Moved synth triggering to the main loop from the Midi receive interrupt routine

Who changed what in which revision?

UserRevisionLine numberNew contents of line
djbottrill 0:4d06e0867376 1 /*
djbottrill 0:4d06e0867376 2 Program to drive organ magnets from a MIDI input
djbottrill 0:4d06e0867376 3 From Midi note 36 the notes are send to a 96 bit shift register organ magnet driver board based on 12 x TPIC6B595 shift registers
djbottrill 9:b0f110c02b1b 4 The program uses the DAC to generate 16 sampled audio channel outputs at up to 32Khz that mirror the solenoid outputs, but also run from
djbottrill 0:4d06e0867376 5 MIDI note 24 so the bottom 16' octave can be generated electronically if 16' pipes are not feasible.
djbottrill 0:4d06e0867376 6 In fact the sampled output could be tailored to fill in any missing note ranges,
djbottrill 0:4d06e0867376 7 Repeated pressing sw3 cycles through a number of display modes.
djbottrill 0:4d06e0867376 8 */
djbottrill 0:4d06e0867376 9 #include "mbed.h"
djbottrill 0:4d06e0867376 10
djbottrill 5:13a1e5e4494d 11 //#include "Rohrflute.h"
djbottrill 2:8b22402c0b0f 12 //#include "Dubbelflojt.h"
djbottrill 2:8b22402c0b0f 13 //#include "Principal.h"
djbottrill 9:b0f110c02b1b 14 //#include "Bourdon.h"
djbottrill 9:b0f110c02b1b 15 #include "Bourdon_32.h" //This is the best sample 32Khz
djbottrill 0:4d06e0867376 16
djbottrill 0:4d06e0867376 17 #include "USBMIDI.h"
djbottrill 0:4d06e0867376 18
djbottrill 0:4d06e0867376 19 #include "TextLCD.h"
djbottrill 0:4d06e0867376 20 //For Linksprite LCD Shield
djbottrill 0:4d06e0867376 21 //TextLCD lcd(PTC12, D9, D4, D5, D6, D7); // rs, e, d4-d7
djbottrill 0:4d06e0867376 22 //DigitalOut bl(D10);
djbottrill 0:4d06e0867376 23 //D8 is wrong on K64F definition it is actually PTC12 not PTA0
djbottrill 0:4d06e0867376 24
djbottrill 0:4d06e0867376 25 //For Midas 2x16 OLED Display
djbottrill 0:4d06e0867376 26 TextLCD lcd (D2, D3, D4, D5,D6, D7, TextLCD::LCD16x2, NC, NC, TextLCD::WS0010 ); // 4bit bus: RS, E, D4-D7, LCDType=LCD16x2, BL=NC, E2=NC, LCDTCtrl=WS0010
djbottrill 0:4d06e0867376 27
djbottrill 0:4d06e0867376 28 //Serial pc(USBTX, USBRX); // tx, rx
djbottrill 0:4d06e0867376 29
djbottrill 0:4d06e0867376 30 AnalogOut Aout(DAC0_OUT);
djbottrill 0:4d06e0867376 31
djbottrill 0:4d06e0867376 32 DigitalOut redled(LED1);
djbottrill 0:4d06e0867376 33 DigitalOut greenled(LED2);
djbottrill 0:4d06e0867376 34 DigitalOut blueled(LED3);
djbottrill 0:4d06e0867376 35
djbottrill 0:4d06e0867376 36 DigitalOut diag(D15);
djbottrill 0:4d06e0867376 37 DigitalOut diag2(D14);
djbottrill 0:4d06e0867376 38
djbottrill 0:4d06e0867376 39 DigitalIn sw1(PTC6);
djbottrill 0:4d06e0867376 40 DigitalIn sw3(PTA4);
djbottrill 0:4d06e0867376 41
djbottrill 0:4d06e0867376 42 //Wi-Fi connector J6 note pin 3 is incorrectly idenifed in the documentation as PTC12
djbottrill 9:b0f110c02b1b 43 //Connects the shift register solenoid driver board
djbottrill 0:4d06e0867376 44 DigitalOut SRCK(PTD7); //Shift Register clock
djbottrill 0:4d06e0867376 45 DigitalOut RCK(PTD5); //Shift Register latch
djbottrill 0:4d06e0867376 46 DigitalOut SER1(PTB20); //Shift Register serial data outout
djbottrill 0:4d06e0867376 47
djbottrill 0:4d06e0867376 48
djbottrill 9:b0f110c02b1b 49 Ticker output_ticker; //Ticker for sound generation
djbottrill 0:4d06e0867376 50
djbottrill 11:a27a71f7c149 51 unsigned char keybuf[128]= {};
djbottrill 11:a27a71f7c149 52 unsigned char oldkeybuf[128]= {};
djbottrill 0:4d06e0867376 53 int keystat[128]= {};
djbottrill 0:4d06e0867376 54 int keyidx=0; //Key index //Polyphony counter
djbottrill 0:4d06e0867376 55 int outidx=96; //Serial output index
djbottrill 0:4d06e0867376 56
djbottrill 0:4d06e0867376 57 int key=0;
djbottrill 0:4d06e0867376 58 int velocity=0;
djbottrill 0:4d06e0867376 59 int chan=0;
djbottrill 0:4d06e0867376 60 int onoff=0;
djbottrill 0:4d06e0867376 61
djbottrill 0:4d06e0867376 62 unsigned int audio_out; //Audio output value accumulator
djbottrill 0:4d06e0867376 63
djbottrill 0:4d06e0867376 64 //OLELD display bar graph characters
djbottrill 0:4d06e0867376 65 const char udc0[] = {0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00};
djbottrill 0:4d06e0867376 66 const char udc1[] = {0x15, 0x10, 0x10, 0x10, 0x10, 0x10, 0x15, 0x00};
djbottrill 0:4d06e0867376 67 const char udc2[] = {0x15, 0x04, 0x04, 0x04, 0x04, 0x04, 0x15, 0x00};
djbottrill 0:4d06e0867376 68 const char udc3[] = {0x15, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x00};
djbottrill 0:4d06e0867376 69 const char udc4[] = {0x15, 0x01, 0x01, 0x01, 0x01, 0x01, 0x15, 0x00};
djbottrill 0:4d06e0867376 70 const char udc5[] = {0x15, 0x11, 0x11, 0x11, 0x11, 0x11, 0x15, 0x00};
djbottrill 0:4d06e0867376 71 const char udc6[] = {0x15, 0x05, 0x05, 0x05, 0x05, 0x05, 0x15, 0x00};
djbottrill 0:4d06e0867376 72 const char udc7[] = {0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00};
djbottrill 0:4d06e0867376 73
djbottrill 0:4d06e0867376 74 //Variables for LCD/OLED display
djbottrill 0:4d06e0867376 75 unsigned long int lcd_stat=0;
djbottrill 0:4d06e0867376 76 unsigned long int lcd_stat_old=1;
djbottrill 0:4d06e0867376 77 char display[2][16]; //Display Buffer
djbottrill 0:4d06e0867376 78 char display_old[2][16]; //Old Display Buffer
djbottrill 0:4d06e0867376 79 int pos=0; //Display Position counter
djbottrill 0:4d06e0867376 80 int row=0;
djbottrill 0:4d06e0867376 81 int tval=0;
djbottrill 0:4d06e0867376 82 int keyidx_t=0;
djbottrill 0:4d06e0867376 83 int lcdmode=0; //LCD Display Mode
djbottrill 8:df5f305aab22 84 int x =0;
djbottrill 8:df5f305aab22 85 int x1=1;
djbottrill 9:b0f110c02b1b 86
djbottrill 0:4d06e0867376 87 int sw1_count=0; //Switch de-bounce counter
djbottrill 0:4d06e0867376 88 int sw1_old=0;
djbottrill 0:4d06e0867376 89 int sw1_phase=0;
djbottrill 0:4d06e0867376 90 int sw3_count=0; //Switch de-bounce counter
djbottrill 0:4d06e0867376 91 int sw3_old=0;
djbottrill 0:4d06e0867376 92 int sw3_phase=0;
djbottrill 0:4d06e0867376 93
djbottrill 0:4d06e0867376 94 //Sound generator variables
djbottrill 0:4d06e0867376 95 int tempidx=0;
djbottrill 0:4d06e0867376 96 int freqidx=45;
djbottrill 0:4d06e0867376 97 float synth[16];
djbottrill 0:4d06e0867376 98 float synthidx[16];
djbottrill 0:4d06e0867376 99 int synth_old[16];
djbottrill 0:4d06e0867376 100 int synthtab[16]= {};
djbottrill 0:4d06e0867376 101 int synthstat[16]= {};
djbottrill 4:9f63e68b548e 102 unsigned char synthoctave[16]= {};
djbottrill 4:9f63e68b548e 103 unsigned char synthnote[16]= {};
djbottrill 0:4d06e0867376 104 int noteidx=0;
djbottrill 0:4d06e0867376 105 int i;
djbottrill 0:4d06e0867376 106 int ii;
djbottrill 9:b0f110c02b1b 107 int cl;
djbottrill 0:4d06e0867376 108
djbottrill 0:4d06e0867376 109 /*
djbottrill 0:4d06e0867376 110 Ticker routine to calculate and output the audio signal.
djbottrill 0:4d06e0867376 111 As the DAC is 12 bit this allows for 16 concurrennt 8 bit samples running with no additional loss of precision.
djbottrill 0:4d06e0867376 112 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.
djbottrill 5:13a1e5e4494d 113 Sound Generation is in 4 states stored in synthstat:
djbottrill 0:4d06e0867376 114 0 = Synth Channel idle
djbottrill 0:4d06e0867376 115 1 = Attack / Sustain phase note running and looping if necessary
djbottrill 5:13a1e5e4494d 116 2 = Signal to start decay this may be delayed until the sound is paat the initial attack point typically 100-200 mS
djbottrill 0:4d06e0867376 117 3 = Sample is in the decay phase.
djbottrill 0:4d06e0867376 118
djbottrill 5:13a1e5e4494d 119 This routine also handles the Synchronous output to a 96 bit shift register Organ Pallet magnet driver board, one bit is sent per tick.
djbottrill 0:4d06e0867376 120 The data clock pulse is generated during the 16 channel synth scan and the final latch pulse is generated on the 96th Tick.
djbottrill 0:4d06e0867376 121 All 96 bits are clocked out in around 4.4mS.
djbottrill 0:4d06e0867376 122 */
djbottrill 0:4d06e0867376 123 void aout()
djbottrill 0:4d06e0867376 124 {
djbottrill 4:9f63e68b548e 125 diag=1; //Pulse DIAG Pin for Scoping purposes IE pin high
djbottrill 0:4d06e0867376 126 redled=0; //Pulse Red LED to indicate Ticker working
djbottrill 0:4d06e0867376 127 audio_out=0; //Clear Audio Accumulator
djbottrill 0:4d06e0867376 128
djbottrill 11:a27a71f7c149 129 // SER1=keybuf[outidx+12]; //Send bit serially
djbottrill 11:a27a71f7c149 130 if (keybuf[outidx+12]>0) {
djbottrill 11:a27a71f7c149 131 SER1=1;
djbottrill 11:a27a71f7c149 132 } else {
djbottrill 11:a27a71f7c149 133 SER1=0;
djbottrill 11:a27a71f7c149 134 }
djbottrill 11:a27a71f7c149 135
djbottrill 0:4d06e0867376 136
djbottrill 0:4d06e0867376 137 for (i =0; i<16; i++) { //Do 16 channels
djbottrill 4:9f63e68b548e 138 switch (synthstat[i]) {
djbottrill 4:9f63e68b548e 139 case 1: //Sustain phase
djbottrill 4:9f63e68b548e 140 if (synth[i]>sample_loop_end[synthoctave[i]]) { //Got to end of buffer?
djbottrill 4:9f63e68b548e 141 synth[i]=sample_loop_start[synthoctave[i]]; //Wrap around back to start
djbottrill 4:9f63e68b548e 142 }
djbottrill 4:9f63e68b548e 143 break;
djbottrill 5:13a1e5e4494d 144 case 2: //Note off demand state
djbottrill 0:4d06e0867376 145 if (synth[i]>=sample_attack[synthoctave[i]]) { //Delay decay phase if not past end of attack
djbottrill 0:4d06e0867376 146 //Check if the waveform is close to zero crossing this helps eliminate clicks looks for rising edge approaching 0x80
djbottrill 0:4d06e0867376 147 tempidx=synth[i];
djbottrill 5:13a1e5e4494d 148 if (sample[synthoctave[i]][tempidx]<128 & sample[synthoctave[i]][tempidx]>120) {
djbottrill 0:4d06e0867376 149 if (sample[synthoctave[i]][tempidx]>synth_old[i]) {
djbottrill 7:e1ea1623c6c2 150 synth[i]=sample_loop_off[synthoctave[i]]; //Jump to start of decay
djbottrill 7:e1ea1623c6c2 151 synthstat[i]=3; //Say note in decay
djbottrill 0:4d06e0867376 152 }
djbottrill 0:4d06e0867376 153 }
djbottrill 0:4d06e0867376 154 }
djbottrill 4:9f63e68b548e 155 break;
djbottrill 7:e1ea1623c6c2 156 case 3: //Check if decay has completed
djbottrill 8:df5f305aab22 157 if (synth[i]>=sample_len[synthoctave[i]]) { //End of decay?
djbottrill 8:df5f305aab22 158 synthstat[i]=0; //say channel free
djbottrill 8:df5f305aab22 159 synth[i]=0; //Set sample pointer to 0
djbottrill 8:df5f305aab22 160 synthidx[i]=0; //Set sample index to 0
djbottrill 8:df5f305aab22 161 synthtab[i]=255; //Set to invalid
djbottrill 7:e1ea1623c6c2 162 }
djbottrill 7:e1ea1623c6c2 163 break ;
djbottrill 0:4d06e0867376 164 }
djbottrill 4:9f63e68b548e 165
djbottrill 4:9f63e68b548e 166 //get sample and add to Audio Accumulator
djbottrill 8:df5f305aab22 167 synth_old[i]=sample[synthoctave[i]][(int)(synth[i])]; //Get and save old sample
djbottrill 0:4d06e0867376 168 audio_out=audio_out+synth_old[i]; //add sample to audio out accumulator
djbottrill 0:4d06e0867376 169 synth[i]=synth[i]+synthidx[i]; //Get next sample pointer
djbottrill 0:4d06e0867376 170
djbottrill 0:4d06e0867376 171
djbottrill 0:4d06e0867376 172 //Generate clock pulses to send data serially
djbottrill 4:9f63e68b548e 173 switch (i) {
djbottrill 4:9f63e68b548e 174 case 2:
djbottrill 4:9f63e68b548e 175 SRCK=1; //Generate serial output clock pulse
djbottrill 4:9f63e68b548e 176 break;
djbottrill 4:9f63e68b548e 177 case 5:
djbottrill 4:9f63e68b548e 178 SRCK=0;
djbottrill 4:9f63e68b548e 179 break;
djbottrill 4:9f63e68b548e 180 case 10:
djbottrill 4:9f63e68b548e 181 if (outidx==0) {
djbottrill 4:9f63e68b548e 182 RCK=1; //Generate latch strobe after 96 bits sent
djbottrill 4:9f63e68b548e 183 }
djbottrill 4:9f63e68b548e 184 break;
djbottrill 4:9f63e68b548e 185 case 15:
djbottrill 4:9f63e68b548e 186 if (outidx==0) {
djbottrill 4:9f63e68b548e 187 RCK=0; //Generate latch strobe after 96 bits sent
djbottrill 4:9f63e68b548e 188 outidx=96;
djbottrill 4:9f63e68b548e 189 }
djbottrill 4:9f63e68b548e 190 break;
djbottrill 0:4d06e0867376 191 }
djbottrill 4:9f63e68b548e 192
djbottrill 0:4d06e0867376 193 } //Next Note
djbottrill 0:4d06e0867376 194 outidx--; //Next serial data bit
djbottrill 0:4d06e0867376 195
djbottrill 8:df5f305aab22 196
djbottrill 0:4d06e0867376 197 //Output to DAC
djbottrill 0:4d06e0867376 198 Aout.write_u16(audio_out*16);
djbottrill 7:e1ea1623c6c2 199
djbottrill 0:4d06e0867376 200 redled=1;
djbottrill 0:4d06e0867376 201 diag=0;
djbottrill 0:4d06e0867376 202 }
djbottrill 0:4d06e0867376 203
djbottrill 0:4d06e0867376 204 /*
djbottrill 0:4d06e0867376 205 Interrupt routine to receive MIDI on/off message and set LED status accordingly
djbottrill 0:4d06e0867376 206 MIDI note on/off events directly start/stop the synth channels and store the note status in keytab.
djbottrill 0:4d06e0867376 207 */
djbottrill 0:4d06e0867376 208 void get_message(MIDIMessage msg)
djbottrill 0:4d06e0867376 209 {
djbottrill 0:4d06e0867376 210 greenled=0; //Pulse Green LED to indicate MIDI activity
djbottrill 0:4d06e0867376 211 key=msg.key();
djbottrill 0:4d06e0867376 212 velocity=msg.velocity();
djbottrill 0:4d06e0867376 213 chan=msg.channel();
djbottrill 0:4d06e0867376 214 switch (msg.type()) {
djbottrill 0:4d06e0867376 215 case MIDIMessage::NoteOnType: //MIDI note on received
djbottrill 8:df5f305aab22 216 if (key>23 & key<120) {
djbottrill 0:4d06e0867376 217 onoff=1;
djbottrill 0:4d06e0867376 218 keybuf[(key-24)]=1; //Store in keybuf, except for notes 24-35
djbottrill 0:4d06e0867376 219 }
djbottrill 6:073e10217962 220
djbottrill 0:4d06e0867376 221 break;
djbottrill 0:4d06e0867376 222
djbottrill 0:4d06e0867376 223 //Process keys off
djbottrill 0:4d06e0867376 224 case MIDIMessage::NoteOffType: //Midi note off received
djbottrill 0:4d06e0867376 225 if (key>23) {
djbottrill 0:4d06e0867376 226 onoff=0;
djbottrill 0:4d06e0867376 227 keybuf[(key-24)]=0; //Update keybuf
djbottrill 0:4d06e0867376 228 }
djbottrill 0:4d06e0867376 229 break;
djbottrill 0:4d06e0867376 230
djbottrill 0:4d06e0867376 231 //Process all notes off command
djbottrill 0:4d06e0867376 232 case MIDIMessage::AllNotesOffType: //Midi all notes off
djbottrill 11:a27a71f7c149 233 for (int it=0; it<108; it++) {
djbottrill 11:a27a71f7c149 234 keybuf[it]=0; //Clear Keybuf
djbottrill 0:4d06e0867376 235 }
djbottrill 0:4d06e0867376 236 break;
djbottrill 4:9f63e68b548e 237
djbottrill 0:4d06e0867376 238 //Any other MIDI Commands just ignore
djbottrill 0:4d06e0867376 239 default:
djbottrill 0:4d06e0867376 240 break;
djbottrill 0:4d06e0867376 241 }
djbottrill 0:4d06e0867376 242 greenled=1;
djbottrill 0:4d06e0867376 243 }
djbottrill 0:4d06e0867376 244
djbottrill 0:4d06e0867376 245
djbottrill 0:4d06e0867376 246 int main()
djbottrill 0:4d06e0867376 247 {
djbottrill 0:4d06e0867376 248 greenled=1;
djbottrill 0:4d06e0867376 249 redled=1;
djbottrill 0:4d06e0867376 250 blueled=1;
djbottrill 0:4d06e0867376 251 SRCK=0; //Serial Clock low
djbottrill 0:4d06e0867376 252 RCK=0; //Latch Clock low
djbottrill 0:4d06e0867376 253
djbottrill 0:4d06e0867376 254 sw1.mode(PullUp);
djbottrill 0:4d06e0867376 255 sw3.mode(PullUp);
djbottrill 0:4d06e0867376 256
djbottrill 0:4d06e0867376 257 output_ticker.attach(&aout, sample_rate); //Set Sample frequency
djbottrill 0:4d06e0867376 258
djbottrill 0:4d06e0867376 259 lcd.cls();
djbottrill 0:4d06e0867376 260 wait(0.1);
djbottrill 0:4d06e0867376 261 lcd.setCursor(TextLCD::CurOff_BlkOff);
djbottrill 0:4d06e0867376 262 lcd.cls();
djbottrill 0:4d06e0867376 263 lcd.printf("MIDI Pipe Organ Waiting for USB");
djbottrill 0:4d06e0867376 264
djbottrill 0:4d06e0867376 265 NVIC_SetPriority(USB0_IRQn, 99); //Reduce Interrupt priority of USB
djbottrill 0:4d06e0867376 266
djbottrill 0:4d06e0867376 267 USBMIDI midi; //Start up MIDI
djbottrill 0:4d06e0867376 268 midi.attach(get_message); //callback for MIDI messages received
djbottrill 0:4d06e0867376 269
djbottrill 0:4d06e0867376 270 lcd.cls();
djbottrill 0:4d06e0867376 271 lcd.printf("MIDI Pipe Organ");
djbottrill 0:4d06e0867376 272 wait(1);
djbottrill 0:4d06e0867376 273 lcd.cls();
djbottrill 0:4d06e0867376 274 lcd.printf("On Chan Note Vel");
djbottrill 0:4d06e0867376 275
djbottrill 0:4d06e0867376 276 key=0;
djbottrill 0:4d06e0867376 277 velocity=0;
djbottrill 0:4d06e0867376 278 chan=0;
djbottrill 0:4d06e0867376 279 onoff=0;
djbottrill 0:4d06e0867376 280
djbottrill 0:4d06e0867376 281 //Main Loop
djbottrill 0:4d06e0867376 282 while(1) {
djbottrill 0:4d06e0867376 283
djbottrill 11:a27a71f7c149 284 diag2=1;
djbottrill 11:a27a71f7c149 285 //Process notes off
djbottrill 11:a27a71f7c149 286 for (ii=0; ii<16; ii++) {
djbottrill 11:a27a71f7c149 287 if (synthstat[ii]==1 & keybuf[synthtab[ii]]==0) { //Note currently playing
djbottrill 11:a27a71f7c149 288 synthstat[ii]=2; //Set Start decay
djbottrill 11:a27a71f7c149 289 }
djbottrill 11:a27a71f7c149 290 }
djbottrill 11:a27a71f7c149 291 //Process keys on
djbottrill 11:a27a71f7c149 292 //Find a free note generator and start the note playing, if no slots available just ignore the note
djbottrill 11:a27a71f7c149 293 for (keyidx=0; keyidx<96; keyidx++) {
djbottrill 11:a27a71f7c149 294 if (keybuf[keyidx]>0 & oldkeybuf[keyidx]==0) { //Key is pressed
djbottrill 11:a27a71f7c149 295 ii=0;
djbottrill 11:a27a71f7c149 296 while (ii<16) { //Find available synth channel
djbottrill 11:a27a71f7c149 297 if (synthstat[ii]==0) { //Is synth channel free?
djbottrill 11:a27a71f7c149 298 synthtab[ii]=keyidx; //Store note value
djbottrill 11:a27a71f7c149 299 synthoctave[ii]=synthtab[ii]/12; //Store the octave
djbottrill 11:a27a71f7c149 300 synthnote[ii]= synthtab[ii]%12; //Note within the octave
djbottrill 11:a27a71f7c149 301 synthstat[ii]=1; //Set status to playing
djbottrill 11:a27a71f7c149 302 synthidx[ii]=freqtab[synthnote[ii]]; //Set the frequency
djbottrill 11:a27a71f7c149 303 ii=16; //exit loop
djbottrill 11:a27a71f7c149 304 } //Next Synth slot
djbottrill 11:a27a71f7c149 305 ii++;
djbottrill 11:a27a71f7c149 306 }
djbottrill 11:a27a71f7c149 307 }
djbottrill 11:a27a71f7c149 308 oldkeybuf[keyidx]=keybuf[keyidx];
djbottrill 11:a27a71f7c149 309 }
djbottrill 11:a27a71f7c149 310 diag2=0;
djbottrill 11:a27a71f7c149 311 wait_ms(1);
djbottrill 11:a27a71f7c149 312 /*
djbottrill 11:a27a71f7c149 313 Additional code to de-bounce the K64F onboard switches again using multiple loops to de-bounce; has 3 states:
djbottrill 11:a27a71f7c149 314 0 - Button not pressed
djbottrill 11:a27a71f7c149 315 1 - Button pressed waiting for de-bounce count of 10 loops
djbottrill 11:a27a71f7c149 316 2 - Button press stable, this status can be read as the de-bounced status indicating the button press is clean
djbottrill 11:a27a71f7c149 317 */
djbottrill 6:073e10217962 318 // De-bounce SW1
djbottrill 9:b0f110c02b1b 319 if (sw1_phase==0 & sw1==0) { //Button just been pressed
djbottrill 6:073e10217962 320 sw1_phase=1;
djbottrill 6:073e10217962 321 sw1_count=10;
djbottrill 6:073e10217962 322 }
djbottrill 9:b0f110c02b1b 323 if (sw1_phase==1 & sw1_count==0 & sw1==0) { //Button still pressed after de-bounce period
djbottrill 6:073e10217962 324 sw1_phase=2;
djbottrill 6:073e10217962 325 }
djbottrill 9:b0f110c02b1b 326 if (sw1_phase==2 & sw1==1) { //Button released
djbottrill 6:073e10217962 327 sw1_phase=0;
djbottrill 6:073e10217962 328 }
djbottrill 6:073e10217962 329 sw1_count--;
djbottrill 6:073e10217962 330 // De-bounce SW1
djbottrill 9:b0f110c02b1b 331 if (sw3_phase==0 & sw3==0) { //Button just been pressed
djbottrill 7:e1ea1623c6c2 332 sw3_phase=1;
djbottrill 7:e1ea1623c6c2 333 sw3_count=10;
djbottrill 7:e1ea1623c6c2 334 }
djbottrill 9:b0f110c02b1b 335 if (sw3_phase==1 & sw3_count==0 & sw3==0) { //Button still pressed after de-bounce period
djbottrill 7:e1ea1623c6c2 336 sw3_phase=2;
djbottrill 7:e1ea1623c6c2 337 }
djbottrill 6:073e10217962 338
djbottrill 9:b0f110c02b1b 339 if (sw3_phase==2 & sw3==1) { //Button released
djbottrill 7:e1ea1623c6c2 340 sw3_phase=0;
djbottrill 7:e1ea1623c6c2 341 }
djbottrill 7:e1ea1623c6c2 342 sw3_count--;
djbottrill 6:073e10217962 343
djbottrill 6:073e10217962 344
djbottrill 6:073e10217962 345
djbottrill 6:073e10217962 346
djbottrill 0:4d06e0867376 347 if (sw1_phase==2 | sw3_phase==2) {
djbottrill 0:4d06e0867376 348 blueled=0;
djbottrill 0:4d06e0867376 349 } else {
djbottrill 0:4d06e0867376 350 blueled=1;
djbottrill 0:4d06e0867376 351 }
djbottrill 0:4d06e0867376 352
djbottrill 0:4d06e0867376 353
djbottrill 9:b0f110c02b1b 354 //Button 1 will clear all playing notes
djbottrill 9:b0f110c02b1b 355 if (sw1_phase != sw1_old) {
djbottrill 9:b0f110c02b1b 356 if(sw1_phase==2) {
djbottrill 9:b0f110c02b1b 357 for (cl=0; cl<108; cl++) {
djbottrill 9:b0f110c02b1b 358 keybuf[cl]=0; //Clear Keybuf
djbottrill 11:a27a71f7c149 359 // if (cl<16) { //say channel free
djbottrill 11:a27a71f7c149 360 // synth[cl]=0; //Set sample pointer to 0
djbottrill 11:a27a71f7c149 361 // synthidx[cl]=0; //Set sample index to 0
djbottrill 11:a27a71f7c149 362 // synthtab[cl]=255; //Set to invalid
djbottrill 11:a27a71f7c149 363 // }
djbottrill 9:b0f110c02b1b 364 }
djbottrill 9:b0f110c02b1b 365 }
djbottrill 9:b0f110c02b1b 366 }
djbottrill 9:b0f110c02b1b 367
djbottrill 0:4d06e0867376 368 //Check for display mode button being presed
djbottrill 9:b0f110c02b1b 369 if (sw3_phase != sw3_old) { //Mode Switch pressed
djbottrill 0:4d06e0867376 370 if(sw3_phase==2) {
djbottrill 0:4d06e0867376 371 lcdmode++;
djbottrill 8:df5f305aab22 372 if (lcdmode>3) {
djbottrill 0:4d06e0867376 373 lcdmode=0;
djbottrill 0:4d06e0867376 374 }
djbottrill 0:4d06e0867376 375 lcd.cls();
djbottrill 0:4d06e0867376 376 if (lcdmode==0) {
djbottrill 0:4d06e0867376 377 lcd.printf("On Chan Note Vel");
djbottrill 0:4d06e0867376 378 }
djbottrill 0:4d06e0867376 379 if (lcdmode==1) {
djbottrill 0:4d06e0867376 380 //Initialise bar graph display
djbottrill 10:fa2dee836ceb 381 //Program user defined characters into OLED display for bar graph
djbottrill 10:fa2dee836ceb 382 lcd.setUDC(0, (char *) udc0);
djbottrill 10:fa2dee836ceb 383 lcd.setUDC(1, (char *) udc1);
djbottrill 10:fa2dee836ceb 384 lcd.setUDC(2, (char *) udc2);
djbottrill 10:fa2dee836ceb 385 lcd.setUDC(3, (char *) udc3);
djbottrill 10:fa2dee836ceb 386 lcd.setUDC(4, (char *) udc4);
djbottrill 10:fa2dee836ceb 387 lcd.setUDC(5, (char *) udc5);
djbottrill 10:fa2dee836ceb 388 lcd.setUDC(6, (char *) udc6);
djbottrill 10:fa2dee836ceb 389 lcd.setUDC(7, (char *) udc7);
djbottrill 0:4d06e0867376 390 for (row=0; row<2; row++) {
djbottrill 0:4d06e0867376 391 for (pos=0; pos<16; pos++) {
djbottrill 0:4d06e0867376 392 display[row][pos]=0;
djbottrill 0:4d06e0867376 393 display_old[row][pos]=1;
djbottrill 0:4d06e0867376 394 }
djbottrill 0:4d06e0867376 395 }
djbottrill 0:4d06e0867376 396 }
djbottrill 0:4d06e0867376 397 if (lcdmode==2) {
djbottrill 0:4d06e0867376 398 lcd.locate(0,1);
djbottrill 0:4d06e0867376 399 lcd.printf("0123456789ABCDEF");
djbottrill 0:4d06e0867376 400 }
djbottrill 8:df5f305aab22 401 if (lcdmode==3) {
djbottrill 8:df5f305aab22 402 lcd.cls();
djbottrill 8:df5f305aab22 403 lcd.locate(0,0);
djbottrill 8:df5f305aab22 404 lcd.printf("Utilisation:");
djbottrill 8:df5f305aab22 405 }
djbottrill 0:4d06e0867376 406 }
djbottrill 0:4d06e0867376 407 }
djbottrill 0:4d06e0867376 408 sw3_old=sw3_phase;
djbottrill 0:4d06e0867376 409
djbottrill 0:4d06e0867376 410
djbottrill 0:4d06e0867376 411
djbottrill 0:4d06e0867376 412 // OLED MIDI Status display
djbottrill 0:4d06e0867376 413 if (lcdmode==0) {
djbottrill 0:4d06e0867376 414 lcd_stat=key+(128*velocity)+(16384*chan)+(262144*onoff);
djbottrill 0:4d06e0867376 415 if (lcd_stat!=lcd_stat_old) {
djbottrill 0:4d06e0867376 416
djbottrill 0:4d06e0867376 417 lcd.locate(0,1);
djbottrill 0:4d06e0867376 418 lcd.printf("%1d %2d %3d %3d", onoff, chan, key, velocity);
djbottrill 0:4d06e0867376 419 lcd_stat_old=lcd_stat;
djbottrill 0:4d06e0867376 420 }
djbottrill 0:4d06e0867376 421 }
djbottrill 0:4d06e0867376 422
djbottrill 0:4d06e0867376 423 // OLED MIDI Bar Display
djbottrill 0:4d06e0867376 424 if (lcdmode==1) {
djbottrill 0:4d06e0867376 425 keyidx=0;
djbottrill 0:4d06e0867376 426 for (row=1; row>=0; row--) {
djbottrill 0:4d06e0867376 427 for (pos=0; pos<16; pos++) {
djbottrill 0:4d06e0867376 428 keyidx_t=keyidx*2;
djbottrill 0:4d06e0867376 429 if(keyidx_t>94) {
djbottrill 0:4d06e0867376 430 keyidx_t=keyidx_t-95;
djbottrill 0:4d06e0867376 431 }
djbottrill 0:4d06e0867376 432 tval=keybuf[keyidx_t];
djbottrill 0:4d06e0867376 433 keyidx++;
djbottrill 0:4d06e0867376 434 keyidx_t=keyidx*2;
djbottrill 0:4d06e0867376 435 if(keyidx_t>94) {
djbottrill 0:4d06e0867376 436 keyidx_t=keyidx_t-95;
djbottrill 0:4d06e0867376 437 }
djbottrill 0:4d06e0867376 438 tval=tval+(2*keybuf[keyidx_t]);
djbottrill 0:4d06e0867376 439 keyidx++;
djbottrill 0:4d06e0867376 440
djbottrill 0:4d06e0867376 441 keyidx_t=keyidx*2;
djbottrill 0:4d06e0867376 442 if(keyidx_t>94) {
djbottrill 0:4d06e0867376 443 keyidx_t=keyidx_t-95;
djbottrill 0:4d06e0867376 444 }
djbottrill 0:4d06e0867376 445 tval=tval+(4*keybuf[keyidx_t]);
djbottrill 0:4d06e0867376 446 keyidx++;
djbottrill 0:4d06e0867376 447 display[row][pos]=tval;
djbottrill 0:4d06e0867376 448
djbottrill 0:4d06e0867376 449 if(display[row][pos]!=display_old[row][pos]) {
djbottrill 0:4d06e0867376 450 lcd.locate(pos,row);
djbottrill 0:4d06e0867376 451 lcd.putc(display[row][pos]);
djbottrill 0:4d06e0867376 452 display_old[row][pos]=display[row][pos];
djbottrill 0:4d06e0867376 453 }
djbottrill 0:4d06e0867376 454 }
djbottrill 0:4d06e0867376 455 }
djbottrill 0:4d06e0867376 456 }
djbottrill 0:4d06e0867376 457
djbottrill 0:4d06e0867376 458 //Display status of the Synth channels
djbottrill 0:4d06e0867376 459 if (lcdmode==2) {
djbottrill 0:4d06e0867376 460 lcd.locate(0,0);
djbottrill 0:4d06e0867376 461 for (noteidx=0; noteidx<16; noteidx++) {
djbottrill 0:4d06e0867376 462 lcd.putc((synthstat[noteidx]+48));
djbottrill 0:4d06e0867376 463 }
djbottrill 0:4d06e0867376 464 }
djbottrill 4:9f63e68b548e 465
djbottrill 8:df5f305aab22 466 //Display utilisation bar graph
djbottrill 8:df5f305aab22 467 if (lcdmode==3) {
djbottrill 8:df5f305aab22 468 x=0;
djbottrill 8:df5f305aab22 469 for (noteidx=0; noteidx<16; noteidx++) {
djbottrill 8:df5f305aab22 470 if (synthstat[noteidx] >0) {
djbottrill 8:df5f305aab22 471 x++;
djbottrill 8:df5f305aab22 472 }
djbottrill 8:df5f305aab22 473 }
djbottrill 8:df5f305aab22 474 for (pos=0; pos<x; pos++) {
djbottrill 8:df5f305aab22 475 display[1][pos]=0xff;
djbottrill 8:df5f305aab22 476 }
djbottrill 8:df5f305aab22 477 while(pos<16) {
djbottrill 8:df5f305aab22 478 display[1][pos]=0x20;
djbottrill 8:df5f305aab22 479 pos++;
djbottrill 8:df5f305aab22 480 }
djbottrill 8:df5f305aab22 481 row=1;
djbottrill 8:df5f305aab22 482 for (pos=0; pos<16; pos++) {
djbottrill 8:df5f305aab22 483 if (x!=x1) {
djbottrill 8:df5f305aab22 484 lcd.locate(13,0);
djbottrill 8:df5f305aab22 485 lcd.printf("%2d", x);
djbottrill 8:df5f305aab22 486 x1=x;
djbottrill 8:df5f305aab22 487 }
djbottrill 8:df5f305aab22 488 if(display[row][pos]!=display_old[row][pos]) {
djbottrill 8:df5f305aab22 489 lcd.locate(pos,row);
djbottrill 8:df5f305aab22 490 lcd.putc(display[row][pos]);
djbottrill 8:df5f305aab22 491 display_old[row][pos]=display[row][pos];
djbottrill 8:df5f305aab22 492 }
djbottrill 8:df5f305aab22 493 }
djbottrill 8:df5f305aab22 494 }
djbottrill 8:df5f305aab22 495
djbottrill 8:df5f305aab22 496
djbottrill 8:df5f305aab22 497
djbottrill 0:4d06e0867376 498 } //End of main loop
djbottrill 0:4d06e0867376 499 } //End of program
djbottrill 0:4d06e0867376 500
djbottrill 0:4d06e0867376 501
djbottrill 0:4d06e0867376 502
djbottrill 0:4d06e0867376 503