For MAX323630FTHR: Plays a WAV file in the SD card. Interfaced through serial port using puTTY or powershell.
Dependencies: USBMSD_BD SDFileSystem max32630fthr USBDevice
main.cpp@1:7884bc0fb012, 2019-07-26 (annotated)
- Committer:
- Lugs
- Date:
- Fri Jul 26 01:02:51 2019 +0000
- Revision:
- 1:7884bc0fb012
- Parent:
- 0:12c56a256ee1
- Child:
- 2:d4f9c8c25fa6
final version of playwav command line;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Lugs | 0:12c56a256ee1 | 1 | #include "mbed.h" |
Lugs | 0:12c56a256ee1 | 2 | #include "max32630fthr.h" |
Lugs | 0:12c56a256ee1 | 3 | #include "stdio.h" |
Lugs | 1:7884bc0fb012 | 4 | #include "ctype.h" |
Lugs | 1:7884bc0fb012 | 5 | #include "generalinterface.h" |
Lugs | 0:12c56a256ee1 | 6 | #define BUFFER_SIZE 1024 |
Lugs | 0:12c56a256ee1 | 7 | #define HALF_BUFFER 512 |
Lugs | 0:12c56a256ee1 | 8 | |
Lugs | 1:7884bc0fb012 | 9 | bool debugState = 1; |
Lugs | 1:7884bc0fb012 | 10 | |
Lugs | 0:12c56a256ee1 | 11 | DigitalOut rLED(LED1); |
Lugs | 0:12c56a256ee1 | 12 | DigitalOut gLED(LED2); |
Lugs | 0:12c56a256ee1 | 13 | DigitalOut bLED(LED3); |
Lugs | 0:12c56a256ee1 | 14 | |
Lugs | 0:12c56a256ee1 | 15 | DigitalIn Button(P2_3); |
Lugs | 0:12c56a256ee1 | 16 | |
Lugs | 0:12c56a256ee1 | 17 | MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3); |
Lugs | 1:7884bc0fb012 | 18 | PwmOut PWM(P4_0); |
Lugs | 0:12c56a256ee1 | 19 | AnalogIn POT(AIN_0); |
Lugs | 1:7884bc0fb012 | 20 | int i; |
Lugs | 0:12c56a256ee1 | 21 | volatile int bufferPOS = 0; |
Lugs | 1:7884bc0fb012 | 22 | short audioDataBuffer[BUFFER_SIZE]; |
Lugs | 1:7884bc0fb012 | 23 | struct WavFile { |
Lugs | 0:12c56a256ee1 | 24 | long int size; |
Lugs | 0:12c56a256ee1 | 25 | int channels; |
Lugs | 0:12c56a256ee1 | 26 | int sampleRate; |
Lugs | 0:12c56a256ee1 | 27 | int bitsPerSample; |
Lugs | 0:12c56a256ee1 | 28 | }; |
Lugs | 0:12c56a256ee1 | 29 | |
Lugs | 1:7884bc0fb012 | 30 | float maxSampleVal=1; |
Lugs | 0:12c56a256ee1 | 31 | WavFile Track; |
Lugs | 1:7884bc0fb012 | 32 | Ticker SampleTime; |
Lugs | 1:7884bc0fb012 | 33 | |
Lugs | 1:7884bc0fb012 | 34 | DigitalIn db1(P3_3); |
Lugs | 0:12c56a256ee1 | 35 | |
Lugs | 0:12c56a256ee1 | 36 | void placeNewSample(void) |
Lugs | 0:12c56a256ee1 | 37 | { |
Lugs | 1:7884bc0fb012 | 38 | PWM.write((((float)audioDataBuffer[bufferPOS])/maxSampleVal)+1); //multiply by POT value for volume. |
Lugs | 1:7884bc0fb012 | 39 | bufferPOS = (bufferPOS+2)%BUFFER_SIZE; |
Lugs | 1:7884bc0fb012 | 40 | //if(!Button) |
Lugs | 1:7884bc0fb012 | 41 | //{ |
Lugs | 1:7884bc0fb012 | 42 | // SampleTime.detach(); |
Lugs | 1:7884bc0fb012 | 43 | //} |
Lugs | 1:7884bc0fb012 | 44 | //printf("%i/%f = %f\r\n",audioDataBuffer[bufferPOS],(maxSampleVal),((float)audioDataBuffer[bufferPOS])/maxSampleVal)+1; |
Lugs | 0:12c56a256ee1 | 45 | } |
Lugs | 0:12c56a256ee1 | 46 | |
Lugs | 1:7884bc0fb012 | 47 | void presence() |
Lugs | 1:7884bc0fb012 | 48 | { |
Lugs | 0:12c56a256ee1 | 49 | rLED = LED_ON; |
Lugs | 0:12c56a256ee1 | 50 | wait_ms(500); |
Lugs | 0:12c56a256ee1 | 51 | rLED = LED_OFF; |
Lugs | 0:12c56a256ee1 | 52 | gLED = LED_ON; |
Lugs | 0:12c56a256ee1 | 53 | wait_ms(500); |
Lugs | 0:12c56a256ee1 | 54 | bLED = LED_ON; |
Lugs | 0:12c56a256ee1 | 55 | gLED = LED_OFF; |
Lugs | 1:7884bc0fb012 | 56 | } |
Lugs | 1:7884bc0fb012 | 57 | |
Lugs | 1:7884bc0fb012 | 58 | int main() |
Lugs | 1:7884bc0fb012 | 59 | { |
Lugs | 1:7884bc0fb012 | 60 | startFileSystem(); |
Lugs | 1:7884bc0fb012 | 61 | |
Lugs | 1:7884bc0fb012 | 62 | daplink.printf("\f---DAPLINK SERIAL PORT---\r\n\r\nWAV PLAYER VER 2\r\n\r\n"); |
Lugs | 1:7884bc0fb012 | 63 | microUSB.printf("micro USB serial port\r\n"); |
Lugs | 1:7884bc0fb012 | 64 | |
Lugs | 1:7884bc0fb012 | 65 | presence(); |
Lugs | 1:7884bc0fb012 | 66 | |
Lugs | 1:7884bc0fb012 | 67 | restart: |
Lugs | 1:7884bc0fb012 | 68 | |
Lugs | 1:7884bc0fb012 | 69 | char *title = new char[24]; |
Lugs | 1:7884bc0fb012 | 70 | title[0] = '/'; |
Lugs | 1:7884bc0fb012 | 71 | title[1] = 'f'; |
Lugs | 1:7884bc0fb012 | 72 | title[2] = 's'; |
Lugs | 1:7884bc0fb012 | 73 | title[3] = '/'; |
Lugs | 1:7884bc0fb012 | 74 | FILE *audio; |
Lugs | 1:7884bc0fb012 | 75 | while(1) { |
Lugs | 1:7884bc0fb012 | 76 | printf("Please input filename: "); |
Lugs | 1:7884bc0fb012 | 77 | char *inputptr = title+4; |
Lugs | 1:7884bc0fb012 | 78 | if(!getInput(24,inputptr)) { |
Lugs | 1:7884bc0fb012 | 79 | printf("Filenames cannot be more than 20 characters.\033[A\r\n"); |
Lugs | 1:7884bc0fb012 | 80 | } |
Lugs | 1:7884bc0fb012 | 81 | audio = fopen(title,"r"); |
Lugs | 1:7884bc0fb012 | 82 | if(audio == NULL) { |
Lugs | 1:7884bc0fb012 | 83 | printf("File not found. Please append filetype at the end of filename.\033[A\r\n"); |
Lugs | 1:7884bc0fb012 | 84 | continue; |
Lugs | 1:7884bc0fb012 | 85 | } |
Lugs | 1:7884bc0fb012 | 86 | break; |
Lugs | 0:12c56a256ee1 | 87 | } |
Lugs | 1:7884bc0fb012 | 88 | printf("\r\nFile opened.\r\n\r\n"); |
Lugs | 1:7884bc0fb012 | 89 | |
Lugs | 0:12c56a256ee1 | 90 | //find file size |
Lugs | 0:12c56a256ee1 | 91 | fseek(audio,0L,SEEK_END); |
Lugs | 0:12c56a256ee1 | 92 | Track.size = ftell(audio); |
Lugs | 1:7884bc0fb012 | 93 | |
Lugs | 0:12c56a256ee1 | 94 | printf("File Size:%li \r\n",Track.size); |
Lugs | 1:7884bc0fb012 | 95 | |
Lugs | 1:7884bc0fb012 | 96 | //read sample rate and channels of wav file |
Lugs | 0:12c56a256ee1 | 97 | fseek(audio,22,SEEK_SET); |
Lugs | 1:7884bc0fb012 | 98 | fread(&Track.channels, 2, 1,audio); |
Lugs | 1:7884bc0fb012 | 99 | fread(&Track.sampleRate, 2, 1,audio); |
Lugs | 0:12c56a256ee1 | 100 | printf("Sample Rate: %i\r\n",Track.sampleRate); |
Lugs | 0:12c56a256ee1 | 101 | printf("%i channels \r\n",Track.channels); |
Lugs | 1:7884bc0fb012 | 102 | if(Track.sampleRate >= 20000) { |
Lugs | 1:7884bc0fb012 | 103 | printf("WARNING: Microcontroller may not be able to play sample rates higher than 20kHz properly.\r\n"); |
Lugs | 1:7884bc0fb012 | 104 | } |
Lugs | 1:7884bc0fb012 | 105 | |
Lugs | 0:12c56a256ee1 | 106 | //read bits per sample |
Lugs | 0:12c56a256ee1 | 107 | fseek(audio,34,SEEK_SET); |
Lugs | 0:12c56a256ee1 | 108 | fread(audioDataBuffer, 2, 1,audio); |
Lugs | 0:12c56a256ee1 | 109 | Track.bitsPerSample = (audioDataBuffer[1] << 8) + audioDataBuffer[0]; |
Lugs | 0:12c56a256ee1 | 110 | printf("Bits Per Sample: %i\r\n",Track.bitsPerSample); |
Lugs | 1:7884bc0fb012 | 111 | for(int i=0;i<Track.bitsPerSample;i++) |
Lugs | 1:7884bc0fb012 | 112 | { |
Lugs | 1:7884bc0fb012 | 113 | maxSampleVal *= 2; |
Lugs | 1:7884bc0fb012 | 114 | } |
Lugs | 1:7884bc0fb012 | 115 | maxSampleVal/=2; |
Lugs | 1:7884bc0fb012 | 116 | |
Lugs | 1:7884bc0fb012 | 117 | |
Lugs | 0:12c56a256ee1 | 118 | int flag; |
Lugs | 0:12c56a256ee1 | 119 | //find start of actual audio |
Lugs | 0:12c56a256ee1 | 120 | fseek(audio,44,SEEK_SET); |
Lugs | 1:7884bc0fb012 | 121 | |
Lugs | 1:7884bc0fb012 | 122 | printf("Size: %i bytes\r\n",Track.size); |
Lugs | 1:7884bc0fb012 | 123 | |
Lugs | 1:7884bc0fb012 | 124 | PWM.period_us(10); |
Lugs | 1:7884bc0fb012 | 125 | short size = sizeof(short); |
Lugs | 0:12c56a256ee1 | 126 | |
Lugs | 1:7884bc0fb012 | 127 | fread((void *)audioDataBuffer,size,HALF_BUFFER,audio); |
Lugs | 1:7884bc0fb012 | 128 | printf("Sample time will be attached with period %f.",1.0/(double)(Track.sampleRate)); |
Lugs | 1:7884bc0fb012 | 129 | SampleTime.attach(&placeNewSample,1.0/(double)(Track.sampleRate)); |
Lugs | 1:7884bc0fb012 | 130 | //microcontroller may not be strong enough to call fread after attaching a 44.1kHz wav file. |
Lugs | 1:7884bc0fb012 | 131 | printf("\r\nTicker attached.\r\nRunning buffer loop...\r\n\r\n"); |
Lugs | 0:12c56a256ee1 | 132 | |
Lugs | 1:7884bc0fb012 | 133 | //take the first block of audio data into the buffer (buffer size is two blocks) |
Lugs | 1:7884bc0fb012 | 134 | flag = 0; |
Lugs | 1:7884bc0fb012 | 135 | while(ftell(audio) < Track.size) { |
Lugs | 1:7884bc0fb012 | 136 | if((bufferPOS < HALF_BUFFER) && flag == 0) { |
Lugs | 1:7884bc0fb012 | 137 | fread((void *)(audioDataBuffer + HALF_BUFFER),size,HALF_BUFFER,audio); |
Lugs | 1:7884bc0fb012 | 138 | flag = !flag; |
Lugs | 1:7884bc0fb012 | 139 | } else if((bufferPOS >= HALF_BUFFER) && flag == 1) { |
Lugs | 1:7884bc0fb012 | 140 | fread((void *)audioDataBuffer,size,HALF_BUFFER,audio); |
Lugs | 1:7884bc0fb012 | 141 | flag = !flag; |
Lugs | 1:7884bc0fb012 | 142 | } |
Lugs | 1:7884bc0fb012 | 143 | } |
Lugs | 1:7884bc0fb012 | 144 | SampleTime.detach(); |
Lugs | 1:7884bc0fb012 | 145 | bLED=LED_OFF; |
Lugs | 1:7884bc0fb012 | 146 | rLED=LED_ON; |
Lugs | 1:7884bc0fb012 | 147 | while(1) |
Lugs | 0:12c56a256ee1 | 148 | { |
Lugs | 1:7884bc0fb012 | 149 | if(!db1) |
Lugs | 0:12c56a256ee1 | 150 | { |
Lugs | 1:7884bc0fb012 | 151 | goto restart; |
Lugs | 0:12c56a256ee1 | 152 | } |
Lugs | 0:12c56a256ee1 | 153 | } |
Lugs | 0:12c56a256ee1 | 154 | }; |
Lugs | 0:12c56a256ee1 | 155 |