K64F drum machine, with RAW WAV sample playback, and USB midi functionality
Dependencies: FATFileSystem N5110_mod SDFileSystem USBDevice mbed
main.cpp
- Committer:
- el14pjgn
- Date:
- 2016-05-09
- Revision:
- 0:02a88f05d461
File content as of revision 0:02a88f05d461:
# include "main.h"
int main()
{
init(); /// calls initialisation routine
while(1) {
if(USB_mode == 2) { /// prints display output for speaker mode
lcd.clear();
lcd.printString("USB audio",0,2);
lcd.printString("to exit,",0,3);
lcd.printString("press back",0,4);
}
while(USB_mode == 2) { ///loop for while within speaker mode
audio->read((uint8_t *)USBaudio_buffer); ///reads audio stream
USBaudio_packet_available = true; ///sets flag to indicate presence of data
if(buttons.back) { ///withdraw from speaker mode
USB_mode = 3; ///set USB mode to none
audio_tkr.detach(); ///detatch audio ticker
LED_scan_tkr.attach(&LED_scan_ISR,0.005); ///re-attach tickers
Sequence_increment_tkr.attach(&Sequence_increment_ISR,30/tempo);
buttons.back = 0; ///re-set back button flag
USB_init(); ///re-initialise USB
lcd.clear(); ///set display to normal
LCD_printMain();
}
}
check_flags(); ///check for button presses
sleep(); ///return to sleep mode, to save power
}
}
/* General functions */
void init()
{
LCD_init();
USB_init();
Button_init();
LED_init();
IO_init();
tempo_init();
Sequence_init();
}
void IO_init()
{
for (int i = 0; i < 7; i++) {
trigOut[i]->write(1); /// test trigger outputs
wait(0.1);
trigOut[i]->write(0);
}
}
int bool_to_int(bool *array, int shifter)
{
switch(shifter) {
case 0: /// 1:1 mapping
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);
case 1 : /// even mapping
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);
case 2: /// odd mapping
return array[7]+(array[6]*0x4)+(array[5]*0x10)+(array[4]*0x40)+(array[3]*0x100)+(array[2]*0x400)+(array[1]*0x1000)+(array[0]*0x4000);
}
return;
}
void selector(bool *flag, int *variable)
{
for(int i=0; i<8; i++) { /// scans through input button values
if(buttons.steps[i]) { /// sets value if button is pressed
*variable = i;
buttons.steps[i] = 0;
*flag = 0;
lcd.clear(); ///set display to normal
LCD_printMain();
}
}
}
void check_flags()
{
if(Seq_flag) Sequence_increment(); /// increments sequencer if flag is set
if(decay_flag) {
for(int i = 0; i<8; i++) { /// clears midi messages if decay flag is set
if(USB_mode == 0) midi->write(MIDIMessage::NoteOff(Seq_array[Seq_current_seq].structure.MIDI_note[i]));
}
for(int i = 0; i<7; i++) { /// clears trigger outputs if decay flag is set
trigOut[i]->write(0);
}
decay_tkr.detach(); /// detatches decay ticker
decay_flag = 0; /// clears decay flag
}
if(ButtonFlag_press) { /// run if any input buttons are pressed
/// prints button values over serial if available, for debugging
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]);
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);
if(buttons.shift) shift_LED = !shift_LED; /// toggles shift LED
buttons.shift = 0; /// clears shift button flag
//if(buttons.up) buttons.up = 0; /// clears unused button flags
//if(buttons.down) buttons.down = 0;
if(buttons.back) buttons.back = 0;
if(buttons.inst) {
pattern_flag = 0;
inst_flag = !inst_flag; /// toggles instrument selection, and updates LCD & serial
if(inst_flag) {
if(USB_mode == 1) pc->printf("instrument_select\n");
lcd.printString("select inst.",0,5);
} else {
lcd.clear();
LCD_printMain();
}
buttons.inst = 0;
}
if(buttons.pattern) { /// toggles pattern selection, and updates LCD & serial
inst_flag = 0;
pattern_flag = !pattern_flag;
if(pattern_flag) {
if(USB_mode == 1) pc->printf("pattern_select\n");
lcd.printString("select patrn.",0,5);
} else {
lcd.clear();
LCD_printMain();
}
buttons.pattern = 0;
}
if(inst_flag) selector(&inst_flag,&Seq_current_inst); /// selects current instrument if inst_flag is set
else if(pattern_flag) selector(&pattern_flag,&Seq_current_seq); /// selects current pattern if pattern_flag is set
else Sequence_write(); /// otherwise, updates sequence data
LED_write((Seq_array[Seq_current_seq].structure.gate[Seq_current_inst])|(0x8000>>Seq_current_step)); ///writes sequence data & position indicator to matrix
if(buttons.skip) {
if(skip_flag == 0) {
if(USB_mode == 1) pc->printf("skip...\n");
Seq_prev_inst = Seq_current_inst; /// stores current instrument, in order to return once skip setting is complete
Seq_current_inst = 8; /// sets sequencer channel to skip channel
} else {
if(USB_mode == 1) pc->printf("Done skip\n");
Seq_current_inst = Seq_prev_inst; /// returns to previous instrument
}
buttons.skip = 0;
skip_flag = !skip_flag;
LED_write((Seq_array[Seq_current_seq].structure.gate[Seq_current_inst])|(0x8000>>Seq_current_step)); ///updates LED output
lcd.clear(); ///re-draws display
LCD_printMain();
}
if(buttons.start) { ///toggles sequencer ticker
running? Sequence_increment_tkr.detach() : Sequence_increment_tkr.attach(&Sequence_increment_ISR,30/tempo);
lcd.printString(running? "Paused":" ",0,2);
running = !running;
if(running) Sequence_increment_ISR();
buttons.start = 0;
}
if(buttons.enter) { ///draws main menu
buttons.enter = 0;
mainMenu_draw();
}
if(buttons.edit) { ///draws edit menu
buttons.edit = 0;
if(skip_flag == 0) editMenu_draw();
}
if(buttons.load) { ///loads sequence from SD card
load();
buttons.load = 0;
}
if(buttons.save) { ///saves sequence to SD card
save();
buttons.save = 0;
}
ButtonFlag_press = 0; ///clears button press flag
}
if(tempo_flag) { ///runs tempo_set routine if button is pressed
tempo_set();
tempo_flag = 0;
}
}
void null() {} /// no function
void USB_init() /// initialises USB mode, dependent on USB_mode value
{
switch (USB_mode) {
case 0:
if(pc!=0) pc->disconnect(); /// disconnects serial, if connected
if(audio!=0) audio->disconnect(); /// disconnects audio, if connected
midi = new USBMIDI; /// connects midi
break;
case 1:
if(midi!=0) midi->disconnect(); /// disconnects midi, if connected
if(audio!=0) audio->disconnect(); /// disconnects audio, if connected
pc = new USBSerial; /// connects serial
break;
case 2:
if(pc!=0) pc->disconnect(); /// disconnects serial, if connected
if(midi!=0) midi->disconnect(); /// disconnects midi, if connected
audio = new USBAudio; /// connects audio
Sequence_increment_tkr.detach(); /// detatches all tickers, to maximise efficiency
LED_scan_tkr.detach();
audio_tkr.attach_us(audio_tkr_ISR, 1000000.0/(float)48000);
break;
case 3:
if(pc!=0) pc->disconnect(); /// disconnects serial, if connected
if(midi!=0) midi->disconnect(); /// disconnects midi, if connected
break;
}
}
void decay_ISR() /// sets decay flag if called by decay ticker
{
decay_flag = 1;
}
/* Button functions */
void Button_init() /// initialises button matrix
{
Button_scan_tkr.attach(&Button_scan_ISR,0.02); ///attaches button ticker
ButtonIn_A.fall(&ButtonIn_A_ISR); ///connects button to ISR
ButtonIn_A.mode(PullUp); ///sets pullup
ButtonIn_B.fall(&ButtonIn_B_ISR);
ButtonIn_B.mode(PullUp);
ButtonIn_C.fall(&ButtonIn_C_ISR);
ButtonIn_C.mode(PullUp);
ButtonIn_D.fall(&ButtonIn_D_ISR);
ButtonIn_D.mode(PullUp);
ButtonIn_E.fall(&ButtonIn_E_ISR);
ButtonIn_E.mode(PullUp);
}
void Button_scan_ISR()
{
if(ButtonFlag_zero == 0) ButtonFlag_cols[ButtonOut_pos] = 0; /// updates repeat flags
ButtonFlag_zero = 0;
ButtonOut_pos++; /// increments button scan position
if(ButtonOut_pos>3) ButtonOut_pos = 0; /// limits scan range
ButtonOut = ButtonOut_val[ButtonOut_pos]; /// writes to output
}
void ButtonIn_A_ISR()
{
Button_update(0); /// updates button flags
}
void ButtonIn_B_ISR()
{
Button_update(1); /// updates button flags
}
void ButtonIn_C_ISR()
{
Button_update(2); /// updates button flags
}
void ButtonIn_D_ISR()
{
Button_update(3); /// updates button flags
}
void ButtonIn_E_ISR()
{
Button_update(4); /// updates button flags
}
void Button_update(int row)
{
ButtonFlag_zero = 1; /// sets button flags
ButtonFlag_press = 1;
if(ButtonFlag_cols[ButtonOut_pos] == 0) {
*(keyMap_point[row][ButtonOut_pos]) = 1; ///sets flag pointed to by position within matrix
ButtonFlag_cols[ButtonOut_pos] = 1;
}
}
/* LED functions */
void LED_init() ///initialises LEDs
{
LED_scan_tkr.attach(&LED_scan_ISR,0.005); ///Setup matrix scan ticker
int LED_test[] { ///output values for test
0x0,0x180,0x3c0,0x7e0,0xff0,0x1ff8,0x3ffc,0x7ffe,0xFFFF,~0x180,~0x3c0,~0x7e0,~0xff0,~0x1ff8,~0x3ffc,~0x7ffe,0x0
};
for(int j=0; j!=17; j++) { ///scan through output test values
LED_write(LED_test[j]);
wait(0.04);
}
shift_LED = 0; /// clear shift LED
}
void LED_scan_ISR() ///Scan ISR
{
LED_bus = LED_buffer[LED_pos]; ///Sends buffer value to bus output
LED_pos++; ///Increment scan position
if(LED_pos==4) LED_pos = 0; ///limit range
}
void LED_write(uint16_t value) ///Matrix refresh routine
{
uint8_t LED_scan_row = 0x1;
uint16_t LED_loadBuffer = ((value<<4) | (value>>(16-4))); ///initialise LED_loadBuffer
for(int i=0; i<4; i++) { ///Run loop 4 times
LED_buffer[i] = (~LED_loadBuffer)&0xF0|(LED_scan_row)&0xf; ///write LED_loadBuffer nibble to FSM
LED_scan_row=((LED_scan_row>>1) | (LED_scan_row<<(4-1))); ///Rotate row
LED_loadBuffer=((LED_loadBuffer<<4) | (LED_loadBuffer>>(16-4))); ///rotate LED_loadBuffer
};
}
/* LCD functions */
void LCD_init() /// initialise LCD
{
lcd.init();
LCD_set();
lcd.refresh();
lcd.printString("Drumulator",1,1); /// display bootscreen
lcd.printString("Ver 2.5PI",25,3);
wait(1);
lcd.clear();
LCD_printMain();
}
void LCD_set()
{
lcd.setPwmFreq(PWM_freq); /// set PWM frequency (new function added to library)
lcd.setBrightness(brightness); /// set brightness (new function added to library)
}
void LCD_printMain()
{
lcd.drawRect(0,0,84,16,2); /// clear upper section of the screen
char buffer[14]; /// set up buffer for variable printing
int length = sprintf(buffer,"%d bpm",int(tempo)); /// print tempo
if (length <= 14) {
lcd.printString(buffer,0,0);
}
length = sprintf(buffer,"Seq_%d",int(Seq_current_seq)); /// print sequence position
if (length <= 14) {
lcd.printString(buffer,55,0);
}
lcd.printString(inst_names[Seq_current_inst],55,1); /// print current instrument
length = sprintf(buffer,"Stp %d",(Seq_current_step/2)+1); /// print current step
if (length <= 14) {
lcd.printString(buffer,0,1);
}
}
/* Sequencer functions */
void Sequence_init() /// initialise sequencer
{
Sequence_increment_tkr.attach(&Sequence_increment_ISR,30/tempo);
}
void Sequence_increment_ISR() ///Increment sequencer position
{
Seq_current_step++;
Seq_flag = 1;
}
void Sequence_increment() /// output sequence data
{
if(Seq_current_step>15) Seq_current_step = 0;
LED_write((Seq_array[Seq_current_seq].structure.gate[Seq_current_inst])|(0x8000>>Seq_current_step)); /// update LED matrix
while((Seq_array[Seq_current_seq].structure.gate[8]&(0x8000>>(Seq_current_step==15? 0 : Seq_current_step+1)) )!=0) {
Seq_current_step++;
if(Seq_current_step>15) Seq_current_step = 0;
}
for(int i = 0; i<8; i++) {
if((Seq_array[Seq_current_seq].structure.gate[i]&(0x8000>>Seq_current_step) )!=0) {
switch (Seq_array[Seq_current_seq].structure.Output_type[i]) { /// update outputs
case 0: /// midi output
if(USB_mode == 0) midi->write(MIDIMessage::NoteOn(int(Seq_array[Seq_current_seq].structure.MIDI_note[i])));
decay_tkr.attach(&decay_ISR,0.1);
break;
case 1: /// audio output
audio_pos[i] = 0;
audio_flag[i] = 1;
if(USB_mode == 1) pc->printf("audio_flag %d = %d\n",i,audio_flag[i]);
break;
case 2: /// trigger output
trigOut[int(Seq_array[Seq_current_seq].structure.Trig_chan[i])]->write(1);
decay_tkr.attach(&decay_ISR,0.1);
break;
case 3: /// no output
break;
};
}
}
char buffer[14];
int length = sprintf(buffer,"Stp %d",(Seq_current_step/2)+1); /// update step position display
if (length <= 14) {
lcd.printString(buffer,0,1);
}
if(tempo_update_flag) { /// set tempo
Sequence_increment_tkr.detach(); ///detach increment ticker
Sequence_increment_tkr.attach(&Sequence_increment_ISR,30/tempo);
tempo_update_flag = 0;
}
Seq_flag = 0;
}
void Sequence_write() /// write button value to gate channel
{
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));
for(int i = 0; i!=8; i++) {
buttons.steps[i] = 0;
}
}
/* Tap tempo functions */
void tempo_init() /// initialise tap tempo
{
tempo_tapIn.rise(&tempo_ISR); /// attach tap input to ISR
tempo_time.start(); /// start timer
}
void tempo_ISR() //Tap tempo ISR
{
tempo_flag = 1;
}
void tempo_set()
{
if(USB_mode == 1) pc->printf("tapped...");
if(tempo_time.read()>(8*(tempo_timerState+1))) tempo_timerState = 0;
switch(tempo_timerState) {
case 0: ///First press (timer start)
if(tempo_time.read()>DEBOUNCE) { /// to prevent false triggers
if(USB_mode == 1) pc->printf("first tap\n");
tempo_time.stop(); /// reset and restart timer
tempo_time.reset();
tempo_time.start();
tempo_timerState++; /// Increment state variable
if(USB_mode == 1) pc->printf("tap tempo started!\n");
lcd.printString("Set tempo.",0,5);
}
break;
case 1: ///Second press (count)
if(tempo_time.read()>DEBOUNCE) { /// to prevent false triggers
tempo_timerState++; ///Increment state variable
if(USB_mode == 1) pc->printf("second tap\n");
tempo_debounce = tempo_time.read();
lcd.printString(".",59,5);
}
break;
case 2: ///Third press (count)
if((tempo_time.read()-tempo_debounce)>DEBOUNCE) { /// to prevent false triggers
tempo_timerState++; ///Increment state variable
if(USB_mode == 1) pc->printf("third tap\n");
tempo_debounce = tempo_time.read();
lcd.printString(".",64,5);
}
break;
case 3: ///Fourth press (Stop timer & set tempo)
if((tempo_time.read()-tempo_debounce)>DEBOUNCE) { /// to prevent false triggers
tempo_time.stop(); ///Stop timer
if(USB_mode == 1) pc->printf("timer stopped...");
tempo = (180/tempo_time.read());
tempo_update(); /// update tempo
Seq_current_step = 15;
LCD_printMain();
if(USB_mode == 1) pc->printf("tempo updated!\n");
tempo_time.reset();
tempo_time.start(); ///reset tempo timer
tempo_timerState = 0; ///Reset state variable
tempo_debounce = 0;
lcd.clear();
LCD_printMain();
}
}
}
void tempo_update() /// set update flag
{
if(USB_mode == 1) pc->printf("tempo set...");
tempo_update_flag = 1;
}
/* Menu functions */
void mainMenu_draw()
{
switch(drawMenu(mainMenu)) { /// draw main menu
case 0:
drawVariable("Tempo",&tempo,5,500,1,&tempo_update); ///set tempo
break;
case 1:
switch(drawMenu(displayMenu)) { /// draw display menu
case 0:
drawVariable("Brightness", &brightness,0.05,1,0,&LCD_set); /// set brightness
break;
case 1:
drawVariable("PWM frequency", &PWM_freq,10,600,0,&LCD_set); /// set PWM frequency
break;
case 2:
inverse=!inverse; /// toggle screen inversion
if(inverse) {
lcd.inverseMode(); /// inverted display
} else {
lcd.normalMode(); /// normal display
}
lcd.clear(); /// reset display
LCD_printMain();
break;
case 3:
mainMenu_draw(); /// return to main menu when back button is pressed
};
break;
case 2:
USB_mode = drawMenu(usbMenu); /// select USB mode
USB_init();
break;
case 3:
break;
}
lcd.clear(); /// reset display
LCD_printMain();
}
void editMenu_draw()
{
switch (drawMenu(editMenu)) { /// draw editmenu
case 0: /// set output type
Seq_array[Seq_current_seq].structure.Output_type[Seq_current_inst] = drawMenu(outputMenu);
break;
case 1: /// set note value
drawVariable("Note Value",&Seq_array[Seq_current_seq].structure.MIDI_note[Seq_current_inst],1,127,0,&null);
break;
case 2: /// set trigger channel
drawVariable("trig chan",&Seq_array[Seq_current_seq].structure.Trig_chan[Seq_current_inst],1,6,0,&null);
break;
case 3:
Audio_init(); /// call wave file load procedure
break;
case 4:
break;
}
lcd.clear(); /// reset screen
LCD_printMain();
}
int drawMenu(const char* array[]) ///draws single level menu on screen
{
int size=0;
int pos_s=0;
bool data=true;
int menuPos=0;
while(data==true) { /// checks size of array
size++;
if(array[pos_s]==0) {
size--;
data = false;
}
pos_s++;
}
lcd.clear(); /// reset display
LCD_printMain();
for (int pos=0; pos<size; pos++) { ///loops through menu entries
lcd.printString(array[pos],0,pos+2); ///plots menu entries
}
while(1) { /// scans input flags
if(buttons.up) {
lcd.printString(" ",79,menuPos+2); /// clears menu indicator
(menuPos==0)? menuPos = size-1 : menuPos--; /// increments menu position
if(USB_mode == 1) pc->printf("menuPos %d\n",menuPos);
buttons.up = 0;
}
if(buttons.down) {
lcd.printString(" ",79,menuPos+2); /// clears menu indicator
(menuPos==size-1)? menuPos = 0 : menuPos++; /// decrements menu position
if(USB_mode == 1) pc->printf("menuPos %d\n",menuPos);
buttons.down = 0;
}
lcd.printString("<",79,menuPos+2); /// draw menu indicator
if(buttons.enter|buttons.back) { /// return
buttons.enter = 0;
buttons.back = 0;
lcd.clear();
LCD_printMain();
return menuPos;
}
check_flags();
sleep(); /// sleeps until output
}
}
void drawVariable(const char* variableName,float *variable, float step_size, float max, float min, void (*function)())
{
char numberbuffer[14];
lcd.clear();
LCD_printMain();
while(1) {
lcd.printString(variableName,0,3); /// print variable name
if(buttons.up) { /// increment variable
*variable=*variable+step_size;
buttons.up = 0;
}
if(buttons.down) { /// decrement variable
*variable=*variable-step_size;
buttons.down = 0;
}
if (*variable>max) *variable = max; /// limit range
if (*variable<min) *variable = min;
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))));
if (length <= 14) { /// print variable
lcd.printString(" ",0,4);
lcd.printString(numberbuffer,2,4);
}
if(buttons.enter|buttons.back) { /// return
buttons.enter = 0;
buttons.back = 0;
lcd.clear();
LCD_printMain();
return;
}
(*function)();
check_flags();
sleep();
}
}
/* File Functions */
void save()
{
lcd.clear(); /// reset display
LCD_printMain();
lcd.printString("saving...",0,5);
if(USB_mode == 1) pc->printf("saving sequence...\n");
Seq_array[Seq_current_seq].sequence = new char [sizeof(Seq_array[Seq_current_seq].structure)];
std::ofstream outfile ("/sd/sequence.mdrum",std::ofstream::binary); /// create file stream
outfile.seekp(0); /// set file position to zero
if(USB_mode == 1) pc->printf("sequence = %d\n",Seq_array[Seq_current_seq].sequence); /// output file data for debugging
outfile.write(Seq_array[Seq_current_seq].sequence,sizeof(Seq_array[Seq_current_seq].sequence)); /// write data to filestream
outfile.close(); /// close file
if(USB_mode == 1) pc->printf("file closed\n");
lcd.clear(); /// reset display
LCD_printMain();
buttons.save = 0;
}
void load()
{
lcd.clear(); /// reset display
LCD_printMain();
lcd.printString("loading...",0,5);
if(USB_mode == 1) pc->printf("saving sequence...\n");
Seq_array[Seq_current_seq].sequence = new char [sizeof(Seq_array[Seq_current_seq].structure)];
std::ifstream infile ("/sd/sequence.mdrum",std::ifstream::binary); /// setup filestream
infile.seekg(0); /// set to start of file
infile.read(Seq_array[Seq_current_seq].sequence,sizeof(Seq_array[Seq_current_seq].sequence)); /// read file
infile.close(); /// close file
if(USB_mode == 1) pc->printf("file closed\n");
lcd.clear(); /// reset display
LCD_printMain();
buttons.load = 0;
}
/* USB audio functions */
void audio_tkr_ISR() /// ticker to update USB audio output
{
float speaker_value; /// speaker value
if (USBaudio_packet_available) { /// checks if packet is available
speaker_value = (float)(USBaudio_buffer[USBaudio_index_buffer]); /// converts value to float
speaker_value = speaker_value + 32768.0; /// ofsets speaker value
speaker_value *= audio->getVolume(); /// adjusts output level
USBaudio_index_buffer++; /// increment buffer position
if (USBaudio_index_buffer == 96/2) { /// checks if buffer is empty
USBaudio_index_buffer = 0;
USBaudio_packet_available = false;
}
} else {
speaker_value = audio_prev_val; /// sets speaker value to previous available value
}
audio_prev_val = speaker_value;
SOUND_OUT_1.write_u16((uint16_t)speaker_value); /// writes speaker value to analog output
}
/* audio functions */
void Audio_init()
{
if(USB_mode == 1) pc->printf("Initialising Audio file\n");
audio_tkr.detach();
lcd.clear();
LCD_printMain();
lcd.printString("loading WAVs...",0,5);
std::ifstream is (audioFile_map[Seq_current_inst], std::ifstream::binary);
if(is) { /// checks if file is present
if(USB_mode == 1) pc->printf("loading %s\n",audioFile_map[Seq_current_inst]);
is.seekg (0, is.end);
audio_length[Seq_current_inst] = is.tellg(); /// finds length of file
audio_buffer[Seq_current_inst] = new char [(audio_length[Seq_current_inst])]; /// sets buffer size
if(USB_mode == 1) pc->printf("length %d\n",audio_length[Seq_current_inst]);
is.seekg (0, is.beg);
is.read (audio_buffer[Seq_current_inst],audio_length[Seq_current_inst]); /// loads file into buffer
is.close(); /// closes file
}
if(USB_mode == 1) pc->printf("WAVs loaded\n");
lcd.clear();
LCD_printMain();
if(USB_mode == 1){
for(int i=0;i<audio_length[Seq_current_inst];i++)
{
pc->printf("%d",audio_buffer[Seq_current_inst][i]);
}
}
for(int i=0;i<audio_length[Seq_current_inst];i++)
{
SOUND_OUT_1 = float(int(audio_buffer[Seq_current_inst][i]))/255;
wait(0.00002267573);
}
audio_tkr.attach(Audio_ISR,0.00002267573);/// attaches audio update ticker
}
void Audio_ISR(){
/*if(audio_pos[Seq_current_inst]<audio_length[Seq_current_inst]){
SOUND_OUT_1 = float(int(audio_buffer[Seq_current_inst][audio_pos[Seq_current_inst]]))/1800;
audio_pos[Seq_current_inst]++;
}else{
audio_pos[Seq_current_inst] = 0;
}*/
float speaker_value; /// speaker value
for(int i = 0; i<8; i++){
if(audio_flag[i]==1) audio_pos[i]++;
if(audio_pos[i]>=audio_length[i]){
audio_pos[i] = 0;
audio_flag[i] = 0;
}
}
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;
if(speaker_value==0){
speaker_value = audio_prev_val;
}else{
SOUND_OUT_1 = speaker_value;
audio_prev_val = speaker_value;
}
}