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-23
- Revision:
- 9:17de551d2208
- Parent:
- 8:ce16aa4cdb6a
- Child:
- 10:97f600e6eae2
File content as of revision 9:17de551d2208:
#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" #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); // 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")); } struct WavFile { long int size; int channels; int sampleRate; int bitsPerSample; }; 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; } typedef enum : unsigned char { C2,Cs2,D2,Ds2,E2,F2,Fs2,G2,Gs2,A2,As2,B2, //C2:0 C3,Cs3,D3,Ds3,E3,F3,Fs3,G3,Gs3,A3,As3,B3, //C3:12 C4,Cs4,D4,Ds4,E4,F4,Fs4,G4,Gs4,A4,As4,B4, //C4:24 C5,Cs5,D5,Ds5,E5,F5,Fs5,G5,Gs5,A5,As5,B5, //C5:36 C6,Cs6,D6,Ds6,E6,F6,Fs6,G6,Gs6, //C6:48 rest, END } pitchname; typedef struct { unsigned char length; pitchname pitch; } note; 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; goto skipoctaveparse; } songpos++; //parse octaves if('0'<=*songpos<='9') { int num = strtol(songpos,&songpos,10); num+=3;//shift up thrice. board can't handle things this low. if(debugState) { printf("octave parsed: %i \t-> adder:%i\r\n",num,((num-2)*12)); } pn_det=pn_det+((num-2)*12); } else { 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; } skipoctaveparse: 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() { WavFile Track; 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(); //input iterator vars int i; char c; //input holder arrays char *buffer = new char[1024]; //ver 2 update: placed in stack. FILE *txtfile = fopen("/fs/furelise.txt","r"); //find file size fseek(txtfile,0L,SEEK_END); int size = ftell(txtfile); fseek(txtfile,0,SEEK_SET); if(txtfile == NULL) { printf("File not found.\r\n"); while(1) { bLED = 0; rLED = !rLED; wait_ms(500); } } fread(buffer,1,size,txtfile); printf("Printing file...\r\n"); for(i=0;i<size;i++) { printf("%c",buffer[i]); } //open file buffer[i] = ' '; //set EOF marker. buffer[i+1] = '\0'; buffer[i+2] = 'a'; //make sure to put a character after (will allow skipToNextEntry() to find the null character at [songpos-1]) //kunwari open na yung file printf("\r\nFile recieved. Parsing...\r\n"); //parse file into song in heap(remove sharps, put into enums.) note song[1024]; if(!songParse(song,buffer)) { printf("Song parse unsuccessful.\r\n"); return 0; } printSong(song); printf("Generating sine...\r\n"); for(i=0; i<128; i++) { audioDataBuffer[i] =((1.0 + sin((double(i)/16.0*6.28318530717959)))/2.0); //formula copied from mbed example } /* HERE'S WHERE THE MUSIC STARTS */ /* LITERALLY. */ //FORMAT: { NUM_BEATS, PITCH } char bpminp[5]; int PlayingFreq; printf("Please enter desired BPM:\r\n"); for(i=0; i<5 && c!='\r'; i++) { c = daplink.getc(); daplink.putc(c); bpminp[i] = c; } printf("BPM Recieved.\r\n"); c=NULL; //reset C for next time. int BPM = strtol(bpminp,NULL,0); float SPB = 60*4/(float)BPM; printf("BPM: %i",BPM); restart: //buffer input cycle for(i = 0; 1; i++) { //frequency select switch(song[i].pitch) { case rest: wait((1/(float)song[i].length)*SPB); continue; case D2: PlayingFreq = 73; break; case Ds2: PlayingFreq = 78; break; case E2: PlayingFreq = 82; break; case F2: PlayingFreq = 87; break; case Fs2: PlayingFreq = 92; break; case G2: PlayingFreq = 98; break; case Gs2: PlayingFreq = 104; break; case A2: PlayingFreq = 110; break; case As2: PlayingFreq = 117; break; case B2: PlayingFreq = 123; break; case C3: PlayingFreq = 131; break; case Cs3: PlayingFreq = 139; break; case D3: PlayingFreq = 147; break; case Ds3: PlayingFreq = 156; break; case E3: PlayingFreq = 165; break; case F3: PlayingFreq = 175; break; case Fs3: PlayingFreq = 185; break; case G3: PlayingFreq = 196; break; case Gs3: PlayingFreq = 208; break; case A3: PlayingFreq = 220; break; case As3: PlayingFreq = 233; break; case B3: PlayingFreq = 247; break; case C4: PlayingFreq = 262; break; case Cs4: PlayingFreq = 277; break; case D4: PlayingFreq = 294; break; case Ds4: PlayingFreq = 311; break; case E4: PlayingFreq = 330; break; case F4: PlayingFreq = 349; break; case Fs4: PlayingFreq = 370; break; case G4: PlayingFreq = 392; break; case Gs4: PlayingFreq = 415; break; case A4: PlayingFreq = 440; break; case As4: PlayingFreq = 466; break; case B4: PlayingFreq = 494; break; case C5: PlayingFreq = 523; break; case Cs5: PlayingFreq = 554; break; case D5: PlayingFreq = 587; break; case Ds5: PlayingFreq = 622; break; case E5: PlayingFreq = 659; break; case F5: PlayingFreq = 698; break; case Fs5: PlayingFreq = 740; break; case G5: PlayingFreq = 784; break; case Gs5: PlayingFreq = 831; break; case A5: PlayingFreq = 880; break; case As5: PlayingFreq = 932; break; case B5: PlayingFreq = 988; break; case C6: PlayingFreq = 1047; break; case Cs6: PlayingFreq = 1109; break; case D6: PlayingFreq = 1175; break; case Ds6: PlayingFreq = 1245; break; case E6: PlayingFreq = 1319; break; case F6: PlayingFreq = 1397; break; case Fs6: PlayingFreq = 1480; break; case G6: PlayingFreq = 1568; break; case Gs6: PlayingFreq = 1661; break; case END: i = 0; printf("SONG END. PRESS BUTTON TO RESTART."); while(Button) { wait_ms(2); } goto restart; } //calculate ticker, attach ticker. Track.sampleRate = PlayingFreq * 16; //TONE FREQ = SAMPLE RATE / SAMPLES PER CYCLE PWM.period_us(1); //1MHz float ticker_period = (float) 1/(Track.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"); } }