Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: USBMSD_BD SDFileSystem max32630fthr USBDevice
main.cpp
- Committer:
- Lugs
- Date:
- 2019-07-23
- Revision:
- 8:ce16aa4cdb6a
- Parent:
- 7:412761dab446
- Child:
- 9:17de551d2208
File content as of revision 8:ce16aa4cdb6a:
#include "mbed.h" #include "max32630fthr.h" #include "USBSerial.h" #include "stdio.h" #include "SDFileSystem.h" #include "ctype.h" #define BUFFER_SIZE 128 #define HALF_BUFFER 64 #define OS_MAINSTKSIZE 1024 bool debugState = 1; DigitalOut rLED(LED1); DigitalOut gLED(LED2); DigitalOut bLED(LED3); DigitalIn Button(P2_3); MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3); PwmOut PWM(P5_6); AnalogIn POT(AIN_0); volatile int bufferPOS = 0; int i; Serial daplink(P2_1,P2_0); USBSerial microUSB; float audioDataBuffer[BUFFER_SIZE]; struct WavFile { long int size; int channels; int sampleRate; int bitsPerSample; }; float potval,reading; void placeNewSample(void) { PWM.write(audioDataBuffer[bufferPOS++]); //multiply by POT value for volume. bufferPOS = (bufferPOS+1) & 0x07F; } void presence() { rLED = LED_ON; wait_ms(500); rLED = LED_OFF; gLED = LED_ON; wait_ms(500); bLED = LED_ON; gLED = LED_OFF; } typedef enum : unsigned char { C2,Cs2,D2,Ds2,E2,F2,Fs2,G2,Gs2,A2,As2,B2, //C2:0 C3,Cs3,D3,Ds3,E3,F3,Fs3,G3,Gs3,A3,As3,B3, //C3:12 C4,Cs4,D4,Ds4,E4,F4,Fs4,G4,Gs4,A4,As4,B4, //C4:24 C5,Cs5,D5,Ds5,E5,F5,Fs5,G5,Gs5,A5,As5,B5, //C5:36 C6,Cs6,D6,Ds6,E6,F6,Fs6,G6,Gs6, //C6:48 rest, END } pitchname; typedef struct { unsigned char length; pitchname pitch; } note; char *skipToNextEntry(char *songpos, bool skiptype) { if(skiptype = 0) { do { songpos++; } while(!isspace(*(songpos))); do { songpos++; } while(!isalnum(*(songpos))); return songpos; } else if(skiptype = 1) { while(!isspace(*(songpos))) { songpos++; } while(isspace(*(songpos))) { songpos++; }; } } bool songParse(note *song,char *buffer) { int candidate; char *songpos=buffer+1; //song position int pn_det; int i; for(i=0; i<256; i++) { //take the first base 10 integer you see. //this initializes songpos ALWAYS. lol. candidate = strtol(songpos-1,&songpos,10); if(debugState) { printf("Character:%i\r\n",candidate); } if(candidate == 0) { printf("Found invalid NOTE LENGTH value [%c] at position %li. Skipping until next whitespace...\r\n",*songpos,songpos-buffer); songpos = skipToNextEntry(songpos,0); i--; continue; } else { song[i].length = candidate; if(debugState) { printf("Entered candidate [%i] into song[%i].length\r\n",candidate,i); } } //parse next character if(debugState) { printf("Character:%c\r\n",*songpos); } pn_det=0; if(!(*songpos=='#'||'a'<=*songpos<='z'||*songpos=='-')) { printf("Found invalid PITCH NAME value [%c] at position %li. Skipping word...\r\n",*songpos,songpos-buffer); songpos = skipToNextEntry(songpos,0); i--; continue; } if(*songpos=='#') { //watch out for sharps pn_det+=1; songpos++; printf("Sharp found.\r\n"); } switch(*songpos) { case 'c': pn_det+=0; break; case 'd': pn_det+=2; break; case 'e': pn_det+=4; break; case 'f': pn_det+=5; break; case 'g': pn_det+=7; break; case 'a': pn_det+=9; break; case 'b': pn_det+=11; break; case '-': pn_det=57; goto skipoctaveparse; } songpos++; //parse octaves if('0'<=*songpos<='9') { int num = strtol(songpos,&songpos,10); num+=3;//shift up thrice. board can't handle things this low. if(debugState) { printf("octave parsed: %i \t-> adder:%i\r\n",num,((num-2)*12)); } pn_det=pn_det+((num-2)*12); } else { printf("Found invalid OCTAVE value [%c] at position %li. Skipping word...\r\n",*songpos,songpos-buffer); songpos = skipToNextEntry(songpos,0); i--; //rewrite current note continue; } skipoctaveparse: song[i].pitch = (pitchname)pn_det; if(debugState) { printf("Entered pitch [%i] into song[%i].pitch\r\n",song[i].pitch,i); printf("Final: {%i,%i} at i=%i\r\n",song[i].length,song[i].pitch,i); printf("-------------------\r\n"); } songpos = skipToNextEntry(songpos,1); //check for buffer end if(*(songpos) == '\0') { i++; song[i].length = 1; song[i].pitch = END; printf("Parsing done. i = %i\r\n",i); return 1; } if(songpos-buffer > 2048) { printf("songpos exceeded buffer size.\r\n"); return 0; } } printf("Song exceeded maximum number of notes.\r\n"); return 0; } void printSong(note *song) { for(i=0; song[i].pitch != END; i++) { printf("{%i,%i},",song[i].length,song[i].pitch); } printf("{%i,%i},",song[i].length,song[i].pitch); printf("\r\nPrinting done.\r\n"); } int main() { WavFile Track; Ticker SampleTime; daplink.printf("\f---DAPLINK SERIAL PORT---\r\n\r\nMINI PIANO PLAYER ver 2 \r\n\r\n\r\n"); microUSB.printf("micro USB serial port\r\n"); presence(); //input iterator vars int i; char c; //input holder array char *buffer = new char[1024]; //ver 2 update: placed in stack. //open file toolarge: printf("Please copy the text file of the song then right click on the PuTTY screen.\r\n"); for(i=0; 1; i++) { //do the loop at least once c=daplink.getc(); daplink.putc(c); buffer[i]=c; if(i>=4096) { printf("Note data is greater than 2kB! Impossible. Try again.\033[A"); goto toolarge; } wait_ms(1); //wait for the next byte to arrive. every byte takes 1.04ms at 9600 baud. if(!daplink.readable()) { break; } } buffer[i] = ' '; //set EOF marker. buffer[i+1] = '\0'; buffer[i+2] = 'a'; //make sure to put a character after (will allow skipToNextEntry() to find the null character at [songpos-1]) //kunwari open na yung file printf("\r\nFile recieved. Parsing...\r\n"); //parse file into song in heap(remove sharps, put into enums.) note song[1024]; if(!songParse(song,buffer)) { printf("Song parse unsuccessful.\r\n"); } printSong(song); printf("Generating sine...\r\n"); for(i=0; i<128; i++) { audioDataBuffer[i] =((1.0 + sin((double(i)/16.0*6.28318530717959)))/2.0); //formula copied from mbed example } /* HERE'S WHERE THE MUSIC STARTS */ /* LITERALLY. */ //FORMAT: { NUM_BEATS, PITCH } char bpminp[5]; int PlayingFreq; printf("Please enter desired BPM:\r\n"); for(i=0; i<5 && c!='\r'; i++) { c = daplink.getc(); daplink.putc(c); bpminp[i] = c; } printf("BPM Recieved.\r\n"); c=NULL; //reset C for next time. int BPM = strtol(bpminp,NULL,0); float SPB = 60*4/(float)BPM; printf("BPM: %i",BPM); restart: //buffer input cycle for(i = 0; 1; i++) { //frequency select switch(song[i].pitch) { case rest: wait((1/(float)song[i].length)*SPB); continue; case D2: PlayingFreq = 73; break; case Ds2: PlayingFreq = 78; break; case E2: PlayingFreq = 82; break; case F2: PlayingFreq = 87; break; case Fs2: PlayingFreq = 92; break; case G2: PlayingFreq = 98; break; case Gs2: PlayingFreq = 104; break; case A2: PlayingFreq = 110; break; case As2: PlayingFreq = 117; break; case B2: PlayingFreq = 123; break; case C3: PlayingFreq = 131; break; case Cs3: PlayingFreq = 139; break; case D3: PlayingFreq = 147; break; case Ds3: PlayingFreq = 156; break; case E3: PlayingFreq = 165; break; case F3: PlayingFreq = 175; break; case Fs3: PlayingFreq = 185; break; case G3: PlayingFreq = 196; break; case Gs3: PlayingFreq = 208; break; case A3: PlayingFreq = 220; break; case As3: PlayingFreq = 233; break; case B3: PlayingFreq = 247; break; case C4: PlayingFreq = 262; break; case Cs4: PlayingFreq = 277; break; case D4: PlayingFreq = 294; break; case Ds4: PlayingFreq = 311; break; case E4: PlayingFreq = 330; break; case F4: PlayingFreq = 349; break; case Fs4: PlayingFreq = 370; break; case G4: PlayingFreq = 392; break; case Gs4: PlayingFreq = 415; break; case A4: PlayingFreq = 440; break; case As4: PlayingFreq = 466; break; case B4: PlayingFreq = 494; break; case C5: PlayingFreq = 523; break; case Cs5: PlayingFreq = 554; break; case D5: PlayingFreq = 587; break; case Ds5: PlayingFreq = 622; break; case E5: PlayingFreq = 659; break; case F5: PlayingFreq = 698; break; case Fs5: PlayingFreq = 740; break; case G5: PlayingFreq = 784; break; case Gs5: PlayingFreq = 831; break; case A5: PlayingFreq = 880; break; case As5: PlayingFreq = 932; break; case B5: PlayingFreq = 988; break; case C6: PlayingFreq = 1047; break; case Cs6: PlayingFreq = 1109; break; case D6: PlayingFreq = 1175; break; case Ds6: PlayingFreq = 1245; break; case E6: PlayingFreq = 1319; break; case F6: PlayingFreq = 1397; break; case Fs6: PlayingFreq = 1480; break; case G6: PlayingFreq = 1568; break; case Gs6: PlayingFreq = 1661; break; case END: i = 0; printf("SONG END. PRESS BUTTON TO RESTART."); while(Button) { wait_ms(2); } goto restart; } //calculate ticker, attach ticker. Track.sampleRate = PlayingFreq * 16; //TONE FREQ = SAMPLE RATE / SAMPLES PER CYCLE PWM.period_us(1); //1MHz float ticker_period = (float) 1/(Track.sampleRate); printf("\r\nTicker Period: %f\tTicker Freq: %f\r\nTarget Freq: %i \r\n\r\n",ticker_period, 1/ticker_period, PlayingFreq); SampleTime.attach(&placeNewSample,ticker_period); wait( (1/(float)song[i].length) *SPB); SampleTime.detach(); printf("\033[A\033[A\033[A\033[A"); } }