Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: USBMSD_BD SDFileSystem max32630fthr USBDevice
main.cpp
- Committer:
- Lugs
- Date:
- 2019-07-24
- Revision:
- 11:df2fffa042b8
- Parent:
- 10:97f600e6eae2
- Child:
- 12:f9ce63d44ba7
File content as of revision 11:df2fffa042b8:
#include "mbed.h" #include "max32630fthr.h" #include "USBSerial.h" #include "stdio.h" #include "SDFileSystem.h" #include "ctype.h" #include "USBMSD_BD.h" #include "SDBlockDevice.h" #include "HeapBlockDevice.h" #include "FATFileSystem.h" #include "noteplayer.h" #define BUFFER_SIZE 128 #define HALF_BUFFER 64 #define OS_MAINSTKSIZE 1024 bool debugState = 1; DigitalOut rLED(LED1); DigitalOut gLED(LED2); DigitalOut bLED(LED3); DigitalIn Button(P2_3); MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3); PwmOut PWM(P5_6); AnalogIn POT(AIN_0); volatile int bufferPOS = 0; int i; Serial daplink(P2_1,P2_0); USBSerial microUSB; float audioDataBuffer[BUFFER_SIZE]; // Physical block device, can be any device that supports the BlockDevice API // HeapBlockDevice bd(512*BLOCK_SIZE, BLOCK_SIZE); SDBlockDevice bd(P0_5, P0_6, P0_4, P0_7); // File system declaration FATFileSystem fs("fs"); // USB MSD USBMSD_BD msd(&bd); void clearSerialStream() { char c; while(daplink.readable()) { c = daplink.getc(); wait_ms(1); } } bool getInput(int maxSize,char *inputArray) { int i; char c; clearSerialStream(); for(i=0; i<maxSize && c!='\r'; i++) { c = daplink.getc(); daplink.putc(c); inputArray[i] = c; } if(i == maxSize) { return 0; } else { return 1; } } // main() runs in its own thread in the OS // (note the calls to Thread::wait below for delays) void startFileSystem() { printf("\f---STARTING FILESYSTEM...---\r\n"); rLED = LED_ON; gLED = LED_ON; bLED = LED_OFF; Thread::wait(100); // Try to mount the filesystem printf("Mounting the filesystem... "); fflush(stdout); int err = fs.mount(&bd); printf("%s\r\n", (err ? "Fail :(" : "OK")); if (err) { // Reformat if we can't mount the filesystem // this should only happen on the first boot printf("No filesystem found, formatting... "); fflush(stdout); err = fs.reformat(&bd); printf("%s\r\n", (err ? "Fail :(" : "OK")); } rLED = LED_OFF; // Open the numbers file printf("Opening \"/fs/numbers.txt\"... "); fflush(stdout); FILE *f = fopen("/fs/numbers.txt", "r+"); printf("%s\r\n", (!f ? "Fail :(" : "OK")); if (!f) { // Create the numbers file if it doesn't exist printf("No file found, creating a new file... "); fflush(stdout); f = fopen("/fs/numbers.txt", "w+"); printf("%s\r\n", (!f ? "Fail :(" : "OK")); for (int i = 0; i < 10; i++) { printf("\rWriting numbers (%d/%d)... ", i, 10); fflush(stdout); err = fprintf(f, " %d\r\n", i); if (err < 0) { printf("Fail :(\r\n"); } } printf("\rWriting numbers (%d/%d)... OK\r\n", 10, 10); printf("Seeking file... "); fflush(stdout); err = fseek(f, 0, SEEK_SET); printf("%s\r\n", (err < 0 ? "Fail :(" : "OK")); } // Go through and increment the numbers for (int i = 0; i < 10; i++) { printf("\rIncrementing numbers (%d/%d)... ", i, 10); fflush(stdout); // Get current stream position long pos = ftell(f); // Parse out the number and increment int32_t number; fscanf(f, "%d", &number); number += 1; // Seek to beginning of number fseek(f, pos, SEEK_SET); // Store number fprintf(f, " %d\r\n", number); } printf("\rIncrementing numbers (%d/%d)... OK\r\n", 10, 10); // Close the file which also flushes any cached writes printf("Closing \"/fs/numbers.txt\"... "); fflush(stdout); err = fclose(f); printf("%s\r\n", (err < 0 ? "Fail :(" : "OK")); // Display the root directory printf("Opening the root directory... "); fflush(stdout); DIR *d = opendir("/fs/"); printf("%s\r\n", (!d ? "Fail :(" : "OK")); printf("root directory:\r\n"); while (true) { struct dirent *e = readdir(d); if (!e) { break; } printf(" %s\r\n", e->d_name); } printf("Closing the root directory... "); fflush(stdout); err = closedir(d); printf("%s\r\n", (err < 0 ? "Fail :(" : "OK")); // Display the numbers file printf("Opening \"/fs/numbers.txt\"... "); fflush(stdout); f = fopen("/fs/numbers.txt", "r"); printf("%s\r\n", (!f ? "Fail :(" : "OK")); printf("numbers:\r\n"); while (!feof(f)) { int c = fgetc(f); printf("%c", c); } printf("\rClosing \"/fs/numbers.txt\"... "); fflush(stdout); err = fclose(f); printf("%s\r\n", (err < 0 ? "Fail :(" : "OK")); // Switch to MSD // printf("Unmounting... "); // fflush(stdout); // err = fs.unmount(); // printf("%s\r\n", (err < 0 ? "Fail :(" : "OK")); printf("Starting MSD... "); msd.disk_initialize(); err = msd.connect(); bLED = LED_ON; printf("%s\r\n", (err < 0 ? "Fail :(" : "OK")); } float potval,reading; void placeNewSample(void) { PWM.write(audioDataBuffer[bufferPOS++]); //multiply by POT value for volume. bufferPOS = (bufferPOS+1) & 0x07F; } void presence() { rLED = LED_ON; wait_ms(500); rLED = LED_OFF; gLED = LED_ON; wait_ms(500); bLED = LED_ON; gLED = LED_OFF; } 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; 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; break; } songpos++; if('0'<=*songpos<='9') { int num = strtol(songpos,&songpos,10); num+=3; //nokia composer octaves are usually much too low. if(debugState) { printf("octave parsed: %i \t-> adder:%i\r\n",num,((num-2)*12)); } pn_det=pn_det+((num-2)*12); } else if (*songpos != '-') { 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; } 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() { Ticker SampleTime; startFileSystem(); 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(); char *title = new char[24]; title[0] = '/'; title[1] = 'f'; title[2] = 's'; title[3] = '/'; FILE *txtfile; char *buffer = new char[1024]; while(1) { printf("Please input filename: "); char *inputptr = title+4; if(!getInput(24,inputptr)) { printf("Filenames cannot be more than 20 characters.\033[A\r\n"); } txtfile = fopen(title,"r"); if(txtfile == NULL) { printf("File not found. Please append filetype at the end of filename.\033[A\r\n"); continue; } break; } fseek(txtfile,0L,SEEK_END); int size = ftell(txtfile); fseek(txtfile,0,SEEK_SET); fread(buffer,1,size,txtfile); printf("Printing file...\r\n"); for(int i=0; i<size; i++) { printf("%c",buffer[i]); } buffer[i] = ' '; buffer[i+1] = '\0'; buffer[i+2] = 'a'; printf("\r\nFile recieved. Parsing...\r\n"); note song[1024]; if(!songParse(song,buffer)) { printf("Song parse unsuccessful.\r\n"); return 0; } printSong(song); printf("Generating sine...\r\n"); for(int i=0; i<128; i++) { audioDataBuffer[i] =((1.0 + sin((double(i)/16.0*6.28318530717959)))/2.0); //formula copied from mbed example } char bpminp[5]; printf("Please enter desired BPM:\r\n"); getInput(5,bpminp); int BPM = strtol(bpminp,NULL,0); float SPB = 60*4/(float)BPM; int sampleRate; int PlayingFreq; for(int i = 0; 1; i++) { PlayingFreq = pitch2freq(song[i].pitch); if(PlayingFreq == -1) { i = 0; printf("SONG END. PRESS BUTTON TO RESTART."); while(Button) { wait_ms(2); } } else if(PlayingFreq == 0) { //rest wait((1/(float)song[i].length)*SPB); } else { sampleRate = PlayingFreq * 16; PWM.period_us(1); //1MHz float ticker_period = (float) 1/(sampleRate); printf("\r\nTicker Period: %f\tTicker Freq: %f\r\nTarget Freq: %i \r\n\r\n",ticker_period, 1/ticker_period, PlayingFreq); SampleTime.attach(&placeNewSample,ticker_period); wait((1/(float)song[i].length) *SPB); SampleTime.detach(); printf("\033[A\033[A\033[A\033[A"); } } }