ELEC2645 (2015/16) / Mbed 2 deprecated Main_code_ver18

Dependencies:   FATFileSystem N5110_mod SDFileSystem USBDevice mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }