summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Boot <rotator@gmail.com>2006-06-27 22:27:21 +0000
committerAdam Boot <rotator@gmail.com>2006-06-27 22:27:21 +0000
commit71cf604d8d317b7c2b167aac37493795046431cd (patch)
tree1af80810541fe10dc0e974e7daf31c8ead0aa627
parent1f28a141e13a8c0096db3b3ff8f86dc29a629426 (diff)
downloadrockbox-71cf604d8d317b7c2b167aac37493795046431cd.tar.gz
rockbox-71cf604d8d317b7c2b167aac37493795046431cd.zip
Fix for wav files where the fmt chunk is not close to the start of the file
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10149 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/wav.c47
-rw-r--r--apps/metadata.c68
2 files changed, 68 insertions, 47 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
diff --git a/apps/metadata.c b/apps/metadata.c
index 9cb055608a..bdf65b2639 100644
--- a/apps/metadata.c
+++ b/apps/metadata.c
@@ -829,71 +829,84 @@ static bool get_wave_metadata(int fd, struct mp3entry* id3)
829 int read_bytes; 829 int read_bytes;
830 int i; 830 int i;
831 831
832 if ((lseek(fd, 0, SEEK_SET) < 0) 832 /* get RIFF chunk header */
833 || ((read_bytes = read(fd, buf, sizeof(id3->path))) < 44)) 833 if ((lseek(fd, 0, SEEK_SET) < 0)
834 || ((read_bytes = read(fd, buf, 12)) < 12))
834 { 835 {
835 return false; 836 return false;
836 } 837 }
837 838
838 if ((memcmp(buf, "RIFF",4) != 0) 839 if ((memcmp(buf, "RIFF",4) != 0)
839 || (memcmp(&buf[8], "WAVE", 4) !=0 )) 840 || (memcmp(&buf[8], "WAVE", 4) !=0 ))
840 { 841 {
841 return false; 842 return false;
842 } 843 }
843 844
844 buf += 12; 845 /* iterate over WAVE chunks until 'data' chunk */
845 read_bytes -= 12; 846 while (true)
846
847 while ((numbytes == 0) && (read_bytes >= 8))
848 { 847 {
848 /* get chunk header */
849 if ((read_bytes = read(fd, buf, 8)) < 8)
850 return false;
851
849 /* chunkSize */ 852 /* chunkSize */
850 i = get_long(&buf[4]); 853 i = get_long(&buf[4]);
851 854
852 if (memcmp(buf, "fmt ", 4) == 0) 855 if (memcmp(buf, "fmt ", 4) == 0)
853 { 856 {
857 /* get rest of chunk */
858 if ((read_bytes = read(fd, buf, 16)) < 16)
859 return false;
860
861 i -= 16;
862
854 /* skipping wFormatTag */ 863 /* skipping wFormatTag */
855 /* wChannels */ 864 /* wChannels */
856 channels = buf[10] | (buf[11] << 8); 865 channels = buf[2] | (buf[3] << 8);
857 /* dwSamplesPerSec */ 866 /* dwSamplesPerSec */
858 id3->frequency = get_long(&buf[12]); 867 id3->frequency = get_long(&buf[4]);
859 /* dwAvgBytesPerSec */ 868 /* dwAvgBytesPerSec */
860 id3->bitrate = (get_long(&buf[16]) * 8) / 1000; 869 id3->bitrate = (get_long(&buf[8]) * 8) / 1000;
861 /* skipping wBlockAlign */ 870 /* skipping wBlockAlign */
862 /* wBitsPerSample */ 871 /* wBitsPerSample */
863 bitspersample = buf[22] | (buf[23] << 8); 872 bitspersample = buf[14] | (buf[15] << 8);
864 } 873 }
865 else if (memcmp(buf, "data", 4) == 0) 874 else if (memcmp(buf, "data", 4) == 0)
866 { 875 {
867 numbytes = i; 876 numbytes = i;
877 break;
868 } 878 }
869 else if (memcmp(buf, "fact", 4) == 0) 879 else if (memcmp(buf, "fact", 4) == 0)
870 { 880 {
871 /* dwSampleLength */ 881 /* dwSampleLength */
872 if (i >= 4) 882 if (i >= 4)
873 { 883 {
874 totalsamples = get_long(&buf[8]); 884 /* get rest of chunk */
885 if ((read_bytes = read(fd, buf, 2)) < 2)
886 return false;
887
888 i -= 2;
889 totalsamples = get_long(buf);
875 } 890 }
876 } 891 }
877 892
878 /* go to next chunk (even chunk sizes must be padded) */ 893 /* seek to next chunk (even chunk sizes must be padded) */
879 if (i & 0x01) 894 if (i & 0x01)
880 {
881 i++; 895 i++;
882 } 896
883 897 if(lseek(fd, i, SEEK_CUR) < 0)
884 buf += i + 8; 898 return false;
885 read_bytes -= i + 8;
886 } 899 }
887 900
888 if ((numbytes == 0) || (channels == 0)) 901 if ((numbytes == 0) || (channels == 0))
889 { 902 {
890 return false; 903 return false;
891 } 904 }
892 905
893 if (totalsamples == 0) 906 if (totalsamples == 0)
894 { 907 {
895 /* for PCM only */ 908 /* for PCM only */
896 totalsamples = numbytes 909 totalsamples = numbytes
897 / ((((bitspersample - 1) / 8) + 1) * channels); 910 / ((((bitspersample - 1) / 8) + 1) * channels);
898 } 911 }
899 912
@@ -906,7 +919,6 @@ static bool get_wave_metadata(int fd, struct mp3entry* id3)
906 return true; 919 return true;
907} 920}
908 921
909
910static bool get_m4a_metadata(int fd, struct mp3entry* id3) 922static bool get_m4a_metadata(int fd, struct mp3entry* id3)
911{ 923{
912 unsigned char* buf; 924 unsigned char* buf;