A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

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

Adam Boot 71cf604d 1f28a141

+68 -47
+28 -19
apps/codecs/wav.c
··· 256 256 while (!*ci->taginfo_ready) 257 257 ci->yield(); 258 258 259 - /* assume the WAV header is less than 1024 bytes */ 260 - buf = ci->request_buffer(&n, 1024); 261 - if (n < 44) { 259 + /* get RIFF chunk header */ 260 + buf = ci->request_buffer(&n, 12); 261 + if (n < 12) { 262 262 i = CODEC_ERROR; 263 263 goto done; 264 264 } ··· 267 267 goto done; 268 268 } 269 269 270 - buf += 12; 271 - n -= 12; 270 + /* advance to first WAVE chunk */ 271 + ci->advance_buffer(12); 272 + 273 + firstblockposn = 12; 272 274 bitspersample = 0; 273 275 numbytes = 0; 274 276 totalsamples = 0; 275 - /* read until the data chunk, which should be last */ 276 - while (numbytes == 0 && n >= 8) { 277 + 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 288 /* chunkSize */ 278 289 i = (buf[4]|(buf[5]<<8)|(buf[6]<<16)|(buf[7]<<24)); 279 290 if (memcmp(buf, "fmt ", 4) == 0) { ··· 327 338 } 328 339 } else if (memcmp(buf, "data", 4) == 0) { 329 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 345 } else if (memcmp(buf, "fact", 4) == 0) { 332 346 /* dwSampleLength */ 333 347 if (i >= 4) ··· 336 350 DEBUGF("unknown WAVE chunk: '%c%c%c%c', size=%lu\n", 337 351 buf[0], buf[1], buf[2], buf[3], i); 338 352 } 353 + 339 354 /* go to next chunk (even chunk sizes must be padded) */ 340 355 if (i & 0x01) 341 356 i++; 342 - buf += i + 8; 343 - if (n < (i + 8)) { 344 - DEBUGF("CODEC_ERROR: WAVE header size > 1024\n"); 345 - i = CODEC_ERROR; 346 - goto done; 347 - } 348 - n -= i + 8; 357 + ci->advance_buffer(i+8); 358 + firstblockposn += i + 8; 349 359 } 350 360 351 361 if (channels == 0) { ··· 409 419 } 410 420 } 411 421 412 - firstblockposn = 1024 - n; 413 - 422 + /* make sure we're at the correct offset */ 414 423 if (ci->id3->offset > (uint32_t) firstblockposn) { 415 424 /* Round down to previous block */ 416 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 428 bytesdone = offset - firstblockposn; 420 429 } else { 421 - ci->advance_buffer(firstblockposn); 430 + /* already where we need to be */ 422 431 bytesdone = 0; 423 432 } 424 433
+40 -28
apps/metadata.c
··· 829 829 int read_bytes; 830 830 int i; 831 831 832 - if ((lseek(fd, 0, SEEK_SET) < 0) 833 - || ((read_bytes = read(fd, buf, sizeof(id3->path))) < 44)) 832 + /* get RIFF chunk header */ 833 + if ((lseek(fd, 0, SEEK_SET) < 0) 834 + || ((read_bytes = read(fd, buf, 12)) < 12)) 834 835 { 835 836 return false; 836 837 } 837 - 838 + 838 839 if ((memcmp(buf, "RIFF",4) != 0) 839 840 || (memcmp(&buf[8], "WAVE", 4) !=0 )) 840 841 { 841 842 return false; 842 843 } 843 844 844 - buf += 12; 845 - read_bytes -= 12; 846 - 847 - while ((numbytes == 0) && (read_bytes >= 8)) 845 + /* iterate over WAVE chunks until 'data' chunk */ 846 + while (true) 848 847 { 848 + /* get chunk header */ 849 + if ((read_bytes = read(fd, buf, 8)) < 8) 850 + return false; 851 + 849 852 /* chunkSize */ 850 853 i = get_long(&buf[4]); 851 - 854 + 852 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 863 /* skipping wFormatTag */ 855 864 /* wChannels */ 856 - channels = buf[10] | (buf[11] << 8); 865 + channels = buf[2] | (buf[3] << 8); 857 866 /* dwSamplesPerSec */ 858 - id3->frequency = get_long(&buf[12]); 867 + id3->frequency = get_long(&buf[4]); 859 868 /* dwAvgBytesPerSec */ 860 - id3->bitrate = (get_long(&buf[16]) * 8) / 1000; 869 + id3->bitrate = (get_long(&buf[8]) * 8) / 1000; 861 870 /* skipping wBlockAlign */ 862 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 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 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 - 878 - /* go to next chunk (even chunk sizes must be padded) */ 892 + 893 + /* seek to next chunk (even chunk sizes must be padded) */ 879 894 if (i & 0x01) 880 - { 881 895 i++; 882 - } 883 - 884 - buf += i + 8; 885 - read_bytes -= i + 8; 896 + 897 + if(lseek(fd, i, SEEK_CUR) < 0) 898 + return false; 886 899 } 887 900 888 - if ((numbytes == 0) || (channels == 0)) 901 + if ((numbytes == 0) || (channels == 0)) 889 902 { 890 903 return false; 891 904 } 892 - 893 - if (totalsamples == 0) 905 + 906 + if (totalsamples == 0) 894 907 { 895 908 /* for PCM only */ 896 - totalsamples = numbytes 909 + totalsamples = numbytes 897 910 / ((((bitspersample - 1) / 8) + 1) * channels); 898 911 } 899 912 ··· 905 918 906 919 return true; 907 920 } 908 - 909 921 910 922 static bool get_m4a_metadata(int fd, struct mp3entry* id3) 911 923 {