Lawrence Quizon / Mbed OS mini_piano_player

Dependencies:   USBMSD_BD SDFileSystem max32630fthr USBDevice

Committer:
Lugs
Date:
Tue Jul 23 02:48:39 2019 +0000
Revision:
9:17de551d2208
Parent:
8:ce16aa4cdb6a
Child:
10:97f600e6eae2
reads from furelise.txt in the fs. TODO: add variable input.

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