1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 David Bryant
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
27 #include "metadata_common.h"
30 #define ID_UNIQUE 0x3f
32 #define ID_SAMPLE_RATE 0x27
34 static const long wavpack_sample_rates
[] =
36 6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000,
37 32000, 44100, 48000, 64000, 88200, 96000, 192000
40 /* A simple parser to read basic information from a WavPack file. This
41 * now works with self-extrating WavPack files and also will scan the
42 * metadata for non-standard sampling rates. This no longer fails on
43 * WavPack files containing floating-point audio data because these are
44 * now converted to standard Rockbox format in the decoder.
47 bool get_wavpack_metadata(int fd
, struct mp3entry
* id3
)
49 /* Use the trackname part of the id3 structure as a temporary buffer */
50 unsigned char* buf
= (unsigned char *)id3
->path
;
51 uint32_t totalsamples
, blocksamples
;
54 for (i
= 0; i
< 256; ++i
) {
56 /* at every 256 bytes into file, try to read a WavPack header */
58 if ((lseek(fd
, i
* 256, SEEK_SET
) < 0) || (read(fd
, buf
, 32) < 32))
61 /* if valid WavPack 4 header version, break */
63 if (memcmp (buf
, "wvpk", 4) == 0 && buf
[9] == 4 &&
64 (buf
[8] >= 2 && buf
[8] <= 0x10))
69 logf ("Not a WavPack file");
73 id3
->vbr
= true; /* All WavPack files are VBR */
74 id3
->filesize
= filesize (fd
);
75 totalsamples
= get_long_le(&buf
[12]);
76 blocksamples
= get_long_le(&buf
[20]);
78 if (blocksamples
&& totalsamples
!= (uint32_t) -1) {
79 int srindx
= ((buf
[26] >> 7) & 1) + ((buf
[27] << 1) & 14);
82 uint32_t meta_bytes
= buf
[4] + (buf
[5] << 8) + (buf
[6] << 16) - 24;
85 id3
->frequency
= 44100;
87 while (meta_bytes
>= 6) {
88 if (read(fd
, buf
, 2) < 2)
91 if (buf
[0] & ID_LARGE
) {
92 if (read(fd
, buf
+ 2, 2) < 2)
95 meta_size
= (buf
[1] << 1) + (buf
[2] << 9) + (buf
[3] << 17);
96 meta_bytes
-= meta_size
+ 4;
99 meta_size
= buf
[1] << 1;
100 meta_bytes
-= meta_size
+ 2;
102 if ((buf
[0] & ID_UNIQUE
) == ID_SAMPLE_RATE
) {
103 if (meta_size
== 4 && read(fd
, buf
+ 2, 4) == 4)
104 id3
->frequency
= buf
[2] + (buf
[3] << 8) + (buf
[4] << 16);
110 if (meta_size
> 0 && lseek(fd
, meta_size
, SEEK_CUR
) < 0)
115 id3
->frequency
= wavpack_sample_rates
[srindx
];
117 id3
->length
= ((int64_t) totalsamples
* 1000) / id3
->frequency
;
118 id3
->bitrate
= filesize (fd
) / (id3
->length
/ 8);