diff options
Diffstat (limited to 'apps/codecs/wav.c')
-rw-r--r-- | apps/codecs/wav.c | 47 |
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 | ||