Add wave64(.w64) codec (FS#11022)
[kugel-rb.git] / apps / metadata / wave.c
blob8fe755735d3c0b729c667bd0d2656e37f441ba59
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 # define AV_WL32(p, d) do { \
35 ((uint8_t*)(p))[0] = (d); \
36 ((uint8_t*)(p))[1] = (d)>>8; \
37 ((uint8_t*)(p))[2] = (d)>>16; \
38 ((uint8_t*)(p))[3] = (d)>>24; \
39 } while(0)
40 # define AV_WL16(p, d) do { \
41 ((uint8_t*)(p))[0] = (d); \
42 ((uint8_t*)(p))[1] = (d)>>8; \
43 } while(0)
45 /* Wave(RIFF)/Wave64 format */
47 /* Wave64 GUIDs */
48 #define WAVE64_GUID_RIFF "riff\x2e\x91\xcf\x11\xa5\xd6\x28\xdb\x04\xc1\x00\x00"
49 #define WAVE64_GUID_WAVE "wave\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a"
50 #define WAVE64_GUID_FMT "fmt \xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a"
51 #define WAVE64_GUID_FACT "fact\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a"
52 #define WAVE64_GUID_DATA "data\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a"
54 enum
56 WAVE_FORMAT_PCM = 0x0001, /* Microsoft PCM Format */
57 WAVE_FORMAT_ADPCM = 0x0002, /* Microsoft ADPCM Format */
58 WAVE_FORMAT_IEEE_FLOAT = 0x0003, /* IEEE Float */
59 WAVE_FORMAT_ALAW = 0x0006, /* Microsoft ALAW */
60 WAVE_FORMAT_MULAW = 0x0007, /* Microsoft MULAW */
61 WAVE_FORMAT_DVI_ADPCM = 0x0011, /* Intel's DVI ADPCM */
62 WAVE_FORMAT_DIALOGIC_OKI_ADPCM = 0x0017, /* Dialogic OKI ADPCM */
63 WAVE_FORMAT_YAMAHA_ADPCM = 0x0020, /* Yamaha ADPCM */
64 WAVE_FORMAT_XBOX_ADPCM = 0x0069, /* XBOX ADPCM */
65 IBM_FORMAT_MULAW = 0x0101, /* same as WAVE_FORMAT_MULAW */
66 IBM_FORMAT_ALAW = 0x0102, /* same as WAVE_FORMAT_ALAW */
67 WAVE_FORMAT_ATRAC3 = 0x0270, /* Atrac3 stream */
68 WAVE_FORMAT_SWF_ADPCM = 0x5346, /* Adobe SWF ADPCM */
71 struct wave_fmt {
72 unsigned int formattag;
73 unsigned long channels;
74 unsigned int blockalign;
75 unsigned long bitspersample;
76 unsigned int samplesperblock;
77 uint64_t numbytes;
80 static unsigned long get_totalsamples(struct wave_fmt *fmt, struct mp3entry* id3)
82 unsigned long totalsamples = 0;
84 switch (fmt->formattag)
86 case WAVE_FORMAT_PCM:
87 case WAVE_FORMAT_IEEE_FLOAT:
88 case WAVE_FORMAT_ALAW:
89 case WAVE_FORMAT_MULAW:
90 case IBM_FORMAT_ALAW:
91 case IBM_FORMAT_MULAW:
92 totalsamples =
93 fmt->numbytes / ((((fmt->bitspersample - 1) / 8) + 1) * fmt->channels);
94 break;
95 case WAVE_FORMAT_ADPCM:
96 case WAVE_FORMAT_DVI_ADPCM:
97 case WAVE_FORMAT_XBOX_ADPCM:
98 totalsamples = (fmt->numbytes / fmt->blockalign) * fmt->samplesperblock;
99 break;
100 case WAVE_FORMAT_YAMAHA_ADPCM:
101 if (fmt->samplesperblock == 0)
103 if (fmt->blockalign == ((id3->frequency / 60) + 4) * fmt->channels)
104 fmt->samplesperblock = id3->frequency / 30;
105 else
106 fmt->samplesperblock = fmt->blockalign * 2 / fmt->channels;
108 totalsamples = (fmt->numbytes / fmt->blockalign) * fmt->samplesperblock;
109 break;
110 case WAVE_FORMAT_DIALOGIC_OKI_ADPCM:
111 totalsamples = 2 * fmt->numbytes;
112 break;
113 case WAVE_FORMAT_SWF_ADPCM:
114 if (fmt->samplesperblock == 0)
115 fmt->samplesperblock = (((fmt->blockalign << 3) - 2) / fmt->channels - 22)
116 / fmt->bitspersample;
118 totalsamples = (fmt->numbytes / fmt->blockalign) * fmt->samplesperblock;
119 break;
120 default:
121 totalsamples = 0;
122 break;
124 return totalsamples;
127 static void parse_riff_format(unsigned char* buf, int fmtsize, struct wave_fmt *fmt,
128 struct mp3entry* id3)
130 /* wFormatTag */
131 fmt->formattag = buf[0] | (buf[1] << 8);
132 /* wChannels */
133 fmt->channels = buf[2] | (buf[3] << 8);
134 /* dwSamplesPerSec */
135 id3->frequency = get_long_le(&buf[4]);
136 /* dwAvgBytesPerSec */
137 id3->bitrate = (get_long_le(&buf[8]) * 8) / 1000;
138 /* wBlockAlign */
139 fmt->blockalign = buf[12] | (buf[13] << 8);
140 /* wBitsPerSample */
141 fmt->bitspersample = buf[14] | (buf[15] << 8);
142 if (fmtsize > 19)
144 /* wSamplesPerBlock */
145 fmt->samplesperblock = buf[18] | (buf[19] << 8);
149 bool get_wave_metadata(int fd, struct mp3entry* id3)
151 /* Use the trackname part of the id3 structure as a temporary buffer */
152 unsigned char* buf = (unsigned char *)id3->path;
153 struct wave_fmt fmt;
154 unsigned long totalsamples = 0;
155 unsigned long offset = 0;
156 int read_bytes;
157 int i;
159 memset(&fmt, 0, sizeof(struct wave_fmt));
161 /* get RIFF chunk header */
162 if ((lseek(fd, 0, SEEK_SET) < 0) || (read(fd, buf, 12) < 12))
164 return false;
166 offset += 12;
168 if ((memcmp(buf, "RIFF", 4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0))
170 DEBUGF("metadata error: missing riff header.\n");
171 return false;
174 /* iterate over WAVE chunks until 'data' chunk */
175 while (true)
177 /* get chunk header */
178 if (read(fd, buf, 8) < 8)
179 return false;
180 offset += 8;
182 /* chunkSize */
183 i = get_long_le(&buf[4]);
185 if (memcmp(buf, "fmt ", 4) == 0)
187 /* get rest of chunk */
188 if (i < 16)
189 return false;
191 read_bytes = 16;
192 if (i > 19)
193 read_bytes = 20;
195 if (read(fd, buf, read_bytes) != read_bytes)
196 return false;
198 offset += read_bytes;
199 i -= read_bytes;
201 parse_riff_format(buf, i, &fmt, id3);
203 /* Check for ATRAC3 stream */
204 if (fmt.formattag == WAVE_FORMAT_ATRAC3)
206 int jsflag = 0;
207 if(id3->bitrate == 66 || id3->bitrate == 94)
208 jsflag = 1;
210 id3->extradata_size = 14;
211 id3->channels = 2;
212 id3->codectype = AFMT_OMA_ATRAC3;
213 /* Store the extradata for the codec */
214 AV_WL16(&id3->id3v2buf[0], 1); // always 1
215 AV_WL32(&id3->id3v2buf[2], id3->frequency); // samples rate
216 AV_WL16(&id3->id3v2buf[6], jsflag); // coding mode
217 AV_WL16(&id3->id3v2buf[8], jsflag); // coding mode
218 AV_WL16(&id3->id3v2buf[10], 1); // always 1
219 AV_WL16(&id3->id3v2buf[12], 0); // always 0
222 else if (memcmp(buf, "data", 4) == 0)
224 fmt.numbytes = i;
225 if (fmt.formattag == WAVE_FORMAT_ATRAC3)
226 id3->first_frame_offset = offset;
227 break;
229 else if (memcmp(buf, "fact", 4) == 0)
231 /* dwSampleLength */
232 if (i >= 4)
234 /* get rest of chunk */
235 if (read(fd, buf, 4) < 4)
236 return false;
237 offset += 4;
238 i -= 4;
239 totalsamples = get_long_le(buf);
243 /* seek to next chunk (even chunk sizes must be padded) */
244 if (i & 0x01)
245 i++;
247 if(lseek(fd, i, SEEK_CUR) < 0)
248 return false;
249 offset += i;
252 if ((fmt.numbytes == 0) || (fmt.channels == 0) || (fmt.blockalign == 0))
254 DEBUGF("metadata error: numbytes, channels, or blockalign is 0.\n");
255 return false;
258 if (totalsamples == 0)
260 totalsamples = get_totalsamples(&fmt, id3);
263 id3->vbr = false; /* All WAV files are CBR */
264 id3->filesize = filesize(fd);
266 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
267 if(id3->codectype != AFMT_OMA_ATRAC3)
268 id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
269 else
270 id3->length = ((id3->filesize - id3->first_frame_offset) * 8) / id3->bitrate;
272 return true;
275 bool get_wave64_metadata(int fd, struct mp3entry* id3)
277 /* Use the trackname part of the id3 structure as a temporary buffer */
278 unsigned char* buf = (unsigned char *)id3->path;
279 struct wave_fmt fmt;
280 unsigned long totalsamples = 0;
281 int read_bytes;
282 uint64_t i;
284 memset(&fmt, 0, sizeof(struct wave_fmt));
286 /* get RIFF chunk header */
287 if ((lseek(fd, 0, SEEK_SET) < 0) || (read(fd, buf, 40) < 40))
288 return false;
290 if ((memcmp(buf , WAVE64_GUID_RIFF, 16) != 0)||
291 (memcmp(buf+24, WAVE64_GUID_WAVE, 16) != 0))
293 DEBUGF("metada error: does not wave64 file\n");
294 return false;
297 /* iterate over WAVE chunks until 'data' chunk */
298 while (true)
300 /* get chunk header */
301 if (read(fd, buf, 24) < 24)
302 return false;
304 /* chunkSize (excludes GUID and size length) */
305 i = get_uint64_le(&buf[16]) - 24;
307 if (memcmp(buf, WAVE64_GUID_FMT, 16) == 0)
309 DEBUGF("find 'fmt ' chunk\n");
310 if (i < 16)
311 return false;
313 read_bytes = 16;
314 if (i > 16)
316 read_bytes = 24;
317 if (i < 24)
318 i = 24;
321 /* get rest of chunk */
322 if (read(fd, buf, read_bytes) < read_bytes)
323 return false;
325 i -= read_bytes;
326 parse_riff_format(buf, read_bytes, &fmt, id3);
328 else if (memcmp(buf, WAVE64_GUID_DATA, 16) == 0)
330 DEBUGF("find 'data' chunk\n");
331 fmt.numbytes = i;
332 break;
334 else if (memcmp(buf, WAVE64_GUID_FACT, 16) == 0)
336 /* Skip 'fact' chunk */
337 DEBUGF("find 'fact' chunk\n");
340 /* seek to next chunk (8byte bound) */
341 if (i & 0x07)
342 i += 8 - (i & 0x7);
344 if(lseek(fd, i, SEEK_CUR) < 0)
345 return false;
348 if ((fmt.numbytes == 0) || (fmt.channels == 0) || (fmt.blockalign == 0))
350 DEBUGF("metadata error: numbytes, channels, or blockalign is 0\n");
351 return false;
354 if (totalsamples == 0)
356 totalsamples = get_totalsamples(&fmt, id3);
359 id3->vbr = false; /* All Wave64 files are CBR */
360 id3->filesize = filesize(fd);
362 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
363 id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
365 return true;