Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FATFileSystem N5110_mod SDFileSystem USBDevice mbed
main.cpp
00001 # include "main.h" 00002 int main() 00003 { 00004 init(); /// calls initialisation routine 00005 while(1) { 00006 if(USB_mode == 2) { /// prints display output for speaker mode 00007 lcd.clear(); 00008 lcd.printString("USB audio",0,2); 00009 lcd.printString("to exit,",0,3); 00010 lcd.printString("press back",0,4); 00011 } 00012 while(USB_mode == 2) { ///loop for while within speaker mode 00013 audio->read((uint8_t *)USBaudio_buffer); ///reads audio stream 00014 USBaudio_packet_available = true; ///sets flag to indicate presence of data 00015 if(buttons.back) { ///withdraw from speaker mode 00016 USB_mode = 3; ///set USB mode to none 00017 audio_tkr.detach(); ///detatch audio ticker 00018 LED_scan_tkr.attach(&LED_scan_ISR,0.005); ///re-attach tickers 00019 Sequence_increment_tkr.attach(&Sequence_increment_ISR,30/tempo); 00020 buttons.back = 0; ///re-set back button flag 00021 USB_init(); ///re-initialise USB 00022 lcd.clear(); ///set display to normal 00023 LCD_printMain(); 00024 } 00025 } 00026 check_flags(); ///check for button presses 00027 sleep(); ///return to sleep mode, to save power 00028 } 00029 } 00030 00031 /* General functions */ 00032 00033 void init() 00034 { 00035 LCD_init(); 00036 USB_init(); 00037 Button_init(); 00038 LED_init(); 00039 IO_init(); 00040 tempo_init(); 00041 Sequence_init(); 00042 } 00043 00044 void IO_init() 00045 { 00046 for (int i = 0; i < 7; i++) { 00047 trigOut[i]->write(1); /// test trigger outputs 00048 wait(0.1); 00049 trigOut[i]->write(0); 00050 } 00051 } 00052 00053 int bool_to_int (bool *array, int shifter) 00054 { 00055 switch(shifter) { 00056 case 0: /// 1:1 mapping 00057 return array[15]+(array[14]*0x2)+(array[13]*0x4)+(array[12]*0x8)+(array[11]*0x10)+(array[10]*0x20)+(array[9]*0x40)+(array[8]*0x80)+(array[7]*0x100)+(array[6]*0x200)+(array[5]*0x400)+(array[4]*0x800)+(array[3]*0x1000)+(array[2]*0x2000)+(array[1]*0x4000)+(array[0]*0x8000); 00058 case 1 : /// even mapping 00059 return (array[7]*0x2)+(array[6]*0x8)+(array[5]*0x20)+(array[4]*0x80)+(array[3]*0x200)+(array[2]*0x800)+(array[1]*0x2000)+(array[0]*0x8000); 00060 case 2: /// odd mapping 00061 return array[7]+(array[6]*0x4)+(array[5]*0x10)+(array[4]*0x40)+(array[3]*0x100)+(array[2]*0x400)+(array[1]*0x1000)+(array[0]*0x4000); 00062 } 00063 return; 00064 } 00065 00066 void selector (bool *flag, int *variable) 00067 { 00068 for(int i=0; i<8; i++) { /// scans through input button values 00069 if(buttons.steps[i]) { /// sets value if button is pressed 00070 *variable = i; 00071 buttons.steps[i] = 0; 00072 *flag = 0; 00073 lcd.clear(); ///set display to normal 00074 LCD_printMain(); 00075 } 00076 } 00077 } 00078 00079 void check_flags() 00080 { 00081 if(Seq_flag) Sequence_increment(); /// increments sequencer if flag is set 00082 if(decay_flag) { 00083 for(int i = 0; i<8; i++) { /// clears midi messages if decay flag is set 00084 if(USB_mode == 0) midi->write(MIDIMessage::NoteOff(Seq_array[Seq_current_seq].structure.MIDI_note[i])); 00085 } 00086 for(int i = 0; i<7; i++) { /// clears trigger outputs if decay flag is set 00087 trigOut[i]->write(0); 00088 } 00089 decay_tkr.detach(); /// detatches decay ticker 00090 decay_flag = 0; /// clears decay flag 00091 } 00092 if(ButtonFlag_press) { /// run if any input buttons are pressed 00093 /// prints button values over serial if available, for debugging 00094 if(USB_mode == 1) pc->printf("step_0:%d step_1:%d step_2:%d step_3:%d step_4:%d step_5:%d step_6:%d step_7:%d \n",buttons.steps[0],buttons.steps[1],buttons.steps[2],buttons.steps[3],buttons.steps[4],buttons.steps[5],buttons.steps[6],buttons.steps[7]); 00095 if(USB_mode == 1) pc->printf("start:%d skip:%d edit:%d pattern:%d inst:%d save:%d shift:%d load:%d back:%d down:%d enter:%d up:%d \n",buttons.start,buttons.skip,buttons.edit,buttons.pattern,buttons.inst,buttons.save,buttons.shift,buttons.load,buttons.back,buttons.down,buttons.enter,buttons.up); 00096 if(buttons.shift) shift_LED = !shift_LED; /// toggles shift LED 00097 buttons.shift = 0; /// clears shift button flag 00098 //if(buttons.up) buttons.up = 0; /// clears unused button flags 00099 //if(buttons.down) buttons.down = 0; 00100 if(buttons.back) buttons.back = 0; 00101 if(buttons.inst) { 00102 pattern_flag = 0; 00103 inst_flag = !inst_flag; /// toggles instrument selection, and updates LCD & serial 00104 if(inst_flag) { 00105 if(USB_mode == 1) pc->printf("instrument_select\n"); 00106 lcd.printString("select inst.",0,5); 00107 } else { 00108 lcd.clear(); 00109 LCD_printMain(); 00110 } 00111 buttons.inst = 0; 00112 } 00113 if(buttons.pattern) { /// toggles pattern selection, and updates LCD & serial 00114 inst_flag = 0; 00115 pattern_flag = !pattern_flag; 00116 if(pattern_flag) { 00117 if(USB_mode == 1) pc->printf("pattern_select\n"); 00118 lcd.printString("select patrn.",0,5); 00119 } else { 00120 lcd.clear(); 00121 LCD_printMain(); 00122 } 00123 buttons.pattern = 0; 00124 } 00125 if(inst_flag) selector (&inst_flag,&Seq_current_inst); /// selects current instrument if inst_flag is set 00126 else if(pattern_flag) selector (&pattern_flag,&Seq_current_seq); /// selects current pattern if pattern_flag is set 00127 else Sequence_write(); /// otherwise, updates sequence data 00128 LED_write((Seq_array[Seq_current_seq].structure.gate[Seq_current_inst])|(0x8000>>Seq_current_step)); ///writes sequence data & position indicator to matrix 00129 if(buttons.skip) { 00130 if(skip_flag == 0) { 00131 if(USB_mode == 1) pc->printf("skip...\n"); 00132 Seq_prev_inst = Seq_current_inst; /// stores current instrument, in order to return once skip setting is complete 00133 Seq_current_inst = 8; /// sets sequencer channel to skip channel 00134 } else { 00135 if(USB_mode == 1) pc->printf("Done skip\n"); 00136 Seq_current_inst = Seq_prev_inst; /// returns to previous instrument 00137 } 00138 buttons.skip = 0; 00139 skip_flag = !skip_flag; 00140 LED_write((Seq_array[Seq_current_seq].structure.gate[Seq_current_inst])|(0x8000>>Seq_current_step)); ///updates LED output 00141 lcd.clear(); ///re-draws display 00142 LCD_printMain(); 00143 } 00144 if(buttons.start) { ///toggles sequencer ticker 00145 running? Sequence_increment_tkr.detach() : Sequence_increment_tkr.attach(&Sequence_increment_ISR,30/tempo); 00146 lcd.printString(running? "Paused":" ",0,2); 00147 running = !running; 00148 if(running) Sequence_increment_ISR(); 00149 buttons.start = 0; 00150 } 00151 if(buttons.enter) { ///draws main menu 00152 buttons.enter = 0; 00153 mainMenu_draw(); 00154 } 00155 if(buttons.edit) { ///draws edit menu 00156 buttons.edit = 0; 00157 if(skip_flag == 0) editMenu_draw(); 00158 } 00159 if(buttons.load) { ///loads sequence from SD card 00160 load(); 00161 buttons.load = 0; 00162 } 00163 if(buttons.save) { ///saves sequence to SD card 00164 save(); 00165 buttons.save = 0; 00166 } 00167 ButtonFlag_press = 0; ///clears button press flag 00168 } 00169 if(tempo_flag) { ///runs tempo_set routine if button is pressed 00170 tempo_set(); 00171 tempo_flag = 0; 00172 } 00173 } 00174 void null() {} /// no function 00175 00176 void USB_init() /// initialises USB mode, dependent on USB_mode value 00177 { 00178 switch (USB_mode) { 00179 case 0: 00180 if(pc!=0) pc->disconnect(); /// disconnects serial, if connected 00181 if(audio!=0) audio->disconnect(); /// disconnects audio, if connected 00182 midi = new USBMIDI; /// connects midi 00183 break; 00184 case 1: 00185 if(midi!=0) midi->disconnect(); /// disconnects midi, if connected 00186 if(audio!=0) audio->disconnect(); /// disconnects audio, if connected 00187 pc = new USBSerial; /// connects serial 00188 break; 00189 case 2: 00190 if(pc!=0) pc->disconnect(); /// disconnects serial, if connected 00191 if(midi!=0) midi->disconnect(); /// disconnects midi, if connected 00192 audio = new USBAudio; /// connects audio 00193 Sequence_increment_tkr.detach(); /// detatches all tickers, to maximise efficiency 00194 LED_scan_tkr.detach(); 00195 audio_tkr.attach_us(audio_tkr_ISR, 1000000.0/(float)48000); 00196 break; 00197 case 3: 00198 if(pc!=0) pc->disconnect(); /// disconnects serial, if connected 00199 if(midi!=0) midi->disconnect(); /// disconnects midi, if connected 00200 break; 00201 } 00202 } 00203 void decay_ISR() /// sets decay flag if called by decay ticker 00204 { 00205 decay_flag = 1; 00206 } 00207 00208 /* Button functions */ 00209 void Button_init() /// initialises button matrix 00210 { 00211 Button_scan_tkr.attach(&Button_scan_ISR ,0.02); ///attaches button ticker 00212 ButtonIn_A.fall(&ButtonIn_A_ISR); ///connects button to ISR 00213 ButtonIn_A.mode(PullUp); ///sets pullup 00214 ButtonIn_B.fall(&ButtonIn_B_ISR ); 00215 ButtonIn_B.mode(PullUp); 00216 ButtonIn_C.fall(&ButtonIn_C_ISR ); 00217 ButtonIn_C.mode(PullUp); 00218 ButtonIn_D.fall(&ButtonIn_D_ISR ); 00219 ButtonIn_D.mode(PullUp); 00220 ButtonIn_E.fall(&ButtonIn_E_ISR ); 00221 ButtonIn_E.mode(PullUp); 00222 } 00223 void Button_scan_ISR () 00224 { 00225 if(ButtonFlag_zero == 0) ButtonFlag_cols[ButtonOut_pos] = 0; /// updates repeat flags 00226 ButtonFlag_zero = 0; 00227 ButtonOut_pos++; /// increments button scan position 00228 if(ButtonOut_pos>3) ButtonOut_pos = 0; /// limits scan range 00229 ButtonOut = ButtonOut_val[ButtonOut_pos]; /// writes to output 00230 } 00231 void ButtonIn_A_ISR() 00232 { 00233 Button_update (0); /// updates button flags 00234 } 00235 void ButtonIn_B_ISR () 00236 { 00237 Button_update (1); /// updates button flags 00238 } 00239 void ButtonIn_C_ISR () 00240 { 00241 Button_update (2); /// updates button flags 00242 } 00243 void ButtonIn_D_ISR () 00244 { 00245 Button_update (3); /// updates button flags 00246 } 00247 void ButtonIn_E_ISR () 00248 { 00249 Button_update (4); /// updates button flags 00250 } 00251 void Button_update (int row) 00252 { 00253 ButtonFlag_zero = 1; /// sets button flags 00254 ButtonFlag_press = 1; 00255 if(ButtonFlag_cols[ButtonOut_pos] == 0) { 00256 *(keyMap_point[row][ButtonOut_pos]) = 1; ///sets flag pointed to by position within matrix 00257 ButtonFlag_cols[ButtonOut_pos] = 1; 00258 } 00259 } 00260 00261 /* LED functions */ 00262 void LED_init() ///initialises LEDs 00263 { 00264 LED_scan_tkr.attach(&LED_scan_ISR,0.005); ///Setup matrix scan ticker 00265 int LED_test[] { ///output values for test 00266 0x0,0x180,0x3c0,0x7e0,0xff0,0x1ff8,0x3ffc,0x7ffe,0xFFFF,~0x180,~0x3c0,~0x7e0,~0xff0,~0x1ff8,~0x3ffc,~0x7ffe,0x0 00267 }; 00268 for(int j=0; j!=17; j++) { ///scan through output test values 00269 LED_write(LED_test[j]); 00270 wait(0.04); 00271 } 00272 shift_LED = 0; /// clear shift LED 00273 } 00274 void LED_scan_ISR() ///Scan ISR 00275 { 00276 LED_bus = LED_buffer[LED_pos]; ///Sends buffer value to bus output 00277 LED_pos++; ///Increment scan position 00278 if(LED_pos==4) LED_pos = 0; ///limit range 00279 } 00280 void LED_write(uint16_t value) ///Matrix refresh routine 00281 { 00282 uint8_t LED_scan_row = 0x1; 00283 uint16_t LED_loadBuffer = ((value<<4) | (value>>(16-4))); ///initialise LED_loadBuffer 00284 for(int i=0; i<4; i++) { ///Run loop 4 times 00285 LED_buffer[i] = (~LED_loadBuffer)&0xF0|(LED_scan_row)&0xf; ///write LED_loadBuffer nibble to FSM 00286 LED_scan_row=((LED_scan_row>>1) | (LED_scan_row<<(4-1))); ///Rotate row 00287 LED_loadBuffer=((LED_loadBuffer<<4) | (LED_loadBuffer>>(16-4))); ///rotate LED_loadBuffer 00288 }; 00289 } 00290 00291 /* LCD functions */ 00292 void LCD_init() /// initialise LCD 00293 { 00294 lcd.init(); 00295 LCD_set(); 00296 lcd.refresh(); 00297 lcd.printString("Drumulator",1,1); /// display bootscreen 00298 lcd.printString("Ver 2.5PI",25,3); 00299 wait(1); 00300 lcd.clear(); 00301 LCD_printMain(); 00302 } 00303 void LCD_set() 00304 { 00305 lcd.setPwmFreq(PWM_freq); /// set PWM frequency (new function added to library) 00306 lcd.setBrightness(brightness); /// set brightness (new function added to library) 00307 } 00308 void LCD_printMain() 00309 { 00310 lcd.drawRect(0,0,84,16,2); /// clear upper section of the screen 00311 char buffer[14]; /// set up buffer for variable printing 00312 int length = sprintf(buffer,"%d bpm",int(tempo)); /// print tempo 00313 if (length <= 14) { 00314 lcd.printString(buffer,0,0); 00315 } 00316 length = sprintf(buffer,"Seq_%d",int(Seq_current_seq)); /// print sequence position 00317 if (length <= 14) { 00318 lcd.printString(buffer,55,0); 00319 } 00320 lcd.printString(inst_names[Seq_current_inst],55,1); /// print current instrument 00321 length = sprintf(buffer,"Stp %d",(Seq_current_step/2)+1); /// print current step 00322 if (length <= 14) { 00323 lcd.printString(buffer,0,1); 00324 } 00325 } 00326 00327 /* Sequencer functions */ 00328 void Sequence_init() /// initialise sequencer 00329 { 00330 Sequence_increment_tkr.attach(&Sequence_increment_ISR,30/tempo); 00331 } 00332 void Sequence_increment_ISR() ///Increment sequencer position 00333 { 00334 Seq_current_step++; 00335 Seq_flag = 1; 00336 } 00337 void Sequence_increment() /// output sequence data 00338 { 00339 if(Seq_current_step>15) Seq_current_step = 0; 00340 LED_write((Seq_array[Seq_current_seq].structure.gate[Seq_current_inst])|(0x8000>>Seq_current_step)); /// update LED matrix 00341 while((Seq_array[Seq_current_seq].structure.gate[8]&(0x8000>>(Seq_current_step==15? 0 : Seq_current_step+1)) )!=0) { 00342 Seq_current_step++; 00343 if(Seq_current_step>15) Seq_current_step = 0; 00344 } 00345 for(int i = 0; i<8; i++) { 00346 if((Seq_array[Seq_current_seq].structure.gate[i]&(0x8000>>Seq_current_step) )!=0) { 00347 switch (Seq_array[Seq_current_seq].structure.Output_type[i]) { /// update outputs 00348 case 0: /// midi output 00349 if(USB_mode == 0) midi->write(MIDIMessage::NoteOn(int(Seq_array[Seq_current_seq].structure.MIDI_note[i]))); 00350 decay_tkr.attach(&decay_ISR,0.1); 00351 break; 00352 case 1: /// audio output 00353 audio_pos[i] = 0; 00354 audio_flag[i] = 1; 00355 if(USB_mode == 1) pc->printf("audio_flag %d = %d\n",i,audio_flag[i]); 00356 break; 00357 case 2: /// trigger output 00358 trigOut[int(Seq_array[Seq_current_seq].structure.Trig_chan[i])]->write(1); 00359 decay_tkr.attach(&decay_ISR,0.1); 00360 break; 00361 case 3: /// no output 00362 break; 00363 }; 00364 } 00365 } 00366 char buffer[14]; 00367 int length = sprintf(buffer,"Stp %d",(Seq_current_step/2)+1); /// update step position display 00368 if (length <= 14) { 00369 lcd.printString(buffer,0,1); 00370 } 00371 if(tempo_update_flag) { /// set tempo 00372 Sequence_increment_tkr.detach(); ///detach increment ticker 00373 Sequence_increment_tkr.attach(&Sequence_increment_ISR,30/tempo); 00374 tempo_update_flag = 0; 00375 } 00376 Seq_flag = 0; 00377 } 00378 void Sequence_write() /// write button value to gate channel 00379 { 00380 Seq_array[Seq_current_seq].structure.gate[Seq_current_inst] = Seq_array[Seq_current_seq].structure.gate[Seq_current_inst]^bool_to_int (buttons.steps,(shift_LED+1)); 00381 for(int i = 0; i!=8; i++) { 00382 buttons.steps[i] = 0; 00383 } 00384 } 00385 00386 /* Tap tempo functions */ 00387 void tempo_init() /// initialise tap tempo 00388 { 00389 tempo_tapIn.rise(&tempo_ISR); /// attach tap input to ISR 00390 tempo_time.start(); /// start timer 00391 } 00392 void tempo_ISR() //Tap tempo ISR 00393 { 00394 tempo_flag = 1; 00395 } 00396 void tempo_set() 00397 { 00398 if(USB_mode == 1) pc->printf("tapped..."); 00399 if(tempo_time.read()>(8*(tempo_timerState+1))) tempo_timerState = 0; 00400 switch(tempo_timerState) { 00401 case 0: ///First press (timer start) 00402 if(tempo_time.read()>DEBOUNCE) { /// to prevent false triggers 00403 if(USB_mode == 1) pc->printf("first tap\n"); 00404 tempo_time.stop(); /// reset and restart timer 00405 tempo_time.reset(); 00406 tempo_time.start(); 00407 tempo_timerState++; /// Increment state variable 00408 if(USB_mode == 1) pc->printf("tap tempo started!\n"); 00409 lcd.printString("Set tempo.",0,5); 00410 } 00411 break; 00412 case 1: ///Second press (count) 00413 if(tempo_time.read()>DEBOUNCE) { /// to prevent false triggers 00414 tempo_timerState++; ///Increment state variable 00415 if(USB_mode == 1) pc->printf("second tap\n"); 00416 tempo_debounce = tempo_time.read(); 00417 lcd.printString(".",59,5); 00418 } 00419 break; 00420 case 2: ///Third press (count) 00421 if((tempo_time.read()-tempo_debounce)>DEBOUNCE) { /// to prevent false triggers 00422 tempo_timerState++; ///Increment state variable 00423 if(USB_mode == 1) pc->printf("third tap\n"); 00424 tempo_debounce = tempo_time.read(); 00425 lcd.printString(".",64,5); 00426 } 00427 break; 00428 case 3: ///Fourth press (Stop timer & set tempo) 00429 if((tempo_time.read()-tempo_debounce)>DEBOUNCE) { /// to prevent false triggers 00430 tempo_time.stop(); ///Stop timer 00431 if(USB_mode == 1) pc->printf("timer stopped..."); 00432 tempo = (180/tempo_time.read()); 00433 tempo_update(); /// update tempo 00434 Seq_current_step = 15; 00435 LCD_printMain(); 00436 if(USB_mode == 1) pc->printf("tempo updated!\n"); 00437 tempo_time.reset(); 00438 tempo_time.start(); ///reset tempo timer 00439 tempo_timerState = 0; ///Reset state variable 00440 tempo_debounce = 0; 00441 lcd.clear(); 00442 LCD_printMain(); 00443 } 00444 } 00445 } 00446 void tempo_update() /// set update flag 00447 { 00448 if(USB_mode == 1) pc->printf("tempo set..."); 00449 tempo_update_flag = 1; 00450 } 00451 00452 /* Menu functions */ 00453 void mainMenu_draw() 00454 { 00455 switch(drawMenu(mainMenu)) { /// draw main menu 00456 case 0: 00457 drawVariable ("Tempo",&tempo,5,500,1,&tempo_update); ///set tempo 00458 break; 00459 case 1: 00460 switch(drawMenu(displayMenu)) { /// draw display menu 00461 case 0: 00462 drawVariable ("Brightness", &brightness,0.05,1,0,&LCD_set); /// set brightness 00463 break; 00464 case 1: 00465 drawVariable ("PWM frequency", &PWM_freq,10,600,0,&LCD_set); /// set PWM frequency 00466 break; 00467 case 2: 00468 inverse=!inverse; /// toggle screen inversion 00469 if(inverse) { 00470 lcd.inverseMode(); /// inverted display 00471 } else { 00472 lcd.normalMode(); /// normal display 00473 } 00474 lcd.clear(); /// reset display 00475 LCD_printMain(); 00476 break; 00477 case 3: 00478 mainMenu_draw(); /// return to main menu when back button is pressed 00479 }; 00480 break; 00481 case 2: 00482 USB_mode = drawMenu(usbMenu); /// select USB mode 00483 USB_init(); 00484 break; 00485 case 3: 00486 break; 00487 } 00488 lcd.clear(); /// reset display 00489 LCD_printMain(); 00490 } 00491 void editMenu_draw() 00492 { 00493 switch (drawMenu(editMenu)) { /// draw editmenu 00494 case 0: /// set output type 00495 Seq_array[Seq_current_seq].structure.Output_type[Seq_current_inst] = drawMenu(outputMenu); 00496 break; 00497 case 1: /// set note value 00498 drawVariable ("Note Value",&Seq_array[Seq_current_seq].structure.MIDI_note[Seq_current_inst],1,127,0,&null); 00499 break; 00500 case 2: /// set trigger channel 00501 drawVariable ("trig chan",&Seq_array[Seq_current_seq].structure.Trig_chan[Seq_current_inst],1,6,0,&null); 00502 break; 00503 case 3: 00504 Audio_init(); /// call wave file load procedure 00505 break; 00506 case 4: 00507 break; 00508 } 00509 lcd.clear(); /// reset screen 00510 LCD_printMain(); 00511 } 00512 int drawMenu(const char* array[]) ///draws single level menu on screen 00513 { 00514 int size=0; 00515 int pos_s=0; 00516 bool data=true; 00517 int menuPos=0; 00518 while(data==true) { /// checks size of array 00519 size++; 00520 if(array[pos_s]==0) { 00521 size--; 00522 data = false; 00523 } 00524 pos_s++; 00525 } 00526 lcd.clear(); /// reset display 00527 LCD_printMain(); 00528 for (int pos=0; pos<size; pos++) { ///loops through menu entries 00529 lcd.printString(array[pos],0,pos+2); ///plots menu entries 00530 } 00531 while(1) { /// scans input flags 00532 if(buttons.up) { 00533 lcd.printString(" ",79,menuPos+2); /// clears menu indicator 00534 (menuPos==0)? menuPos = size-1 : menuPos--; /// increments menu position 00535 if(USB_mode == 1) pc->printf("menuPos %d\n",menuPos); 00536 buttons.up = 0; 00537 } 00538 if(buttons.down) { 00539 lcd.printString(" ",79,menuPos+2); /// clears menu indicator 00540 (menuPos==size-1)? menuPos = 0 : menuPos++; /// decrements menu position 00541 if(USB_mode == 1) pc->printf("menuPos %d\n",menuPos); 00542 buttons.down = 0; 00543 } 00544 lcd.printString("<",79,menuPos+2); /// draw menu indicator 00545 if(buttons.enter|buttons.back) { /// return 00546 buttons.enter = 0; 00547 buttons.back = 0; 00548 lcd.clear(); 00549 LCD_printMain(); 00550 return menuPos; 00551 } 00552 check_flags(); 00553 sleep(); /// sleeps until output 00554 } 00555 } 00556 00557 void drawVariable (const char* variableName,float *variable, float step_size, float max, float min, void (*function)()) 00558 { 00559 char numberbuffer[14]; 00560 lcd.clear(); 00561 LCD_printMain(); 00562 while(1) { 00563 lcd.printString(variableName,0,3); /// print variable name 00564 if(buttons.up) { /// increment variable 00565 *variable=*variable+step_size; 00566 buttons.up = 0; 00567 } 00568 if(buttons.down) { /// decrement variable 00569 *variable=*variable-step_size; 00570 buttons.down = 0; 00571 } 00572 if (*variable>max) *variable = max; /// limit range 00573 if (*variable<min) *variable = min; 00574 int length = sprintf(numberbuffer,((*variable<0.1)&&(*variable>-0.1))? ((*variable<0)?"-%d.0%d":"%d.0%d"):((*variable<0)?"-%d.%d":"%d.%d"),abs(int(*variable)),abs(int(*variable*100-(int(*variable)*100)))); 00575 if (length <= 14) { /// print variable 00576 lcd.printString(" ",0,4); 00577 lcd.printString(numberbuffer,2,4); 00578 } 00579 if(buttons.enter|buttons.back) { /// return 00580 buttons.enter = 0; 00581 buttons.back = 0; 00582 lcd.clear(); 00583 LCD_printMain(); 00584 return; 00585 } 00586 (*function)(); 00587 check_flags(); 00588 sleep(); 00589 } 00590 } 00591 00592 /* File Functions */ 00593 00594 void save() 00595 { 00596 lcd.clear(); /// reset display 00597 LCD_printMain(); 00598 lcd.printString("saving...",0,5); 00599 if(USB_mode == 1) pc->printf("saving sequence...\n"); 00600 Seq_array[Seq_current_seq].sequence = new char [sizeof(Seq_array[Seq_current_seq].structure)]; 00601 std::ofstream outfile ("/sd/sequence.mdrum",std::ofstream::binary); /// create file stream 00602 outfile.seekp(0); /// set file position to zero 00603 if(USB_mode == 1) pc->printf("sequence = %d\n",Seq_array[Seq_current_seq].sequence); /// output file data for debugging 00604 outfile.write(Seq_array[Seq_current_seq].sequence,sizeof(Seq_array[Seq_current_seq].sequence)); /// write data to filestream 00605 outfile.close(); /// close file 00606 if(USB_mode == 1) pc->printf("file closed\n"); 00607 lcd.clear(); /// reset display 00608 LCD_printMain(); 00609 buttons.save = 0; 00610 } 00611 00612 void load() 00613 { 00614 lcd.clear(); /// reset display 00615 LCD_printMain(); 00616 lcd.printString("loading...",0,5); 00617 if(USB_mode == 1) pc->printf("saving sequence...\n"); 00618 Seq_array[Seq_current_seq].sequence = new char [sizeof(Seq_array[Seq_current_seq].structure)]; 00619 std::ifstream infile ("/sd/sequence.mdrum",std::ifstream::binary); /// setup filestream 00620 infile.seekg(0); /// set to start of file 00621 infile.read(Seq_array[Seq_current_seq].sequence,sizeof(Seq_array[Seq_current_seq].sequence)); /// read file 00622 infile.close(); /// close file 00623 if(USB_mode == 1) pc->printf("file closed\n"); 00624 lcd.clear(); /// reset display 00625 LCD_printMain(); 00626 buttons.load = 0; 00627 } 00628 00629 /* USB audio functions */ 00630 void audio_tkr_ISR() /// ticker to update USB audio output 00631 { 00632 float speaker_value; /// speaker value 00633 if (USBaudio_packet_available) { /// checks if packet is available 00634 speaker_value = (float)(USBaudio_buffer[USBaudio_index_buffer]); /// converts value to float 00635 speaker_value = speaker_value + 32768.0; /// ofsets speaker value 00636 speaker_value *= audio->getVolume(); /// adjusts output level 00637 USBaudio_index_buffer++; /// increment buffer position 00638 if (USBaudio_index_buffer == 96/2) { /// checks if buffer is empty 00639 USBaudio_index_buffer = 0; 00640 USBaudio_packet_available = false; 00641 } 00642 } else { 00643 speaker_value = audio_prev_val; /// sets speaker value to previous available value 00644 } 00645 audio_prev_val = speaker_value; 00646 SOUND_OUT_1.write_u16((uint16_t)speaker_value); /// writes speaker value to analog output 00647 } 00648 00649 /* audio functions */ 00650 void Audio_init() 00651 { 00652 if(USB_mode == 1) pc->printf("Initialising Audio file\n"); 00653 audio_tkr.detach(); 00654 lcd.clear(); 00655 LCD_printMain(); 00656 lcd.printString("loading WAVs...",0,5); 00657 std::ifstream is (audioFile_map[Seq_current_inst], std::ifstream::binary); 00658 if(is) { /// checks if file is present 00659 if(USB_mode == 1) pc->printf("loading %s\n",audioFile_map[Seq_current_inst]); 00660 is.seekg (0, is.end); 00661 audio_length[Seq_current_inst] = is.tellg(); /// finds length of file 00662 audio_buffer[Seq_current_inst] = new char [(audio_length[Seq_current_inst])]; /// sets buffer size 00663 if(USB_mode == 1) pc->printf("length %d\n",audio_length[Seq_current_inst]); 00664 is.seekg (0, is.beg); 00665 is.read (audio_buffer[Seq_current_inst],audio_length[Seq_current_inst]); /// loads file into buffer 00666 is.close(); /// closes file 00667 } 00668 if(USB_mode == 1) pc->printf("WAVs loaded\n"); 00669 lcd.clear(); 00670 LCD_printMain(); 00671 if(USB_mode == 1){ 00672 for(int i=0;i<audio_length[Seq_current_inst];i++) 00673 { 00674 pc->printf("%d",audio_buffer[Seq_current_inst][i]); 00675 } 00676 } 00677 for(int i=0;i<audio_length[Seq_current_inst];i++) 00678 { 00679 SOUND_OUT_1 = float(int(audio_buffer[Seq_current_inst][i]))/255; 00680 wait(0.00002267573); 00681 } 00682 audio_tkr.attach(Audio_ISR,0.00002267573);/// attaches audio update ticker 00683 } 00684 void Audio_ISR(){ 00685 /*if(audio_pos[Seq_current_inst]<audio_length[Seq_current_inst]){ 00686 SOUND_OUT_1 = float(int(audio_buffer[Seq_current_inst][audio_pos[Seq_current_inst]]))/1800; 00687 audio_pos[Seq_current_inst]++; 00688 }else{ 00689 audio_pos[Seq_current_inst] = 0; 00690 }*/ 00691 float speaker_value; /// speaker value 00692 for(int i = 0; i<8; i++){ 00693 if(audio_flag[i]==1) audio_pos[i]++; 00694 if(audio_pos[i]>=audio_length[i]){ 00695 audio_pos[i] = 0; 00696 audio_flag[i] = 0; 00697 } 00698 } 00699 speaker_value = float(int(audio_buffer[0][audio_pos[0]])+int(audio_buffer[1][audio_pos[1]])+int(audio_buffer[2][audio_pos[2]])+int(audio_buffer[3][audio_pos[3]])+int(audio_buffer[4][audio_pos[4]])+int(audio_buffer[5][audio_pos[5]])+int(audio_buffer[6][audio_pos[6]])+int(audio_buffer[7][audio_pos[7]]))/1800; 00700 if(speaker_value==0){ 00701 speaker_value = audio_prev_val; 00702 }else{ 00703 SOUND_OUT_1 = speaker_value; 00704 audio_prev_val = speaker_value; 00705 } 00706 }
Generated on Tue Jul 12 2022 13:31:54 by
1.7.2