Lawrence Quizon / Mbed OS mini_piano_player

Dependencies:   USBMSD_BD SDFileSystem max32630fthr USBDevice

Committer:
Lugs
Date:
Tue Jul 23 03:34:18 2019 +0000
Revision:
10:97f600e6eae2
Parent:
9:17de551d2208
Child:
11:df2fffa042b8
Working file seeker through daplink. Robustness test not done.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Lugs 0:ad5ce0aff429 1 #include "mbed.h"
Lugs 0:ad5ce0aff429 2 #include "max32630fthr.h"
Lugs 0:ad5ce0aff429 3 #include "USBSerial.h"
Lugs 0:ad5ce0aff429 4 #include "stdio.h"
Lugs 0:ad5ce0aff429 5 #include "SDFileSystem.h"
Lugs 4:24086b80928e 6 #include "ctype.h"
Lugs 9:17de551d2208 7 #include "USBMSD_BD.h"
Lugs 9:17de551d2208 8 #include "SDBlockDevice.h"
Lugs 9:17de551d2208 9 #include "HeapBlockDevice.h"
Lugs 9:17de551d2208 10 #include "FATFileSystem.h"
Lugs 3:fcf745cd4f6d 11
Lugs 0:ad5ce0aff429 12 #define BUFFER_SIZE 128
Lugs 0:ad5ce0aff429 13 #define HALF_BUFFER 64
Lugs 8:ce16aa4cdb6a 14 #define OS_MAINSTKSIZE 1024
Lugs 8:ce16aa4cdb6a 15
Lugs 8:ce16aa4cdb6a 16
Lugs 8:ce16aa4cdb6a 17 bool debugState = 1;
Lugs 0:ad5ce0aff429 18
Lugs 0:ad5ce0aff429 19 DigitalOut rLED(LED1);
Lugs 0:ad5ce0aff429 20 DigitalOut gLED(LED2);
Lugs 0:ad5ce0aff429 21 DigitalOut bLED(LED3);
Lugs 0:ad5ce0aff429 22
Lugs 0:ad5ce0aff429 23 DigitalIn Button(P2_3);
Lugs 0:ad5ce0aff429 24
Lugs 0:ad5ce0aff429 25 MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
Lugs 0:ad5ce0aff429 26 PwmOut PWM(P5_6);
Lugs 0:ad5ce0aff429 27 AnalogIn POT(AIN_0);
Lugs 0:ad5ce0aff429 28 volatile int bufferPOS = 0;
Lugs 8:ce16aa4cdb6a 29 int i;
Lugs 0:ad5ce0aff429 30
Lugs 0:ad5ce0aff429 31 Serial daplink(P2_1,P2_0);
Lugs 0:ad5ce0aff429 32 USBSerial microUSB;
Lugs 0:ad5ce0aff429 33
Lugs 0:ad5ce0aff429 34 float audioDataBuffer[BUFFER_SIZE];
Lugs 0:ad5ce0aff429 35
Lugs 9:17de551d2208 36 // Physical block device, can be any device that supports the BlockDevice API
Lugs 9:17de551d2208 37 // HeapBlockDevice bd(512*BLOCK_SIZE, BLOCK_SIZE);
Lugs 9:17de551d2208 38 SDBlockDevice bd(P0_5, P0_6, P0_4, P0_7);
Lugs 9:17de551d2208 39
Lugs 9:17de551d2208 40 // File system declaration
Lugs 9:17de551d2208 41 FATFileSystem fs("fs");
Lugs 9:17de551d2208 42
Lugs 10:97f600e6eae2 43 // USB MSD
Lugs 10:97f600e6eae2 44 USBMSD_BD msd(&bd);
Lugs 10:97f600e6eae2 45
Lugs 10:97f600e6eae2 46 void clearSerialStream()
Lugs 10:97f600e6eae2 47 {
Lugs 10:97f600e6eae2 48 char c;
Lugs 10:97f600e6eae2 49 while(daplink.readable())
Lugs 10:97f600e6eae2 50 {
Lugs 10:97f600e6eae2 51 c = daplink.getc();
Lugs 10:97f600e6eae2 52 wait_ms(1);
Lugs 10:97f600e6eae2 53 }
Lugs 10:97f600e6eae2 54 }
Lugs 9:17de551d2208 55
Lugs 10:97f600e6eae2 56 bool getInput(int maxSize,char *inputArray)
Lugs 10:97f600e6eae2 57 {
Lugs 10:97f600e6eae2 58 int i;
Lugs 10:97f600e6eae2 59 char c;
Lugs 10:97f600e6eae2 60 clearSerialStream();
Lugs 10:97f600e6eae2 61 for(i=0; i<maxSize && c!='\r'; i++) {
Lugs 10:97f600e6eae2 62 c = daplink.getc();
Lugs 10:97f600e6eae2 63 daplink.putc(c);
Lugs 10:97f600e6eae2 64 inputArray[i] = c;
Lugs 10:97f600e6eae2 65 }
Lugs 10:97f600e6eae2 66 if(i == maxSize){
Lugs 10:97f600e6eae2 67 return 0;
Lugs 10:97f600e6eae2 68 } else {
Lugs 10:97f600e6eae2 69 return 1;
Lugs 10:97f600e6eae2 70 }
Lugs 10:97f600e6eae2 71 }
Lugs 9:17de551d2208 72
Lugs 9:17de551d2208 73 // main() runs in its own thread in the OS
Lugs 9:17de551d2208 74 // (note the calls to Thread::wait below for delays)
Lugs 9:17de551d2208 75 void startFileSystem()
Lugs 9:17de551d2208 76 {
Lugs 9:17de551d2208 77 printf("\f---STARTING FILESYSTEM...---\r\n");
Lugs 9:17de551d2208 78 rLED = LED_ON;
Lugs 9:17de551d2208 79 gLED = LED_ON;
Lugs 9:17de551d2208 80 bLED = LED_OFF;
Lugs 9:17de551d2208 81
Lugs 9:17de551d2208 82 Thread::wait(100);
Lugs 9:17de551d2208 83
Lugs 9:17de551d2208 84 // Try to mount the filesystem
Lugs 9:17de551d2208 85 printf("Mounting the filesystem... ");
Lugs 9:17de551d2208 86 fflush(stdout);
Lugs 9:17de551d2208 87 int err = fs.mount(&bd);
Lugs 9:17de551d2208 88 printf("%s\r\n", (err ? "Fail :(" : "OK"));
Lugs 9:17de551d2208 89 if (err) {
Lugs 9:17de551d2208 90 // Reformat if we can't mount the filesystem
Lugs 9:17de551d2208 91 // this should only happen on the first boot
Lugs 9:17de551d2208 92 printf("No filesystem found, formatting... ");
Lugs 9:17de551d2208 93 fflush(stdout);
Lugs 9:17de551d2208 94 err = fs.reformat(&bd);
Lugs 9:17de551d2208 95 printf("%s\r\n", (err ? "Fail :(" : "OK"));
Lugs 9:17de551d2208 96 }
Lugs 9:17de551d2208 97
Lugs 9:17de551d2208 98 rLED = LED_OFF;
Lugs 9:17de551d2208 99
Lugs 9:17de551d2208 100 // Open the numbers file
Lugs 9:17de551d2208 101 printf("Opening \"/fs/numbers.txt\"... ");
Lugs 9:17de551d2208 102 fflush(stdout);
Lugs 9:17de551d2208 103 FILE *f = fopen("/fs/numbers.txt", "r+");
Lugs 9:17de551d2208 104 printf("%s\r\n", (!f ? "Fail :(" : "OK"));
Lugs 9:17de551d2208 105 if (!f) {
Lugs 9:17de551d2208 106 // Create the numbers file if it doesn't exist
Lugs 9:17de551d2208 107 printf("No file found, creating a new file... ");
Lugs 9:17de551d2208 108 fflush(stdout);
Lugs 9:17de551d2208 109 f = fopen("/fs/numbers.txt", "w+");
Lugs 9:17de551d2208 110 printf("%s\r\n", (!f ? "Fail :(" : "OK"));
Lugs 9:17de551d2208 111
Lugs 9:17de551d2208 112 for (int i = 0; i < 10; i++) {
Lugs 9:17de551d2208 113 printf("\rWriting numbers (%d/%d)... ", i, 10);
Lugs 9:17de551d2208 114 fflush(stdout);
Lugs 9:17de551d2208 115 err = fprintf(f, " %d\r\n", i);
Lugs 9:17de551d2208 116 if (err < 0) {
Lugs 9:17de551d2208 117 printf("Fail :(\r\n");
Lugs 9:17de551d2208 118 }
Lugs 9:17de551d2208 119 }
Lugs 9:17de551d2208 120 printf("\rWriting numbers (%d/%d)... OK\r\n", 10, 10);
Lugs 9:17de551d2208 121
Lugs 9:17de551d2208 122 printf("Seeking file... ");
Lugs 9:17de551d2208 123 fflush(stdout);
Lugs 9:17de551d2208 124 err = fseek(f, 0, SEEK_SET);
Lugs 9:17de551d2208 125 printf("%s\r\n", (err < 0 ? "Fail :(" : "OK"));
Lugs 9:17de551d2208 126 }
Lugs 9:17de551d2208 127
Lugs 9:17de551d2208 128 // Go through and increment the numbers
Lugs 9:17de551d2208 129 for (int i = 0; i < 10; i++) {
Lugs 9:17de551d2208 130 printf("\rIncrementing numbers (%d/%d)... ", i, 10);
Lugs 9:17de551d2208 131 fflush(stdout);
Lugs 9:17de551d2208 132
Lugs 9:17de551d2208 133 // Get current stream position
Lugs 9:17de551d2208 134 long pos = ftell(f);
Lugs 9:17de551d2208 135
Lugs 9:17de551d2208 136 // Parse out the number and increment
Lugs 9:17de551d2208 137 int32_t number;
Lugs 9:17de551d2208 138 fscanf(f, "%d", &number);
Lugs 9:17de551d2208 139 number += 1;
Lugs 9:17de551d2208 140
Lugs 9:17de551d2208 141 // Seek to beginning of number
Lugs 9:17de551d2208 142 fseek(f, pos, SEEK_SET);
Lugs 10:97f600e6eae2 143
Lugs 9:17de551d2208 144 // Store number
Lugs 9:17de551d2208 145 fprintf(f, " %d\r\n", number);
Lugs 9:17de551d2208 146 }
Lugs 9:17de551d2208 147 printf("\rIncrementing numbers (%d/%d)... OK\r\n", 10, 10);
Lugs 9:17de551d2208 148
Lugs 9:17de551d2208 149 // Close the file which also flushes any cached writes
Lugs 9:17de551d2208 150 printf("Closing \"/fs/numbers.txt\"... ");
Lugs 9:17de551d2208 151 fflush(stdout);
Lugs 9:17de551d2208 152 err = fclose(f);
Lugs 9:17de551d2208 153 printf("%s\r\n", (err < 0 ? "Fail :(" : "OK"));
Lugs 9:17de551d2208 154
Lugs 9:17de551d2208 155 // Display the root directory
Lugs 9:17de551d2208 156 printf("Opening the root directory... ");
Lugs 9:17de551d2208 157 fflush(stdout);
Lugs 9:17de551d2208 158 DIR *d = opendir("/fs/");
Lugs 9:17de551d2208 159 printf("%s\r\n", (!d ? "Fail :(" : "OK"));
Lugs 9:17de551d2208 160
Lugs 9:17de551d2208 161 printf("root directory:\r\n");
Lugs 9:17de551d2208 162 while (true) {
Lugs 9:17de551d2208 163 struct dirent *e = readdir(d);
Lugs 9:17de551d2208 164 if (!e) {
Lugs 9:17de551d2208 165 break;
Lugs 9:17de551d2208 166 }
Lugs 9:17de551d2208 167 printf(" %s\r\n", e->d_name);
Lugs 9:17de551d2208 168 }
Lugs 9:17de551d2208 169
Lugs 9:17de551d2208 170 printf("Closing the root directory... ");
Lugs 9:17de551d2208 171 fflush(stdout);
Lugs 9:17de551d2208 172 err = closedir(d);
Lugs 9:17de551d2208 173 printf("%s\r\n", (err < 0 ? "Fail :(" : "OK"));
Lugs 9:17de551d2208 174
Lugs 9:17de551d2208 175 // Display the numbers file
Lugs 9:17de551d2208 176 printf("Opening \"/fs/numbers.txt\"... ");
Lugs 9:17de551d2208 177 fflush(stdout);
Lugs 9:17de551d2208 178 f = fopen("/fs/numbers.txt", "r");
Lugs 9:17de551d2208 179 printf("%s\r\n", (!f ? "Fail :(" : "OK"));
Lugs 9:17de551d2208 180
Lugs 9:17de551d2208 181 printf("numbers:\r\n");
Lugs 9:17de551d2208 182 while (!feof(f)) {
Lugs 9:17de551d2208 183 int c = fgetc(f);
Lugs 9:17de551d2208 184 printf("%c", c);
Lugs 9:17de551d2208 185 }
Lugs 9:17de551d2208 186
Lugs 9:17de551d2208 187 printf("\rClosing \"/fs/numbers.txt\"... ");
Lugs 9:17de551d2208 188 fflush(stdout);
Lugs 9:17de551d2208 189 err = fclose(f);
Lugs 9:17de551d2208 190 printf("%s\r\n", (err < 0 ? "Fail :(" : "OK"));
Lugs 9:17de551d2208 191
Lugs 9:17de551d2208 192
Lugs 9:17de551d2208 193
Lugs 9:17de551d2208 194
Lugs 9:17de551d2208 195 // Switch to MSD
Lugs 9:17de551d2208 196 // printf("Unmounting... ");
Lugs 9:17de551d2208 197 // fflush(stdout);
Lugs 9:17de551d2208 198 // err = fs.unmount();
Lugs 9:17de551d2208 199 // printf("%s\r\n", (err < 0 ? "Fail :(" : "OK"));
Lugs 10:97f600e6eae2 200
Lugs 9:17de551d2208 201
Lugs 9:17de551d2208 202 printf("Starting MSD... ");
Lugs 9:17de551d2208 203 msd.disk_initialize();
Lugs 9:17de551d2208 204 err = msd.connect();
Lugs 9:17de551d2208 205 bLED = LED_ON;
Lugs 9:17de551d2208 206 printf("%s\r\n", (err < 0 ? "Fail :(" : "OK"));
Lugs 9:17de551d2208 207 }
Lugs 9:17de551d2208 208
Lugs 4:24086b80928e 209 struct WavFile {
Lugs 0:ad5ce0aff429 210 long int size;
Lugs 0:ad5ce0aff429 211 int channels;
Lugs 0:ad5ce0aff429 212 int sampleRate;
Lugs 0:ad5ce0aff429 213 int bitsPerSample;
Lugs 0:ad5ce0aff429 214 };
Lugs 0:ad5ce0aff429 215
Lugs 0:ad5ce0aff429 216 float potval,reading;
Lugs 0:ad5ce0aff429 217
Lugs 0:ad5ce0aff429 218 void placeNewSample(void)
Lugs 0:ad5ce0aff429 219 {
Lugs 2:93da96b41127 220 PWM.write(audioDataBuffer[bufferPOS++]); //multiply by POT value for volume.
Lugs 0:ad5ce0aff429 221 bufferPOS = (bufferPOS+1) & 0x07F;
Lugs 0:ad5ce0aff429 222 }
Lugs 0:ad5ce0aff429 223
Lugs 8:ce16aa4cdb6a 224 void presence()
Lugs 4:24086b80928e 225 {
Lugs 0:ad5ce0aff429 226 rLED = LED_ON;
Lugs 0:ad5ce0aff429 227 wait_ms(500);
Lugs 0:ad5ce0aff429 228 rLED = LED_OFF;
Lugs 0:ad5ce0aff429 229 gLED = LED_ON;
Lugs 0:ad5ce0aff429 230 wait_ms(500);
Lugs 0:ad5ce0aff429 231 bLED = LED_ON;
Lugs 0:ad5ce0aff429 232 gLED = LED_OFF;
Lugs 8:ce16aa4cdb6a 233 }
Lugs 4:24086b80928e 234
Lugs 8:ce16aa4cdb6a 235 typedef enum : unsigned char {
Lugs 8:ce16aa4cdb6a 236 C2,Cs2,D2,Ds2,E2,F2,Fs2,G2,Gs2,A2,As2,B2, //C2:0
Lugs 8:ce16aa4cdb6a 237 C3,Cs3,D3,Ds3,E3,F3,Fs3,G3,Gs3,A3,As3,B3, //C3:12
Lugs 8:ce16aa4cdb6a 238 C4,Cs4,D4,Ds4,E4,F4,Fs4,G4,Gs4,A4,As4,B4, //C4:24
Lugs 8:ce16aa4cdb6a 239 C5,Cs5,D5,Ds5,E5,F5,Fs5,G5,Gs5,A5,As5,B5, //C5:36
Lugs 8:ce16aa4cdb6a 240 C6,Cs6,D6,Ds6,E6,F6,Fs6,G6,Gs6, //C6:48
Lugs 8:ce16aa4cdb6a 241 rest,
Lugs 8:ce16aa4cdb6a 242 END
Lugs 8:ce16aa4cdb6a 243 } pitchname;
Lugs 8:ce16aa4cdb6a 244
Lugs 8:ce16aa4cdb6a 245 typedef struct {
Lugs 8:ce16aa4cdb6a 246 unsigned char length;
Lugs 8:ce16aa4cdb6a 247 pitchname pitch;
Lugs 8:ce16aa4cdb6a 248 } note;
Lugs 8:ce16aa4cdb6a 249
Lugs 8:ce16aa4cdb6a 250 char *skipToNextEntry(char *songpos, bool skiptype)
Lugs 8:ce16aa4cdb6a 251 {
Lugs 9:17de551d2208 252 if(skiptype == 0) {
Lugs 8:ce16aa4cdb6a 253 do {
Lugs 8:ce16aa4cdb6a 254 songpos++;
Lugs 8:ce16aa4cdb6a 255 } while(!isspace(*(songpos)));
Lugs 8:ce16aa4cdb6a 256 do {
Lugs 8:ce16aa4cdb6a 257 songpos++;
Lugs 8:ce16aa4cdb6a 258 } while(!isalnum(*(songpos)));
Lugs 8:ce16aa4cdb6a 259 return songpos;
Lugs 9:17de551d2208 260 } else if(skiptype == 1) {
Lugs 8:ce16aa4cdb6a 261 while(!isspace(*(songpos))) {
Lugs 8:ce16aa4cdb6a 262 songpos++;
Lugs 8:ce16aa4cdb6a 263 }
Lugs 8:ce16aa4cdb6a 264 while(isspace(*(songpos))) {
Lugs 8:ce16aa4cdb6a 265 songpos++;
Lugs 8:ce16aa4cdb6a 266 };
Lugs 8:ce16aa4cdb6a 267 }
Lugs 8:ce16aa4cdb6a 268 }
Lugs 8:ce16aa4cdb6a 269
Lugs 8:ce16aa4cdb6a 270 bool songParse(note *song,char *buffer)
Lugs 8:ce16aa4cdb6a 271 {
Lugs 8:ce16aa4cdb6a 272 int candidate;
Lugs 8:ce16aa4cdb6a 273 char *songpos=buffer+1; //song position
Lugs 8:ce16aa4cdb6a 274 int pn_det;
Lugs 8:ce16aa4cdb6a 275 int i;
Lugs 8:ce16aa4cdb6a 276 for(i=0; i<256; i++) {
Lugs 8:ce16aa4cdb6a 277 //take the first base 10 integer you see.
Lugs 8:ce16aa4cdb6a 278 //this initializes songpos ALWAYS. lol.
Lugs 8:ce16aa4cdb6a 279 candidate = strtol(songpos-1,&songpos,10);
Lugs 8:ce16aa4cdb6a 280
Lugs 8:ce16aa4cdb6a 281 if(debugState) {
Lugs 8:ce16aa4cdb6a 282 printf("Character:%i\r\n",candidate);
Lugs 8:ce16aa4cdb6a 283 }
Lugs 8:ce16aa4cdb6a 284
Lugs 8:ce16aa4cdb6a 285 if(candidate == 0) {
Lugs 8:ce16aa4cdb6a 286 printf("Found invalid NOTE LENGTH value [%c] at position %li. Skipping until next whitespace...\r\n",*songpos,songpos-buffer);
Lugs 8:ce16aa4cdb6a 287 songpos = skipToNextEntry(songpos,0);
Lugs 8:ce16aa4cdb6a 288 i--;
Lugs 8:ce16aa4cdb6a 289 continue;
Lugs 8:ce16aa4cdb6a 290 } else {
Lugs 8:ce16aa4cdb6a 291 song[i].length = candidate;
Lugs 8:ce16aa4cdb6a 292 if(debugState) {
Lugs 8:ce16aa4cdb6a 293 printf("Entered candidate [%i] into song[%i].length\r\n",candidate,i);
Lugs 8:ce16aa4cdb6a 294 }
Lugs 8:ce16aa4cdb6a 295 }
Lugs 8:ce16aa4cdb6a 296
Lugs 8:ce16aa4cdb6a 297 //parse next character
Lugs 8:ce16aa4cdb6a 298 if(debugState) {
Lugs 8:ce16aa4cdb6a 299 printf("Character:%c\r\n",*songpos);
Lugs 8:ce16aa4cdb6a 300 }
Lugs 8:ce16aa4cdb6a 301
Lugs 8:ce16aa4cdb6a 302 pn_det=0;
Lugs 4:24086b80928e 303
Lugs 8:ce16aa4cdb6a 304 if(!(*songpos=='#'||'a'<=*songpos<='z'||*songpos=='-')) {
Lugs 8:ce16aa4cdb6a 305 printf("Found invalid PITCH NAME value [%c] at position %li. Skipping word...\r\n",*songpos,songpos-buffer);
Lugs 8:ce16aa4cdb6a 306 songpos = skipToNextEntry(songpos,0);
Lugs 8:ce16aa4cdb6a 307 i--;
Lugs 8:ce16aa4cdb6a 308 continue;
Lugs 8:ce16aa4cdb6a 309 }
Lugs 8:ce16aa4cdb6a 310 if(*songpos=='#') { //watch out for sharps
Lugs 8:ce16aa4cdb6a 311 pn_det+=1;
Lugs 8:ce16aa4cdb6a 312 songpos++;
Lugs 8:ce16aa4cdb6a 313 printf("Sharp found.\r\n");
Lugs 8:ce16aa4cdb6a 314 }
Lugs 8:ce16aa4cdb6a 315 switch(*songpos) {
Lugs 8:ce16aa4cdb6a 316 case 'c':
Lugs 8:ce16aa4cdb6a 317 pn_det+=0;
Lugs 8:ce16aa4cdb6a 318 break;
Lugs 8:ce16aa4cdb6a 319 case 'd':
Lugs 8:ce16aa4cdb6a 320 pn_det+=2;
Lugs 8:ce16aa4cdb6a 321 break;
Lugs 8:ce16aa4cdb6a 322 case 'e':
Lugs 8:ce16aa4cdb6a 323 pn_det+=4;
Lugs 8:ce16aa4cdb6a 324 break;
Lugs 8:ce16aa4cdb6a 325 case 'f':
Lugs 8:ce16aa4cdb6a 326 pn_det+=5;
Lugs 8:ce16aa4cdb6a 327 break;
Lugs 8:ce16aa4cdb6a 328 case 'g':
Lugs 8:ce16aa4cdb6a 329 pn_det+=7;
Lugs 8:ce16aa4cdb6a 330 break;
Lugs 8:ce16aa4cdb6a 331 case 'a':
Lugs 8:ce16aa4cdb6a 332 pn_det+=9;
Lugs 8:ce16aa4cdb6a 333 break;
Lugs 8:ce16aa4cdb6a 334 case 'b':
Lugs 8:ce16aa4cdb6a 335 pn_det+=11;
Lugs 8:ce16aa4cdb6a 336 break;
Lugs 8:ce16aa4cdb6a 337 case '-':
Lugs 8:ce16aa4cdb6a 338 pn_det=57;
Lugs 8:ce16aa4cdb6a 339 goto skipoctaveparse;
Lugs 8:ce16aa4cdb6a 340 }
Lugs 8:ce16aa4cdb6a 341
Lugs 8:ce16aa4cdb6a 342 songpos++;
Lugs 8:ce16aa4cdb6a 343
Lugs 8:ce16aa4cdb6a 344 //parse octaves
Lugs 8:ce16aa4cdb6a 345 if('0'<=*songpos<='9') {
Lugs 8:ce16aa4cdb6a 346 int num = strtol(songpos,&songpos,10);
Lugs 8:ce16aa4cdb6a 347 num+=3;//shift up thrice. board can't handle things this low.
Lugs 8:ce16aa4cdb6a 348 if(debugState) {
Lugs 8:ce16aa4cdb6a 349 printf("octave parsed: %i \t-> adder:%i\r\n",num,((num-2)*12));
Lugs 8:ce16aa4cdb6a 350 }
Lugs 8:ce16aa4cdb6a 351 pn_det=pn_det+((num-2)*12);
Lugs 8:ce16aa4cdb6a 352 } else {
Lugs 8:ce16aa4cdb6a 353 printf("Found invalid OCTAVE value [%c] at position %li. Skipping word...\r\n",*songpos,songpos-buffer);
Lugs 8:ce16aa4cdb6a 354 songpos = skipToNextEntry(songpos,0);
Lugs 8:ce16aa4cdb6a 355 i--; //rewrite current note
Lugs 8:ce16aa4cdb6a 356 continue;
Lugs 8:ce16aa4cdb6a 357 }
Lugs 10:97f600e6eae2 358
Lugs 10:97f600e6eae2 359 skipoctaveparse:
Lugs 8:ce16aa4cdb6a 360
Lugs 8:ce16aa4cdb6a 361 song[i].pitch = (pitchname)pn_det;
Lugs 8:ce16aa4cdb6a 362
Lugs 8:ce16aa4cdb6a 363 if(debugState) {
Lugs 8:ce16aa4cdb6a 364 printf("Entered pitch [%i] into song[%i].pitch\r\n",song[i].pitch,i);
Lugs 8:ce16aa4cdb6a 365 printf("Final: {%i,%i} at i=%i\r\n",song[i].length,song[i].pitch,i);
Lugs 8:ce16aa4cdb6a 366 printf("-------------------\r\n");
Lugs 8:ce16aa4cdb6a 367 }
Lugs 8:ce16aa4cdb6a 368
Lugs 8:ce16aa4cdb6a 369 songpos = skipToNextEntry(songpos,1);
Lugs 8:ce16aa4cdb6a 370
Lugs 8:ce16aa4cdb6a 371 //check for buffer end
Lugs 8:ce16aa4cdb6a 372 if(*(songpos) == '\0') {
Lugs 8:ce16aa4cdb6a 373 i++;
Lugs 8:ce16aa4cdb6a 374 song[i].length = 1;
Lugs 8:ce16aa4cdb6a 375 song[i].pitch = END;
Lugs 8:ce16aa4cdb6a 376 printf("Parsing done. i = %i\r\n",i);
Lugs 8:ce16aa4cdb6a 377 return 1;
Lugs 8:ce16aa4cdb6a 378 }
Lugs 8:ce16aa4cdb6a 379 if(songpos-buffer > 2048) {
Lugs 8:ce16aa4cdb6a 380 printf("songpos exceeded buffer size.\r\n");
Lugs 8:ce16aa4cdb6a 381 return 0;
Lugs 8:ce16aa4cdb6a 382 }
Lugs 8:ce16aa4cdb6a 383 }
Lugs 8:ce16aa4cdb6a 384 printf("Song exceeded maximum number of notes.\r\n");
Lugs 8:ce16aa4cdb6a 385 return 0;
Lugs 8:ce16aa4cdb6a 386 }
Lugs 8:ce16aa4cdb6a 387
Lugs 8:ce16aa4cdb6a 388 void printSong(note *song)
Lugs 8:ce16aa4cdb6a 389 {
Lugs 8:ce16aa4cdb6a 390 for(i=0; song[i].pitch != END; i++) {
Lugs 8:ce16aa4cdb6a 391 printf("{%i,%i},",song[i].length,song[i].pitch);
Lugs 8:ce16aa4cdb6a 392 }
Lugs 8:ce16aa4cdb6a 393 printf("{%i,%i},",song[i].length,song[i].pitch);
Lugs 8:ce16aa4cdb6a 394 printf("\r\nPrinting done.\r\n");
Lugs 8:ce16aa4cdb6a 395 }
Lugs 8:ce16aa4cdb6a 396
Lugs 8:ce16aa4cdb6a 397 int main()
Lugs 8:ce16aa4cdb6a 398 {
Lugs 8:ce16aa4cdb6a 399 WavFile Track;
Lugs 8:ce16aa4cdb6a 400 Ticker SampleTime;
Lugs 8:ce16aa4cdb6a 401
Lugs 9:17de551d2208 402 startFileSystem();
Lugs 9:17de551d2208 403
Lugs 8:ce16aa4cdb6a 404 daplink.printf("\f---DAPLINK SERIAL PORT---\r\n\r\nMINI PIANO PLAYER ver 2 \r\n\r\n\r\n");
Lugs 8:ce16aa4cdb6a 405 microUSB.printf("micro USB serial port\r\n");
Lugs 8:ce16aa4cdb6a 406 presence();
Lugs 4:24086b80928e 407
Lugs 4:24086b80928e 408 //input iterator vars
Lugs 4:24086b80928e 409 int i;
Lugs 10:97f600e6eae2 410
Lugs 10:97f600e6eae2 411 char *title = new char[24];
Lugs 10:97f600e6eae2 412 title[0] = '/';
Lugs 10:97f600e6eae2 413 title[1] = 'f';
Lugs 10:97f600e6eae2 414 title[2] = 's';
Lugs 10:97f600e6eae2 415 title[3] = '/';
Lugs 10:97f600e6eae2 416 FILE *txtfile;
Lugs 8:ce16aa4cdb6a 417 char *buffer = new char[1024]; //ver 2 update: placed in stack.
Lugs 10:97f600e6eae2 418 while(1) {
Lugs 10:97f600e6eae2 419 printf("Please input filename: ");
Lugs 10:97f600e6eae2 420 char *inputptr = title+4;
Lugs 10:97f600e6eae2 421 if(!getInput(24,inputptr))
Lugs 10:97f600e6eae2 422 {
Lugs 10:97f600e6eae2 423 printf("Filenames cannot be more than 20 characters.\033[A\r\n");
Lugs 10:97f600e6eae2 424 }
Lugs 9:17de551d2208 425
Lugs 10:97f600e6eae2 426 //input holder arrays
Lugs 10:97f600e6eae2 427 txtfile = fopen(title,"r");
Lugs 10:97f600e6eae2 428 if(txtfile == NULL) {
Lugs 10:97f600e6eae2 429 printf("File not found. Please append filetype at the end of filename.\033[A\r\n");
Lugs 10:97f600e6eae2 430 continue;
Lugs 10:97f600e6eae2 431 }
Lugs 10:97f600e6eae2 432 break;
Lugs 10:97f600e6eae2 433 }
Lugs 10:97f600e6eae2 434
Lugs 9:17de551d2208 435 //find file size
Lugs 9:17de551d2208 436 fseek(txtfile,0L,SEEK_END);
Lugs 9:17de551d2208 437 int size = ftell(txtfile);
Lugs 9:17de551d2208 438 fseek(txtfile,0,SEEK_SET);
Lugs 9:17de551d2208 439 fread(buffer,1,size,txtfile);
Lugs 9:17de551d2208 440 printf("Printing file...\r\n");
Lugs 10:97f600e6eae2 441 for(i=0; i<size; i++) {
Lugs 9:17de551d2208 442 printf("%c",buffer[i]);
Lugs 9:17de551d2208 443 }
Lugs 9:17de551d2208 444 //open file
Lugs 4:24086b80928e 445 buffer[i] = ' '; //set EOF marker.
Lugs 8:ce16aa4cdb6a 446 buffer[i+1] = '\0';
Lugs 8:ce16aa4cdb6a 447 buffer[i+2] = 'a'; //make sure to put a character after (will allow skipToNextEntry() to find the null character at [songpos-1])
Lugs 4:24086b80928e 448
Lugs 4:24086b80928e 449 //kunwari open na yung file
Lugs 4:24086b80928e 450 printf("\r\nFile recieved. Parsing...\r\n");
Lugs 8:ce16aa4cdb6a 451
Lugs 3:fcf745cd4f6d 452 //parse file into song in heap(remove sharps, put into enums.)
Lugs 8:ce16aa4cdb6a 453 note song[1024];
Lugs 8:ce16aa4cdb6a 454 if(!songParse(song,buffer)) {
Lugs 8:ce16aa4cdb6a 455 printf("Song parse unsuccessful.\r\n");
Lugs 9:17de551d2208 456 return 0;
Lugs 4:24086b80928e 457 }
Lugs 4:24086b80928e 458
Lugs 8:ce16aa4cdb6a 459 printSong(song);
Lugs 4:24086b80928e 460
Lugs 0:ad5ce0aff429 461 printf("Generating sine...\r\n");
Lugs 4:24086b80928e 462 for(i=0; i<128; i++) {
Lugs 0:ad5ce0aff429 463 audioDataBuffer[i] =((1.0 + sin((double(i)/16.0*6.28318530717959)))/2.0); //formula copied from mbed example
Lugs 0:ad5ce0aff429 464 }
Lugs 4:24086b80928e 465
Lugs 4:24086b80928e 466 /* HERE'S WHERE THE MUSIC STARTS */
Lugs 4:24086b80928e 467 /* LITERALLY. */
Lugs 4:24086b80928e 468
Lugs 4:24086b80928e 469 //FORMAT: { NUM_BEATS, PITCH }
Lugs 4:24086b80928e 470 char bpminp[5];
Lugs 4:24086b80928e 471 int PlayingFreq;
Lugs 4:24086b80928e 472 printf("Please enter desired BPM:\r\n");
Lugs 10:97f600e6eae2 473 getInput(5,bpminp);
Lugs 8:ce16aa4cdb6a 474
Lugs 4:24086b80928e 475 printf("BPM Recieved.\r\n");
Lugs 4:24086b80928e 476 int BPM = strtol(bpminp,NULL,0);
Lugs 4:24086b80928e 477 float SPB = 60*4/(float)BPM;
Lugs 4:24086b80928e 478 printf("BPM: %i",BPM);
Lugs 8:ce16aa4cdb6a 479
Lugs 4:24086b80928e 480 restart:
Lugs 4:24086b80928e 481
Lugs 8:ce16aa4cdb6a 482 //buffer input cycle
Lugs 4:24086b80928e 483 for(i = 0; 1; i++) {
Lugs 8:ce16aa4cdb6a 484 //frequency select
Lugs 4:24086b80928e 485 switch(song[i].pitch) {
Lugs 3:fcf745cd4f6d 486 case rest:
Lugs 5:8ba2f1e291b9 487 wait((1/(float)song[i].length)*SPB);
Lugs 3:fcf745cd4f6d 488 continue;
Lugs 3:fcf745cd4f6d 489 case D2:
Lugs 3:fcf745cd4f6d 490 PlayingFreq = 73;
Lugs 3:fcf745cd4f6d 491 break;
Lugs 3:fcf745cd4f6d 492 case Ds2:
Lugs 3:fcf745cd4f6d 493 PlayingFreq = 78;
Lugs 3:fcf745cd4f6d 494 break;
Lugs 3:fcf745cd4f6d 495 case E2:
Lugs 3:fcf745cd4f6d 496 PlayingFreq = 82;
Lugs 3:fcf745cd4f6d 497 break;
Lugs 3:fcf745cd4f6d 498 case F2:
Lugs 3:fcf745cd4f6d 499 PlayingFreq = 87;
Lugs 3:fcf745cd4f6d 500 break;
Lugs 3:fcf745cd4f6d 501 case Fs2:
Lugs 3:fcf745cd4f6d 502 PlayingFreq = 92;
Lugs 3:fcf745cd4f6d 503 break;
Lugs 3:fcf745cd4f6d 504 case G2:
Lugs 2:93da96b41127 505 PlayingFreq = 98;
Lugs 2:93da96b41127 506 break;
Lugs 3:fcf745cd4f6d 507 case Gs2:
Lugs 3:fcf745cd4f6d 508 PlayingFreq = 104;
Lugs 2:93da96b41127 509 break;
Lugs 3:fcf745cd4f6d 510 case A2:
Lugs 2:93da96b41127 511 PlayingFreq = 110;
Lugs 2:93da96b41127 512 break;
Lugs 3:fcf745cd4f6d 513 case As2:
Lugs 2:93da96b41127 514 PlayingFreq = 117;
Lugs 2:93da96b41127 515 break;
Lugs 3:fcf745cd4f6d 516 case B2:
Lugs 2:93da96b41127 517 PlayingFreq = 123;
Lugs 2:93da96b41127 518 break;
Lugs 3:fcf745cd4f6d 519 case C3:
Lugs 2:93da96b41127 520 PlayingFreq = 131;
Lugs 2:93da96b41127 521 break;
Lugs 3:fcf745cd4f6d 522 case Cs3:
Lugs 2:93da96b41127 523 PlayingFreq = 139;
Lugs 2:93da96b41127 524 break;
Lugs 3:fcf745cd4f6d 525 case D3:
Lugs 2:93da96b41127 526 PlayingFreq = 147;
Lugs 2:93da96b41127 527 break;
Lugs 3:fcf745cd4f6d 528 case Ds3:
Lugs 2:93da96b41127 529 PlayingFreq = 156;
Lugs 2:93da96b41127 530 break;
Lugs 3:fcf745cd4f6d 531 case E3:
Lugs 2:93da96b41127 532 PlayingFreq = 165;
Lugs 2:93da96b41127 533 break;
Lugs 3:fcf745cd4f6d 534 case F3:
Lugs 2:93da96b41127 535 PlayingFreq = 175;
Lugs 2:93da96b41127 536 break;
Lugs 3:fcf745cd4f6d 537 case Fs3:
Lugs 2:93da96b41127 538 PlayingFreq = 185;
Lugs 2:93da96b41127 539 break;
Lugs 3:fcf745cd4f6d 540 case G3:
Lugs 2:93da96b41127 541 PlayingFreq = 196;
Lugs 2:93da96b41127 542 break;
Lugs 3:fcf745cd4f6d 543 case Gs3:
Lugs 2:93da96b41127 544 PlayingFreq = 208;
Lugs 2:93da96b41127 545 break;
Lugs 3:fcf745cd4f6d 546 case A3:
Lugs 2:93da96b41127 547 PlayingFreq = 220;
Lugs 2:93da96b41127 548 break;
Lugs 3:fcf745cd4f6d 549 case As3:
Lugs 2:93da96b41127 550 PlayingFreq = 233;
Lugs 2:93da96b41127 551 break;
Lugs 3:fcf745cd4f6d 552 case B3:
Lugs 2:93da96b41127 553 PlayingFreq = 247;
Lugs 2:93da96b41127 554 break;
Lugs 3:fcf745cd4f6d 555 case C4:
Lugs 2:93da96b41127 556 PlayingFreq = 262;
Lugs 2:93da96b41127 557 break;
Lugs 3:fcf745cd4f6d 558 case Cs4:
Lugs 2:93da96b41127 559 PlayingFreq = 277;
Lugs 2:93da96b41127 560 break;
Lugs 3:fcf745cd4f6d 561 case D4:
Lugs 2:93da96b41127 562 PlayingFreq = 294;
Lugs 2:93da96b41127 563 break;
Lugs 3:fcf745cd4f6d 564 case Ds4:
Lugs 2:93da96b41127 565 PlayingFreq = 311;
Lugs 2:93da96b41127 566 break;
Lugs 3:fcf745cd4f6d 567 case E4:
Lugs 2:93da96b41127 568 PlayingFreq = 330;
Lugs 2:93da96b41127 569 break;
Lugs 3:fcf745cd4f6d 570 case F4:
Lugs 2:93da96b41127 571 PlayingFreq = 349;
Lugs 2:93da96b41127 572 break;
Lugs 3:fcf745cd4f6d 573 case Fs4:
Lugs 2:93da96b41127 574 PlayingFreq = 370;
Lugs 2:93da96b41127 575 break;
Lugs 3:fcf745cd4f6d 576 case G4:
Lugs 2:93da96b41127 577 PlayingFreq = 392;
Lugs 2:93da96b41127 578 break;
Lugs 3:fcf745cd4f6d 579 case Gs4:
Lugs 2:93da96b41127 580 PlayingFreq = 415;
Lugs 2:93da96b41127 581 break;
Lugs 3:fcf745cd4f6d 582 case A4:
Lugs 2:93da96b41127 583 PlayingFreq = 440;
Lugs 2:93da96b41127 584 break;
Lugs 3:fcf745cd4f6d 585 case As4:
Lugs 2:93da96b41127 586 PlayingFreq = 466;
Lugs 2:93da96b41127 587 break;
Lugs 3:fcf745cd4f6d 588 case B4:
Lugs 2:93da96b41127 589 PlayingFreq = 494;
Lugs 2:93da96b41127 590 break;
Lugs 3:fcf745cd4f6d 591 case C5:
Lugs 2:93da96b41127 592 PlayingFreq = 523;
Lugs 2:93da96b41127 593 break;
Lugs 3:fcf745cd4f6d 594 case Cs5:
Lugs 2:93da96b41127 595 PlayingFreq = 554;
Lugs 2:93da96b41127 596 break;
Lugs 3:fcf745cd4f6d 597 case D5:
Lugs 2:93da96b41127 598 PlayingFreq = 587;
Lugs 2:93da96b41127 599 break;
Lugs 3:fcf745cd4f6d 600 case Ds5:
Lugs 2:93da96b41127 601 PlayingFreq = 622;
Lugs 2:93da96b41127 602 break;
Lugs 3:fcf745cd4f6d 603 case E5:
Lugs 2:93da96b41127 604 PlayingFreq = 659;
Lugs 2:93da96b41127 605 break;
Lugs 3:fcf745cd4f6d 606 case F5:
Lugs 2:93da96b41127 607 PlayingFreq = 698;
Lugs 2:93da96b41127 608 break;
Lugs 3:fcf745cd4f6d 609 case Fs5:
Lugs 2:93da96b41127 610 PlayingFreq = 740;
Lugs 2:93da96b41127 611 break;
Lugs 3:fcf745cd4f6d 612 case G5:
Lugs 2:93da96b41127 613 PlayingFreq = 784;
Lugs 2:93da96b41127 614 break;
Lugs 3:fcf745cd4f6d 615 case Gs5:
Lugs 2:93da96b41127 616 PlayingFreq = 831;
Lugs 2:93da96b41127 617 break;
Lugs 3:fcf745cd4f6d 618 case A5:
Lugs 2:93da96b41127 619 PlayingFreq = 880;
Lugs 2:93da96b41127 620 break;
Lugs 3:fcf745cd4f6d 621 case As5:
Lugs 2:93da96b41127 622 PlayingFreq = 932;
Lugs 2:93da96b41127 623 break;
Lugs 3:fcf745cd4f6d 624 case B5:
Lugs 2:93da96b41127 625 PlayingFreq = 988;
Lugs 2:93da96b41127 626 break;
Lugs 3:fcf745cd4f6d 627 case C6:
Lugs 2:93da96b41127 628 PlayingFreq = 1047;
Lugs 2:93da96b41127 629 break;
Lugs 3:fcf745cd4f6d 630 case Cs6:
Lugs 2:93da96b41127 631 PlayingFreq = 1109;
Lugs 2:93da96b41127 632 break;
Lugs 3:fcf745cd4f6d 633 case D6:
Lugs 2:93da96b41127 634 PlayingFreq = 1175;
Lugs 2:93da96b41127 635 break;
Lugs 3:fcf745cd4f6d 636 case Ds6:
Lugs 2:93da96b41127 637 PlayingFreq = 1245;
Lugs 2:93da96b41127 638 break;
Lugs 3:fcf745cd4f6d 639 case E6:
Lugs 2:93da96b41127 640 PlayingFreq = 1319;
Lugs 2:93da96b41127 641 break;
Lugs 3:fcf745cd4f6d 642 case F6:
Lugs 2:93da96b41127 643 PlayingFreq = 1397;
Lugs 2:93da96b41127 644 break;
Lugs 3:fcf745cd4f6d 645 case Fs6:
Lugs 2:93da96b41127 646 PlayingFreq = 1480;
Lugs 2:93da96b41127 647 break;
Lugs 3:fcf745cd4f6d 648 case G6:
Lugs 2:93da96b41127 649 PlayingFreq = 1568;
Lugs 2:93da96b41127 650 break;
Lugs 3:fcf745cd4f6d 651 case Gs6:
Lugs 2:93da96b41127 652 PlayingFreq = 1661;
Lugs 2:93da96b41127 653 break;
Lugs 3:fcf745cd4f6d 654 case END:
Lugs 3:fcf745cd4f6d 655 i = 0;
Lugs 4:24086b80928e 656 printf("SONG END. PRESS BUTTON TO RESTART.");
Lugs 8:ce16aa4cdb6a 657 while(Button) {
Lugs 5:8ba2f1e291b9 658 wait_ms(2);
Lugs 4:24086b80928e 659 }
Lugs 3:fcf745cd4f6d 660 goto restart;
Lugs 2:93da96b41127 661 }
Lugs 4:24086b80928e 662
Lugs 8:ce16aa4cdb6a 663 //calculate ticker, attach ticker.
Lugs 3:fcf745cd4f6d 664 Track.sampleRate = PlayingFreq * 16; //TONE FREQ = SAMPLE RATE / SAMPLES PER CYCLE
Lugs 3:fcf745cd4f6d 665 PWM.period_us(1); //1MHz
Lugs 3:fcf745cd4f6d 666 float ticker_period = (float) 1/(Track.sampleRate);
Lugs 3:fcf745cd4f6d 667 printf("\r\nTicker Period: %f\tTicker Freq: %f\r\nTarget Freq: %i \r\n\r\n",ticker_period, 1/ticker_period, PlayingFreq);
Lugs 2:93da96b41127 668
Lugs 3:fcf745cd4f6d 669 SampleTime.attach(&placeNewSample,ticker_period);
Lugs 4:24086b80928e 670 wait( (1/(float)song[i].length) *SPB);
Lugs 3:fcf745cd4f6d 671 SampleTime.detach();
Lugs 8:ce16aa4cdb6a 672
Lugs 8:ce16aa4cdb6a 673
Lugs 4:24086b80928e 674
Lugs 2:93da96b41127 675 printf("\033[A\033[A\033[A\033[A");
Lugs 0:ad5ce0aff429 676 }
Lugs 3:fcf745cd4f6d 677 }
Lugs 0:ad5ce0aff429 678