For MAX32630FTHR microcontroller: Plays piano notes in Nokia composer format text file placed in the SD card
Dependencies: USBMSD_BD SDFileSystem max32630fthr USBDevice
main.cpp@13:e28ed9475bde, 2019-11-09 (annotated)
- Committer:
- Lugs
- Date:
- Sat Nov 09 01:10:05 2019 +0000
- Revision:
- 13:e28ed9475bde
- Parent:
- 12:f9ce63d44ba7
Final Ver
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Lugs | 0:ad5ce0aff429 | 1 | #include "stdio.h" |
Lugs | 4:24086b80928e | 2 | #include "ctype.h" |
Lugs | 11:df2fffa042b8 | 3 | #include "noteplayer.h" |
Lugs | 12:f9ce63d44ba7 | 4 | #include "generalinterface.h" |
Lugs | 12:f9ce63d44ba7 | 5 | #include "max32630fthr.h" |
Lugs | 3:fcf745cd4f6d | 6 | |
Lugs | 0:ad5ce0aff429 | 7 | #define BUFFER_SIZE 128 |
Lugs | 0:ad5ce0aff429 | 8 | #define HALF_BUFFER 64 |
Lugs | 8:ce16aa4cdb6a | 9 | #define OS_MAINSTKSIZE 1024 |
Lugs | 8:ce16aa4cdb6a | 10 | |
Lugs | 12:f9ce63d44ba7 | 11 | bool debugState = 0; |
Lugs | 8:ce16aa4cdb6a | 12 | |
Lugs | 12:f9ce63d44ba7 | 13 | MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3); |
Lugs | 0:ad5ce0aff429 | 14 | |
Lugs | 12:f9ce63d44ba7 | 15 | PwmOut speaker(P4_0); |
Lugs | 12:f9ce63d44ba7 | 16 | AnalogIn POT(AIN_0); |
Lugs | 0:ad5ce0aff429 | 17 | DigitalOut rLED(LED1); |
Lugs | 0:ad5ce0aff429 | 18 | DigitalOut gLED(LED2); |
Lugs | 0:ad5ce0aff429 | 19 | DigitalOut bLED(LED3); |
Lugs | 0:ad5ce0aff429 | 20 | DigitalIn Button(P2_3); |
Lugs | 0:ad5ce0aff429 | 21 | |
Lugs | 0:ad5ce0aff429 | 22 | float potval,reading; |
Lugs | 0:ad5ce0aff429 | 23 | |
Lugs | 8:ce16aa4cdb6a | 24 | void presence() |
Lugs | 4:24086b80928e | 25 | { |
Lugs | 0:ad5ce0aff429 | 26 | rLED = LED_ON; |
Lugs | 0:ad5ce0aff429 | 27 | wait_ms(500); |
Lugs | 0:ad5ce0aff429 | 28 | rLED = LED_OFF; |
Lugs | 0:ad5ce0aff429 | 29 | gLED = LED_ON; |
Lugs | 0:ad5ce0aff429 | 30 | wait_ms(500); |
Lugs | 0:ad5ce0aff429 | 31 | bLED = LED_ON; |
Lugs | 0:ad5ce0aff429 | 32 | gLED = LED_OFF; |
Lugs | 8:ce16aa4cdb6a | 33 | } |
Lugs | 4:24086b80928e | 34 | |
Lugs | 8:ce16aa4cdb6a | 35 | char *skipToNextEntry(char *songpos, bool skiptype) |
Lugs | 8:ce16aa4cdb6a | 36 | { |
Lugs | 9:17de551d2208 | 37 | if(skiptype == 0) { |
Lugs | 8:ce16aa4cdb6a | 38 | do { |
Lugs | 8:ce16aa4cdb6a | 39 | songpos++; |
Lugs | 8:ce16aa4cdb6a | 40 | } while(!isspace(*(songpos))); |
Lugs | 8:ce16aa4cdb6a | 41 | do { |
Lugs | 8:ce16aa4cdb6a | 42 | songpos++; |
Lugs | 8:ce16aa4cdb6a | 43 | } while(!isalnum(*(songpos))); |
Lugs | 8:ce16aa4cdb6a | 44 | return songpos; |
Lugs | 9:17de551d2208 | 45 | } else if(skiptype == 1) { |
Lugs | 8:ce16aa4cdb6a | 46 | while(!isspace(*(songpos))) { |
Lugs | 8:ce16aa4cdb6a | 47 | songpos++; |
Lugs | 8:ce16aa4cdb6a | 48 | } |
Lugs | 8:ce16aa4cdb6a | 49 | while(isspace(*(songpos))) { |
Lugs | 8:ce16aa4cdb6a | 50 | songpos++; |
Lugs | 8:ce16aa4cdb6a | 51 | }; |
Lugs | 8:ce16aa4cdb6a | 52 | } |
Lugs | 12:f9ce63d44ba7 | 53 | return songpos; |
Lugs | 8:ce16aa4cdb6a | 54 | } |
Lugs | 8:ce16aa4cdb6a | 55 | |
Lugs | 8:ce16aa4cdb6a | 56 | bool songParse(note *song,char *buffer) |
Lugs | 8:ce16aa4cdb6a | 57 | { |
Lugs | 8:ce16aa4cdb6a | 58 | int candidate; |
Lugs | 8:ce16aa4cdb6a | 59 | char *songpos=buffer+1; //song position |
Lugs | 8:ce16aa4cdb6a | 60 | int pn_det; |
Lugs | 8:ce16aa4cdb6a | 61 | int i; |
Lugs | 12:f9ce63d44ba7 | 62 | for(i=0; i<1024; i++) { |
Lugs | 8:ce16aa4cdb6a | 63 | //take the first base 10 integer you see. |
Lugs | 8:ce16aa4cdb6a | 64 | //this initializes songpos ALWAYS. lol. |
Lugs | 8:ce16aa4cdb6a | 65 | candidate = strtol(songpos-1,&songpos,10); |
Lugs | 8:ce16aa4cdb6a | 66 | |
Lugs | 8:ce16aa4cdb6a | 67 | if(debugState) { |
Lugs | 8:ce16aa4cdb6a | 68 | printf("Character:%i\r\n",candidate); |
Lugs | 8:ce16aa4cdb6a | 69 | } |
Lugs | 8:ce16aa4cdb6a | 70 | |
Lugs | 8:ce16aa4cdb6a | 71 | if(candidate == 0) { |
Lugs | 8:ce16aa4cdb6a | 72 | printf("Found invalid NOTE LENGTH value [%c] at position %li. Skipping until next whitespace...\r\n",*songpos,songpos-buffer); |
Lugs | 8:ce16aa4cdb6a | 73 | songpos = skipToNextEntry(songpos,0); |
Lugs | 8:ce16aa4cdb6a | 74 | i--; |
Lugs | 8:ce16aa4cdb6a | 75 | continue; |
Lugs | 8:ce16aa4cdb6a | 76 | } else { |
Lugs | 8:ce16aa4cdb6a | 77 | song[i].length = candidate; |
Lugs | 8:ce16aa4cdb6a | 78 | if(debugState) { |
Lugs | 8:ce16aa4cdb6a | 79 | printf("Entered candidate [%i] into song[%i].length\r\n",candidate,i); |
Lugs | 8:ce16aa4cdb6a | 80 | } |
Lugs | 8:ce16aa4cdb6a | 81 | } |
Lugs | 8:ce16aa4cdb6a | 82 | |
Lugs | 8:ce16aa4cdb6a | 83 | //parse next character |
Lugs | 8:ce16aa4cdb6a | 84 | if(debugState) { |
Lugs | 8:ce16aa4cdb6a | 85 | printf("Character:%c\r\n",*songpos); |
Lugs | 8:ce16aa4cdb6a | 86 | } |
Lugs | 8:ce16aa4cdb6a | 87 | |
Lugs | 8:ce16aa4cdb6a | 88 | pn_det=0; |
Lugs | 4:24086b80928e | 89 | |
Lugs | 8:ce16aa4cdb6a | 90 | if(!(*songpos=='#'||'a'<=*songpos<='z'||*songpos=='-')) { |
Lugs | 8:ce16aa4cdb6a | 91 | printf("Found invalid PITCH NAME value [%c] at position %li. Skipping word...\r\n",*songpos,songpos-buffer); |
Lugs | 8:ce16aa4cdb6a | 92 | songpos = skipToNextEntry(songpos,0); |
Lugs | 8:ce16aa4cdb6a | 93 | i--; |
Lugs | 8:ce16aa4cdb6a | 94 | continue; |
Lugs | 8:ce16aa4cdb6a | 95 | } |
Lugs | 8:ce16aa4cdb6a | 96 | if(*songpos=='#') { //watch out for sharps |
Lugs | 8:ce16aa4cdb6a | 97 | pn_det+=1; |
Lugs | 8:ce16aa4cdb6a | 98 | songpos++; |
Lugs | 12:f9ce63d44ba7 | 99 | if(debugState) |
Lugs | 12:f9ce63d44ba7 | 100 | { |
Lugs | 12:f9ce63d44ba7 | 101 | printf("Sharp found.\r\n"); |
Lugs | 12:f9ce63d44ba7 | 102 | } |
Lugs | 8:ce16aa4cdb6a | 103 | } |
Lugs | 8:ce16aa4cdb6a | 104 | switch(*songpos) { |
Lugs | 8:ce16aa4cdb6a | 105 | case 'c': |
Lugs | 8:ce16aa4cdb6a | 106 | pn_det+=0; |
Lugs | 8:ce16aa4cdb6a | 107 | break; |
Lugs | 8:ce16aa4cdb6a | 108 | case 'd': |
Lugs | 8:ce16aa4cdb6a | 109 | pn_det+=2; |
Lugs | 8:ce16aa4cdb6a | 110 | break; |
Lugs | 8:ce16aa4cdb6a | 111 | case 'e': |
Lugs | 8:ce16aa4cdb6a | 112 | pn_det+=4; |
Lugs | 8:ce16aa4cdb6a | 113 | break; |
Lugs | 8:ce16aa4cdb6a | 114 | case 'f': |
Lugs | 8:ce16aa4cdb6a | 115 | pn_det+=5; |
Lugs | 8:ce16aa4cdb6a | 116 | break; |
Lugs | 8:ce16aa4cdb6a | 117 | case 'g': |
Lugs | 8:ce16aa4cdb6a | 118 | pn_det+=7; |
Lugs | 8:ce16aa4cdb6a | 119 | break; |
Lugs | 8:ce16aa4cdb6a | 120 | case 'a': |
Lugs | 8:ce16aa4cdb6a | 121 | pn_det+=9; |
Lugs | 8:ce16aa4cdb6a | 122 | break; |
Lugs | 8:ce16aa4cdb6a | 123 | case 'b': |
Lugs | 8:ce16aa4cdb6a | 124 | pn_det+=11; |
Lugs | 8:ce16aa4cdb6a | 125 | break; |
Lugs | 8:ce16aa4cdb6a | 126 | case '-': |
Lugs | 8:ce16aa4cdb6a | 127 | pn_det=57; |
Lugs | 12:f9ce63d44ba7 | 128 | goto skipoctaveparse; |
Lugs | 8:ce16aa4cdb6a | 129 | } |
Lugs | 8:ce16aa4cdb6a | 130 | |
Lugs | 8:ce16aa4cdb6a | 131 | songpos++; |
Lugs | 8:ce16aa4cdb6a | 132 | if('0'<=*songpos<='9') { |
Lugs | 8:ce16aa4cdb6a | 133 | int num = strtol(songpos,&songpos,10); |
Lugs | 11:df2fffa042b8 | 134 | num+=3; //nokia composer octaves are usually much too low. |
Lugs | 8:ce16aa4cdb6a | 135 | if(debugState) { |
Lugs | 8:ce16aa4cdb6a | 136 | printf("octave parsed: %i \t-> adder:%i\r\n",num,((num-2)*12)); |
Lugs | 8:ce16aa4cdb6a | 137 | } |
Lugs | 8:ce16aa4cdb6a | 138 | pn_det=pn_det+((num-2)*12); |
Lugs | 12:f9ce63d44ba7 | 139 | } else { |
Lugs | 8:ce16aa4cdb6a | 140 | printf("Found invalid OCTAVE value [%c] at position %li. Skipping word...\r\n",*songpos,songpos-buffer); |
Lugs | 8:ce16aa4cdb6a | 141 | songpos = skipToNextEntry(songpos,0); |
Lugs | 8:ce16aa4cdb6a | 142 | i--; //rewrite current note |
Lugs | 8:ce16aa4cdb6a | 143 | continue; |
Lugs | 8:ce16aa4cdb6a | 144 | } |
Lugs | 12:f9ce63d44ba7 | 145 | skipoctaveparse: |
Lugs | 11:df2fffa042b8 | 146 | song[i].pitch = (pitchname)pn_det; |
Lugs | 10:97f600e6eae2 | 147 | |
Lugs | 8:ce16aa4cdb6a | 148 | if(debugState) { |
Lugs | 8:ce16aa4cdb6a | 149 | printf("Entered pitch [%i] into song[%i].pitch\r\n",song[i].pitch,i); |
Lugs | 8:ce16aa4cdb6a | 150 | printf("Final: {%i,%i} at i=%i\r\n",song[i].length,song[i].pitch,i); |
Lugs | 8:ce16aa4cdb6a | 151 | printf("-------------------\r\n"); |
Lugs | 8:ce16aa4cdb6a | 152 | } |
Lugs | 8:ce16aa4cdb6a | 153 | |
Lugs | 8:ce16aa4cdb6a | 154 | songpos = skipToNextEntry(songpos,1); |
Lugs | 8:ce16aa4cdb6a | 155 | |
Lugs | 8:ce16aa4cdb6a | 156 | //check for buffer end |
Lugs | 8:ce16aa4cdb6a | 157 | if(*(songpos) == '\0') { |
Lugs | 8:ce16aa4cdb6a | 158 | i++; |
Lugs | 8:ce16aa4cdb6a | 159 | song[i].length = 1; |
Lugs | 8:ce16aa4cdb6a | 160 | song[i].pitch = END; |
Lugs | 8:ce16aa4cdb6a | 161 | printf("Parsing done. i = %i\r\n",i); |
Lugs | 8:ce16aa4cdb6a | 162 | return 1; |
Lugs | 8:ce16aa4cdb6a | 163 | } |
Lugs | 8:ce16aa4cdb6a | 164 | if(songpos-buffer > 2048) { |
Lugs | 8:ce16aa4cdb6a | 165 | printf("songpos exceeded buffer size.\r\n"); |
Lugs | 8:ce16aa4cdb6a | 166 | return 0; |
Lugs | 8:ce16aa4cdb6a | 167 | } |
Lugs | 8:ce16aa4cdb6a | 168 | } |
Lugs | 8:ce16aa4cdb6a | 169 | printf("Song exceeded maximum number of notes.\r\n"); |
Lugs | 8:ce16aa4cdb6a | 170 | return 0; |
Lugs | 8:ce16aa4cdb6a | 171 | } |
Lugs | 8:ce16aa4cdb6a | 172 | void printSong(note *song) |
Lugs | 8:ce16aa4cdb6a | 173 | { |
Lugs | 12:f9ce63d44ba7 | 174 | int i; |
Lugs | 8:ce16aa4cdb6a | 175 | for(i=0; song[i].pitch != END; i++) { |
Lugs | 8:ce16aa4cdb6a | 176 | printf("{%i,%i},",song[i].length,song[i].pitch); |
Lugs | 8:ce16aa4cdb6a | 177 | } |
Lugs | 8:ce16aa4cdb6a | 178 | printf("{%i,%i},",song[i].length,song[i].pitch); |
Lugs | 8:ce16aa4cdb6a | 179 | printf("\r\nPrinting done.\r\n"); |
Lugs | 8:ce16aa4cdb6a | 180 | } |
Lugs | 8:ce16aa4cdb6a | 181 | |
Lugs | 8:ce16aa4cdb6a | 182 | int main() |
Lugs | 8:ce16aa4cdb6a | 183 | { |
Lugs | 8:ce16aa4cdb6a | 184 | |
Lugs | 9:17de551d2208 | 185 | startFileSystem(); |
Lugs | 9:17de551d2208 | 186 | |
Lugs | 12:f9ce63d44ba7 | 187 | daplink.printf("\f---daplink SERIAL PORT---\r\n\r\nMINI PIANO PLAYER ver 3 \r\n\r\n\r\n"); |
Lugs | 8:ce16aa4cdb6a | 188 | microUSB.printf("micro USB serial port\r\n"); |
Lugs | 8:ce16aa4cdb6a | 189 | presence(); |
Lugs | 4:24086b80928e | 190 | |
Lugs | 10:97f600e6eae2 | 191 | char *title = new char[24]; |
Lugs | 10:97f600e6eae2 | 192 | title[0] = '/'; |
Lugs | 10:97f600e6eae2 | 193 | title[1] = 'f'; |
Lugs | 10:97f600e6eae2 | 194 | title[2] = 's'; |
Lugs | 10:97f600e6eae2 | 195 | title[3] = '/'; |
Lugs | 10:97f600e6eae2 | 196 | FILE *txtfile; |
Lugs | 11:df2fffa042b8 | 197 | char *buffer = new char[1024]; |
Lugs | 10:97f600e6eae2 | 198 | while(1) { |
Lugs | 10:97f600e6eae2 | 199 | printf("Please input filename: "); |
Lugs | 10:97f600e6eae2 | 200 | char *inputptr = title+4; |
Lugs | 11:df2fffa042b8 | 201 | if(!getInput(24,inputptr)) { |
Lugs | 10:97f600e6eae2 | 202 | printf("Filenames cannot be more than 20 characters.\033[A\r\n"); |
Lugs | 10:97f600e6eae2 | 203 | } |
Lugs | 10:97f600e6eae2 | 204 | txtfile = fopen(title,"r"); |
Lugs | 10:97f600e6eae2 | 205 | if(txtfile == NULL) { |
Lugs | 10:97f600e6eae2 | 206 | printf("File not found. Please append filetype at the end of filename.\033[A\r\n"); |
Lugs | 10:97f600e6eae2 | 207 | continue; |
Lugs | 10:97f600e6eae2 | 208 | } |
Lugs | 10:97f600e6eae2 | 209 | break; |
Lugs | 10:97f600e6eae2 | 210 | } |
Lugs | 10:97f600e6eae2 | 211 | |
Lugs | 9:17de551d2208 | 212 | fseek(txtfile,0L,SEEK_END); |
Lugs | 9:17de551d2208 | 213 | int size = ftell(txtfile); |
Lugs | 9:17de551d2208 | 214 | fseek(txtfile,0,SEEK_SET); |
Lugs | 9:17de551d2208 | 215 | fread(buffer,1,size,txtfile); |
Lugs | 9:17de551d2208 | 216 | printf("Printing file...\r\n"); |
Lugs | 12:f9ce63d44ba7 | 217 | { |
Lugs | 12:f9ce63d44ba7 | 218 | int i; |
Lugs | 12:f9ce63d44ba7 | 219 | for(i=0; i<size; i++) { |
Lugs | 12:f9ce63d44ba7 | 220 | printf("%c",buffer[i]); |
Lugs | 12:f9ce63d44ba7 | 221 | } |
Lugs | 12:f9ce63d44ba7 | 222 | buffer[i] = ' '; |
Lugs | 12:f9ce63d44ba7 | 223 | buffer[i+1] = '\0'; |
Lugs | 12:f9ce63d44ba7 | 224 | buffer[i+2] = 'a'; |
Lugs | 9:17de551d2208 | 225 | } |
Lugs | 4:24086b80928e | 226 | |
Lugs | 4:24086b80928e | 227 | printf("\r\nFile recieved. Parsing...\r\n"); |
Lugs | 8:ce16aa4cdb6a | 228 | |
Lugs | 8:ce16aa4cdb6a | 229 | note song[1024]; |
Lugs | 8:ce16aa4cdb6a | 230 | if(!songParse(song,buffer)) { |
Lugs | 8:ce16aa4cdb6a | 231 | printf("Song parse unsuccessful.\r\n"); |
Lugs | 9:17de551d2208 | 232 | return 0; |
Lugs | 4:24086b80928e | 233 | } |
Lugs | 8:ce16aa4cdb6a | 234 | printSong(song); |
Lugs | 12:f9ce63d44ba7 | 235 | |
Lugs | 12:f9ce63d44ba7 | 236 | loadBuffer(); |
Lugs | 4:24086b80928e | 237 | |
Lugs | 11:df2fffa042b8 | 238 | for(int i = 0; 1; i++) { |
Lugs | 12:f9ce63d44ba7 | 239 | if(pitch2freq(song[i].pitch)==-1) |
Lugs | 12:f9ce63d44ba7 | 240 | { |
Lugs | 12:f9ce63d44ba7 | 241 | break; |
Lugs | 2:93da96b41127 | 242 | } |
Lugs | 12:f9ce63d44ba7 | 243 | playNote(song[i]); |
Lugs | 12:f9ce63d44ba7 | 244 | } |
Lugs | 12:f9ce63d44ba7 | 245 | while(1){ |
Lugs | 12:f9ce63d44ba7 | 246 | rLED = !rLED; |
Lugs | 12:f9ce63d44ba7 | 247 | wait(1); |
Lugs | 0:ad5ce0aff429 | 248 | } |
Lugs | 3:fcf745cd4f6d | 249 | } |
Lugs | 0:ad5ce0aff429 | 250 |