1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 David Bryant
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
29 #include "metadata_common.h"
30 #include "metadata_parsers.h"
33 #define ID_UNIQUE 0x3f
35 #define ID_SAMPLE_RATE 0x27
40 static const long wavpack_sample_rates
[] =
42 6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000,
43 32000, 44100, 48000, 64000, 88200, 96000, 192000
46 /* A simple parser to read basic information from a WavPack file. This
47 * now works with self-extrating WavPack files and also will scan the
48 * metadata for non-standard sampling rates. This no longer fails on
49 * WavPack files containing floating-point audio data because these are
50 * now converted to standard Rockbox format in the decoder, and also
51 * handles the case where up to 15 non-audio blocks might occur at the
52 * beginning of the file.
55 bool get_wavpack_metadata(int fd
, struct mp3entry
* id3
)
57 /* Use the trackname part of the id3 structure as a temporary buffer */
58 unsigned char* buf
= (unsigned char *)id3
->path
;
59 uint32_t totalsamples
= (uint32_t) -1;
62 for (i
= 0; i
< 256; ++i
) {
64 /* at every 256 bytes into file, try to read a WavPack header */
66 if ((lseek(fd
, i
* 256, SEEK_SET
) < 0) || (read(fd
, buf
, 32) < 32))
69 /* if valid WavPack 4 header version, break */
71 if (memcmp (buf
, "wvpk", 4) == 0 && buf
[9] == 4 &&
72 (buf
[8] >= 2 && buf
[8] <= 0x10))
77 logf ("Not a WavPack file");
81 id3
->vbr
= true; /* All WavPack files are VBR */
82 id3
->filesize
= filesize (fd
);
84 /* check up to 16 headers before we give up finding one with audio */
86 for (i
= 0; i
< 16; ++i
) {
87 uint32_t meta_bytes
= get_long_le(&buf
[4]) - 24;
88 uint32_t trial_totalsamples
= get_long_le(&buf
[12]);
89 uint32_t blockindex
= get_long_le(&buf
[16]);
90 uint32_t blocksamples
= get_long_le(&buf
[20]);
91 uint32_t flags
= get_long_le(&buf
[24]);
93 if (totalsamples
== (uint32_t) -1 && blockindex
== 0)
94 totalsamples
= trial_totalsamples
;
97 int srindx
= ((buf
[26] >> 7) & 1) + ((buf
[27] << 1) & 14);
102 id3
->frequency
= 44100;
104 while (meta_bytes
>= 6) {
105 if (read(fd
, buf
, 2) < 2)
108 if (buf
[0] & ID_LARGE
) {
109 if (read(fd
, buf
+ 2, 2) < 2)
112 meta_size
= (buf
[1] << 1) + (buf
[2] << 9) + (buf
[3] << 17);
113 meta_bytes
-= meta_size
+ 4;
116 meta_size
= buf
[1] << 1;
117 meta_bytes
-= meta_size
+ 2;
119 if ((buf
[0] & ID_UNIQUE
) == ID_SAMPLE_RATE
) {
120 if (meta_size
== 4 && read(fd
, buf
+ 2, 4) == 4)
121 id3
->frequency
= buf
[2] + (buf
[3] << 8) + (buf
[4] << 16);
127 if (meta_size
> 0 && lseek(fd
, meta_size
, SEEK_CUR
) < 0)
132 id3
->frequency
= wavpack_sample_rates
[srindx
];
134 /* if the total number of samples is still unknown, make a guess on the high side (for now) */
136 if (totalsamples
== (uint32_t) -1) {
137 totalsamples
= id3
->filesize
* 3;
139 if (!(flags
& HYBRID_FLAG
))
142 if (!(flags
& MONO_FLAG
))
146 id3
->length
= ((int64_t) totalsamples
* 1000) / id3
->frequency
;
147 id3
->bitrate
= id3
->filesize
/ (id3
->length
/ 8);
149 read_ape_tags(fd
, id3
);
152 else { /* block did not contain audio, so seek to the end and see if there's another */
153 if ((meta_bytes
> 0 && lseek(fd
, meta_bytes
, SEEK_CUR
) < 0) ||
154 read(fd
, buf
, 32) < 32 || memcmp (buf
, "wvpk", 4) != 0)