summaryrefslogtreecommitdiff
path: root/apps/codecs/wav.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/wav.c')
-rw-r--r--apps/codecs/wav.c47
1 files changed, 28 insertions, 19 deletions
diff --git a/apps/codecs/wav.c b/apps/codecs/wav.c
index f83f1d1e58..6bf2cb5864 100644
--- a/apps/codecs/wav.c
+++ b/apps/codecs/wav.c
@@ -256,9 +256,9 @@ next_track:
256 while (!*ci->taginfo_ready) 256 while (!*ci->taginfo_ready)
257 ci->yield(); 257 ci->yield();
258 258
259 /* assume the WAV header is less than 1024 bytes */ 259 /* get RIFF chunk header */
260 buf = ci->request_buffer(&n, 1024); 260 buf = ci->request_buffer(&n, 12);
261 if (n < 44) { 261 if (n < 12) {
262 i = CODEC_ERROR; 262 i = CODEC_ERROR;
263 goto done; 263 goto done;
264 } 264 }
@@ -267,13 +267,24 @@ next_track:
267 goto done; 267 goto done;
268 } 268 }
269 269
270 buf += 12; 270 /* advance to first WAVE chunk */
271 n -= 12; 271 ci->advance_buffer(12);
272
273 firstblockposn = 12;
272 bitspersample = 0; 274 bitspersample = 0;
273 numbytes = 0; 275 numbytes = 0;
274 totalsamples = 0; 276 totalsamples = 0;
275 /* read until the data chunk, which should be last */ 277
276 while (numbytes == 0 && n >= 8) { 278 /* iterate over WAVE chunks until the 'data' chunk, which should be after the 'fmt ' chunk */
279 while (true) {
280 /* get WAVE chunk header */
281 buf = ci->request_buffer(&n, 1024);
282 if (n < 8) {
283 /* no more chunks, 'data' chunk must not have been found */
284 i = CODEC_ERROR;
285 goto done;
286 }
287
277 /* chunkSize */ 288 /* chunkSize */
278 i = (buf[4]|(buf[5]<<8)|(buf[6]<<16)|(buf[7]<<24)); 289 i = (buf[4]|(buf[5]<<8)|(buf[6]<<16)|(buf[7]<<24));
279 if (memcmp(buf, "fmt ", 4) == 0) { 290 if (memcmp(buf, "fmt ", 4) == 0) {
@@ -327,7 +338,10 @@ next_track:
327 } 338 }
328 } else if (memcmp(buf, "data", 4) == 0) { 339 } else if (memcmp(buf, "data", 4) == 0) {
329 numbytes = i; 340 numbytes = i;
330 i = 0; /* advance to the beginning of data */ 341 /* advance to start of data */
342 ci->advance_buffer(8);
343 firstblockposn += 8;
344 break;
331 } else if (memcmp(buf, "fact", 4) == 0) { 345 } else if (memcmp(buf, "fact", 4) == 0) {
332 /* dwSampleLength */ 346 /* dwSampleLength */
333 if (i >= 4) 347 if (i >= 4)
@@ -336,16 +350,12 @@ next_track:
336 DEBUGF("unknown WAVE chunk: '%c%c%c%c', size=%lu\n", 350 DEBUGF("unknown WAVE chunk: '%c%c%c%c', size=%lu\n",
337 buf[0], buf[1], buf[2], buf[3], i); 351 buf[0], buf[1], buf[2], buf[3], i);
338 } 352 }
353
339 /* go to next chunk (even chunk sizes must be padded) */ 354 /* go to next chunk (even chunk sizes must be padded) */
340 if (i & 0x01) 355 if (i & 0x01)
341 i++; 356 i++;
342 buf += i + 8; 357 ci->advance_buffer(i+8);
343 if (n < (i + 8)) { 358 firstblockposn += i + 8;
344 DEBUGF("CODEC_ERROR: WAVE header size > 1024\n");
345 i = CODEC_ERROR;
346 goto done;
347 }
348 n -= i + 8;
349 } 359 }
350 360
351 if (channels == 0) { 361 if (channels == 0) {
@@ -409,16 +419,15 @@ next_track:
409 } 419 }
410 } 420 }
411 421
412 firstblockposn = 1024 - n; 422 /* make sure we're at the correct offset */
413
414 if (ci->id3->offset > (uint32_t) firstblockposn) { 423 if (ci->id3->offset > (uint32_t) firstblockposn) {
415 /* Round down to previous block */ 424 /* Round down to previous block */
416 uint32_t offset = ci->id3->offset - ci->id3->offset % blockalign; 425 uint32_t offset = ci->id3->offset - ci->id3->offset % blockalign;
417 426
418 ci->advance_buffer(offset); 427 ci->advance_buffer(offset-firstblockposn);
419 bytesdone = offset - firstblockposn; 428 bytesdone = offset - firstblockposn;
420 } else { 429 } else {
421 ci->advance_buffer(firstblockposn); 430 /* already where we need to be */
422 bytesdone = 0; 431 bytesdone = 0;
423 } 432 }
424 433