K64F drum machine, with RAW WAV sample playback, and USB midi functionality

Dependencies:   FATFileSystem N5110_mod SDFileSystem USBDevice mbed

Committer:
el14pjgn
Date:
Mon May 09 14:20:16 2016 +0000
Revision:
0:02a88f05d461
K64F drum machine, with sample playback and USB midi functionality

Who changed what in which revision?

UserRevisionLine numberNew contents of line
el14pjgn 0:02a88f05d461 1 # include "main.h"
el14pjgn 0:02a88f05d461 2 int main()
el14pjgn 0:02a88f05d461 3 {
el14pjgn 0:02a88f05d461 4 init(); /// calls initialisation routine
el14pjgn 0:02a88f05d461 5 while(1) {
el14pjgn 0:02a88f05d461 6 if(USB_mode == 2) { /// prints display output for speaker mode
el14pjgn 0:02a88f05d461 7 lcd.clear();
el14pjgn 0:02a88f05d461 8 lcd.printString("USB audio",0,2);
el14pjgn 0:02a88f05d461 9 lcd.printString("to exit,",0,3);
el14pjgn 0:02a88f05d461 10 lcd.printString("press back",0,4);
el14pjgn 0:02a88f05d461 11 }
el14pjgn 0:02a88f05d461 12 while(USB_mode == 2) { ///loop for while within speaker mode
el14pjgn 0:02a88f05d461 13 audio->read((uint8_t *)USBaudio_buffer); ///reads audio stream
el14pjgn 0:02a88f05d461 14 USBaudio_packet_available = true; ///sets flag to indicate presence of data
el14pjgn 0:02a88f05d461 15 if(buttons.back) { ///withdraw from speaker mode
el14pjgn 0:02a88f05d461 16 USB_mode = 3; ///set USB mode to none
el14pjgn 0:02a88f05d461 17 audio_tkr.detach(); ///detatch audio ticker
el14pjgn 0:02a88f05d461 18 LED_scan_tkr.attach(&LED_scan_ISR,0.005); ///re-attach tickers
el14pjgn 0:02a88f05d461 19 Sequence_increment_tkr.attach(&Sequence_increment_ISR,30/tempo);
el14pjgn 0:02a88f05d461 20 buttons.back = 0; ///re-set back button flag
el14pjgn 0:02a88f05d461 21 USB_init(); ///re-initialise USB
el14pjgn 0:02a88f05d461 22 lcd.clear(); ///set display to normal
el14pjgn 0:02a88f05d461 23 LCD_printMain();
el14pjgn 0:02a88f05d461 24 }
el14pjgn 0:02a88f05d461 25 }
el14pjgn 0:02a88f05d461 26 check_flags(); ///check for button presses
el14pjgn 0:02a88f05d461 27 sleep(); ///return to sleep mode, to save power
el14pjgn 0:02a88f05d461 28 }
el14pjgn 0:02a88f05d461 29 }
el14pjgn 0:02a88f05d461 30
el14pjgn 0:02a88f05d461 31 /* General functions */
el14pjgn 0:02a88f05d461 32
el14pjgn 0:02a88f05d461 33 void init()
el14pjgn 0:02a88f05d461 34 {
el14pjgn 0:02a88f05d461 35 LCD_init();
el14pjgn 0:02a88f05d461 36 USB_init();
el14pjgn 0:02a88f05d461 37 Button_init();
el14pjgn 0:02a88f05d461 38 LED_init();
el14pjgn 0:02a88f05d461 39 IO_init();
el14pjgn 0:02a88f05d461 40 tempo_init();
el14pjgn 0:02a88f05d461 41 Sequence_init();
el14pjgn 0:02a88f05d461 42 }
el14pjgn 0:02a88f05d461 43
el14pjgn 0:02a88f05d461 44 void IO_init()
el14pjgn 0:02a88f05d461 45 {
el14pjgn 0:02a88f05d461 46 for (int i = 0; i < 7; i++) {
el14pjgn 0:02a88f05d461 47 trigOut[i]->write(1); /// test trigger outputs
el14pjgn 0:02a88f05d461 48 wait(0.1);
el14pjgn 0:02a88f05d461 49 trigOut[i]->write(0);
el14pjgn 0:02a88f05d461 50 }
el14pjgn 0:02a88f05d461 51 }
el14pjgn 0:02a88f05d461 52
el14pjgn 0:02a88f05d461 53 int bool_to_int(bool *array, int shifter)
el14pjgn 0:02a88f05d461 54 {
el14pjgn 0:02a88f05d461 55 switch(shifter) {
el14pjgn 0:02a88f05d461 56 case 0: /// 1:1 mapping
el14pjgn 0:02a88f05d461 57 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);
el14pjgn 0:02a88f05d461 58 case 1 : /// even mapping
el14pjgn 0:02a88f05d461 59 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);
el14pjgn 0:02a88f05d461 60 case 2: /// odd mapping
el14pjgn 0:02a88f05d461 61 return array[7]+(array[6]*0x4)+(array[5]*0x10)+(array[4]*0x40)+(array[3]*0x100)+(array[2]*0x400)+(array[1]*0x1000)+(array[0]*0x4000);
el14pjgn 0:02a88f05d461 62 }
el14pjgn 0:02a88f05d461 63 return;
el14pjgn 0:02a88f05d461 64 }
el14pjgn 0:02a88f05d461 65
el14pjgn 0:02a88f05d461 66 void selector(bool *flag, int *variable)
el14pjgn 0:02a88f05d461 67 {
el14pjgn 0:02a88f05d461 68 for(int i=0; i<8; i++) { /// scans through input button values
el14pjgn 0:02a88f05d461 69 if(buttons.steps[i]) { /// sets value if button is pressed
el14pjgn 0:02a88f05d461 70 *variable = i;
el14pjgn 0:02a88f05d461 71 buttons.steps[i] = 0;
el14pjgn 0:02a88f05d461 72 *flag = 0;
el14pjgn 0:02a88f05d461 73 lcd.clear(); ///set display to normal
el14pjgn 0:02a88f05d461 74 LCD_printMain();
el14pjgn 0:02a88f05d461 75 }
el14pjgn 0:02a88f05d461 76 }
el14pjgn 0:02a88f05d461 77 }
el14pjgn 0:02a88f05d461 78
el14pjgn 0:02a88f05d461 79 void check_flags()
el14pjgn 0:02a88f05d461 80 {
el14pjgn 0:02a88f05d461 81 if(Seq_flag) Sequence_increment(); /// increments sequencer if flag is set
el14pjgn 0:02a88f05d461 82 if(decay_flag) {
el14pjgn 0:02a88f05d461 83 for(int i = 0; i<8; i++) { /// clears midi messages if decay flag is set
el14pjgn 0:02a88f05d461 84 if(USB_mode == 0) midi->write(MIDIMessage::NoteOff(Seq_array[Seq_current_seq].structure.MIDI_note[i]));
el14pjgn 0:02a88f05d461 85 }
el14pjgn 0:02a88f05d461 86 for(int i = 0; i<7; i++) { /// clears trigger outputs if decay flag is set
el14pjgn 0:02a88f05d461 87 trigOut[i]->write(0);
el14pjgn 0:02a88f05d461 88 }
el14pjgn 0:02a88f05d461 89 decay_tkr.detach(); /// detatches decay ticker
el14pjgn 0:02a88f05d461 90 decay_flag = 0; /// clears decay flag
el14pjgn 0:02a88f05d461 91 }
el14pjgn 0:02a88f05d461 92 if(ButtonFlag_press) { /// run if any input buttons are pressed
el14pjgn 0:02a88f05d461 93 /// prints button values over serial if available, for debugging
el14pjgn 0:02a88f05d461 94 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]);
el14pjgn 0:02a88f05d461 95 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);
el14pjgn 0:02a88f05d461 96 if(buttons.shift) shift_LED = !shift_LED; /// toggles shift LED
el14pjgn 0:02a88f05d461 97 buttons.shift = 0; /// clears shift button flag
el14pjgn 0:02a88f05d461 98 //if(buttons.up) buttons.up = 0; /// clears unused button flags
el14pjgn 0:02a88f05d461 99 //if(buttons.down) buttons.down = 0;
el14pjgn 0:02a88f05d461 100 if(buttons.back) buttons.back = 0;
el14pjgn 0:02a88f05d461 101 if(buttons.inst) {
el14pjgn 0:02a88f05d461 102 pattern_flag = 0;
el14pjgn 0:02a88f05d461 103 inst_flag = !inst_flag; /// toggles instrument selection, and updates LCD & serial
el14pjgn 0:02a88f05d461 104 if(inst_flag) {
el14pjgn 0:02a88f05d461 105 if(USB_mode == 1) pc->printf("instrument_select\n");
el14pjgn 0:02a88f05d461 106 lcd.printString("select inst.",0,5);
el14pjgn 0:02a88f05d461 107 } else {
el14pjgn 0:02a88f05d461 108 lcd.clear();
el14pjgn 0:02a88f05d461 109 LCD_printMain();
el14pjgn 0:02a88f05d461 110 }
el14pjgn 0:02a88f05d461 111 buttons.inst = 0;
el14pjgn 0:02a88f05d461 112 }
el14pjgn 0:02a88f05d461 113 if(buttons.pattern) { /// toggles pattern selection, and updates LCD & serial
el14pjgn 0:02a88f05d461 114 inst_flag = 0;
el14pjgn 0:02a88f05d461 115 pattern_flag = !pattern_flag;
el14pjgn 0:02a88f05d461 116 if(pattern_flag) {
el14pjgn 0:02a88f05d461 117 if(USB_mode == 1) pc->printf("pattern_select\n");
el14pjgn 0:02a88f05d461 118 lcd.printString("select patrn.",0,5);
el14pjgn 0:02a88f05d461 119 } else {
el14pjgn 0:02a88f05d461 120 lcd.clear();
el14pjgn 0:02a88f05d461 121 LCD_printMain();
el14pjgn 0:02a88f05d461 122 }
el14pjgn 0:02a88f05d461 123 buttons.pattern = 0;
el14pjgn 0:02a88f05d461 124 }
el14pjgn 0:02a88f05d461 125 if(inst_flag) selector(&inst_flag,&Seq_current_inst); /// selects current instrument if inst_flag is set
el14pjgn 0:02a88f05d461 126 else if(pattern_flag) selector(&pattern_flag,&Seq_current_seq); /// selects current pattern if pattern_flag is set
el14pjgn 0:02a88f05d461 127 else Sequence_write(); /// otherwise, updates sequence data
el14pjgn 0:02a88f05d461 128 LED_write((Seq_array[Seq_current_seq].structure.gate[Seq_current_inst])|(0x8000>>Seq_current_step)); ///writes sequence data & position indicator to matrix
el14pjgn 0:02a88f05d461 129 if(buttons.skip) {
el14pjgn 0:02a88f05d461 130 if(skip_flag == 0) {
el14pjgn 0:02a88f05d461 131 if(USB_mode == 1) pc->printf("skip...\n");
el14pjgn 0:02a88f05d461 132 Seq_prev_inst = Seq_current_inst; /// stores current instrument, in order to return once skip setting is complete
el14pjgn 0:02a88f05d461 133 Seq_current_inst = 8; /// sets sequencer channel to skip channel
el14pjgn 0:02a88f05d461 134 } else {
el14pjgn 0:02a88f05d461 135 if(USB_mode == 1) pc->printf("Done skip\n");
el14pjgn 0:02a88f05d461 136 Seq_current_inst = Seq_prev_inst; /// returns to previous instrument
el14pjgn 0:02a88f05d461 137 }
el14pjgn 0:02a88f05d461 138 buttons.skip = 0;
el14pjgn 0:02a88f05d461 139 skip_flag = !skip_flag;
el14pjgn 0:02a88f05d461 140 LED_write((Seq_array[Seq_current_seq].structure.gate[Seq_current_inst])|(0x8000>>Seq_current_step)); ///updates LED output
el14pjgn 0:02a88f05d461 141 lcd.clear(); ///re-draws display
el14pjgn 0:02a88f05d461 142 LCD_printMain();
el14pjgn 0:02a88f05d461 143 }
el14pjgn 0:02a88f05d461 144 if(buttons.start) { ///toggles sequencer ticker
el14pjgn 0:02a88f05d461 145 running? Sequence_increment_tkr.detach() : Sequence_increment_tkr.attach(&Sequence_increment_ISR,30/tempo);
el14pjgn 0:02a88f05d461 146 lcd.printString(running? "Paused":" ",0,2);
el14pjgn 0:02a88f05d461 147 running = !running;
el14pjgn 0:02a88f05d461 148 if(running) Sequence_increment_ISR();
el14pjgn 0:02a88f05d461 149 buttons.start = 0;
el14pjgn 0:02a88f05d461 150 }
el14pjgn 0:02a88f05d461 151 if(buttons.enter) { ///draws main menu
el14pjgn 0:02a88f05d461 152 buttons.enter = 0;
el14pjgn 0:02a88f05d461 153 mainMenu_draw();
el14pjgn 0:02a88f05d461 154 }
el14pjgn 0:02a88f05d461 155 if(buttons.edit) { ///draws edit menu
el14pjgn 0:02a88f05d461 156 buttons.edit = 0;
el14pjgn 0:02a88f05d461 157 if(skip_flag == 0) editMenu_draw();
el14pjgn 0:02a88f05d461 158 }
el14pjgn 0:02a88f05d461 159 if(buttons.load) { ///loads sequence from SD card
el14pjgn 0:02a88f05d461 160 load();
el14pjgn 0:02a88f05d461 161 buttons.load = 0;
el14pjgn 0:02a88f05d461 162 }
el14pjgn 0:02a88f05d461 163 if(buttons.save) { ///saves sequence to SD card
el14pjgn 0:02a88f05d461 164 save();
el14pjgn 0:02a88f05d461 165 buttons.save = 0;
el14pjgn 0:02a88f05d461 166 }
el14pjgn 0:02a88f05d461 167 ButtonFlag_press = 0; ///clears button press flag
el14pjgn 0:02a88f05d461 168 }
el14pjgn 0:02a88f05d461 169 if(tempo_flag) { ///runs tempo_set routine if button is pressed
el14pjgn 0:02a88f05d461 170 tempo_set();
el14pjgn 0:02a88f05d461 171 tempo_flag = 0;
el14pjgn 0:02a88f05d461 172 }
el14pjgn 0:02a88f05d461 173 }
el14pjgn 0:02a88f05d461 174 void null() {} /// no function
el14pjgn 0:02a88f05d461 175
el14pjgn 0:02a88f05d461 176 void USB_init() /// initialises USB mode, dependent on USB_mode value
el14pjgn 0:02a88f05d461 177 {
el14pjgn 0:02a88f05d461 178 switch (USB_mode) {
el14pjgn 0:02a88f05d461 179 case 0:
el14pjgn 0:02a88f05d461 180 if(pc!=0) pc->disconnect(); /// disconnects serial, if connected
el14pjgn 0:02a88f05d461 181 if(audio!=0) audio->disconnect(); /// disconnects audio, if connected
el14pjgn 0:02a88f05d461 182 midi = new USBMIDI; /// connects midi
el14pjgn 0:02a88f05d461 183 break;
el14pjgn 0:02a88f05d461 184 case 1:
el14pjgn 0:02a88f05d461 185 if(midi!=0) midi->disconnect(); /// disconnects midi, if connected
el14pjgn 0:02a88f05d461 186 if(audio!=0) audio->disconnect(); /// disconnects audio, if connected
el14pjgn 0:02a88f05d461 187 pc = new USBSerial; /// connects serial
el14pjgn 0:02a88f05d461 188 break;
el14pjgn 0:02a88f05d461 189 case 2:
el14pjgn 0:02a88f05d461 190 if(pc!=0) pc->disconnect(); /// disconnects serial, if connected
el14pjgn 0:02a88f05d461 191 if(midi!=0) midi->disconnect(); /// disconnects midi, if connected
el14pjgn 0:02a88f05d461 192 audio = new USBAudio; /// connects audio
el14pjgn 0:02a88f05d461 193 Sequence_increment_tkr.detach(); /// detatches all tickers, to maximise efficiency
el14pjgn 0:02a88f05d461 194 LED_scan_tkr.detach();
el14pjgn 0:02a88f05d461 195 audio_tkr.attach_us(audio_tkr_ISR, 1000000.0/(float)48000);
el14pjgn 0:02a88f05d461 196 break;
el14pjgn 0:02a88f05d461 197 case 3:
el14pjgn 0:02a88f05d461 198 if(pc!=0) pc->disconnect(); /// disconnects serial, if connected
el14pjgn 0:02a88f05d461 199 if(midi!=0) midi->disconnect(); /// disconnects midi, if connected
el14pjgn 0:02a88f05d461 200 break;
el14pjgn 0:02a88f05d461 201 }
el14pjgn 0:02a88f05d461 202 }
el14pjgn 0:02a88f05d461 203 void decay_ISR() /// sets decay flag if called by decay ticker
el14pjgn 0:02a88f05d461 204 {
el14pjgn 0:02a88f05d461 205 decay_flag = 1;
el14pjgn 0:02a88f05d461 206 }
el14pjgn 0:02a88f05d461 207
el14pjgn 0:02a88f05d461 208 /* Button functions */
el14pjgn 0:02a88f05d461 209 void Button_init() /// initialises button matrix
el14pjgn 0:02a88f05d461 210 {
el14pjgn 0:02a88f05d461 211 Button_scan_tkr.attach(&Button_scan_ISR,0.02); ///attaches button ticker
el14pjgn 0:02a88f05d461 212 ButtonIn_A.fall(&ButtonIn_A_ISR); ///connects button to ISR
el14pjgn 0:02a88f05d461 213 ButtonIn_A.mode(PullUp); ///sets pullup
el14pjgn 0:02a88f05d461 214 ButtonIn_B.fall(&ButtonIn_B_ISR);
el14pjgn 0:02a88f05d461 215 ButtonIn_B.mode(PullUp);
el14pjgn 0:02a88f05d461 216 ButtonIn_C.fall(&ButtonIn_C_ISR);
el14pjgn 0:02a88f05d461 217 ButtonIn_C.mode(PullUp);
el14pjgn 0:02a88f05d461 218 ButtonIn_D.fall(&ButtonIn_D_ISR);
el14pjgn 0:02a88f05d461 219 ButtonIn_D.mode(PullUp);
el14pjgn 0:02a88f05d461 220 ButtonIn_E.fall(&ButtonIn_E_ISR);
el14pjgn 0:02a88f05d461 221 ButtonIn_E.mode(PullUp);
el14pjgn 0:02a88f05d461 222 }
el14pjgn 0:02a88f05d461 223 void Button_scan_ISR()
el14pjgn 0:02a88f05d461 224 {
el14pjgn 0:02a88f05d461 225 if(ButtonFlag_zero == 0) ButtonFlag_cols[ButtonOut_pos] = 0; /// updates repeat flags
el14pjgn 0:02a88f05d461 226 ButtonFlag_zero = 0;
el14pjgn 0:02a88f05d461 227 ButtonOut_pos++; /// increments button scan position
el14pjgn 0:02a88f05d461 228 if(ButtonOut_pos>3) ButtonOut_pos = 0; /// limits scan range
el14pjgn 0:02a88f05d461 229 ButtonOut = ButtonOut_val[ButtonOut_pos]; /// writes to output
el14pjgn 0:02a88f05d461 230 }
el14pjgn 0:02a88f05d461 231 void ButtonIn_A_ISR()
el14pjgn 0:02a88f05d461 232 {
el14pjgn 0:02a88f05d461 233 Button_update(0); /// updates button flags
el14pjgn 0:02a88f05d461 234 }
el14pjgn 0:02a88f05d461 235 void ButtonIn_B_ISR()
el14pjgn 0:02a88f05d461 236 {
el14pjgn 0:02a88f05d461 237 Button_update(1); /// updates button flags
el14pjgn 0:02a88f05d461 238 }
el14pjgn 0:02a88f05d461 239 void ButtonIn_C_ISR()
el14pjgn 0:02a88f05d461 240 {
el14pjgn 0:02a88f05d461 241 Button_update(2); /// updates button flags
el14pjgn 0:02a88f05d461 242 }
el14pjgn 0:02a88f05d461 243 void ButtonIn_D_ISR()
el14pjgn 0:02a88f05d461 244 {
el14pjgn 0:02a88f05d461 245 Button_update(3); /// updates button flags
el14pjgn 0:02a88f05d461 246 }
el14pjgn 0:02a88f05d461 247 void ButtonIn_E_ISR()
el14pjgn 0:02a88f05d461 248 {
el14pjgn 0:02a88f05d461 249 Button_update(4); /// updates button flags
el14pjgn 0:02a88f05d461 250 }
el14pjgn 0:02a88f05d461 251 void Button_update(int row)
el14pjgn 0:02a88f05d461 252 {
el14pjgn 0:02a88f05d461 253 ButtonFlag_zero = 1; /// sets button flags
el14pjgn 0:02a88f05d461 254 ButtonFlag_press = 1;
el14pjgn 0:02a88f05d461 255 if(ButtonFlag_cols[ButtonOut_pos] == 0) {
el14pjgn 0:02a88f05d461 256 *(keyMap_point[row][ButtonOut_pos]) = 1; ///sets flag pointed to by position within matrix
el14pjgn 0:02a88f05d461 257 ButtonFlag_cols[ButtonOut_pos] = 1;
el14pjgn 0:02a88f05d461 258 }
el14pjgn 0:02a88f05d461 259 }
el14pjgn 0:02a88f05d461 260
el14pjgn 0:02a88f05d461 261 /* LED functions */
el14pjgn 0:02a88f05d461 262 void LED_init() ///initialises LEDs
el14pjgn 0:02a88f05d461 263 {
el14pjgn 0:02a88f05d461 264 LED_scan_tkr.attach(&LED_scan_ISR,0.005); ///Setup matrix scan ticker
el14pjgn 0:02a88f05d461 265 int LED_test[] { ///output values for test
el14pjgn 0:02a88f05d461 266 0x0,0x180,0x3c0,0x7e0,0xff0,0x1ff8,0x3ffc,0x7ffe,0xFFFF,~0x180,~0x3c0,~0x7e0,~0xff0,~0x1ff8,~0x3ffc,~0x7ffe,0x0
el14pjgn 0:02a88f05d461 267 };
el14pjgn 0:02a88f05d461 268 for(int j=0; j!=17; j++) { ///scan through output test values
el14pjgn 0:02a88f05d461 269 LED_write(LED_test[j]);
el14pjgn 0:02a88f05d461 270 wait(0.04);
el14pjgn 0:02a88f05d461 271 }
el14pjgn 0:02a88f05d461 272 shift_LED = 0; /// clear shift LED
el14pjgn 0:02a88f05d461 273 }
el14pjgn 0:02a88f05d461 274 void LED_scan_ISR() ///Scan ISR
el14pjgn 0:02a88f05d461 275 {
el14pjgn 0:02a88f05d461 276 LED_bus = LED_buffer[LED_pos]; ///Sends buffer value to bus output
el14pjgn 0:02a88f05d461 277 LED_pos++; ///Increment scan position
el14pjgn 0:02a88f05d461 278 if(LED_pos==4) LED_pos = 0; ///limit range
el14pjgn 0:02a88f05d461 279 }
el14pjgn 0:02a88f05d461 280 void LED_write(uint16_t value) ///Matrix refresh routine
el14pjgn 0:02a88f05d461 281 {
el14pjgn 0:02a88f05d461 282 uint8_t LED_scan_row = 0x1;
el14pjgn 0:02a88f05d461 283 uint16_t LED_loadBuffer = ((value<<4) | (value>>(16-4))); ///initialise LED_loadBuffer
el14pjgn 0:02a88f05d461 284 for(int i=0; i<4; i++) { ///Run loop 4 times
el14pjgn 0:02a88f05d461 285 LED_buffer[i] = (~LED_loadBuffer)&0xF0|(LED_scan_row)&0xf; ///write LED_loadBuffer nibble to FSM
el14pjgn 0:02a88f05d461 286 LED_scan_row=((LED_scan_row>>1) | (LED_scan_row<<(4-1))); ///Rotate row
el14pjgn 0:02a88f05d461 287 LED_loadBuffer=((LED_loadBuffer<<4) | (LED_loadBuffer>>(16-4))); ///rotate LED_loadBuffer
el14pjgn 0:02a88f05d461 288 };
el14pjgn 0:02a88f05d461 289 }
el14pjgn 0:02a88f05d461 290
el14pjgn 0:02a88f05d461 291 /* LCD functions */
el14pjgn 0:02a88f05d461 292 void LCD_init() /// initialise LCD
el14pjgn 0:02a88f05d461 293 {
el14pjgn 0:02a88f05d461 294 lcd.init();
el14pjgn 0:02a88f05d461 295 LCD_set();
el14pjgn 0:02a88f05d461 296 lcd.refresh();
el14pjgn 0:02a88f05d461 297 lcd.printString("Drumulator",1,1); /// display bootscreen
el14pjgn 0:02a88f05d461 298 lcd.printString("Ver 2.5PI",25,3);
el14pjgn 0:02a88f05d461 299 wait(1);
el14pjgn 0:02a88f05d461 300 lcd.clear();
el14pjgn 0:02a88f05d461 301 LCD_printMain();
el14pjgn 0:02a88f05d461 302 }
el14pjgn 0:02a88f05d461 303 void LCD_set()
el14pjgn 0:02a88f05d461 304 {
el14pjgn 0:02a88f05d461 305 lcd.setPwmFreq(PWM_freq); /// set PWM frequency (new function added to library)
el14pjgn 0:02a88f05d461 306 lcd.setBrightness(brightness); /// set brightness (new function added to library)
el14pjgn 0:02a88f05d461 307 }
el14pjgn 0:02a88f05d461 308 void LCD_printMain()
el14pjgn 0:02a88f05d461 309 {
el14pjgn 0:02a88f05d461 310 lcd.drawRect(0,0,84,16,2); /// clear upper section of the screen
el14pjgn 0:02a88f05d461 311 char buffer[14]; /// set up buffer for variable printing
el14pjgn 0:02a88f05d461 312 int length = sprintf(buffer,"%d bpm",int(tempo)); /// print tempo
el14pjgn 0:02a88f05d461 313 if (length <= 14) {
el14pjgn 0:02a88f05d461 314 lcd.printString(buffer,0,0);
el14pjgn 0:02a88f05d461 315 }
el14pjgn 0:02a88f05d461 316 length = sprintf(buffer,"Seq_%d",int(Seq_current_seq)); /// print sequence position
el14pjgn 0:02a88f05d461 317 if (length <= 14) {
el14pjgn 0:02a88f05d461 318 lcd.printString(buffer,55,0);
el14pjgn 0:02a88f05d461 319 }
el14pjgn 0:02a88f05d461 320 lcd.printString(inst_names[Seq_current_inst],55,1); /// print current instrument
el14pjgn 0:02a88f05d461 321 length = sprintf(buffer,"Stp %d",(Seq_current_step/2)+1); /// print current step
el14pjgn 0:02a88f05d461 322 if (length <= 14) {
el14pjgn 0:02a88f05d461 323 lcd.printString(buffer,0,1);
el14pjgn 0:02a88f05d461 324 }
el14pjgn 0:02a88f05d461 325 }
el14pjgn 0:02a88f05d461 326
el14pjgn 0:02a88f05d461 327 /* Sequencer functions */
el14pjgn 0:02a88f05d461 328 void Sequence_init() /// initialise sequencer
el14pjgn 0:02a88f05d461 329 {
el14pjgn 0:02a88f05d461 330 Sequence_increment_tkr.attach(&Sequence_increment_ISR,30/tempo);
el14pjgn 0:02a88f05d461 331 }
el14pjgn 0:02a88f05d461 332 void Sequence_increment_ISR() ///Increment sequencer position
el14pjgn 0:02a88f05d461 333 {
el14pjgn 0:02a88f05d461 334 Seq_current_step++;
el14pjgn 0:02a88f05d461 335 Seq_flag = 1;
el14pjgn 0:02a88f05d461 336 }
el14pjgn 0:02a88f05d461 337 void Sequence_increment() /// output sequence data
el14pjgn 0:02a88f05d461 338 {
el14pjgn 0:02a88f05d461 339 if(Seq_current_step>15) Seq_current_step = 0;
el14pjgn 0:02a88f05d461 340 LED_write((Seq_array[Seq_current_seq].structure.gate[Seq_current_inst])|(0x8000>>Seq_current_step)); /// update LED matrix
el14pjgn 0:02a88f05d461 341 while((Seq_array[Seq_current_seq].structure.gate[8]&(0x8000>>(Seq_current_step==15? 0 : Seq_current_step+1)) )!=0) {
el14pjgn 0:02a88f05d461 342 Seq_current_step++;
el14pjgn 0:02a88f05d461 343 if(Seq_current_step>15) Seq_current_step = 0;
el14pjgn 0:02a88f05d461 344 }
el14pjgn 0:02a88f05d461 345 for(int i = 0; i<8; i++) {
el14pjgn 0:02a88f05d461 346 if((Seq_array[Seq_current_seq].structure.gate[i]&(0x8000>>Seq_current_step) )!=0) {
el14pjgn 0:02a88f05d461 347 switch (Seq_array[Seq_current_seq].structure.Output_type[i]) { /// update outputs
el14pjgn 0:02a88f05d461 348 case 0: /// midi output
el14pjgn 0:02a88f05d461 349 if(USB_mode == 0) midi->write(MIDIMessage::NoteOn(int(Seq_array[Seq_current_seq].structure.MIDI_note[i])));
el14pjgn 0:02a88f05d461 350 decay_tkr.attach(&decay_ISR,0.1);
el14pjgn 0:02a88f05d461 351 break;
el14pjgn 0:02a88f05d461 352 case 1: /// audio output
el14pjgn 0:02a88f05d461 353 audio_pos[i] = 0;
el14pjgn 0:02a88f05d461 354 audio_flag[i] = 1;
el14pjgn 0:02a88f05d461 355 if(USB_mode == 1) pc->printf("audio_flag %d = %d\n",i,audio_flag[i]);
el14pjgn 0:02a88f05d461 356 break;
el14pjgn 0:02a88f05d461 357 case 2: /// trigger output
el14pjgn 0:02a88f05d461 358 trigOut[int(Seq_array[Seq_current_seq].structure.Trig_chan[i])]->write(1);
el14pjgn 0:02a88f05d461 359 decay_tkr.attach(&decay_ISR,0.1);
el14pjgn 0:02a88f05d461 360 break;
el14pjgn 0:02a88f05d461 361 case 3: /// no output
el14pjgn 0:02a88f05d461 362 break;
el14pjgn 0:02a88f05d461 363 };
el14pjgn 0:02a88f05d461 364 }
el14pjgn 0:02a88f05d461 365 }
el14pjgn 0:02a88f05d461 366 char buffer[14];
el14pjgn 0:02a88f05d461 367 int length = sprintf(buffer,"Stp %d",(Seq_current_step/2)+1); /// update step position display
el14pjgn 0:02a88f05d461 368 if (length <= 14) {
el14pjgn 0:02a88f05d461 369 lcd.printString(buffer,0,1);
el14pjgn 0:02a88f05d461 370 }
el14pjgn 0:02a88f05d461 371 if(tempo_update_flag) { /// set tempo
el14pjgn 0:02a88f05d461 372 Sequence_increment_tkr.detach(); ///detach increment ticker
el14pjgn 0:02a88f05d461 373 Sequence_increment_tkr.attach(&Sequence_increment_ISR,30/tempo);
el14pjgn 0:02a88f05d461 374 tempo_update_flag = 0;
el14pjgn 0:02a88f05d461 375 }
el14pjgn 0:02a88f05d461 376 Seq_flag = 0;
el14pjgn 0:02a88f05d461 377 }
el14pjgn 0:02a88f05d461 378 void Sequence_write() /// write button value to gate channel
el14pjgn 0:02a88f05d461 379 {
el14pjgn 0:02a88f05d461 380 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));
el14pjgn 0:02a88f05d461 381 for(int i = 0; i!=8; i++) {
el14pjgn 0:02a88f05d461 382 buttons.steps[i] = 0;
el14pjgn 0:02a88f05d461 383 }
el14pjgn 0:02a88f05d461 384 }
el14pjgn 0:02a88f05d461 385
el14pjgn 0:02a88f05d461 386 /* Tap tempo functions */
el14pjgn 0:02a88f05d461 387 void tempo_init() /// initialise tap tempo
el14pjgn 0:02a88f05d461 388 {
el14pjgn 0:02a88f05d461 389 tempo_tapIn.rise(&tempo_ISR); /// attach tap input to ISR
el14pjgn 0:02a88f05d461 390 tempo_time.start(); /// start timer
el14pjgn 0:02a88f05d461 391 }
el14pjgn 0:02a88f05d461 392 void tempo_ISR() //Tap tempo ISR
el14pjgn 0:02a88f05d461 393 {
el14pjgn 0:02a88f05d461 394 tempo_flag = 1;
el14pjgn 0:02a88f05d461 395 }
el14pjgn 0:02a88f05d461 396 void tempo_set()
el14pjgn 0:02a88f05d461 397 {
el14pjgn 0:02a88f05d461 398 if(USB_mode == 1) pc->printf("tapped...");
el14pjgn 0:02a88f05d461 399 if(tempo_time.read()>(8*(tempo_timerState+1))) tempo_timerState = 0;
el14pjgn 0:02a88f05d461 400 switch(tempo_timerState) {
el14pjgn 0:02a88f05d461 401 case 0: ///First press (timer start)
el14pjgn 0:02a88f05d461 402 if(tempo_time.read()>DEBOUNCE) { /// to prevent false triggers
el14pjgn 0:02a88f05d461 403 if(USB_mode == 1) pc->printf("first tap\n");
el14pjgn 0:02a88f05d461 404 tempo_time.stop(); /// reset and restart timer
el14pjgn 0:02a88f05d461 405 tempo_time.reset();
el14pjgn 0:02a88f05d461 406 tempo_time.start();
el14pjgn 0:02a88f05d461 407 tempo_timerState++; /// Increment state variable
el14pjgn 0:02a88f05d461 408 if(USB_mode == 1) pc->printf("tap tempo started!\n");
el14pjgn 0:02a88f05d461 409 lcd.printString("Set tempo.",0,5);
el14pjgn 0:02a88f05d461 410 }
el14pjgn 0:02a88f05d461 411 break;
el14pjgn 0:02a88f05d461 412 case 1: ///Second press (count)
el14pjgn 0:02a88f05d461 413 if(tempo_time.read()>DEBOUNCE) { /// to prevent false triggers
el14pjgn 0:02a88f05d461 414 tempo_timerState++; ///Increment state variable
el14pjgn 0:02a88f05d461 415 if(USB_mode == 1) pc->printf("second tap\n");
el14pjgn 0:02a88f05d461 416 tempo_debounce = tempo_time.read();
el14pjgn 0:02a88f05d461 417 lcd.printString(".",59,5);
el14pjgn 0:02a88f05d461 418 }
el14pjgn 0:02a88f05d461 419 break;
el14pjgn 0:02a88f05d461 420 case 2: ///Third press (count)
el14pjgn 0:02a88f05d461 421 if((tempo_time.read()-tempo_debounce)>DEBOUNCE) { /// to prevent false triggers
el14pjgn 0:02a88f05d461 422 tempo_timerState++; ///Increment state variable
el14pjgn 0:02a88f05d461 423 if(USB_mode == 1) pc->printf("third tap\n");
el14pjgn 0:02a88f05d461 424 tempo_debounce = tempo_time.read();
el14pjgn 0:02a88f05d461 425 lcd.printString(".",64,5);
el14pjgn 0:02a88f05d461 426 }
el14pjgn 0:02a88f05d461 427 break;
el14pjgn 0:02a88f05d461 428 case 3: ///Fourth press (Stop timer & set tempo)
el14pjgn 0:02a88f05d461 429 if((tempo_time.read()-tempo_debounce)>DEBOUNCE) { /// to prevent false triggers
el14pjgn 0:02a88f05d461 430 tempo_time.stop(); ///Stop timer
el14pjgn 0:02a88f05d461 431 if(USB_mode == 1) pc->printf("timer stopped...");
el14pjgn 0:02a88f05d461 432 tempo = (180/tempo_time.read());
el14pjgn 0:02a88f05d461 433 tempo_update(); /// update tempo
el14pjgn 0:02a88f05d461 434 Seq_current_step = 15;
el14pjgn 0:02a88f05d461 435 LCD_printMain();
el14pjgn 0:02a88f05d461 436 if(USB_mode == 1) pc->printf("tempo updated!\n");
el14pjgn 0:02a88f05d461 437 tempo_time.reset();
el14pjgn 0:02a88f05d461 438 tempo_time.start(); ///reset tempo timer
el14pjgn 0:02a88f05d461 439 tempo_timerState = 0; ///Reset state variable
el14pjgn 0:02a88f05d461 440 tempo_debounce = 0;
el14pjgn 0:02a88f05d461 441 lcd.clear();
el14pjgn 0:02a88f05d461 442 LCD_printMain();
el14pjgn 0:02a88f05d461 443 }
el14pjgn 0:02a88f05d461 444 }
el14pjgn 0:02a88f05d461 445 }
el14pjgn 0:02a88f05d461 446 void tempo_update() /// set update flag
el14pjgn 0:02a88f05d461 447 {
el14pjgn 0:02a88f05d461 448 if(USB_mode == 1) pc->printf("tempo set...");
el14pjgn 0:02a88f05d461 449 tempo_update_flag = 1;
el14pjgn 0:02a88f05d461 450 }
el14pjgn 0:02a88f05d461 451
el14pjgn 0:02a88f05d461 452 /* Menu functions */
el14pjgn 0:02a88f05d461 453 void mainMenu_draw()
el14pjgn 0:02a88f05d461 454 {
el14pjgn 0:02a88f05d461 455 switch(drawMenu(mainMenu)) { /// draw main menu
el14pjgn 0:02a88f05d461 456 case 0:
el14pjgn 0:02a88f05d461 457 drawVariable("Tempo",&tempo,5,500,1,&tempo_update); ///set tempo
el14pjgn 0:02a88f05d461 458 break;
el14pjgn 0:02a88f05d461 459 case 1:
el14pjgn 0:02a88f05d461 460 switch(drawMenu(displayMenu)) { /// draw display menu
el14pjgn 0:02a88f05d461 461 case 0:
el14pjgn 0:02a88f05d461 462 drawVariable("Brightness", &brightness,0.05,1,0,&LCD_set); /// set brightness
el14pjgn 0:02a88f05d461 463 break;
el14pjgn 0:02a88f05d461 464 case 1:
el14pjgn 0:02a88f05d461 465 drawVariable("PWM frequency", &PWM_freq,10,600,0,&LCD_set); /// set PWM frequency
el14pjgn 0:02a88f05d461 466 break;
el14pjgn 0:02a88f05d461 467 case 2:
el14pjgn 0:02a88f05d461 468 inverse=!inverse; /// toggle screen inversion
el14pjgn 0:02a88f05d461 469 if(inverse) {
el14pjgn 0:02a88f05d461 470 lcd.inverseMode(); /// inverted display
el14pjgn 0:02a88f05d461 471 } else {
el14pjgn 0:02a88f05d461 472 lcd.normalMode(); /// normal display
el14pjgn 0:02a88f05d461 473 }
el14pjgn 0:02a88f05d461 474 lcd.clear(); /// reset display
el14pjgn 0:02a88f05d461 475 LCD_printMain();
el14pjgn 0:02a88f05d461 476 break;
el14pjgn 0:02a88f05d461 477 case 3:
el14pjgn 0:02a88f05d461 478 mainMenu_draw(); /// return to main menu when back button is pressed
el14pjgn 0:02a88f05d461 479 };
el14pjgn 0:02a88f05d461 480 break;
el14pjgn 0:02a88f05d461 481 case 2:
el14pjgn 0:02a88f05d461 482 USB_mode = drawMenu(usbMenu); /// select USB mode
el14pjgn 0:02a88f05d461 483 USB_init();
el14pjgn 0:02a88f05d461 484 break;
el14pjgn 0:02a88f05d461 485 case 3:
el14pjgn 0:02a88f05d461 486 break;
el14pjgn 0:02a88f05d461 487 }
el14pjgn 0:02a88f05d461 488 lcd.clear(); /// reset display
el14pjgn 0:02a88f05d461 489 LCD_printMain();
el14pjgn 0:02a88f05d461 490 }
el14pjgn 0:02a88f05d461 491 void editMenu_draw()
el14pjgn 0:02a88f05d461 492 {
el14pjgn 0:02a88f05d461 493 switch (drawMenu(editMenu)) { /// draw editmenu
el14pjgn 0:02a88f05d461 494 case 0: /// set output type
el14pjgn 0:02a88f05d461 495 Seq_array[Seq_current_seq].structure.Output_type[Seq_current_inst] = drawMenu(outputMenu);
el14pjgn 0:02a88f05d461 496 break;
el14pjgn 0:02a88f05d461 497 case 1: /// set note value
el14pjgn 0:02a88f05d461 498 drawVariable("Note Value",&Seq_array[Seq_current_seq].structure.MIDI_note[Seq_current_inst],1,127,0,&null);
el14pjgn 0:02a88f05d461 499 break;
el14pjgn 0:02a88f05d461 500 case 2: /// set trigger channel
el14pjgn 0:02a88f05d461 501 drawVariable("trig chan",&Seq_array[Seq_current_seq].structure.Trig_chan[Seq_current_inst],1,6,0,&null);
el14pjgn 0:02a88f05d461 502 break;
el14pjgn 0:02a88f05d461 503 case 3:
el14pjgn 0:02a88f05d461 504 Audio_init(); /// call wave file load procedure
el14pjgn 0:02a88f05d461 505 break;
el14pjgn 0:02a88f05d461 506 case 4:
el14pjgn 0:02a88f05d461 507 break;
el14pjgn 0:02a88f05d461 508 }
el14pjgn 0:02a88f05d461 509 lcd.clear(); /// reset screen
el14pjgn 0:02a88f05d461 510 LCD_printMain();
el14pjgn 0:02a88f05d461 511 }
el14pjgn 0:02a88f05d461 512 int drawMenu(const char* array[]) ///draws single level menu on screen
el14pjgn 0:02a88f05d461 513 {
el14pjgn 0:02a88f05d461 514 int size=0;
el14pjgn 0:02a88f05d461 515 int pos_s=0;
el14pjgn 0:02a88f05d461 516 bool data=true;
el14pjgn 0:02a88f05d461 517 int menuPos=0;
el14pjgn 0:02a88f05d461 518 while(data==true) { /// checks size of array
el14pjgn 0:02a88f05d461 519 size++;
el14pjgn 0:02a88f05d461 520 if(array[pos_s]==0) {
el14pjgn 0:02a88f05d461 521 size--;
el14pjgn 0:02a88f05d461 522 data = false;
el14pjgn 0:02a88f05d461 523 }
el14pjgn 0:02a88f05d461 524 pos_s++;
el14pjgn 0:02a88f05d461 525 }
el14pjgn 0:02a88f05d461 526 lcd.clear(); /// reset display
el14pjgn 0:02a88f05d461 527 LCD_printMain();
el14pjgn 0:02a88f05d461 528 for (int pos=0; pos<size; pos++) { ///loops through menu entries
el14pjgn 0:02a88f05d461 529 lcd.printString(array[pos],0,pos+2); ///plots menu entries
el14pjgn 0:02a88f05d461 530 }
el14pjgn 0:02a88f05d461 531 while(1) { /// scans input flags
el14pjgn 0:02a88f05d461 532 if(buttons.up) {
el14pjgn 0:02a88f05d461 533 lcd.printString(" ",79,menuPos+2); /// clears menu indicator
el14pjgn 0:02a88f05d461 534 (menuPos==0)? menuPos = size-1 : menuPos--; /// increments menu position
el14pjgn 0:02a88f05d461 535 if(USB_mode == 1) pc->printf("menuPos %d\n",menuPos);
el14pjgn 0:02a88f05d461 536 buttons.up = 0;
el14pjgn 0:02a88f05d461 537 }
el14pjgn 0:02a88f05d461 538 if(buttons.down) {
el14pjgn 0:02a88f05d461 539 lcd.printString(" ",79,menuPos+2); /// clears menu indicator
el14pjgn 0:02a88f05d461 540 (menuPos==size-1)? menuPos = 0 : menuPos++; /// decrements menu position
el14pjgn 0:02a88f05d461 541 if(USB_mode == 1) pc->printf("menuPos %d\n",menuPos);
el14pjgn 0:02a88f05d461 542 buttons.down = 0;
el14pjgn 0:02a88f05d461 543 }
el14pjgn 0:02a88f05d461 544 lcd.printString("<",79,menuPos+2); /// draw menu indicator
el14pjgn 0:02a88f05d461 545 if(buttons.enter|buttons.back) { /// return
el14pjgn 0:02a88f05d461 546 buttons.enter = 0;
el14pjgn 0:02a88f05d461 547 buttons.back = 0;
el14pjgn 0:02a88f05d461 548 lcd.clear();
el14pjgn 0:02a88f05d461 549 LCD_printMain();
el14pjgn 0:02a88f05d461 550 return menuPos;
el14pjgn 0:02a88f05d461 551 }
el14pjgn 0:02a88f05d461 552 check_flags();
el14pjgn 0:02a88f05d461 553 sleep(); /// sleeps until output
el14pjgn 0:02a88f05d461 554 }
el14pjgn 0:02a88f05d461 555 }
el14pjgn 0:02a88f05d461 556
el14pjgn 0:02a88f05d461 557 void drawVariable(const char* variableName,float *variable, float step_size, float max, float min, void (*function)())
el14pjgn 0:02a88f05d461 558 {
el14pjgn 0:02a88f05d461 559 char numberbuffer[14];
el14pjgn 0:02a88f05d461 560 lcd.clear();
el14pjgn 0:02a88f05d461 561 LCD_printMain();
el14pjgn 0:02a88f05d461 562 while(1) {
el14pjgn 0:02a88f05d461 563 lcd.printString(variableName,0,3); /// print variable name
el14pjgn 0:02a88f05d461 564 if(buttons.up) { /// increment variable
el14pjgn 0:02a88f05d461 565 *variable=*variable+step_size;
el14pjgn 0:02a88f05d461 566 buttons.up = 0;
el14pjgn 0:02a88f05d461 567 }
el14pjgn 0:02a88f05d461 568 if(buttons.down) { /// decrement variable
el14pjgn 0:02a88f05d461 569 *variable=*variable-step_size;
el14pjgn 0:02a88f05d461 570 buttons.down = 0;
el14pjgn 0:02a88f05d461 571 }
el14pjgn 0:02a88f05d461 572 if (*variable>max) *variable = max; /// limit range
el14pjgn 0:02a88f05d461 573 if (*variable<min) *variable = min;
el14pjgn 0:02a88f05d461 574 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))));
el14pjgn 0:02a88f05d461 575 if (length <= 14) { /// print variable
el14pjgn 0:02a88f05d461 576 lcd.printString(" ",0,4);
el14pjgn 0:02a88f05d461 577 lcd.printString(numberbuffer,2,4);
el14pjgn 0:02a88f05d461 578 }
el14pjgn 0:02a88f05d461 579 if(buttons.enter|buttons.back) { /// return
el14pjgn 0:02a88f05d461 580 buttons.enter = 0;
el14pjgn 0:02a88f05d461 581 buttons.back = 0;
el14pjgn 0:02a88f05d461 582 lcd.clear();
el14pjgn 0:02a88f05d461 583 LCD_printMain();
el14pjgn 0:02a88f05d461 584 return;
el14pjgn 0:02a88f05d461 585 }
el14pjgn 0:02a88f05d461 586 (*function)();
el14pjgn 0:02a88f05d461 587 check_flags();
el14pjgn 0:02a88f05d461 588 sleep();
el14pjgn 0:02a88f05d461 589 }
el14pjgn 0:02a88f05d461 590 }
el14pjgn 0:02a88f05d461 591
el14pjgn 0:02a88f05d461 592 /* File Functions */
el14pjgn 0:02a88f05d461 593
el14pjgn 0:02a88f05d461 594 void save()
el14pjgn 0:02a88f05d461 595 {
el14pjgn 0:02a88f05d461 596 lcd.clear(); /// reset display
el14pjgn 0:02a88f05d461 597 LCD_printMain();
el14pjgn 0:02a88f05d461 598 lcd.printString("saving...",0,5);
el14pjgn 0:02a88f05d461 599 if(USB_mode == 1) pc->printf("saving sequence...\n");
el14pjgn 0:02a88f05d461 600 Seq_array[Seq_current_seq].sequence = new char [sizeof(Seq_array[Seq_current_seq].structure)];
el14pjgn 0:02a88f05d461 601 std::ofstream outfile ("/sd/sequence.mdrum",std::ofstream::binary); /// create file stream
el14pjgn 0:02a88f05d461 602 outfile.seekp(0); /// set file position to zero
el14pjgn 0:02a88f05d461 603 if(USB_mode == 1) pc->printf("sequence = %d\n",Seq_array[Seq_current_seq].sequence); /// output file data for debugging
el14pjgn 0:02a88f05d461 604 outfile.write(Seq_array[Seq_current_seq].sequence,sizeof(Seq_array[Seq_current_seq].sequence)); /// write data to filestream
el14pjgn 0:02a88f05d461 605 outfile.close(); /// close file
el14pjgn 0:02a88f05d461 606 if(USB_mode == 1) pc->printf("file closed\n");
el14pjgn 0:02a88f05d461 607 lcd.clear(); /// reset display
el14pjgn 0:02a88f05d461 608 LCD_printMain();
el14pjgn 0:02a88f05d461 609 buttons.save = 0;
el14pjgn 0:02a88f05d461 610 }
el14pjgn 0:02a88f05d461 611
el14pjgn 0:02a88f05d461 612 void load()
el14pjgn 0:02a88f05d461 613 {
el14pjgn 0:02a88f05d461 614 lcd.clear(); /// reset display
el14pjgn 0:02a88f05d461 615 LCD_printMain();
el14pjgn 0:02a88f05d461 616 lcd.printString("loading...",0,5);
el14pjgn 0:02a88f05d461 617 if(USB_mode == 1) pc->printf("saving sequence...\n");
el14pjgn 0:02a88f05d461 618 Seq_array[Seq_current_seq].sequence = new char [sizeof(Seq_array[Seq_current_seq].structure)];
el14pjgn 0:02a88f05d461 619 std::ifstream infile ("/sd/sequence.mdrum",std::ifstream::binary); /// setup filestream
el14pjgn 0:02a88f05d461 620 infile.seekg(0); /// set to start of file
el14pjgn 0:02a88f05d461 621 infile.read(Seq_array[Seq_current_seq].sequence,sizeof(Seq_array[Seq_current_seq].sequence)); /// read file
el14pjgn 0:02a88f05d461 622 infile.close(); /// close file
el14pjgn 0:02a88f05d461 623 if(USB_mode == 1) pc->printf("file closed\n");
el14pjgn 0:02a88f05d461 624 lcd.clear(); /// reset display
el14pjgn 0:02a88f05d461 625 LCD_printMain();
el14pjgn 0:02a88f05d461 626 buttons.load = 0;
el14pjgn 0:02a88f05d461 627 }
el14pjgn 0:02a88f05d461 628
el14pjgn 0:02a88f05d461 629 /* USB audio functions */
el14pjgn 0:02a88f05d461 630 void audio_tkr_ISR() /// ticker to update USB audio output
el14pjgn 0:02a88f05d461 631 {
el14pjgn 0:02a88f05d461 632 float speaker_value; /// speaker value
el14pjgn 0:02a88f05d461 633 if (USBaudio_packet_available) { /// checks if packet is available
el14pjgn 0:02a88f05d461 634 speaker_value = (float)(USBaudio_buffer[USBaudio_index_buffer]); /// converts value to float
el14pjgn 0:02a88f05d461 635 speaker_value = speaker_value + 32768.0; /// ofsets speaker value
el14pjgn 0:02a88f05d461 636 speaker_value *= audio->getVolume(); /// adjusts output level
el14pjgn 0:02a88f05d461 637 USBaudio_index_buffer++; /// increment buffer position
el14pjgn 0:02a88f05d461 638 if (USBaudio_index_buffer == 96/2) { /// checks if buffer is empty
el14pjgn 0:02a88f05d461 639 USBaudio_index_buffer = 0;
el14pjgn 0:02a88f05d461 640 USBaudio_packet_available = false;
el14pjgn 0:02a88f05d461 641 }
el14pjgn 0:02a88f05d461 642 } else {
el14pjgn 0:02a88f05d461 643 speaker_value = audio_prev_val; /// sets speaker value to previous available value
el14pjgn 0:02a88f05d461 644 }
el14pjgn 0:02a88f05d461 645 audio_prev_val = speaker_value;
el14pjgn 0:02a88f05d461 646 SOUND_OUT_1.write_u16((uint16_t)speaker_value); /// writes speaker value to analog output
el14pjgn 0:02a88f05d461 647 }
el14pjgn 0:02a88f05d461 648
el14pjgn 0:02a88f05d461 649 /* audio functions */
el14pjgn 0:02a88f05d461 650 void Audio_init()
el14pjgn 0:02a88f05d461 651 {
el14pjgn 0:02a88f05d461 652 if(USB_mode == 1) pc->printf("Initialising Audio file\n");
el14pjgn 0:02a88f05d461 653 audio_tkr.detach();
el14pjgn 0:02a88f05d461 654 lcd.clear();
el14pjgn 0:02a88f05d461 655 LCD_printMain();
el14pjgn 0:02a88f05d461 656 lcd.printString("loading WAVs...",0,5);
el14pjgn 0:02a88f05d461 657 std::ifstream is (audioFile_map[Seq_current_inst], std::ifstream::binary);
el14pjgn 0:02a88f05d461 658 if(is) { /// checks if file is present
el14pjgn 0:02a88f05d461 659 if(USB_mode == 1) pc->printf("loading %s\n",audioFile_map[Seq_current_inst]);
el14pjgn 0:02a88f05d461 660 is.seekg (0, is.end);
el14pjgn 0:02a88f05d461 661 audio_length[Seq_current_inst] = is.tellg(); /// finds length of file
el14pjgn 0:02a88f05d461 662 audio_buffer[Seq_current_inst] = new char [(audio_length[Seq_current_inst])]; /// sets buffer size
el14pjgn 0:02a88f05d461 663 if(USB_mode == 1) pc->printf("length %d\n",audio_length[Seq_current_inst]);
el14pjgn 0:02a88f05d461 664 is.seekg (0, is.beg);
el14pjgn 0:02a88f05d461 665 is.read (audio_buffer[Seq_current_inst],audio_length[Seq_current_inst]); /// loads file into buffer
el14pjgn 0:02a88f05d461 666 is.close(); /// closes file
el14pjgn 0:02a88f05d461 667 }
el14pjgn 0:02a88f05d461 668 if(USB_mode == 1) pc->printf("WAVs loaded\n");
el14pjgn 0:02a88f05d461 669 lcd.clear();
el14pjgn 0:02a88f05d461 670 LCD_printMain();
el14pjgn 0:02a88f05d461 671 if(USB_mode == 1){
el14pjgn 0:02a88f05d461 672 for(int i=0;i<audio_length[Seq_current_inst];i++)
el14pjgn 0:02a88f05d461 673 {
el14pjgn 0:02a88f05d461 674 pc->printf("%d",audio_buffer[Seq_current_inst][i]);
el14pjgn 0:02a88f05d461 675 }
el14pjgn 0:02a88f05d461 676 }
el14pjgn 0:02a88f05d461 677 for(int i=0;i<audio_length[Seq_current_inst];i++)
el14pjgn 0:02a88f05d461 678 {
el14pjgn 0:02a88f05d461 679 SOUND_OUT_1 = float(int(audio_buffer[Seq_current_inst][i]))/255;
el14pjgn 0:02a88f05d461 680 wait(0.00002267573);
el14pjgn 0:02a88f05d461 681 }
el14pjgn 0:02a88f05d461 682 audio_tkr.attach(Audio_ISR,0.00002267573);/// attaches audio update ticker
el14pjgn 0:02a88f05d461 683 }
el14pjgn 0:02a88f05d461 684 void Audio_ISR(){
el14pjgn 0:02a88f05d461 685 /*if(audio_pos[Seq_current_inst]<audio_length[Seq_current_inst]){
el14pjgn 0:02a88f05d461 686 SOUND_OUT_1 = float(int(audio_buffer[Seq_current_inst][audio_pos[Seq_current_inst]]))/1800;
el14pjgn 0:02a88f05d461 687 audio_pos[Seq_current_inst]++;
el14pjgn 0:02a88f05d461 688 }else{
el14pjgn 0:02a88f05d461 689 audio_pos[Seq_current_inst] = 0;
el14pjgn 0:02a88f05d461 690 }*/
el14pjgn 0:02a88f05d461 691 float speaker_value; /// speaker value
el14pjgn 0:02a88f05d461 692 for(int i = 0; i<8; i++){
el14pjgn 0:02a88f05d461 693 if(audio_flag[i]==1) audio_pos[i]++;
el14pjgn 0:02a88f05d461 694 if(audio_pos[i]>=audio_length[i]){
el14pjgn 0:02a88f05d461 695 audio_pos[i] = 0;
el14pjgn 0:02a88f05d461 696 audio_flag[i] = 0;
el14pjgn 0:02a88f05d461 697 }
el14pjgn 0:02a88f05d461 698 }
el14pjgn 0:02a88f05d461 699 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;
el14pjgn 0:02a88f05d461 700 if(speaker_value==0){
el14pjgn 0:02a88f05d461 701 speaker_value = audio_prev_val;
el14pjgn 0:02a88f05d461 702 }else{
el14pjgn 0:02a88f05d461 703 SOUND_OUT_1 = speaker_value;
el14pjgn 0:02a88f05d461 704 audio_prev_val = speaker_value;
el14pjgn 0:02a88f05d461 705 }
el14pjgn 0:02a88f05d461 706 }