Oops. forget static.
[kugel-rb.git] / apps / metadata / wave.c
blob1753b64330ee4f75791e58e78e08b2119f3c678e
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 Dave Chapman
11 * Copyright (C) 2010 Yoshihisa Uchida
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <ctype.h>
26 #include <inttypes.h>
28 #include "system.h"
29 #include "metadata.h"
30 #include "metadata_common.h"
31 #include "metadata_parsers.h"
32 #include "logf.h"
34 /* Wave(RIFF)/Wave64 format */
37 # define AV_WL32(p, d) do { \
38 ((uint8_t*)(p))[0] = (d); \
39 ((uint8_t*)(p))[1] = (d)>>8; \
40 ((uint8_t*)(p))[2] = (d)>>16; \
41 ((uint8_t*)(p))[3] = (d)>>24; \
42 } while(0)
43 # define AV_WL16(p, d) do { \
44 ((uint8_t*)(p))[0] = (d); \
45 ((uint8_t*)(p))[1] = (d)>>8; \
46 } while(0)
48 enum {
49 RIFF_CHUNK = 0,
50 WAVE_CHUNK,
51 FMT_CHUNK,
52 FACT_CHUNK,
53 DATA_CHUNK,
54 NUM_CHUNKS,
57 /* Wave chunk names */
58 static const unsigned char *wave_chunknames[NUM_CHUNKS] =
60 [RIFF_CHUNK] = "RIFF",
61 [WAVE_CHUNK] = "WAVE",
62 [FMT_CHUNK] = "fmt ",
63 [FACT_CHUNK] = "fact",
64 [DATA_CHUNK] = "data",
67 /* Wave64 GUIDs */
68 static const unsigned char *wave64_chunknames[NUM_CHUNKS] =
70 [RIFF_CHUNK] = "riff\x2e\x91\xcf\x11\xa5\xd6\x28\xdb\x04\xc1\x00\x00",
71 [WAVE_CHUNK] = "wave\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a",
72 [FMT_CHUNK] = "fmt \xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a",
73 [FACT_CHUNK] = "fact\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a",
74 [DATA_CHUNK] = "data\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a",
77 /* support formats */
78 enum
80 WAVE_FORMAT_PCM = 0x0001, /* Microsoft PCM Format */
81 WAVE_FORMAT_ADPCM = 0x0002, /* Microsoft ADPCM Format */
82 WAVE_FORMAT_IEEE_FLOAT = 0x0003, /* IEEE Float */
83 WAVE_FORMAT_ALAW = 0x0006, /* Microsoft ALAW */
84 WAVE_FORMAT_MULAW = 0x0007, /* Microsoft MULAW */
85 WAVE_FORMAT_DVI_ADPCM = 0x0011, /* Intel's DVI ADPCM */
86 WAVE_FORMAT_DIALOGIC_OKI_ADPCM = 0x0017, /* Dialogic OKI ADPCM */
87 WAVE_FORMAT_YAMAHA_ADPCM = 0x0020, /* Yamaha ADPCM */
88 WAVE_FORMAT_XBOX_ADPCM = 0x0069, /* XBOX ADPCM */
89 IBM_FORMAT_MULAW = 0x0101, /* same as WAVE_FORMAT_MULAW */
90 IBM_FORMAT_ALAW = 0x0102, /* same as WAVE_FORMAT_ALAW */
91 WAVE_FORMAT_ATRAC3 = 0x0270, /* Atrac3 stream */
92 WAVE_FORMAT_SWF_ADPCM = 0x5346, /* Adobe SWF ADPCM */
93 WAVE_FORMAT_EXTENSIBLE = 0xFFFE,
96 struct wave_fmt {
97 unsigned int formattag;
98 unsigned int channels;
99 unsigned int blockalign;
100 unsigned int bitspersample;
101 unsigned int samplesperblock;
102 uint32_t totalsamples;
103 uint64_t numbytes;
106 static void set_totalsamples(struct wave_fmt *fmt, struct mp3entry* id3)
108 switch (fmt->formattag)
110 case WAVE_FORMAT_PCM:
111 case WAVE_FORMAT_IEEE_FLOAT:
112 case WAVE_FORMAT_ALAW:
113 case WAVE_FORMAT_MULAW:
114 case IBM_FORMAT_ALAW:
115 case IBM_FORMAT_MULAW:
116 if (fmt->bitspersample != 0 && fmt->channels != 0)
117 fmt->totalsamples = fmt->numbytes / ((fmt->bitspersample >> 3) * fmt->channels);
118 break;
119 case WAVE_FORMAT_ADPCM:
120 case WAVE_FORMAT_DVI_ADPCM:
121 case WAVE_FORMAT_XBOX_ADPCM:
122 if (fmt->blockalign != 0)
123 fmt->totalsamples = (fmt->numbytes / fmt->blockalign) * fmt->samplesperblock;
124 break;
125 case WAVE_FORMAT_YAMAHA_ADPCM:
126 if (fmt->blockalign != 0 && fmt->channels != 0)
128 if (fmt->samplesperblock == 0)
130 if (fmt->blockalign == ((id3->frequency / 60) + 4) * fmt->channels)
131 fmt->samplesperblock = id3->frequency / 30;
132 else
133 fmt->samplesperblock = (fmt->blockalign << 1) / fmt->channels;
135 fmt->totalsamples = (fmt->numbytes / fmt->blockalign) * fmt->samplesperblock;
137 break;
138 case WAVE_FORMAT_DIALOGIC_OKI_ADPCM:
139 fmt->totalsamples = fmt->numbytes << 1;
140 break;
141 case WAVE_FORMAT_SWF_ADPCM:
142 if (fmt->blockalign != 0 && fmt->bitspersample != 0 && fmt->channels != 0)
144 if (fmt->samplesperblock == 0)
145 fmt->samplesperblock = (((fmt->blockalign << 3) - 2) / fmt->channels - 22)
146 / fmt->bitspersample;
148 fmt->totalsamples = (fmt->numbytes / fmt->blockalign) * fmt->samplesperblock;
150 break;
151 default:
152 fmt->totalsamples = 0;
153 break;
157 static void parse_riff_format(unsigned char* buf, int fmtsize, struct wave_fmt *fmt,
158 struct mp3entry* id3)
160 /* wFormatTag */
161 fmt->formattag = buf[0] | (buf[1] << 8);
162 /* wChannels */
163 fmt->channels = buf[2] | (buf[3] << 8);
164 /* dwSamplesPerSec */
165 id3->frequency = get_long_le(&buf[4]);
166 /* dwAvgBytesPerSec */
167 id3->bitrate = (get_long_le(&buf[8]) * 8) / 1000;
168 /* wBlockAlign */
169 fmt->blockalign = buf[12] | (buf[13] << 8);
170 /* wBitsPerSample */
171 fmt->bitspersample = buf[14] | (buf[15] << 8);
173 if (fmt->formattag != WAVE_FORMAT_EXTENSIBLE)
175 if (fmtsize > 19)
177 /* wSamplesPerBlock */
178 fmt->samplesperblock = buf[18] | (buf[19] << 8);
181 else if (fmtsize > 25)
183 /* wValidBitsPerSample */
184 fmt->bitspersample = buf[18] | (buf[19] << 8);
185 /* SubFormat */
186 fmt->formattag = buf[24] | (buf[25] << 8);
189 /* Check for ATRAC3 stream */
190 if (fmt->formattag == WAVE_FORMAT_ATRAC3)
192 int jsflag = 0;
193 if(id3->bitrate == 66 || id3->bitrate == 94)
194 jsflag = 1;
196 id3->extradata_size = 14;
197 id3->channels = 2;
198 id3->codectype = AFMT_OMA_ATRAC3;
199 /* Store the extradata for the codec */
200 AV_WL16(&id3->id3v2buf[0], 1); // always 1
201 AV_WL32(&id3->id3v2buf[2], id3->frequency);// samples rate
202 AV_WL16(&id3->id3v2buf[6], jsflag); // coding mode
203 AV_WL16(&id3->id3v2buf[8], jsflag); // coding mode
204 AV_WL16(&id3->id3v2buf[10], 1); // always 1
205 AV_WL16(&id3->id3v2buf[12], 0); // always 0
209 static bool read_header(int fd, struct mp3entry* id3, const unsigned char **chunknames, bool is_64)
211 /* Use the temporary buffer */
212 unsigned char* buf = (unsigned char *)id3->path;
214 struct wave_fmt fmt;
216 unsigned int namelen = (is_64)? 16 : 4;
217 unsigned int sizelen = (is_64)? 8 : 4;
218 unsigned int len = namelen + sizelen;
219 uint64_t chunksize;
220 uint64_t offset = len + namelen;
221 int read_data;
223 memset(&fmt, 0, sizeof(struct wave_fmt));
225 /* get RIFF chunk header */
226 lseek(fd, 0, SEEK_SET);
227 read(fd, buf, offset);
229 if ((memcmp(buf, chunknames[RIFF_CHUNK], namelen) != 0) ||
230 (memcmp(buf + len, chunknames[WAVE_CHUNK], namelen) != 0))
232 DEBUGF("metadata error: missing riff header.\n");
233 return false;
236 /* iterate over WAVE chunks until 'data' chunk */
237 while (true)
239 /* get chunk header */
240 if (read(fd, buf, len) <= 0)
242 DEBUGF("metadata error: read error or missing 'data' chunk.\n");
243 return false;
246 offset += len;
248 /* get chunk size (when the header is wave64, chunksize includes GUID and data length) */
249 chunksize = (is_64) ? get_uint64_le(buf + namelen) - len :
250 get_long_le(buf + namelen);
252 if (memcmp(buf, chunknames[DATA_CHUNK], namelen) == 0)
254 DEBUGF("find 'data' chunk\n");
255 fmt.numbytes = chunksize;
256 if (fmt.formattag == WAVE_FORMAT_ATRAC3)
257 id3->first_frame_offset = offset;
258 break;
261 /* padded to next chunk */
262 chunksize += ((is_64)? ((1 + ~chunksize) & 0x07) : (chunksize & 1));
263 offset += chunksize;
265 read_data = 0;
266 if (memcmp(buf, chunknames[FMT_CHUNK], namelen) == 0)
268 DEBUGF("find 'fmt ' chunk\n");
270 if (chunksize < 16)
272 DEBUGF("metadata error: 'fmt ' chunk is too small: %d\n", (int)chunksize);
273 return false;
276 /* get and parse format */
277 read_data = (chunksize > 25)? 26 : chunksize;
279 read(fd, buf, read_data);
280 parse_riff_format(buf, read_data, &fmt, id3);
282 else if (memcmp(buf, chunknames[FACT_CHUNK], namelen) == 0)
284 DEBUGF("find 'fact' chunk\n");
286 /* dwSampleLength */
287 if (chunksize >= sizelen)
289 /* get totalsamples */
290 read_data = sizelen;
291 read(fd, buf, read_data);
292 fmt.totalsamples = (is_64)? get_uint64_le(buf) : get_long_le(buf);
296 lseek(fd, chunksize - read_data, SEEK_CUR);
299 if (fmt.totalsamples == 0)
300 set_totalsamples(&fmt, id3);
302 id3->vbr = false; /* All Wave/Wave64 files are CBR */
303 id3->filesize = filesize(fd);
305 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
306 if(fmt.formattag != AFMT_OMA_ATRAC3)
308 if (id3->frequency != 0)
309 id3->length = ((int64_t) fmt.totalsamples * 1000) / id3->frequency;
311 else
313 if (id3->bitrate != 0)
314 id3->length = ((id3->filesize - id3->first_frame_offset) * 8) / id3->bitrate;
317 /* output header/id3 info (for debug) */
318 DEBUGF("%s header info ----\n", (is_64)? "wave64" : "wave");
319 DEBUGF(" format: %04x\n", (int)fmt.formattag);
320 DEBUGF(" channels: %u\n", fmt.channels);
321 DEBUGF(" blockalign: %u\n", fmt.blockalign);
322 DEBUGF(" bitspersample: %u\n", fmt.bitspersample);
323 DEBUGF(" samplesperblock: %u\n", fmt.samplesperblock);
324 DEBUGF(" totalsamples: %u\n", (unsigned int)fmt.totalsamples);
325 DEBUGF(" numbytes; %u\n", (unsigned int)fmt.numbytes);
326 DEBUGF("id3 info ----\n");
327 DEBUGF(" frquency: %u\n", (unsigned int)id3->frequency);
328 DEBUGF(" bitrate: %d\n", id3->bitrate);
329 DEBUGF(" length: %u\n", (unsigned int)id3->length);
331 return true;
334 bool get_wave_metadata(int fd, struct mp3entry* id3)
336 return read_header(fd, id3, (const unsigned char **)&wave_chunknames, false);
339 bool get_wave64_metadata(int fd, struct mp3entry* id3)
341 return read_header(fd, id3, (const unsigned char **)&wave64_chunknames, true);