Lawrence Quizon / Mbed OS mini_piano_player

Dependencies:   USBMSD_BD SDFileSystem max32630fthr USBDevice

Revision:
8:ce16aa4cdb6a
Parent:
7:412761dab446
Child:
9:17de551d2208
--- a/main.cpp	Fri Jul 19 08:55:15 2019 +0000
+++ b/main.cpp	Tue Jul 23 01:42:34 2019 +0000
@@ -7,6 +7,10 @@
 
 #define BUFFER_SIZE 128
 #define HALF_BUFFER 64
+#define OS_MAINSTKSIZE 1024
+
+
+bool debugState = 1;
 
 DigitalOut rLED(LED1);
 DigitalOut gLED(LED2);
@@ -18,6 +22,7 @@
 PwmOut PWM(P5_6);
 AnalogIn POT(AIN_0);
 volatile int bufferPOS = 0;
+int i;
 
 Serial daplink(P2_1,P2_0);
 USBSerial microUSB;
@@ -39,13 +44,8 @@
     bufferPOS = (bufferPOS+1) & 0x07F;
 }
 
-int main()
+void presence()
 {
-    WavFile Track;
-    Ticker SampleTime;
-
-    daplink.printf("\f---DAPLINK SERIAL PORT---\r\n\r\nMINI PIANO PLAYER ver 1 \r\n\r\n\r\n");
-    microUSB.printf("micro USB serial port\r\n");
     rLED = LED_ON;
     wait_ms(500);
     rLED = LED_OFF;
@@ -53,73 +53,183 @@
     wait_ms(500);
     bLED = LED_ON;
     gLED = LED_OFF;
+}
 
-    typedef enum {
-        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 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;
 
-    typedef struct {
-        int length;
-        pitchname pitch;
-    } note;
+        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 arrays
-    char buffer[256];
-    char inputtype[30];
-    typedef enum {
-        nokiacomposer,
-        normal
-    } inputtypes;
-    inputtypes current_inputtype;
-
-    //parse input type
-    int g;
-    tryagain:
-    printf("Please specify the input type.\r\nAvailable types:\r\nnokiacomposer\r\nnormal\r\n\r\n>");
-    for(i=0; i<30; i++) {
-        c=daplink.getc();
-        if(c == '\r')
-        {
-            g=i+2;
-            inputtype[i] = '\0';
-            break;
-        }
-        daplink.putc(c);
-        inputtype[i]=c;
-    }
-    printf("\r\n");
-    for(i=0;i<=g;i++)
-    {
-        printf("%i\t",inputtype[i]);
-    }
-    printf("\r\nSTRING LITERAL:\r\n");
-    char test[] = "nokiacomposer";
-    for(i=0;i<=g;i++)
-    {
-        printf("%i\t",test[i]);
-    }
-
-    if(!strcmp(inputtype,"nokiacomposer")) {
-        printf("\r\nType chosen: nokiacomposer\r\n");
-        current_inputtype = nokiacomposer;
-    } else if(!strcmp(inputtype,"normal")) {
-        printf("\r\nType chosen: normal\r\n");
-        current_inputtype = normal;
-    } else {
-        c=NULL;
-        printf("Invalid input type. Try again.");
-        goto tryagain; //prints message below input area
-    }
+    //input holder array
+    char *buffer = new char[1024]; //ver 2 update: placed in stack.
 
     //open file
 toolarge:
@@ -128,166 +238,29 @@
         c=daplink.getc();
         daplink.putc(c);
         buffer[i]=c;
-        if(i>=256) {
+        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())
-        {
-            printf("That'sallll\r\n");
-            break;   
+        if(!daplink.readable()) {
+            break;
         }
     }
     buffer[i] = ' '; //set EOF marker.
-    buffer[i++] = '\0';
+    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.)
-    
-    //useful benchmarks to find which characters are valid.
-    int candidate_number;
-    char *songpos=buffer+1; //song position
-    note song[256];
-    int pn_det;
-    //asdasd
-
-    if(current_inputtype == nokiacomposer) {
-        //for every [note] slot in [song]
-        for(i=0; i<256; i++) {
-            //take the first base 10 integer you see.
-            //this initializes songpos ALWAYS. lol.
-            candidate_number = strtol(songpos-1,&songpos,10);
-            printf("Character:%i\r\n",candidate_number);
-            //if it's 1,2,4,8,16 or 32, VALID.
-            if((candidate_number==1)||candidate_number==2||candidate_number==4||candidate_number==8||candidate_number==16||candidate_number==32) {
-                song[i].length = candidate_number;
-                printf("Entered candidate [%i] into song[%i].length\r\n",candidate_number,i);
-            } else {
-                printf("Found invalid NOTE LENGTH value [%c] at position %li. Skipping until next whitespace...\r\n",*songpos,songpos-buffer);
-                //skip to after next whitespace
-                do {
-                    songpos++;
-                } while(!isspace(*(songpos)));
-                do {
-                    songpos++;
-                } while(!isalnum(*(songpos)));
-                //then do next iteration of LENGTH,PITCH,OCTAVE parse
-                i--;
-                continue;
-            }
-            //parse next character
-            printf("Character:%c\r\n",*songpos);
-            pn_det=0;
-            //watch out for sharps
-            if(!(*songpos=='#'||'a'<=*songpos<='z'||*songpos=='-')) {
-                printf("Found invalid PITCH NAME value [%c] at position %li. Skipping word...\r\n",*songpos,songpos-buffer);
-                //skip to after next whitespace
-                do {
-                    songpos++;
-                } while(!isspace(*(songpos)));
-                do {
-                    songpos++;
-                } while(!isalnum(*(songpos)));
-                //then do next iteration of LENGTH,PITCH,OCTAVE parse
-                i--;
-                continue;
-            }
-            if(*songpos=='#') {
-                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 skipoctave;
-            }
-            //check for invalid character at current position
-            //means that character was valid. move on.
-            songpos++;
-            printf("%c\n",*songpos);
-            if('0'<=*songpos<='9') {
-                int num = strtol(songpos,&songpos,10);
-                num+=3;//shift up thrice. board can't handle things this low.
-                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);
-                //skip to after next whitespace
-                while(!isspace(*(songpos))) {
-                    songpos++;
-                }
-                while(!isalnum(*(songpos))) {
-                    songpos++;
-                }
-                //then do next iteration of LENGTH,PITCH,OCTAVE parse
-                i--;
-                continue;
-            }
-            skipoctave:
-            song[i].pitch = (pitchname)pn_det;
-            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");
-            //make sure you're after the next whitespace
-            while(!isspace(*(songpos))) {
-                songpos++;
-            }
-            while(isspace(*(songpos))) {
-                songpos++;
-            };
-            if(*songpos == '\0'){
-                printf("NULL found. Escaping...\r\n");
-                goto esc;
-            }
-        }
-    } else if(current_inputtype == normal) {
-        //add normaltype parser here.
+    note song[1024];
+    if(!songParse(song,buffer)) {
+        printf("Song parse unsuccessful.\r\n");
     }
 
-    //add end term
-
-    //parsing is done
-esc:
-
-    printf("at end: i = %i\r\n",i);
-    i++;
-    song[i].length = 1;
-    song[i].pitch = END;
-    
-    printf("Parsing done.\r\n");
-    
-    //ENDOFPARSER
-    
-    int k;
-    for(k=0; song[k].pitch != END; k++) {
-        printf("{%i,%i},",song[k].length,song[k].pitch);
-    }
-    printf("{%i,%i},",song[k].length,song[k].pitch);
-    printf("\r\nPrinting done.\r\n");
+    printSong(song);
 
     printf("Generating sine...\r\n");
     for(i=0; i<128; i++) {
@@ -309,41 +282,18 @@
         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:
 
-    /*
-    HARVEST MOON SONG IN NORMAL FORMAT
-
-    note song[] = {
-        //batch 1
-        {4,(pitchname)38},{4,E5},{4,Fs5},{4,D5},{4,Fs5},{4,G5},{4,A5},{4,Fs5},{4,D5},
-        {4,A5},{4,B5},{4,A5},{4,G5},{4,B5},{4,A5},
-        {4,rest},
-        //batch 2
-        {4,D5},{4,E5},{4,Fs5},{4,D5},{4,Fs5},{4,G5},{4,A5},{4,Fs5},{4,D5},
-        {4,A5},{4,G5},{4,D5},{4,Fs5},{4,D5},{4,E5},
-        {4,rest},
-        //batch 1
-        {4,D5},{4,E5},{4,Fs5},{4,D5},{4,Fs5},{4,G5},{4,A5},{4,Fs5},{4,D5},
-        {4,A5},{4,B5},{4,A5},{4,G5},{4,B5},{4,A5},
-        {4,rest},
-        //batch 3
-        {2,G5},{4,G5},{4,E5},{4,Fs5},{4,E5},{4,D5},{4,Cs5},{4,D5},
-        //END
-        {1,END}
-    };
-    */
-
+    //buffer input cycle
     for(i = 0; 1; i++) {
+        //frequency select
         switch(song[i].pitch) {
             case rest:
                 wait((1/(float)song[i].length)*SPB);
@@ -516,13 +466,13 @@
             case END:
                 i = 0;
                 printf("SONG END. PRESS BUTTON TO RESTART.");
-                while(Button)
-                {
+                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);
@@ -531,8 +481,8 @@
         SampleTime.attach(&placeNewSample,ticker_period);
         wait( (1/(float)song[i].length) *SPB);
         SampleTime.detach();
-        
-        
+
+
 
         printf("\033[A\033[A\033[A\033[A");
     }