For MAX32630FTHR microcontroller: Plays piano notes in Nokia composer format text file placed in the SD card

Dependencies:   USBMSD_BD SDFileSystem max32630fthr USBDevice

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?

UserRevisionLine numberNew 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