Read an wav file from sdcard and play it through I2S on LPC4088 QSB platform
Dependencies: EALib I2SSlave TLV320 mbed
Fork of playback by
works with 16bits / 44,1 khz files.
I'm going to work on 24/32 bits, 48khz 96 khz files...
main.cpp@2:ce93bf118649, 2016-07-23 (annotated)
- Committer:
- Grag38
- Date:
- Sat Jul 23 21:29:39 2016 +0000
- Revision:
- 2:ce93bf118649
- Parent:
- 0:3d6892f6384f
This example project works with the LPC4088 QSB.; It reads a wav file from the sdcard (libs are in the EALib from Embedded Artist) and output it to the dac (TLV320 as RS-Audio board).; ; Hope it will helps who works with I2S with LPC4088
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
d_worrall | 0:3d6892f6384f | 1 | #include "mbed.h" |
d_worrall | 0:3d6892f6384f | 2 | #include "TLV320.h" |
Grag38 | 2:ce93bf118649 | 3 | |
Grag38 | 2:ce93bf118649 | 4 | Serial pc(USBTX, USBRX); |
d_worrall | 0:3d6892f6384f | 5 | |
Grag38 | 2:ce93bf118649 | 6 | /****************************************************************************** |
Grag38 | 2:ce93bf118649 | 7 | * Includes |
Grag38 | 2:ce93bf118649 | 8 | *****************************************************************************/ |
Grag38 | 2:ce93bf118649 | 9 | #include "MCIFileSystem.h" |
Grag38 | 2:ce93bf118649 | 10 | |
Grag38 | 2:ce93bf118649 | 11 | /****************************************************************************** |
Grag38 | 2:ce93bf118649 | 12 | * Typedefs and defines |
Grag38 | 2:ce93bf118649 | 13 | *****************************************************************************/ |
Grag38 | 2:ce93bf118649 | 14 | |
Grag38 | 2:ce93bf118649 | 15 | typedef bool (*syncFunc)(const char* name, bool isDir); |
Grag38 | 2:ce93bf118649 | 16 | |
Grag38 | 2:ce93bf118649 | 17 | /****************************************************************************** |
Grag38 | 2:ce93bf118649 | 18 | * Local variables |
Grag38 | 2:ce93bf118649 | 19 | *****************************************************************************/ |
Grag38 | 2:ce93bf118649 | 20 | |
Grag38 | 2:ce93bf118649 | 21 | MCIFileSystem mcifs("mci"); |
Grag38 | 2:ce93bf118649 | 22 | |
Grag38 | 2:ce93bf118649 | 23 | DigitalOut myled1(LED1); |
Grag38 | 2:ce93bf118649 | 24 | DigitalOut myled2(LED2); |
Grag38 | 2:ce93bf118649 | 25 | |
Grag38 | 2:ce93bf118649 | 26 | /****************************************************************************** |
Grag38 | 2:ce93bf118649 | 27 | * Local functions |
Grag38 | 2:ce93bf118649 | 28 | *****************************************************************************/ |
Grag38 | 2:ce93bf118649 | 29 | |
Grag38 | 2:ce93bf118649 | 30 | static void ledShowProgress() |
Grag38 | 2:ce93bf118649 | 31 | { |
Grag38 | 2:ce93bf118649 | 32 | static int state = 0; |
Grag38 | 2:ce93bf118649 | 33 | state = (state + 1) % 2; |
Grag38 | 2:ce93bf118649 | 34 | switch (state) |
Grag38 | 2:ce93bf118649 | 35 | { |
Grag38 | 2:ce93bf118649 | 36 | case 0: |
Grag38 | 2:ce93bf118649 | 37 | myled1 = 1; |
Grag38 | 2:ce93bf118649 | 38 | myled2 = 0; |
Grag38 | 2:ce93bf118649 | 39 | break; |
Grag38 | 2:ce93bf118649 | 40 | |
Grag38 | 2:ce93bf118649 | 41 | case 1: |
Grag38 | 2:ce93bf118649 | 42 | default: |
Grag38 | 2:ce93bf118649 | 43 | myled1 = 0; |
Grag38 | 2:ce93bf118649 | 44 | myled2 = 1; |
Grag38 | 2:ce93bf118649 | 45 | } |
Grag38 | 2:ce93bf118649 | 46 | } |
Grag38 | 2:ce93bf118649 | 47 | |
Grag38 | 2:ce93bf118649 | 48 | static void handleError(const char* msg) |
Grag38 | 2:ce93bf118649 | 49 | { |
Grag38 | 2:ce93bf118649 | 50 | printf(msg); |
Grag38 | 2:ce93bf118649 | 51 | while(true) { |
Grag38 | 2:ce93bf118649 | 52 | myled1 = 1; |
Grag38 | 2:ce93bf118649 | 53 | myled2 = 1; |
Grag38 | 2:ce93bf118649 | 54 | wait(0.3); |
Grag38 | 2:ce93bf118649 | 55 | myled1 = 0; |
Grag38 | 2:ce93bf118649 | 56 | myled2 = 0; |
Grag38 | 2:ce93bf118649 | 57 | wait(0.3); |
Grag38 | 2:ce93bf118649 | 58 | } |
Grag38 | 2:ce93bf118649 | 59 | } |
Grag38 | 2:ce93bf118649 | 60 | |
Grag38 | 2:ce93bf118649 | 61 | static bool recursiveProcessFS(char* buff, const char* name, syncFunc func, bool adding) |
Grag38 | 2:ce93bf118649 | 62 | { |
Grag38 | 2:ce93bf118649 | 63 | uint32_t len = strlen(buff); |
Grag38 | 2:ce93bf118649 | 64 | if (len > 0) { |
Grag38 | 2:ce93bf118649 | 65 | if (buff[len - 1] != '/') { |
Grag38 | 2:ce93bf118649 | 66 | buff[len++] = '/'; |
Grag38 | 2:ce93bf118649 | 67 | buff[len] = '\0'; |
Grag38 | 2:ce93bf118649 | 68 | } |
Grag38 | 2:ce93bf118649 | 69 | } |
Grag38 | 2:ce93bf118649 | 70 | strcat(buff, name); |
Grag38 | 2:ce93bf118649 | 71 | len += strlen(name); |
Grag38 | 2:ce93bf118649 | 72 | |
Grag38 | 2:ce93bf118649 | 73 | if (len > 60) { |
Grag38 | 2:ce93bf118649 | 74 | // ugly fix to avoid crashes that occurs when file name is larger than buffer |
Grag38 | 2:ce93bf118649 | 75 | // in FATFileSystem. |
Grag38 | 2:ce93bf118649 | 76 | printf("skipped: %s\n", buff); |
Grag38 | 2:ce93bf118649 | 77 | return true; |
Grag38 | 2:ce93bf118649 | 78 | } |
Grag38 | 2:ce93bf118649 | 79 | |
Grag38 | 2:ce93bf118649 | 80 | DIR *d = opendir(buff); |
Grag38 | 2:ce93bf118649 | 81 | bool result = true; // success |
Grag38 | 2:ce93bf118649 | 82 | if (d != NULL) { |
Grag38 | 2:ce93bf118649 | 83 | if (adding) { |
Grag38 | 2:ce93bf118649 | 84 | // when processing in adding mode folders must be created before it's content |
Grag38 | 2:ce93bf118649 | 85 | result = func(buff, true); |
Grag38 | 2:ce93bf118649 | 86 | } |
Grag38 | 2:ce93bf118649 | 87 | struct dirent *p; |
Grag38 | 2:ce93bf118649 | 88 | while (result && ((p = readdir(d)) != NULL)) { |
Grag38 | 2:ce93bf118649 | 89 | result = recursiveProcessFS(buff, p->d_name, func, adding); |
Grag38 | 2:ce93bf118649 | 90 | buff[len] = '\0'; |
Grag38 | 2:ce93bf118649 | 91 | } |
Grag38 | 2:ce93bf118649 | 92 | closedir(d); |
Grag38 | 2:ce93bf118649 | 93 | if (result && !adding) { |
Grag38 | 2:ce93bf118649 | 94 | // when processing in removing mode folders must be deleted after it's content |
Grag38 | 2:ce93bf118649 | 95 | result = func(buff, true); |
Grag38 | 2:ce93bf118649 | 96 | } |
Grag38 | 2:ce93bf118649 | 97 | } else { |
Grag38 | 2:ce93bf118649 | 98 | // a file |
Grag38 | 2:ce93bf118649 | 99 | result = func(buff, false); |
Grag38 | 2:ce93bf118649 | 100 | } |
Grag38 | 2:ce93bf118649 | 101 | return result; |
Grag38 | 2:ce93bf118649 | 102 | } |
Grag38 | 2:ce93bf118649 | 103 | |
Grag38 | 2:ce93bf118649 | 104 | static uint32_t fileLen(FILE* f) |
Grag38 | 2:ce93bf118649 | 105 | { |
Grag38 | 2:ce93bf118649 | 106 | uint32_t pos = ftell(f); |
Grag38 | 2:ce93bf118649 | 107 | fseek(f, 0, SEEK_END); |
Grag38 | 2:ce93bf118649 | 108 | uint32_t size = ftell(f); |
Grag38 | 2:ce93bf118649 | 109 | fseek(f, pos, SEEK_SET); |
Grag38 | 2:ce93bf118649 | 110 | return size; |
Grag38 | 2:ce93bf118649 | 111 | } |
Grag38 | 2:ce93bf118649 | 112 | |
Grag38 | 2:ce93bf118649 | 113 | static bool copyFH(FILE* fSrc, FILE* fDst) |
Grag38 | 2:ce93bf118649 | 114 | { |
Grag38 | 2:ce93bf118649 | 115 | char buff[512]; |
Grag38 | 2:ce93bf118649 | 116 | uint32_t left = fileLen(fSrc); |
Grag38 | 2:ce93bf118649 | 117 | uint32_t num; |
Grag38 | 2:ce93bf118649 | 118 | uint32_t chunk; |
Grag38 | 2:ce93bf118649 | 119 | |
Grag38 | 2:ce93bf118649 | 120 | fseek(fSrc, 0, SEEK_SET); |
Grag38 | 2:ce93bf118649 | 121 | do { |
Grag38 | 2:ce93bf118649 | 122 | chunk = (left < 512) ? left : 512; |
Grag38 | 2:ce93bf118649 | 123 | num = fread(buff, 1, chunk, fSrc); |
Grag38 | 2:ce93bf118649 | 124 | if (num > 0) { |
Grag38 | 2:ce93bf118649 | 125 | uint32_t tmp = fwrite(buff, 1, num, fDst); |
Grag38 | 2:ce93bf118649 | 126 | if (tmp != num) { |
Grag38 | 2:ce93bf118649 | 127 | // failed to write |
Grag38 | 2:ce93bf118649 | 128 | return false; |
Grag38 | 2:ce93bf118649 | 129 | } |
Grag38 | 2:ce93bf118649 | 130 | left -= num; |
Grag38 | 2:ce93bf118649 | 131 | ledShowProgress(); |
Grag38 | 2:ce93bf118649 | 132 | } |
Grag38 | 2:ce93bf118649 | 133 | } while(num > 0 && left > 0); |
Grag38 | 2:ce93bf118649 | 134 | |
Grag38 | 2:ce93bf118649 | 135 | // copied entire file |
Grag38 | 2:ce93bf118649 | 136 | return true; |
Grag38 | 2:ce93bf118649 | 137 | } |
Grag38 | 2:ce93bf118649 | 138 | |
Grag38 | 2:ce93bf118649 | 139 | static bool copy(const char* fnameSrc, const char* fnameDest) |
Grag38 | 2:ce93bf118649 | 140 | { |
Grag38 | 2:ce93bf118649 | 141 | FILE* fhSrc = NULL; |
Grag38 | 2:ce93bf118649 | 142 | FILE* fhDest = NULL; |
Grag38 | 2:ce93bf118649 | 143 | bool success = false; |
Grag38 | 2:ce93bf118649 | 144 | |
Grag38 | 2:ce93bf118649 | 145 | do { |
Grag38 | 2:ce93bf118649 | 146 | fhSrc = fopen(fnameSrc, "r"); |
Grag38 | 2:ce93bf118649 | 147 | if (fhSrc == NULL) { |
Grag38 | 2:ce93bf118649 | 148 | break; |
Grag38 | 2:ce93bf118649 | 149 | } |
Grag38 | 2:ce93bf118649 | 150 | |
Grag38 | 2:ce93bf118649 | 151 | fhDest = fopen(fnameDest, "w"); |
Grag38 | 2:ce93bf118649 | 152 | if (fhDest == NULL) { |
Grag38 | 2:ce93bf118649 | 153 | break; |
Grag38 | 2:ce93bf118649 | 154 | } |
Grag38 | 2:ce93bf118649 | 155 | |
Grag38 | 2:ce93bf118649 | 156 | if (!copyFH(fhSrc, fhDest)) { |
Grag38 | 2:ce93bf118649 | 157 | break; |
Grag38 | 2:ce93bf118649 | 158 | } |
Grag38 | 2:ce93bf118649 | 159 | |
Grag38 | 2:ce93bf118649 | 160 | success = true; |
Grag38 | 2:ce93bf118649 | 161 | } while (false); |
Grag38 | 2:ce93bf118649 | 162 | |
Grag38 | 2:ce93bf118649 | 163 | if (fhSrc != NULL) { |
Grag38 | 2:ce93bf118649 | 164 | fclose(fhSrc); |
Grag38 | 2:ce93bf118649 | 165 | } |
Grag38 | 2:ce93bf118649 | 166 | if (fhDest != NULL) { |
Grag38 | 2:ce93bf118649 | 167 | fclose(fhDest); |
Grag38 | 2:ce93bf118649 | 168 | } |
Grag38 | 2:ce93bf118649 | 169 | |
Grag38 | 2:ce93bf118649 | 170 | return success; |
Grag38 | 2:ce93bf118649 | 171 | } |
Grag38 | 2:ce93bf118649 | 172 | |
Grag38 | 2:ce93bf118649 | 173 | static bool list(const char* name, bool isDir) |
Grag38 | 2:ce93bf118649 | 174 | { |
Grag38 | 2:ce93bf118649 | 175 | if (isDir) { |
Grag38 | 2:ce93bf118649 | 176 | printf("d: %s\n", name); |
Grag38 | 2:ce93bf118649 | 177 | } else { |
Grag38 | 2:ce93bf118649 | 178 | FILE* f = fopen(name, "r"); |
Grag38 | 2:ce93bf118649 | 179 | if (f != NULL) { |
Grag38 | 2:ce93bf118649 | 180 | uint32_t len = fileLen(f); |
Grag38 | 2:ce93bf118649 | 181 | printf("f: %7u %s\n", len, name); |
Grag38 | 2:ce93bf118649 | 182 | fclose(f); |
Grag38 | 2:ce93bf118649 | 183 | } else { |
Grag38 | 2:ce93bf118649 | 184 | printf("f: ??? %s\n", name); |
Grag38 | 2:ce93bf118649 | 185 | } |
Grag38 | 2:ce93bf118649 | 186 | } |
Grag38 | 2:ce93bf118649 | 187 | return true; |
Grag38 | 2:ce93bf118649 | 188 | } |
Grag38 | 2:ce93bf118649 | 189 | |
Grag38 | 2:ce93bf118649 | 190 | static void recursiveList(const char* dirname) |
Grag38 | 2:ce93bf118649 | 191 | { |
Grag38 | 2:ce93bf118649 | 192 | printf("\nRecursive list of file and folders in %s\n", dirname); |
Grag38 | 2:ce93bf118649 | 193 | char* buff = (char*)malloc(512); |
Grag38 | 2:ce93bf118649 | 194 | if (buff != NULL) |
Grag38 | 2:ce93bf118649 | 195 | { |
Grag38 | 2:ce93bf118649 | 196 | buff[0] = '\0'; |
Grag38 | 2:ce93bf118649 | 197 | recursiveProcessFS(buff, dirname, list, true); |
Grag38 | 2:ce93bf118649 | 198 | free(buff); |
Grag38 | 2:ce93bf118649 | 199 | } |
Grag38 | 2:ce93bf118649 | 200 | } |
Grag38 | 2:ce93bf118649 | 201 | |
Grag38 | 2:ce93bf118649 | 202 | static void testAppend(const char* filename) |
Grag38 | 2:ce93bf118649 | 203 | { |
Grag38 | 2:ce93bf118649 | 204 | FILE *fp = fopen(filename, "a"); |
Grag38 | 2:ce93bf118649 | 205 | if (fp != NULL) { |
Grag38 | 2:ce93bf118649 | 206 | fprintf(fp, "Hello World!"); |
Grag38 | 2:ce93bf118649 | 207 | fclose(fp); |
Grag38 | 2:ce93bf118649 | 208 | } |
Grag38 | 2:ce93bf118649 | 209 | } |
Grag38 | 2:ce93bf118649 | 210 | |
Grag38 | 2:ce93bf118649 | 211 | /****************************************************************************** |
Grag38 | 2:ce93bf118649 | 212 | * TestSdCard function |
Grag38 | 2:ce93bf118649 | 213 | *****************************************************************************/ |
Grag38 | 2:ce93bf118649 | 214 | |
Grag38 | 2:ce93bf118649 | 215 | int TestSdCard() |
Grag38 | 2:ce93bf118649 | 216 | { |
Grag38 | 2:ce93bf118649 | 217 | printf("\n-----------------\n\nWelcome to the MCI file system example...\n"); |
Grag38 | 2:ce93bf118649 | 218 | |
Grag38 | 2:ce93bf118649 | 219 | if (!mcifs.cardInserted()) { |
Grag38 | 2:ce93bf118649 | 220 | printf("Please insert a SD/MMC card...\n"); |
Grag38 | 2:ce93bf118649 | 221 | while (!mcifs.cardInserted()) { |
Grag38 | 2:ce93bf118649 | 222 | wait(0.5); |
Grag38 | 2:ce93bf118649 | 223 | } |
Grag38 | 2:ce93bf118649 | 224 | printf("Card detected!\n"); |
Grag38 | 2:ce93bf118649 | 225 | } |
Grag38 | 2:ce93bf118649 | 226 | |
Grag38 | 2:ce93bf118649 | 227 | recursiveList("/mci/"); |
Grag38 | 2:ce93bf118649 | 228 | |
Grag38 | 2:ce93bf118649 | 229 | copy("/mci/expanding.txt", "/mci/expanding.old"); |
Grag38 | 2:ce93bf118649 | 230 | testAppend("/mci/expanding.txt"); |
Grag38 | 2:ce93bf118649 | 231 | |
Grag38 | 2:ce93bf118649 | 232 | //recursiveList("/mci/"); |
Grag38 | 2:ce93bf118649 | 233 | |
Grag38 | 2:ce93bf118649 | 234 | |
Grag38 | 2:ce93bf118649 | 235 | |
Grag38 | 2:ce93bf118649 | 236 | printf("Found SD/MMC card, writing to /mci/myfile.txt ...\n"); |
Grag38 | 2:ce93bf118649 | 237 | |
Grag38 | 2:ce93bf118649 | 238 | Timer t; |
Grag38 | 2:ce93bf118649 | 239 | |
Grag38 | 2:ce93bf118649 | 240 | t.start(); |
Grag38 | 2:ce93bf118649 | 241 | |
Grag38 | 2:ce93bf118649 | 242 | FILE *fp = fopen("/mci/myfile.txt", "w"); |
Grag38 | 2:ce93bf118649 | 243 | if (fp != NULL) |
Grag38 | 2:ce93bf118649 | 244 | { |
Grag38 | 2:ce93bf118649 | 245 | for (long i=0; i<100000L; i++) |
Grag38 | 2:ce93bf118649 | 246 | fprintf(fp, "Hello World!\n"); |
Grag38 | 2:ce93bf118649 | 247 | fclose(fp); |
Grag38 | 2:ce93bf118649 | 248 | printf("Wrote to /mci/myfile.txt\n"); |
Grag38 | 2:ce93bf118649 | 249 | } else { |
Grag38 | 2:ce93bf118649 | 250 | printf("Failed to open /mci/myfile.txt\n"); |
Grag38 | 2:ce93bf118649 | 251 | } |
Grag38 | 2:ce93bf118649 | 252 | t.stop(); |
Grag38 | 2:ce93bf118649 | 253 | |
Grag38 | 2:ce93bf118649 | 254 | printf("The time taken was %f seconds\n", t.read()); |
Grag38 | 2:ce93bf118649 | 255 | |
Grag38 | 2:ce93bf118649 | 256 | |
Grag38 | 2:ce93bf118649 | 257 | handleError("Program completed!\n"); |
Grag38 | 2:ce93bf118649 | 258 | return 1; |
Grag38 | 2:ce93bf118649 | 259 | } |
Grag38 | 2:ce93bf118649 | 260 | |
Grag38 | 2:ce93bf118649 | 261 | |
Grag38 | 2:ce93bf118649 | 262 | |
Grag38 | 2:ce93bf118649 | 263 | TLV320 audio(p9, p10, 52, p11, p12, p13, p14, p16); //TLV320 object |
Grag38 | 2:ce93bf118649 | 264 | |
d_worrall | 0:3d6892f6384f | 265 | InterruptIn volumeSet(p17); |
d_worrall | 0:3d6892f6384f | 266 | AnalogIn aIn(p19); |
d_worrall | 0:3d6892f6384f | 267 | FILE *infp; //File pointer object |
d_worrall | 0:3d6892f6384f | 268 | /* Buffers */ |
d_worrall | 0:3d6892f6384f | 269 | int circularBuffer[4096]; |
d_worrall | 0:3d6892f6384f | 270 | volatile int readPointer = 0; |
d_worrall | 0:3d6892f6384f | 271 | volatile int theta = 0; |
d_worrall | 0:3d6892f6384f | 272 | /* Wav file header data, for setting up the transfer protocol */ |
d_worrall | 0:3d6892f6384f | 273 | short channels; |
d_worrall | 0:3d6892f6384f | 274 | long sampleRate; |
d_worrall | 0:3d6892f6384f | 275 | short wordWidth; |
d_worrall | 0:3d6892f6384f | 276 | /* Function to set volume*/ |
d_worrall | 0:3d6892f6384f | 277 | void setVolume(void){ |
d_worrall | 0:3d6892f6384f | 278 | audio.outputVolume(aIn, aIn); |
d_worrall | 0:3d6892f6384f | 279 | } |
d_worrall | 0:3d6892f6384f | 280 | /* Function to read from circular buffer and send data to TLV320 */ |
d_worrall | 0:3d6892f6384f | 281 | void play(void){ |
d_worrall | 0:3d6892f6384f | 282 | audio.write(circularBuffer, readPointer, 8); |
d_worrall | 0:3d6892f6384f | 283 | //Pointer fun :-) |
d_worrall | 0:3d6892f6384f | 284 | readPointer += 8; |
d_worrall | 0:3d6892f6384f | 285 | readPointer &= 0xfff; |
d_worrall | 0:3d6892f6384f | 286 | theta -= 8; |
d_worrall | 0:3d6892f6384f | 287 | } |
d_worrall | 0:3d6892f6384f | 288 | /* Function to load circular buffer from SD Card */ |
d_worrall | 0:3d6892f6384f | 289 | void fillBuffer(void){ |
d_worrall | 0:3d6892f6384f | 290 | while(!feof(infp)){ //fill the circular buffer until the end of the file |
d_worrall | 0:3d6892f6384f | 291 | static volatile int writePointer = 0; |
d_worrall | 0:3d6892f6384f | 292 | if(theta < 4096){ |
d_worrall | 0:3d6892f6384f | 293 | fread(&circularBuffer[writePointer], 4, 4, infp); //read 4 integers into the circular buffer at a time |
d_worrall | 0:3d6892f6384f | 294 | //More pointer fun :D |
d_worrall | 0:3d6892f6384f | 295 | theta+=4; |
d_worrall | 0:3d6892f6384f | 296 | writePointer+=4; |
d_worrall | 0:3d6892f6384f | 297 | writePointer &= 0xfff; |
d_worrall | 0:3d6892f6384f | 298 | } |
d_worrall | 0:3d6892f6384f | 299 | } |
d_worrall | 0:3d6892f6384f | 300 | } |
d_worrall | 0:3d6892f6384f | 301 | /* main */ |
Grag38 | 2:ce93bf118649 | 302 | int main() |
Grag38 | 2:ce93bf118649 | 303 | { |
Grag38 | 2:ce93bf118649 | 304 | pc.baud(460800); |
Grag38 | 2:ce93bf118649 | 305 | |
Grag38 | 2:ce93bf118649 | 306 | infp = fopen("/mci/agnes.wav","rb"); |
d_worrall | 0:3d6892f6384f | 307 | if(infp == NULL){ //make sure it's been opened |
d_worrall | 0:3d6892f6384f | 308 | perror("Error opening file!"); |
d_worrall | 0:3d6892f6384f | 309 | exit(1); |
d_worrall | 0:3d6892f6384f | 310 | } |
d_worrall | 0:3d6892f6384f | 311 | /* Parse wav file header */ |
d_worrall | 0:3d6892f6384f | 312 | fseek(infp, 22, SEEK_SET); |
d_worrall | 0:3d6892f6384f | 313 | fread(&channels, 2, 1, infp); |
d_worrall | 0:3d6892f6384f | 314 | fseek(infp, 24, SEEK_SET); |
d_worrall | 0:3d6892f6384f | 315 | fread(&sampleRate, 4, 1, infp); |
d_worrall | 0:3d6892f6384f | 316 | fseek(infp, 34, SEEK_SET); |
d_worrall | 0:3d6892f6384f | 317 | fread(&wordWidth, 2, 1, infp); |
d_worrall | 0:3d6892f6384f | 318 | |
d_worrall | 0:3d6892f6384f | 319 | volumeSet.rise(&setVolume); //attach set volume function to digital input |
d_worrall | 0:3d6892f6384f | 320 | audio.power(0x07); //power up TLV apart from analogue input |
d_worrall | 0:3d6892f6384f | 321 | audio.frequency(sampleRate); //set sample frequency |
d_worrall | 0:3d6892f6384f | 322 | audio.format(wordWidth, (2-channels)); //set transfer protocol |
d_worrall | 0:3d6892f6384f | 323 | audio.attach(&play); //attach interrupt handler to send data to TLV320 |
d_worrall | 0:3d6892f6384f | 324 | for(int j = 0; j < 4096; ++j){ //upon interrupt generation |
d_worrall | 0:3d6892f6384f | 325 | circularBuffer[j] = 0; //clear circular buffer |
d_worrall | 0:3d6892f6384f | 326 | } |
d_worrall | 0:3d6892f6384f | 327 | audio.start(TRANSMIT); //interrupt come from the I2STXFIFO only |
d_worrall | 0:3d6892f6384f | 328 | fillBuffer(); //continually fill circular buffer |
d_worrall | 0:3d6892f6384f | 329 | } |