summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcoen Hirschberg <marcoen@gmail.com>2007-06-16 18:19:51 +0000
committerMarcoen Hirschberg <marcoen@gmail.com>2007-06-16 18:19:51 +0000
commit2175d1edf65367fd3fe3cff266b8d6ea12930f2f (patch)
tree9d6f50ebfc7919b4e2f0853fc8c0cb844cabe995
parentc3206a455a455fadb282d09f9af482c66b6bdf8e (diff)
downloadrockbox-2175d1edf65367fd3fe3cff266b8d6ea12930f2f.tar.gz
rockbox-2175d1edf65367fd3fe3cff266b8d6ea12930f2f.zip
split up the metadata parser
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13637 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/FILES1
-rw-r--r--apps/SOURCES15
-rw-r--r--apps/metadata.c2154
-rw-r--r--apps/metadata/adx.c115
-rw-r--r--apps/metadata/aiff.c98
-rw-r--r--apps/metadata/ape.c132
-rw-r--r--apps/metadata/flac.c122
-rw-r--r--apps/metadata/metadata_common.c273
-rw-r--r--apps/metadata/metadata_common.h45
-rw-r--r--apps/metadata/metadata_parsers.h31
-rw-r--r--apps/metadata/monkeys.c92
-rw-r--r--apps/metadata/mp4.c669
-rw-r--r--apps/metadata/mpc.c118
-rw-r--r--apps/metadata/sid.c88
-rw-r--r--apps/metadata/spc.c126
-rw-r--r--apps/metadata/speex.c212
-rw-r--r--apps/metadata/vorbis.c330
-rw-r--r--apps/metadata/wave.c128
18 files changed, 2601 insertions, 2148 deletions
diff --git a/apps/FILES b/apps/FILES
index 936e817fd3..85d70cbe74 100644
--- a/apps/FILES
+++ b/apps/FILES
@@ -35,6 +35,7 @@ gui/*.[ch]
35keymaps/*.[ch] 35keymaps/*.[ch]
36lang/*.lang 36lang/*.lang
37menus/*.[ch] 37menus/*.[ch]
38metadata/*.[ch]
38player/*.[ch] 39player/*.[ch]
39plugins/*.[ch] 40plugins/*.[ch]
40plugins/*.pl 41plugins/*.pl
diff --git a/apps/SOURCES b/apps/SOURCES
index ccb9ca2772..a48017c7cd 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -106,6 +106,21 @@ eq_arm.S
106#endif 106#endif
107#endif 107#endif
108metadata.c 108metadata.c
109#if CONFIG_CODEC == SWCODEC
110metadata/metadata_common.c
111metadata/aiff.c
112metadata/ape.c
113metadata/adx.c
114metadata/flac.c
115metadata/monkeys.c
116metadata/mp4.c
117metadata/mpc.c
118metadata/sid.c
119metadata/spc.c
120metadata/speex.c
121metadata/vorbis.c
122metadata/wave.c
123#endif
109#ifdef HAVE_TAGCACHE 124#ifdef HAVE_TAGCACHE
110tagcache.c 125tagcache.c
111#endif 126#endif
diff --git a/apps/metadata.c b/apps/metadata.c
index a0c2f31eee..3b2855bc24 100644
--- a/apps/metadata.c
+++ b/apps/metadata.c
@@ -22,84 +22,17 @@
22#include <ctype.h> 22#include <ctype.h>
23#include <inttypes.h> 23#include <inttypes.h>
24 24
25#include "errno.h"
26#include "metadata.h"
27#include "mp3_playback.h"
28#include "logf.h"
29#include "rbunicode.h"
30#include "atoi.h"
31#include "replaygain.h"
32#include "debug.h"
33#include "system.h" 25#include "system.h"
26#include "playback.h"
27#include "debug.h"
28#include "logf.h"
34#include "cuesheet.h" 29#include "cuesheet.h"
35#include "structec.h"
36
37enum tagtype { TAGTYPE_APE = 1, TAGTYPE_VORBIS };
38
39#ifdef ROCKBOX_BIG_ENDIAN
40#define IS_BIG_ENDIAN 1
41#else
42#define IS_BIG_ENDIAN 0
43#endif
44 30
45#define APETAG_HEADER_LENGTH 32 31#if CONFIG_CODEC == SWCODEC
46#define APETAG_HEADER_FORMAT "8llll8"
47#define APETAG_ITEM_HEADER_FORMAT "ll"
48#define APETAG_ITEM_TYPE_MASK 3
49
50#define TAG_NAME_LENGTH 32
51#define TAG_VALUE_LENGTH 128
52
53#define MP4_ID(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
54
55#define MP4_3gp6 MP4_ID('3', 'g', 'p', '6')
56#define MP4_alac MP4_ID('a', 'l', 'a', 'c')
57#define MP4_calb MP4_ID(0xa9, 'a', 'l', 'b')
58#define MP4_cART MP4_ID(0xa9, 'A', 'R', 'T')
59#define MP4_cnam MP4_ID(0xa9, 'n', 'a', 'm')
60#define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't')
61#define MP4_esds MP4_ID('e', 's', 'd', 's')
62#define MP4_ftyp MP4_ID('f', 't', 'y', 'p')
63#define MP4_gnre MP4_ID('g', 'n', 'r', 'e')
64#define MP4_hdlr MP4_ID('h', 'd', 'l', 'r')
65#define MP4_ilst MP4_ID('i', 'l', 's', 't')
66#define MP4_M4A MP4_ID('M', '4', 'A', ' ')
67#define MP4_M4B MP4_ID('M', '4', 'B', ' ')
68#define MP4_mdat MP4_ID('m', 'd', 'a', 't')
69#define MP4_mdia MP4_ID('m', 'd', 'i', 'a')
70#define MP4_mdir MP4_ID('m', 'd', 'i', 'r')
71#define MP4_meta MP4_ID('m', 'e', 't', 'a')
72#define MP4_minf MP4_ID('m', 'i', 'n', 'f')
73#define MP4_moov MP4_ID('m', 'o', 'o', 'v')
74#define MP4_mp4a MP4_ID('m', 'p', '4', 'a')
75#define MP4_mp42 MP4_ID('m', 'p', '4', '2')
76#define MP4_qt MP4_ID('q', 't', ' ', ' ')
77#define MP4_soun MP4_ID('s', 'o', 'u', 'n')
78#define MP4_stbl MP4_ID('s', 't', 'b', 'l')
79#define MP4_stsd MP4_ID('s', 't', 's', 'd')
80#define MP4_stts MP4_ID('s', 't', 't', 's')
81#define MP4_trak MP4_ID('t', 'r', 'a', 'k')
82#define MP4_trkn MP4_ID('t', 'r', 'k', 'n')
83#define MP4_udta MP4_ID('u', 'd', 't', 'a')
84#define MP4_extra MP4_ID('-', '-', '-', '-')
85
86struct apetag_header
87{
88 char id[8];
89 long version;
90 long length;
91 long item_count;
92 long flags;
93 char reserved[8];
94};
95 32
96struct apetag_item_header 33#include "metadata/metadata_common.h"
97{ 34#include "metadata/metadata_parsers.h"
98 long length;
99 long flags;
100};
101 35
102#if CONFIG_CODEC == SWCODEC
103static const unsigned short a52_bitrates[] = 36static const unsigned short a52_bitrates[] =
104{ 37{
105 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 38 32, 40, 48, 56, 64, 80, 96, 112, 128, 160,
@@ -124,2081 +57,6 @@ static const long wavpack_sample_rates [] =
124 32000, 44100, 48000, 64000, 88200, 96000, 192000 57 32000, 44100, 48000, 64000, 88200, 96000, 192000
125}; 58};
126 59
127/* Read a string from the file. Read up to size bytes, or, if eos != -1,
128 * until the eos character is found (eos is not stored in buf, unless it is
129 * nil). Writes up to buf_size chars to buf, always terminating with a nil.
130 * Returns number of chars read or -1 on read error.
131 */
132static long read_string(int fd, char* buf, long buf_size, int eos, long size)
133{
134 long read_bytes = 0;
135 char c;
136
137 while (size != 0)
138 {
139 if (read(fd, &c, 1) != 1)
140 {
141 read_bytes = -1;
142 break;
143 }
144
145 read_bytes++;
146 size--;
147
148 if ((eos != -1) && (eos == (unsigned char) c))
149 {
150 break;
151 }
152
153 if (buf_size > 1)
154 {
155 *buf++ = c;
156 buf_size--;
157 }
158 }
159
160 *buf = 0;
161 return read_bytes;
162}
163
164/* Read an unsigned 32-bit integer from a big-endian file. */
165#ifdef ROCKBOX_BIG_ENDIAN
166#define read_uint32be(fd,buf) read((fd), (buf), 4)
167#else
168static int read_uint32be(int fd, unsigned int* buf)
169{
170 size_t n;
171
172 n = read(fd, (char*) buf, 4);
173 *buf = betoh32(*buf);
174 return n;
175}
176#endif
177
178/* Read an unaligned 32-bit little endian long from buffer. */
179static unsigned long get_long_le(void* buf)
180{
181 unsigned char* p = (unsigned char*) buf;
182
183 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
184}
185
186/* Read an unaligned 16-bit little endian short from buffer. */
187static unsigned short get_short_le(void* buf)
188{
189 unsigned char* p = (unsigned char*) buf;
190
191 return p[0] | (p[1] << 8);
192}
193
194/* Read an unaligned 32-bit big endian long from buffer. */
195static unsigned long get_long_be(void* buf)
196{
197 unsigned char* p = (unsigned char*) buf;
198
199 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
200}
201
202/* Read an unaligned 32-bit little endian long from buffer. */
203static long get_slong(void* buf)
204{
205 unsigned char* p = (unsigned char*) buf;
206
207 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
208}
209
210static char* skip_space(char* str)
211{
212 while (isspace(*str))
213 {
214 str++;
215 }
216
217 return str;
218}
219
220static unsigned long get_itunes_int32(char* value, int count)
221{
222 static const char hexdigits[] = "0123456789ABCDEF";
223 const char* c;
224 int r = 0;
225
226 while (count-- > 0)
227 {
228 value = skip_space(value);
229
230 while (*value && !isspace(*value))
231 {
232 value++;
233 }
234 }
235
236 value = skip_space(value);
237
238 while (*value && ((c = strchr(hexdigits, toupper(*value))) != NULL))
239 {
240 r = (r << 4) | (c - hexdigits);
241 value++;
242 }
243
244 return r;
245}
246
247/* Parse the tag (the name-value pair) and fill id3 and buffer accordingly.
248 * String values to keep are written to buf. Returns number of bytes written
249 * to buf (including end nil).
250 */
251static long parse_tag(const char* name, char* value, struct mp3entry* id3,
252 char* buf, long buf_remaining, enum tagtype type)
253{
254 long len = 0;
255 char** p;
256
257 if ((((strcasecmp(name, "track") == 0) && (type == TAGTYPE_APE)))
258 || ((strcasecmp(name, "tracknumber") == 0) && (type == TAGTYPE_VORBIS)))
259 {
260 id3->tracknum = atoi(value);
261 p = &(id3->track_string);
262 }
263 else if (((strcasecmp(name, "year") == 0) && (type == TAGTYPE_APE))
264 || ((strcasecmp(name, "date") == 0) && (type == TAGTYPE_VORBIS)))
265 {
266 /* Date's can be in any format in Vorbis. However most of them
267 * are in ISO8601 format so if we try and parse the first part
268 * of the tag as a number, we should get the year. If we get crap,
269 * then act like we never parsed it.
270 */
271 id3->year = atoi(value);
272 if (id3->year < 1900)
273 { /* yeah, not likely */
274 id3->year = 0;
275 }
276 p = &(id3->year_string);
277 }
278 else if (strcasecmp(name, "title") == 0)
279 {
280 p = &(id3->title);
281 }
282 else if (strcasecmp(name, "artist") == 0)
283 {
284 p = &(id3->artist);
285 }
286 else if (strcasecmp(name, "album") == 0)
287 {
288 p = &(id3->album);
289 }
290 else if (strcasecmp(name, "genre") == 0)
291 {
292 p = &(id3->genre_string);
293 }
294 else if (strcasecmp(name, "composer") == 0)
295 {
296 p = &(id3->composer);
297 }
298 else if (strcasecmp(name, "comment") == 0)
299 {
300 p = &(id3->comment);
301 }
302 else if (strcasecmp(name, "albumartist") == 0)
303 {
304 p = &(id3->albumartist);
305 }
306 else if (strcasecmp(name, "album artist") == 0)
307 {
308 p = &(id3->albumartist);
309 }
310 else if (strcasecmp(name, "ensemble") == 0)
311 {
312 p = &(id3->albumartist);
313 }
314 else
315 {
316 len = parse_replaygain(name, value, id3, buf, buf_remaining);
317 p = NULL;
318 }
319
320 if (p)
321 {
322 len = strlen(value);
323 len = MIN(len, buf_remaining - 1);
324
325 if (len > 0)
326 {
327 strncpy(buf, value, len);
328 buf[len] = 0;
329 *p = buf;
330 len++;
331 }
332 else
333 {
334 len = 0;
335 }
336 }
337
338 return len;
339}
340
341/* Read the items in an APEV2 tag. Only looks for a tag at the end of a
342 * file. Returns true if a tag was found and fully read, false otherwise.
343 */
344static bool read_ape_tags(int fd, struct mp3entry* id3)
345{
346 struct apetag_header header;
347
348 if ((lseek(fd, -APETAG_HEADER_LENGTH, SEEK_END) < 0)
349 || (ecread(fd, &header, 1, APETAG_HEADER_FORMAT, IS_BIG_ENDIAN) != APETAG_HEADER_LENGTH)
350 || (memcmp(header.id, "APETAGEX", sizeof(header.id))))
351 {
352 return false;
353 }
354
355 if ((header.version == 2000) && (header.item_count > 0)
356 && (header.length > APETAG_HEADER_LENGTH))
357 {
358 char *buf = id3->id3v2buf;
359 unsigned int buf_remaining = sizeof(id3->id3v2buf)
360 + sizeof(id3->id3v1buf);
361 unsigned int tag_remaining = header.length - APETAG_HEADER_LENGTH;
362 int i;
363
364 if (lseek(fd, -header.length, SEEK_END) < 0)
365 {
366 return false;
367 }
368
369 for (i = 0; i < header.item_count; i++)
370 {
371 struct apetag_item_header item;
372 char name[TAG_NAME_LENGTH];
373 char value[TAG_VALUE_LENGTH];
374 long r;
375
376 if (tag_remaining < sizeof(item))
377 {
378 break;
379 }
380
381 if (ecread(fd, &item, 1, APETAG_ITEM_HEADER_FORMAT, IS_BIG_ENDIAN) < (long) sizeof(item))
382 {
383 return false;
384 }
385
386 tag_remaining -= sizeof(item);
387 r = read_string(fd, name, sizeof(name), 0, tag_remaining);
388
389 if (r == -1)
390 {
391 return false;
392 }
393
394 tag_remaining -= r + item.length;
395
396 if ((item.flags & APETAG_ITEM_TYPE_MASK) == 0)
397 {
398 long len;
399
400 if (read_string(fd, value, sizeof(value), -1, item.length)
401 != item.length)
402 {
403 return false;
404 }
405
406 len = parse_tag(name, value, id3, buf, buf_remaining,
407 TAGTYPE_APE);
408 buf += len;
409 buf_remaining -= len;
410 }
411 else
412 {
413 if (lseek(fd, item.length, SEEK_CUR) < 0)
414 {
415 return false;
416 }
417 }
418 }
419 }
420
421 return true;
422}
423
424/* Read the items in a Vorbis comment packet. Returns true the items were
425 * fully read, false otherwise.
426 */
427static bool read_vorbis_tags(int fd, struct mp3entry *id3,
428 long tag_remaining)
429{
430 char *buf = id3->id3v2buf;
431 int32_t comment_count;
432 int32_t len;
433 int buf_remaining = sizeof(id3->id3v2buf) + sizeof(id3->id3v1buf);
434 int i;
435
436 if (ecread(fd, &len, 1, "l", IS_BIG_ENDIAN) < (long) sizeof(len))
437 {
438 return false;
439 }
440
441 if ((lseek(fd, len, SEEK_CUR) < 0)
442 || (ecread(fd, &comment_count, 1, "l", IS_BIG_ENDIAN)
443 < (long) sizeof(comment_count)))
444 {
445 return false;
446 }
447
448 tag_remaining -= len + sizeof(len) + sizeof(comment_count);
449
450 if (tag_remaining <= 0)
451 {
452 return true;
453 }
454
455 for (i = 0; i < comment_count; i++)
456 {
457 char name[TAG_NAME_LENGTH];
458 char value[TAG_VALUE_LENGTH];
459 int32_t read_len;
460
461 if (tag_remaining < 4)
462 {
463 break;
464 }
465
466 if (ecread(fd, &len, 1, "l", IS_BIG_ENDIAN) < (long) sizeof(len))
467 {
468 return false;
469 }
470
471 tag_remaining -= 4;
472
473 /* Quit if we've passed the end of the page */
474 if (tag_remaining < len)
475 {
476 break;
477 }
478
479 tag_remaining -= len;
480 read_len = read_string(fd, name, sizeof(name), '=', len);
481
482 if (read_len < 0)
483 {
484 return false;
485 }
486
487 len -= read_len;
488
489 if (read_string(fd, value, sizeof(value), -1, len) < 0)
490 {
491 return false;
492 }
493
494 len = parse_tag(name, value, id3, buf, buf_remaining,
495 TAGTYPE_VORBIS);
496 buf += len;
497 buf_remaining -= len;
498 }
499
500 /* Skip to the end of the block */
501 if (tag_remaining)
502 {
503 if (lseek(fd, tag_remaining, SEEK_CUR) < 0)
504 {
505 return false;
506 }
507 }
508
509 return true;
510}
511
512/* Skip an ID3v2 tag if it can be found. We assume the tag is located at the
513 * start of the file, which should be true in all cases where we need to skip it.
514 * Returns true if successfully skipped or not skipped, and false if
515 * something went wrong while skipping.
516 */
517static bool skip_id3v2(int fd, struct mp3entry *id3)
518{
519 char buf[4];
520
521 read(fd, buf, 4);
522 if (memcmp(buf, "ID3", 3) == 0)
523 {
524 /* We have found an ID3v2 tag at the start of the file - find its
525 length and then skip it. */
526 if ((id3->first_frame_offset = getid3v2len(fd)) == 0)
527 return false;
528
529 if ((lseek(fd, id3->first_frame_offset, SEEK_SET) < 0))
530 return false;
531
532 return true;
533 } else {
534 lseek(fd, 0, SEEK_SET);
535 id3->first_frame_offset = 0;
536 return true;
537 }
538}
539
540/* A simple parser to read vital metadata from an Ogg Speex file. Returns
541 * false if metadata needed by the Speex codec couldn't be read.
542 */
543
544static bool get_speex_metadata(int fd, struct mp3entry* id3)
545{
546 /* An Ogg File is split into pages, each starting with the string
547 * "OggS". Each page has a timestamp (in PCM samples) referred to as
548 * the "granule position".
549 *
550 * An Ogg Speex has the following structure:
551 * 1) Identification header (containing samplerate, numchannels, etc)
552 Described in this page: (http://www.speex.org/manual2/node7.html)
553 * 2) Comment header - containing the Vorbis Comments
554 * 3) Many audio packets...
555 */
556
557 /* Use the path name of the id3 structure as a temporary buffer. */
558 unsigned char* buf = (unsigned char*)id3->path;
559 long comment_size;
560 long remaining = 0;
561 long last_serial = 0;
562 long serial, r;
563 int segments;
564 int i;
565 bool eof = false;
566
567 if ((lseek(fd, 0, SEEK_SET) < 0) || (read(fd, buf, 58) < 33))
568 {
569 return false;
570 }
571
572 if ((memcmp(buf, "OggS", 4) != 0) || (memcmp(&buf[28], "Speex", 5) != 0))
573 {
574 return false;
575 }
576
577 /* We need to ensure the serial number from this page is the same as the
578 * one from the last page (since we only support a single bitstream).
579 */
580 serial = get_long_le(&buf[14]);
581 if ((lseek(fd, 33, SEEK_SET) < 0)||(read(fd, buf, 58) < 4))
582 {
583 return false;
584 }
585
586 id3->frequency = get_slong(&buf[31]);
587 last_serial = get_long_le(&buf[27]);/*temporary, header size*/
588 id3->bitrate = get_long_le(&buf[47]);
589 id3->vbr = get_long_le(&buf[55]);
590 id3->filesize = filesize(fd);
591 /* Comments are in second Ogg page */
592 if (lseek(fd, 28+last_serial/*(temporary for header size)*/, SEEK_SET) < 0)
593 {
594 return false;
595 }
596
597 /* Minimum header length for Ogg pages is 27. */
598 if (read(fd, buf, 27) < 27)
599 {
600 return false;
601 }
602
603 if (memcmp(buf, "OggS", 4) !=0 )
604 {
605 return false;
606 }
607
608 segments = buf[26];
609 /* read in segment table */
610 if (read(fd, buf, segments) < segments)
611 {
612 return false;
613 }
614
615 /* The second packet in a vorbis stream is the comment packet. It *may*
616 * extend beyond the second page, but usually does not. Here we find the
617 * length of the comment packet (or the rest of the page if the comment
618 * packet extends to the third page).
619 */
620 for (i = 0; i < segments; i++)
621 {
622 remaining += buf[i];
623 /* The last segment of a packet is always < 255 bytes */
624 if (buf[i] < 255)
625 {
626 break;
627 }
628 }
629
630 comment_size = remaining;
631
632 /* Failure to read the tags isn't fatal. */
633 read_vorbis_tags(fd, id3, remaining);
634
635 /* We now need to search for the last page in the file - identified by
636 * by ('O','g','g','S',0) and retrieve totalsamples.
637 */
638
639 /* A page is always < 64 kB */
640 if (lseek(fd, -(MIN(64 * 1024, id3->filesize)), SEEK_END) < 0)
641 {
642 return false;
643 }
644
645 remaining = 0;
646
647 while (!eof)
648 {
649 r = read(fd, &buf[remaining], MAX_PATH - remaining);
650
651 if (r <= 0)
652 {
653 eof = true;
654 }
655 else
656 {
657 remaining += r;
658 }
659
660 /* Inefficient (but simple) search */
661 i = 0;
662
663 while (i < (remaining - 3))
664 {
665 if ((buf[i] == 'O') && (memcmp(&buf[i], "OggS", 4) == 0))
666 {
667 if (i < (remaining - 17))
668 {
669 /* Note that this only reads the low 32 bits of a
670 * 64 bit value.
671 */
672 id3->samples = get_long_le(&buf[i + 6]);
673 last_serial = get_long_le(&buf[i + 14]);
674
675 /* If this page is very small the beginning of the next
676 * header could be in buffer. Jump near end of this header
677 * and continue */
678 i += 27;
679 }
680 else
681 {
682 break;
683 }
684 }
685 else
686 {
687 i++;
688 }
689 }
690
691 if (i < remaining)
692 {
693 /* Move the remaining bytes to start of buffer.
694 * Reuse var 'segments' as it is no longer needed */
695 segments = 0;
696 while (i < remaining)
697 {
698 buf[segments++] = buf[i++];
699 }
700 remaining = segments;
701 }
702 else
703 {
704 /* Discard the rest of the buffer */
705 remaining = 0;
706 }
707 }
708
709 /* This file has mutiple vorbis bitstreams (or is corrupt). */
710 /* FIXME we should display an error here. */
711 if (serial != last_serial)
712 {
713 logf("serialno mismatch");
714 logf("%ld", serial);
715 logf("%ld", last_serial);
716 return false;
717 }
718
719 id3->length = (id3->samples / id3->frequency) * 1000;
720 id3->bitrate = (((int64_t) id3->filesize - comment_size) * 8) / id3->length;
721 return true;
722}
723
724
725/* A simple parser to read vital metadata from an Ogg Vorbis file.
726 * Calls get_speex_metadata if a speex file is identified. Returns
727 * false if metadata needed by the Vorbis codec couldn't be read.
728 */
729static bool get_vorbis_metadata(int fd, struct mp3entry* id3)
730{
731 /* An Ogg File is split into pages, each starting with the string
732 * "OggS". Each page has a timestamp (in PCM samples) referred to as
733 * the "granule position".
734 *
735 * An Ogg Vorbis has the following structure:
736 * 1) Identification header (containing samplerate, numchannels, etc)
737 * 2) Comment header - containing the Vorbis Comments
738 * 3) Setup header - containing codec setup information
739 * 4) Many audio packets...
740 */
741
742 /* Use the path name of the id3 structure as a temporary buffer. */
743 unsigned char* buf = (unsigned char *)id3->path;
744 long comment_size;
745 long remaining = 0;
746 long last_serial = 0;
747 long serial, r;
748 int segments;
749 int i;
750 bool eof = false;
751
752 if ((lseek(fd, 0, SEEK_SET) < 0) || (read(fd, buf, 58) < 4))
753 {
754 return false;
755 }
756
757 if ((memcmp(buf, "OggS", 4) != 0) || (memcmp(&buf[29], "vorbis", 6) != 0))
758 {
759 if ((memcmp(buf, "OggS", 4) != 0) || (memcmp(&buf[28], "Speex", 5) != 0))
760 {
761 return false;
762 }
763 else
764 {
765 id3->codectype = AFMT_SPEEX;
766 return get_speex_metadata(fd, id3);
767 }
768 }
769
770 /* We need to ensure the serial number from this page is the same as the
771 * one from the last page (since we only support a single bitstream).
772 */
773 serial = get_long_le(&buf[14]);
774 id3->frequency = get_long_le(&buf[40]);
775 id3->filesize = filesize(fd);
776
777 /* Comments are in second Ogg page */
778 if (lseek(fd, 58, SEEK_SET) < 0)
779 {
780 return false;
781 }
782
783 /* Minimum header length for Ogg pages is 27. */
784 if (read(fd, buf, 27) < 27)
785 {
786 return false;
787 }
788
789 if (memcmp(buf, "OggS", 4) !=0 )
790 {
791 return false;
792 }
793
794 segments = buf[26];
795
796 /* read in segment table */
797 if (read(fd, buf, segments) < segments)
798 {
799 return false;
800 }
801
802 /* The second packet in a vorbis stream is the comment packet. It *may*
803 * extend beyond the second page, but usually does not. Here we find the
804 * length of the comment packet (or the rest of the page if the comment
805 * packet extends to the third page).
806 */
807 for (i = 0; i < segments; i++)
808 {
809 remaining += buf[i];
810
811 /* The last segment of a packet is always < 255 bytes */
812 if (buf[i] < 255)
813 {
814 break;
815 }
816 }
817
818 /* Now read in packet header (type and id string) */
819 if (read(fd, buf, 7) < 7)
820 {
821 return false;
822 }
823
824 comment_size = remaining;
825 remaining -= 7;
826
827 /* The first byte of a packet is the packet type; comment packets are
828 * type 3.
829 */
830 if ((buf[0] != 3) || (memcmp(buf + 1, "vorbis", 6) !=0))
831 {
832 return false;
833 }
834
835 /* Failure to read the tags isn't fatal. */
836 read_vorbis_tags(fd, id3, remaining);
837
838 /* We now need to search for the last page in the file - identified by
839 * by ('O','g','g','S',0) and retrieve totalsamples.
840 */
841
842 /* A page is always < 64 kB */
843 if (lseek(fd, -(MIN(64 * 1024, id3->filesize)), SEEK_END) < 0)
844 {
845 return false;
846 }
847
848 remaining = 0;
849
850 while (!eof)
851 {
852 r = read(fd, &buf[remaining], MAX_PATH - remaining);
853
854 if (r <= 0)
855 {
856 eof = true;
857 }
858 else
859 {
860 remaining += r;
861 }
862
863 /* Inefficient (but simple) search */
864 i = 0;
865
866 while (i < (remaining - 3))
867 {
868 if ((buf[i] == 'O') && (memcmp(&buf[i], "OggS", 4) == 0))
869 {
870 if (i < (remaining - 17))
871 {
872 /* Note that this only reads the low 32 bits of a
873 * 64 bit value.
874 */
875 id3->samples = get_long_le(&buf[i + 6]);
876 last_serial = get_long_le(&buf[i + 14]);
877
878 /* If this page is very small the beginning of the next
879 * header could be in buffer. Jump near end of this header
880 * and continue */
881 i += 27;
882 }
883 else
884 {
885 break;
886 }
887 }
888 else
889 {
890 i++;
891 }
892 }
893
894 if (i < remaining)
895 {
896 /* Move the remaining bytes to start of buffer.
897 * Reuse var 'segments' as it is no longer needed */
898 segments = 0;
899 while (i < remaining)
900 {
901 buf[segments++] = buf[i++];
902 }
903 remaining = segments;
904 }
905 else
906 {
907 /* Discard the rest of the buffer */
908 remaining = 0;
909 }
910 }
911
912 /* This file has mutiple vorbis bitstreams (or is corrupt). */
913 /* FIXME we should display an error here. */
914 if (serial != last_serial)
915 {
916 logf("serialno mismatch");
917 logf("%ld", serial);
918 logf("%ld", last_serial);
919 return false;
920 }
921
922 id3->length = ((int64_t) id3->samples * 1000) / id3->frequency;
923
924 if (id3->length <= 0)
925 {
926 logf("ogg length invalid!");
927 return false;
928 }
929
930 id3->bitrate = (((int64_t) id3->filesize - comment_size) * 8) / id3->length;
931 id3->vbr = true;
932
933 return true;
934}
935
936static bool get_flac_metadata(int fd, struct mp3entry* id3)
937{
938 /* A simple parser to read vital metadata from a FLAC file - length,
939 * frequency, bitrate etc. This code should either be moved to a
940 * seperate file, or discarded in favour of the libFLAC code.
941 * The FLAC stream specification can be found at
942 * http://flac.sourceforge.net/format.html#stream
943 */
944
945 /* Use the trackname part of the id3 structure as a temporary buffer */
946 unsigned char* buf = (unsigned char *)id3->path;
947 bool rc = false;
948
949 if (!skip_id3v2(fd, id3) || (read(fd, buf, 4) < 4))
950 {
951 return rc;
952 }
953
954 if (memcmp(buf, "fLaC", 4) != 0)
955 {
956 return rc;
957 }
958
959 while (true)
960 {
961 long i;
962
963 if (read(fd, buf, 4) < 0)
964 {
965 return rc;
966 }
967
968 /* The length of the block */
969 i = (buf[1] << 16) | (buf[2] << 8) | buf[3];
970
971 if ((buf[0] & 0x7f) == 0) /* 0 is the STREAMINFO block */
972 {
973 unsigned long totalsamples;
974
975 /* FIXME: Don't trust the value of i */
976 if (read(fd, buf, i) < 0)
977 {
978 return rc;
979 }
980
981 id3->vbr = true; /* All FLAC files are VBR */
982 id3->filesize = filesize(fd);
983 id3->frequency = (buf[10] << 12) | (buf[11] << 4)
984 | ((buf[12] & 0xf0) >> 4);
985 rc = true; /* Got vital metadata */
986
987 /* totalsamples is a 36-bit field, but we assume <= 32 bits are used */
988 totalsamples = get_long_be(&buf[14]);
989
990 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
991 id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
992
993 if (id3->length <= 0)
994 {
995 logf("flac length invalid!");
996 return false;
997 }
998
999 id3->bitrate = (id3->filesize * 8) / id3->length;
1000 }
1001 else if ((buf[0] & 0x7f) == 4) /* 4 is the VORBIS_COMMENT block */
1002 {
1003 /* The next i bytes of the file contain the VORBIS COMMENTS. */
1004 if (!read_vorbis_tags(fd, id3, i))
1005 {
1006 return rc;
1007 }
1008 }
1009 else
1010 {
1011 if (buf[0] & 0x80)
1012 {
1013 /* If we have reached the last metadata block, abort. */
1014 break;
1015 }
1016 else
1017 {
1018 /* Skip to next metadata block */
1019 if (lseek(fd, i, SEEK_CUR) < 0)
1020 {
1021 return rc;
1022 }
1023 }
1024 }
1025 }
1026
1027 return true;
1028}
1029
1030static bool get_monkeys_metadata(int fd, struct mp3entry* id3)
1031{
1032 /* Use the trackname part of the id3 structure as a temporary buffer */
1033 unsigned char* buf = (unsigned char *)id3->path;
1034 unsigned char* header;
1035 bool rc = false;
1036 uint32_t descriptorlength;
1037 uint32_t totalsamples;
1038 uint32_t blocksperframe, finalframeblocks, totalframes;
1039 int fileversion;
1040
1041 lseek(fd, 0, SEEK_SET);
1042
1043 if (read(fd, buf, 4) < 4)
1044 {
1045 return rc;
1046 }
1047
1048 if (memcmp(buf, "MAC ", 4) != 0)
1049 {
1050 return rc;
1051 }
1052
1053 read(fd, buf + 4, MAX_PATH - 4);
1054
1055 fileversion = get_short_le(buf+4);
1056 if (fileversion < 3970)
1057 {
1058 /* Not supported */
1059 return false;
1060 }
1061
1062 if (fileversion >= 3980)
1063 {
1064 descriptorlength = get_long_le(buf+8);
1065
1066 header = buf + descriptorlength;
1067
1068 blocksperframe = get_long_le(header+4);
1069 finalframeblocks = get_long_le(header+8);
1070 totalframes = get_long_le(header+12);
1071 id3->frequency = get_long_le(header+20);
1072 }
1073 else
1074 {
1075 /* v3.95 and later files all have a fixed framesize */
1076 blocksperframe = 73728 * 4;
1077
1078 finalframeblocks = get_long_le(buf+28);
1079 totalframes = get_long_le(buf+24);
1080 id3->frequency = get_long_le(buf+12);
1081 }
1082
1083 id3->vbr = true; /* All FLAC files are VBR */
1084 id3->filesize = filesize(fd);
1085
1086 totalsamples = finalframeblocks;
1087 if (totalframes > 1)
1088 totalsamples += blocksperframe * (totalframes-1);
1089
1090 id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
1091 id3->bitrate = (id3->filesize * 8) / id3->length;
1092 return true;
1093}
1094
1095static bool get_wave_metadata(int fd, struct mp3entry* id3)
1096{
1097 /* Use the trackname part of the id3 structure as a temporary buffer */
1098 unsigned char* buf = (unsigned char *)id3->path;
1099 unsigned long totalsamples = 0;
1100 unsigned long channels = 0;
1101 unsigned long bitspersample = 0;
1102 unsigned long numbytes = 0;
1103 int read_bytes;
1104 int i;
1105
1106 /* get RIFF chunk header */
1107 if ((lseek(fd, 0, SEEK_SET) < 0)
1108 || ((read_bytes = read(fd, buf, 12)) < 12))
1109 {
1110 return false;
1111 }
1112
1113 if ((memcmp(buf, "RIFF",4) != 0)
1114 || (memcmp(&buf[8], "WAVE", 4) !=0 ))
1115 {
1116 return false;
1117 }
1118
1119 /* iterate over WAVE chunks until 'data' chunk */
1120 while (true)
1121 {
1122 /* get chunk header */
1123 if ((read_bytes = read(fd, buf, 8)) < 8)
1124 return false;
1125
1126 /* chunkSize */
1127 i = get_long_le(&buf[4]);
1128
1129 if (memcmp(buf, "fmt ", 4) == 0)
1130 {
1131 /* get rest of chunk */
1132 if ((read_bytes = read(fd, buf, 16)) < 16)
1133 return false;
1134
1135 i -= 16;
1136
1137 /* skipping wFormatTag */
1138 /* wChannels */
1139 channels = buf[2] | (buf[3] << 8);
1140 /* dwSamplesPerSec */
1141 id3->frequency = get_long_le(&buf[4]);
1142 /* dwAvgBytesPerSec */
1143 id3->bitrate = (get_long_le(&buf[8]) * 8) / 1000;
1144 /* skipping wBlockAlign */
1145 /* wBitsPerSample */
1146 bitspersample = buf[14] | (buf[15] << 8);
1147 }
1148 else if (memcmp(buf, "data", 4) == 0)
1149 {
1150 numbytes = i;
1151 break;
1152 }
1153 else if (memcmp(buf, "fact", 4) == 0)
1154 {
1155 /* dwSampleLength */
1156 if (i >= 4)
1157 {
1158 /* get rest of chunk */
1159 if ((read_bytes = read(fd, buf, 4)) < 4)
1160 return false;
1161
1162 i -= 4;
1163 totalsamples = get_long_le(buf);
1164 }
1165 }
1166
1167 /* seek to next chunk (even chunk sizes must be padded) */
1168 if (i & 0x01)
1169 i++;
1170
1171 if(lseek(fd, i, SEEK_CUR) < 0)
1172 return false;
1173 }
1174
1175 if ((numbytes == 0) || (channels == 0))
1176 {
1177 return false;
1178 }
1179
1180 if (totalsamples == 0)
1181 {
1182 /* for PCM only */
1183 totalsamples = numbytes
1184 / ((((bitspersample - 1) / 8) + 1) * channels);
1185 }
1186
1187 id3->vbr = false; /* All WAV files are CBR */
1188 id3->filesize = filesize(fd);
1189
1190 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
1191 id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
1192
1193 return true;
1194}
1195
1196/* Read the tag data from an MP4 file, storing up to buffer_size bytes in
1197 * buffer.
1198 */
1199static unsigned long read_mp4_tag(int fd, unsigned int size_left, char* buffer,
1200 unsigned int buffer_left)
1201{
1202 unsigned int bytes_read = 0;
1203
1204 if (buffer_left == 0)
1205 {
1206 lseek(fd, size_left, SEEK_CUR); /* Skip everything */
1207 }
1208 else
1209 {
1210 /* Skip the data tag header - maybe we should parse it properly? */
1211 lseek(fd, 16, SEEK_CUR);
1212 size_left -= 16;
1213
1214 if (size_left > buffer_left)
1215 {
1216 read(fd, buffer, buffer_left);
1217 lseek(fd, size_left - buffer_left, SEEK_CUR);
1218 bytes_read = buffer_left;
1219 }
1220 else
1221 {
1222 read(fd, buffer, size_left);
1223 bytes_read = size_left;
1224 }
1225 }
1226
1227 return bytes_read;
1228}
1229
1230/* Read a string tag from an MP4 file */
1231static unsigned int read_mp4_tag_string(int fd, int size_left, char** buffer,
1232 unsigned int* buffer_left, char** dest)
1233{
1234 unsigned int bytes_read = read_mp4_tag(fd, size_left, *buffer,
1235 *buffer_left - 1);
1236 unsigned int length = 0;
1237
1238 if (bytes_read)
1239 {
1240 (*buffer)[bytes_read] = 0;
1241 *dest = *buffer;
1242 length = strlen(*buffer) + 1;
1243 *buffer_left -= length;
1244 *buffer += length;
1245 }
1246 else
1247 {
1248 *dest = NULL;
1249 }
1250
1251 return length;
1252}
1253
1254static unsigned int read_mp4_atom(int fd, unsigned int* size,
1255 unsigned int* type, unsigned int size_left)
1256{
1257 read_uint32be(fd, size);
1258 read_uint32be(fd, type);
1259
1260 if (*size == 1)
1261 {
1262 /* FAT32 doesn't support files this big, so something seems to
1263 * be wrong. (64-bit sizes should only be used when required.)
1264 */
1265 errno = EFBIG;
1266 *type = 0;
1267 return 0;
1268 }
1269
1270 if (*size > 0)
1271 {
1272 if (*size > size_left)
1273 {
1274 size_left = 0;
1275 }
1276 else
1277 {
1278 size_left -= *size;
1279 }
1280
1281 *size -= 8;
1282 }
1283 else
1284 {
1285 *size = size_left;
1286 size_left = 0;
1287 }
1288
1289 return size_left;
1290}
1291
1292static unsigned int read_mp4_length(int fd, unsigned int* size)
1293{
1294 unsigned int length = 0;
1295 int bytes = 0;
1296 unsigned char c;
1297
1298 do
1299 {
1300 read(fd, &c, 1);
1301 bytes++;
1302 (*size)--;
1303 length = (length << 7) | (c & 0x7F);
1304 }
1305 while ((c & 0x80) && (bytes < 4) && (*size > 0));
1306
1307 return length;
1308}
1309
1310static bool read_mp4_esds(int fd, struct mp3entry* id3,
1311 unsigned int* size)
1312{
1313 unsigned char buf[8];
1314 bool sbr = false;
1315
1316 lseek(fd, 4, SEEK_CUR); /* Version and flags. */
1317 read(fd, buf, 1); /* Verify ES_DescrTag. */
1318 *size -= 5;
1319
1320 if (*buf == 3)
1321 {
1322 /* read length */
1323 if (read_mp4_length(fd, size) < 20)
1324 {
1325 return sbr;
1326 }
1327
1328 lseek(fd, 3, SEEK_CUR);
1329 *size -= 3;
1330 }
1331 else
1332 {
1333 lseek(fd, 2, SEEK_CUR);
1334 *size -= 2;
1335 }
1336
1337 read(fd, buf, 1); /* Verify DecoderConfigDescrTab. */
1338 *size -= 1;
1339
1340 if (*buf != 4)
1341 {
1342 return sbr;
1343 }
1344
1345 if (read_mp4_length(fd, size) < 13)
1346 {
1347 return sbr;
1348 }
1349
1350 lseek(fd, 13, SEEK_CUR); /* Skip audio type, bit rates, etc. */
1351 read(fd, buf, 1);
1352 *size -= 14;
1353
1354 if (*buf != 5) /* Verify DecSpecificInfoTag. */
1355 {
1356 return sbr;
1357 }
1358
1359 {
1360 static const int sample_rates[] =
1361 {
1362 96000, 88200, 64000, 48000, 44100, 32000,
1363 24000, 22050, 16000, 12000, 11025, 8000
1364 };
1365 unsigned long bits;
1366 unsigned int length;
1367 unsigned int index;
1368 unsigned int type;
1369
1370 /* Read the (leading part of the) decoder config. */
1371 length = read_mp4_length(fd, size);
1372 length = MIN(length, *size);
1373 length = MIN(length, sizeof(buf));
1374 memset(buf, 0, sizeof(buf));
1375 read(fd, buf, length);
1376 *size -= length;
1377
1378 /* Maybe time to write a simple read_bits function... */
1379
1380 /* Decoder config format:
1381 * Object type - 5 bits
1382 * Frequency index - 4 bits
1383 * Channel configuration - 4 bits
1384 */
1385 bits = get_long_be(buf);
1386 type = bits >> 27; /* Object type - 5 bits */
1387 index = (bits >> 23) & 0xf; /* Frequency index - 4 bits */
1388
1389 if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
1390 {
1391 id3->frequency = sample_rates[index];
1392 }
1393
1394 if (type == 5)
1395 {
1396 DEBUGF("MP4: SBR\n");
1397 unsigned int old_index = index;
1398
1399 sbr = true;
1400 index = (bits >> 15) & 0xf; /* Frequency index - 4 bits */
1401
1402 if (index == 15)
1403 {
1404 /* 17 bits read so far... */
1405 bits = get_long_be(&buf[2]);
1406 id3->frequency = (bits >> 7) & 0x00ffffff;
1407 }
1408 else if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
1409 {
1410 id3->frequency = sample_rates[index];
1411 }
1412
1413 if (old_index == index)
1414 {
1415 /* Downsampled SBR */
1416 id3->frequency *= 2;
1417 }
1418 }
1419 /* Skip 13 bits from above, plus 3 bits, then read 11 bits */
1420 else if ((length >= 4) && (((bits >> 5) & 0x7ff) == 0x2b7))
1421 {
1422 /* extensionAudioObjectType */
1423 DEBUGF("MP4: extensionAudioType\n");
1424 type = bits & 0x1f; /* Object type - 5 bits*/
1425 bits = get_long_be(&buf[4]);
1426
1427 if (type == 5)
1428 {
1429 sbr = bits >> 31;
1430
1431 if (sbr)
1432 {
1433 unsigned int old_index = index;
1434
1435 /* 1 bit read so far */
1436 index = (bits >> 27) & 0xf; /* Frequency index - 4 bits */
1437
1438 if (index == 15)
1439 {
1440 /* 5 bits read so far */
1441 id3->frequency = (bits >> 3) & 0x00ffffff;
1442 }
1443 else if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
1444 {
1445 id3->frequency = sample_rates[index];
1446 }
1447
1448 if (old_index == index)
1449 {
1450 /* Downsampled SBR */
1451 id3->frequency *= 2;
1452 }
1453 }
1454 }
1455 }
1456
1457 if (!sbr && (id3->frequency <= 24000) && (length <= 2))
1458 {
1459 /* Double the frequency for low-frequency files without a "long"
1460 * DecSpecificConfig header. The file may or may not contain SBR,
1461 * but here we guess it does if the header is short. This can
1462 * fail on some files, but it's the best we can do, short of
1463 * decoding (parts of) the file.
1464 */
1465 id3->frequency *= 2;
1466 }
1467 }
1468
1469 return sbr;
1470}
1471
1472static bool read_mp4_tags(int fd, struct mp3entry* id3,
1473 unsigned int size_left)
1474{
1475 unsigned int size;
1476 unsigned int type;
1477 unsigned int buffer_left = sizeof(id3->id3v2buf) + sizeof(id3->id3v1buf);
1478 char* buffer = id3->id3v2buf;
1479 bool cwrt = false;
1480
1481 do
1482 {
1483 size_left = read_mp4_atom(fd, &size, &type, size_left);
1484
1485 /* DEBUGF("Tag atom: '%c%c%c%c' (%d bytes left)\n", type >> 24 & 0xff,
1486 type >> 16 & 0xff, type >> 8 & 0xff, type & 0xff, size); */
1487
1488 switch (type)
1489 {
1490 case MP4_cnam:
1491 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
1492 &id3->title);
1493 break;
1494
1495 case MP4_cART:
1496 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
1497 &id3->artist);
1498 break;
1499
1500 case MP4_calb:
1501 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
1502 &id3->album);
1503 break;
1504
1505 case MP4_cwrt:
1506 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
1507 &id3->composer);
1508 cwrt = false;
1509 break;
1510
1511 case MP4_gnre:
1512 {
1513 unsigned short genre;
1514
1515 read_mp4_tag(fd, size, (char*) &genre, sizeof(genre));
1516 id3->genre_string = id3_get_num_genre(betoh16(genre) - 1);
1517 }
1518 break;
1519
1520 case MP4_trkn:
1521 {
1522 unsigned short n[2];
1523
1524 read_mp4_tag(fd, size, (char*) &n, sizeof(n));
1525 id3->tracknum = betoh16(n[1]);
1526 }
1527 break;
1528
1529 case MP4_extra:
1530 {
1531 char tag_name[TAG_NAME_LENGTH];
1532 unsigned int sub_size;
1533
1534 /* "mean" atom */
1535 read_uint32be(fd, &sub_size);
1536 size -= sub_size;
1537 lseek(fd, sub_size - 4, SEEK_CUR);
1538 /* "name" atom */
1539 read_uint32be(fd, &sub_size);
1540 size -= sub_size;
1541 lseek(fd, 8, SEEK_CUR);
1542 sub_size -= 12;
1543
1544 if (sub_size > sizeof(tag_name) - 1)
1545 {
1546 read(fd, tag_name, sizeof(tag_name) - 1);
1547 lseek(fd, sub_size - sizeof(tag_name) - 1, SEEK_CUR);
1548 tag_name[sizeof(tag_name) - 1] = 0;
1549 }
1550 else
1551 {
1552 read(fd, tag_name, sub_size);
1553 tag_name[sub_size] = 0;
1554 }
1555
1556 if ((strcasecmp(tag_name, "composer") == 0) && !cwrt)
1557 {
1558 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
1559 &id3->composer);
1560 }
1561 else if (strcasecmp(tag_name, "iTunSMPB") == 0)
1562 {
1563 char value[TAG_VALUE_LENGTH];
1564 char* value_p = value;
1565 char* any;
1566 unsigned int length = sizeof(value);
1567
1568 read_mp4_tag_string(fd, size, &value_p, &length, &any);
1569 id3->lead_trim = get_itunes_int32(value, 1);
1570 id3->tail_trim = get_itunes_int32(value, 2);
1571 DEBUGF("AAC: lead_trim %d, tail_trim %d\n",
1572 id3->lead_trim, id3->tail_trim);
1573 }
1574 else
1575 {
1576 char* any;
1577 unsigned int length = read_mp4_tag_string(fd, size,
1578 &buffer, &buffer_left, &any);
1579
1580 if (length > 0)
1581 {
1582 /* Re-use the read buffer as the dest buffer... */
1583 buffer -= length;
1584 buffer_left += length;
1585
1586 if (parse_replaygain(tag_name, buffer, id3,
1587 buffer, buffer_left) > 0)
1588 {
1589 /* Data used, keep it. */
1590 buffer += length;
1591 buffer_left -= length;
1592 }
1593 }
1594 }
1595 }
1596 break;
1597
1598 default:
1599 lseek(fd, size, SEEK_CUR);
1600 break;
1601 }
1602 }
1603 while ((size_left > 0) && (errno == 0));
1604
1605 return true;
1606}
1607
1608static bool read_mp4_container(int fd, struct mp3entry* id3,
1609 unsigned int size_left)
1610{
1611 unsigned int size;
1612 unsigned int type;
1613 unsigned int handler = 0;
1614 bool rc = true;
1615
1616 do
1617 {
1618 size_left = read_mp4_atom(fd, &size, &type, size_left);
1619
1620 /* DEBUGF("Atom: '%c%c%c%c' (0x%08x, %d bytes left)\n",
1621 (type >> 24) & 0xff, (type >> 16) & 0xff, (type >> 8) & 0xff,
1622 type & 0xff, type, size); */
1623
1624 switch (type)
1625 {
1626 case MP4_ftyp:
1627 {
1628 unsigned int id;
1629
1630 read_uint32be(fd, &id);
1631 size -= 4;
1632
1633 if ((id != MP4_M4A) && (id != MP4_M4B) && (id != MP4_mp42)
1634 && (id != MP4_qt) && (id != MP4_3gp6))
1635 {
1636 DEBUGF("Unknown MP4 file type: '%c%c%c%c'\n",
1637 id >> 24 & 0xff, id >> 16 & 0xff, id >> 8 & 0xff,
1638 id & 0xff);
1639 return false;
1640 }
1641 }
1642 break;
1643
1644 case MP4_meta:
1645 lseek(fd, 4, SEEK_CUR); /* Skip version */
1646 size -= 4;
1647 /* Fall through */
1648
1649 case MP4_moov:
1650 case MP4_udta:
1651 case MP4_mdia:
1652 case MP4_stbl:
1653 case MP4_trak:
1654 rc = read_mp4_container(fd, id3, size);
1655 size = 0;
1656 break;
1657
1658 case MP4_ilst:
1659 if (handler == MP4_mdir)
1660 {
1661 rc = read_mp4_tags(fd, id3, size);
1662 size = 0;
1663 }
1664 break;
1665
1666 case MP4_minf:
1667 if (handler == MP4_soun)
1668 {
1669 rc = read_mp4_container(fd, id3, size);
1670 size = 0;
1671 }
1672 break;
1673
1674 case MP4_stsd:
1675 lseek(fd, 8, SEEK_CUR);
1676 size -= 8;
1677 rc = read_mp4_container(fd, id3, size);
1678 size = 0;
1679 break;
1680
1681 case MP4_hdlr:
1682 lseek(fd, 8, SEEK_CUR);
1683 read_uint32be(fd, &handler);
1684 size -= 12;
1685 /* DEBUGF(" Handler '%c%c%c%c'\n", handler >> 24 & 0xff,
1686 handler >> 16 & 0xff, handler >> 8 & 0xff,handler & 0xff); */
1687 break;
1688
1689 case MP4_stts:
1690 {
1691 unsigned int entries;
1692 unsigned int i;
1693
1694 lseek(fd, 4, SEEK_CUR);
1695 read_uint32be(fd, &entries);
1696 id3->samples = 0;
1697
1698 for (i = 0; i < entries; i++)
1699 {
1700 unsigned int n;
1701 unsigned int l;
1702
1703 read_uint32be(fd, &n);
1704 read_uint32be(fd, &l);
1705 id3->samples += n * l;
1706 }
1707
1708 size = 0;
1709 }
1710 break;
1711
1712 case MP4_mp4a:
1713 case MP4_alac:
1714 {
1715 unsigned int frequency;
1716
1717 id3->codectype = (type == MP4_mp4a) ? AFMT_AAC : AFMT_ALAC;
1718 lseek(fd, 22, SEEK_CUR);
1719 read_uint32be(fd, &frequency);
1720 size -= 26;
1721 id3->frequency = frequency;
1722
1723 if (type == MP4_mp4a)
1724 {
1725 unsigned int subsize;
1726 unsigned int subtype;
1727
1728 /* Get frequency from the decoder info tag, if possible. */
1729 lseek(fd, 2, SEEK_CUR);
1730 /* The esds atom is a part of the mp4a atom, so ignore
1731 * the returned size (it's already accounted for).
1732 */
1733 read_mp4_atom(fd, &subsize, &subtype, size);
1734 size -= 10;
1735
1736 if (subtype == MP4_esds)
1737 {
1738 read_mp4_esds(fd, id3, &size);
1739 }
1740 }
1741 }
1742 break;
1743
1744 case MP4_mdat:
1745 id3->filesize = size;
1746 break;
1747
1748 default:
1749 break;
1750 }
1751
1752 lseek(fd, size, SEEK_CUR);
1753 }
1754 while (rc && (size_left > 0) && (errno == 0) && (id3->filesize == 0));
1755 /* Break on non-zero filesize, since Rockbox currently doesn't support
1756 * metadata after the mdat atom (which sets the filesize field).
1757 */
1758
1759 return rc;
1760}
1761
1762static bool get_mp4_metadata(int fd, struct mp3entry* id3)
1763{
1764 id3->codectype = AFMT_UNKNOWN;
1765 id3->filesize = 0;
1766 errno = 0;
1767
1768 if (read_mp4_container(fd, id3, filesize(fd)) && (errno == 0)
1769 && (id3->samples > 0) && (id3->frequency > 0)
1770 && (id3->filesize > 0))
1771 {
1772 if (id3->codectype == AFMT_UNKNOWN)
1773 {
1774 logf("Not an ALAC or AAC file");
1775 return false;
1776 }
1777
1778 id3->length = ((int64_t) id3->samples * 1000) / id3->frequency;
1779
1780 if (id3->length <= 0)
1781 {
1782 logf("mp4 length invalid!");
1783 return false;
1784 }
1785
1786 id3->bitrate = ((int64_t) id3->filesize * 8) / id3->length;
1787 DEBUGF("MP4 bitrate %d, frequency %ld Hz, length %ld ms\n",
1788 id3->bitrate, id3->frequency, id3->length);
1789 }
1790 else
1791 {
1792 logf("MP4 metadata error");
1793 DEBUGF("MP4 metadata error. errno %d, length %ld, frequency %ld, filesize %ld\n",
1794 errno, id3->length, id3->frequency, id3->filesize);
1795 return false;
1796 }
1797
1798 return true;
1799}
1800
1801static bool get_musepack_metadata(int fd, struct mp3entry *id3)
1802{
1803 const int32_t sfreqs_sv7[4] = { 44100, 48000, 37800, 32000 };
1804 uint32_t header[8];
1805 uint64_t samples = 0;
1806 int i;
1807
1808 if (!skip_id3v2(fd, id3))
1809 return false;
1810 if (read(fd, header, 4*8) != 4*8) return false;
1811 /* Musepack files are little endian, might need swapping */
1812 for (i = 1; i < 8; i++)
1813 header[i] = letoh32(header[i]);
1814 if (!memcmp(header, "MP+", 3)) { /* Compare to sig "MP+" */
1815 unsigned int streamversion;
1816
1817 header[0] = letoh32(header[0]);
1818 streamversion = (header[0] >> 24) & 15;
1819 if (streamversion >= 8) {
1820 return false; /* SV8 or higher don't exist yet, so no support */
1821 } else if (streamversion == 7) {
1822 unsigned int gapless = (header[5] >> 31) & 0x0001;
1823 unsigned int last_frame_samples = (header[5] >> 20) & 0x07ff;
1824 int track_gain, album_gain;
1825 unsigned int bufused;
1826
1827 id3->frequency = sfreqs_sv7[(header[2] >> 16) & 0x0003];
1828 samples = (uint64_t)header[1]*1152; /* 1152 is mpc frame size */
1829 if (gapless)
1830 samples -= 1152 - last_frame_samples;
1831 else
1832 samples -= 481; /* Musepack subband synth filter delay */
1833
1834 /* Extract ReplayGain data from header */
1835 track_gain = (int16_t)((header[3] >> 16) & 0xffff);
1836 id3->track_gain = get_replaygain_int(track_gain);
1837 id3->track_peak = ((uint16_t)(header[3] & 0xffff)) << 9;
1838
1839 album_gain = (int16_t)((header[4] >> 16) & 0xffff);
1840 id3->album_gain = get_replaygain_int(album_gain);
1841 id3->album_peak = ((uint16_t)(header[4] & 0xffff)) << 9;
1842
1843 /* Write replaygain values to strings for use in id3 screen. We use
1844 the XING header as buffer space since Musepack files shouldn't
1845 need to use it in any other way */
1846 id3->track_gain_string = (char *)id3->toc;
1847 bufused = snprintf(id3->track_gain_string, 45,
1848 "%d.%d dB", track_gain/100, abs(track_gain)%100);
1849 id3->album_gain_string = (char *)id3->toc + bufused + 1;
1850 bufused = snprintf(id3->album_gain_string, 45,
1851 "%d.%d dB", album_gain/100, abs(album_gain)%100);
1852 }
1853 } else {
1854 header[0] = letoh32(header[0]);
1855 unsigned int streamversion = (header[0] >> 11) & 0x03FF;
1856 if (streamversion != 4 && streamversion != 5 && streamversion != 6)
1857 return false;
1858 id3->frequency = 44100;
1859 id3->track_gain = 0;
1860 id3->track_peak = 0;
1861 id3->album_gain = 0;
1862 id3->album_peak = 0;
1863
1864 if (streamversion >= 5)
1865 samples = (uint64_t)header[1]*1152; // 32 bit
1866 else
1867 samples = (uint64_t)(header[1] >> 16)*1152; // 16 bit
1868
1869 samples -= 576;
1870 if (streamversion < 6)
1871 samples -= 1152;
1872 }
1873
1874 id3->vbr = true;
1875 /* Estimate bitrate, we should probably subtract the various header sizes
1876 here for super-accurate results */
1877 id3->length = ((int64_t) samples * 1000) / id3->frequency;
1878
1879 if (id3->length <= 0)
1880 {
1881 logf("mpc length invalid!");
1882 return false;
1883 }
1884
1885 id3->filesize = filesize(fd);
1886 id3->bitrate = id3->filesize * 8 / id3->length;
1887 return true;
1888}
1889
1890/* PSID metadata info is available here:
1891 http://www.unusedino.de/ec64/technical/formats/sidplay.html */
1892static bool get_sid_metadata(int fd, struct mp3entry* id3)
1893{
1894 /* Use the trackname part of the id3 structure as a temporary buffer */
1895 unsigned char* buf = (unsigned char *)id3->path;
1896 int read_bytes;
1897 char *p;
1898
1899
1900 if ((lseek(fd, 0, SEEK_SET) < 0)
1901 || ((read_bytes = read(fd, buf, 0x80)) < 0x80))
1902 {
1903 return false;
1904 }
1905
1906 if ((memcmp(buf, "PSID",4) != 0))
1907 {
1908 return false;
1909 }
1910
1911 p = id3->id3v2buf;
1912
1913 /* Copy Title (assumed max 0x1f letters + 1 zero byte) */
1914 id3->title = p;
1915 buf[0x16+0x1f] = 0;
1916 p = iso_decode(&buf[0x16], p, 0, strlen(&buf[0x16])+1);
1917
1918 /* Copy Artist (assumed max 0x1f letters + 1 zero byte) */
1919 id3->artist = p;
1920 buf[0x36+0x1f] = 0;
1921 p = iso_decode(&buf[0x36], p, 0, strlen(&buf[0x36])+1);
1922
1923 /* Copy Year (assumed max 4 letters + 1 zero byte) */
1924 buf[0x56+0x4] = 0;
1925 id3->year = atoi(&buf[0x56]);
1926
1927 /* Copy Album (assumed max 0x1f-0x05 letters + 1 zero byte) */
1928 id3->album = p;
1929 buf[0x56+0x1f] = 0;
1930 p = iso_decode(&buf[0x5b], p, 0, strlen(&buf[0x5b])+1);
1931
1932 id3->bitrate = 706;
1933 id3->frequency = 44100;
1934 /* New idea as posted by Marco Alanen (ravon):
1935 * Set the songlength in seconds to the number of subsongs
1936 * so every second represents a subsong.
1937 * Users can then skip the current subsong by seeking
1938 *
1939 * Note: the number of songs is a 16bit value at 0xE, so this code only
1940 * uses the lower 8 bits of the counter.
1941 */
1942 id3->length = (buf[0xf]-1)*1000;
1943 id3->vbr = false;
1944 id3->filesize = filesize(fd);
1945
1946 return true;
1947}
1948
1949static bool get_adx_metadata(int fd, struct mp3entry* id3)
1950{
1951 /* Use the trackname part of the id3 structure as a temporary buffer */
1952 unsigned char * buf = (unsigned char *)id3->path;
1953 int chanstart, channels, read_bytes;
1954 int looping = 0, start_adr = 0, end_adr = 0;
1955
1956 /* try to get the basic header */
1957 if ((lseek(fd, 0, SEEK_SET) < 0)
1958 || ((read_bytes = read(fd, buf, 0x38)) < 0x38))
1959 {
1960 DEBUGF("lseek or read failed\n");
1961 return false;
1962 }
1963
1964 /* ADX starts with 0x80 */
1965 if (buf[0] != 0x80) {
1966 DEBUGF("get_adx_metadata: wrong first byte %c\n",buf[0]);
1967 return false;
1968 }
1969
1970 /* check for a reasonable offset */
1971 chanstart = ((buf[2] << 8) | buf[3]) + 4;
1972 if (chanstart > 4096) {
1973 DEBUGF("get_adx_metadata: bad chanstart %i\n", chanstart);
1974 return false;
1975 }
1976
1977 /* check for a workable number of channels */
1978 channels = buf[7];
1979 if (channels != 1 && channels != 2) {
1980 DEBUGF("get_adx_metadata: bad channel count %i\n",channels);
1981 return false;
1982 }
1983
1984 id3->frequency = get_long_be(&buf[8]);
1985 /* 32 samples per 18 bytes */
1986 id3->bitrate = id3->frequency * channels * 18 * 8 / 32 / 1000;
1987 id3->length = get_long_be(&buf[12]) / id3->frequency * 1000;
1988 id3->vbr = false;
1989 id3->filesize = filesize(fd);
1990
1991 /* get loop info */
1992 if (!memcmp(buf+0x10,"\x01\xF4\x03\x00",4)) {
1993 /* Soul Calibur 2 style (type 03) */
1994 DEBUGF("get_adx_metadata: type 03 found\n");
1995 /* check if header is too small for loop data */
1996 if (chanstart-6 < 0x2c) looping=0;
1997 else {
1998 looping = get_long_be(&buf[0x18]);
1999 end_adr = get_long_be(&buf[0x28]);
2000 start_adr = get_long_be(&buf[0x1c])/32*channels*18+chanstart;
2001 }
2002 } else if (!memcmp(buf+0x10,"\x01\xF4\x04\x00",4)) {
2003 /* Standard (type 04) */
2004 DEBUGF("get_adx_metadata: type 04 found\n");
2005 /* check if header is too small for loop data */
2006 if (chanstart-6 < 0x38) looping=0;
2007 else {
2008 looping = get_long_be(&buf[0x24]);
2009 end_adr = get_long_be(&buf[0x34]);
2010 start_adr = get_long_be(&buf[0x28])/32*channels*18+chanstart;
2011 }
2012 } else {
2013 DEBUGF("get_adx_metadata: error, couldn't determine ADX type\n");
2014 return false;
2015 }
2016
2017 if (looping) {
2018 /* 2 loops, 10 second fade */
2019 id3->length = (start_adr-chanstart + 2*(end_adr-start_adr))
2020 *8 / id3->bitrate + 10000;
2021 }
2022
2023 /* try to get the channel header */
2024 if ((lseek(fd, chanstart-6, SEEK_SET) < 0)
2025 || ((read_bytes = read(fd, buf, 6)) < 6))
2026 {
2027 return false;
2028 }
2029
2030 /* check channel header */
2031 if (memcmp(buf, "(c)CRI", 6) != 0) return false;
2032
2033 return true;
2034}
2035
2036static bool get_spc_metadata(int fd, struct mp3entry* id3)
2037{
2038 /* Use the trackname part of the id3 structure as a temporary buffer */
2039 unsigned char * buf = (unsigned char *)id3->path;
2040 int read_bytes;
2041 char * p;
2042
2043 unsigned long length;
2044 unsigned long fade;
2045 bool isbinary = true;
2046 int i;
2047
2048 /* try to get the ID666 tag */
2049 if ((lseek(fd, 0x2e, SEEK_SET) < 0)
2050 || ((read_bytes = read(fd, buf, 0xD2)) < 0xD2))
2051 {
2052 DEBUGF("lseek or read failed\n");
2053 return false;
2054 }
2055
2056 p = id3->id3v2buf;
2057
2058 id3->title = p;
2059 buf[31] = 0;
2060 p = iso_decode(buf, p, 0, 32);
2061 buf += 32;
2062
2063 id3->album = p;
2064 buf[31] = 0;
2065 p = iso_decode(buf, p, 0, 32);
2066 buf += 48;
2067
2068 id3->comment = p;
2069 buf[31] = 0;
2070 p = iso_decode(buf, p, 0, 32);
2071 buf += 32;
2072
2073 /* Date check */
2074 if(buf[2] == '/' && buf[5] == '/')
2075 isbinary = false;
2076
2077 /* Reserved bytes check */
2078 if(buf[0xD2 - 0x2E - 112] >= '0' &&
2079 buf[0xD2 - 0x2E - 112] <= '9' &&
2080 buf[0xD3 - 0x2E - 112] == 0x00)
2081 isbinary = false;
2082
2083 /* is length & fade only digits? */
2084 for (i=0;i<8 && (
2085 (buf[0xA9 - 0x2E - 112+i]>='0'&&buf[0xA9 - 0x2E - 112+i]<='9') ||
2086 buf[0xA9 - 0x2E - 112+i]=='\0');
2087 i++);
2088 if (i==8) isbinary = false;
2089
2090 if(isbinary) {
2091 id3->year = buf[0] | (buf[1]<<8);
2092 buf += 11;
2093
2094 length = (buf[0] | (buf[1]<<8) | (buf[2]<<16)) * 1000;
2095 buf += 3;
2096
2097 fade = (buf[0] | (buf[1]<<8) | (buf[2]<<16) | (buf[3]<<24));
2098 buf += 4;
2099 } else {
2100 char tbuf[6];
2101
2102 buf += 6;
2103 buf[4] = 0;
2104 id3->year = atoi(buf);
2105 buf += 5;
2106
2107 memcpy(tbuf, buf, 3);
2108 tbuf[3] = 0;
2109 length = atoi(tbuf) * 1000;
2110 buf += 3;
2111
2112 memcpy(tbuf, buf, 5);
2113 tbuf[5] = 0;
2114 fade = atoi(tbuf);
2115 buf += 5;
2116 }
2117
2118 id3->artist = p;
2119 buf[31] = 0;
2120 p = iso_decode(buf, p, 0, 32);
2121
2122 if (length==0) {
2123 length=3*60*1000; /* 3 minutes */
2124 fade=5*1000; /* 5 seconds */
2125 }
2126
2127 id3->length = length+fade;
2128
2129 return true;
2130}
2131
2132static bool get_aiff_metadata(int fd, struct mp3entry* id3)
2133{
2134 /* Use the trackname part of the id3 structure as a temporary buffer */
2135 unsigned char* buf = (unsigned char *)id3->path;
2136 unsigned long numChannels = 0;
2137 unsigned long numSampleFrames = 0;
2138 unsigned long sampleSize = 0;
2139 unsigned long sampleRate = 0;
2140 unsigned long numbytes = 0;
2141 int read_bytes;
2142 int i;
2143
2144 if ((lseek(fd, 0, SEEK_SET) < 0)
2145 || ((read_bytes = read(fd, buf, sizeof(id3->path))) < 54))
2146 {
2147 return false;
2148 }
2149
2150 if ((memcmp(buf, "FORM",4) != 0)
2151 || (memcmp(&buf[8], "AIFF", 4) !=0 ))
2152 {
2153 return false;
2154 }
2155
2156 buf += 12;
2157 read_bytes -= 12;
2158
2159 while ((numbytes == 0) && (read_bytes >= 8))
2160 {
2161 /* chunkSize */
2162 i = get_long_be(&buf[4]);
2163
2164 if (memcmp(buf, "COMM", 4) == 0)
2165 {
2166 /* numChannels */
2167 numChannels = ((buf[8]<<8)|buf[9]);
2168 /* numSampleFrames */
2169 numSampleFrames = get_long_be(&buf[10]);
2170 /* sampleSize */
2171 sampleSize = ((buf[14]<<8)|buf[15]);
2172 /* sampleRate */
2173 sampleRate = get_long_be(&buf[18]);
2174 sampleRate = sampleRate >> (16+14-buf[17]);
2175 /* save format infos */
2176 id3->bitrate = (sampleSize * numChannels * sampleRate) / 1000;
2177 id3->frequency = sampleRate;
2178 id3->length = ((int64_t) numSampleFrames * 1000) / id3->frequency;
2179
2180 id3->vbr = false; /* AIFF files are CBR */
2181 id3->filesize = filesize(fd);
2182 }
2183 else if (memcmp(buf, "SSND", 4) == 0)
2184 {
2185 numbytes = i - 8;
2186 }
2187
2188 if (i & 0x01)
2189 {
2190 i++; /* odd chunk sizes must be padded */
2191 }
2192 buf += i + 8;
2193 read_bytes -= i + 8;
2194 }
2195
2196 if ((numbytes == 0) || (numChannels == 0))
2197 {
2198 return false;
2199 }
2200 return true;
2201}
2202#endif /* CONFIG_CODEC == SWCODEC */ 60#endif /* CONFIG_CODEC == SWCODEC */
2203 61
2204 62
diff --git a/apps/metadata/adx.c b/apps/metadata/adx.c
new file mode 100644
index 0000000000..44b07a14b8
--- /dev/null
+++ b/apps/metadata/adx.c
@@ -0,0 +1,115 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "id3.h"
27#include "metadata_common.h"
28#include "debug.h"
29
30bool get_adx_metadata(int fd, struct mp3entry* id3)
31{
32 /* Use the trackname part of the id3 structure as a temporary buffer */
33 unsigned char * buf = (unsigned char *)id3->path;
34 int chanstart, channels, read_bytes;
35 int looping = 0, start_adr = 0, end_adr = 0;
36
37 /* try to get the basic header */
38 if ((lseek(fd, 0, SEEK_SET) < 0)
39 || ((read_bytes = read(fd, buf, 0x38)) < 0x38))
40 {
41 DEBUGF("lseek or read failed\n");
42 return false;
43 }
44
45 /* ADX starts with 0x80 */
46 if (buf[0] != 0x80) {
47 DEBUGF("get_adx_metadata: wrong first byte %c\n",buf[0]);
48 return false;
49 }
50
51 /* check for a reasonable offset */
52 chanstart = ((buf[2] << 8) | buf[3]) + 4;
53 if (chanstart > 4096) {
54 DEBUGF("get_adx_metadata: bad chanstart %i\n", chanstart);
55 return false;
56 }
57
58 /* check for a workable number of channels */
59 channels = buf[7];
60 if (channels != 1 && channels != 2) {
61 DEBUGF("get_adx_metadata: bad channel count %i\n",channels);
62 return false;
63 }
64
65 id3->frequency = get_long_be(&buf[8]);
66 /* 32 samples per 18 bytes */
67 id3->bitrate = id3->frequency * channels * 18 * 8 / 32 / 1000;
68 id3->length = get_long_be(&buf[12]) / id3->frequency * 1000;
69 id3->vbr = false;
70 id3->filesize = filesize(fd);
71
72 /* get loop info */
73 if (!memcmp(buf+0x10,"\x01\xF4\x03\x00",4)) {
74 /* Soul Calibur 2 style (type 03) */
75 DEBUGF("get_adx_metadata: type 03 found\n");
76 /* check if header is too small for loop data */
77 if (chanstart-6 < 0x2c) looping=0;
78 else {
79 looping = get_long_be(&buf[0x18]);
80 end_adr = get_long_be(&buf[0x28]);
81 start_adr = get_long_be(&buf[0x1c])/32*channels*18+chanstart;
82 }
83 } else if (!memcmp(buf+0x10,"\x01\xF4\x04\x00",4)) {
84 /* Standard (type 04) */
85 DEBUGF("get_adx_metadata: type 04 found\n");
86 /* check if header is too small for loop data */
87 if (chanstart-6 < 0x38) looping=0;
88 else {
89 looping = get_long_be(&buf[0x24]);
90 end_adr = get_long_be(&buf[0x34]);
91 start_adr = get_long_be(&buf[0x28])/32*channels*18+chanstart;
92 }
93 } else {
94 DEBUGF("get_adx_metadata: error, couldn't determine ADX type\n");
95 return false;
96 }
97
98 if (looping) {
99 /* 2 loops, 10 second fade */
100 id3->length = (start_adr-chanstart + 2*(end_adr-start_adr))
101 *8 / id3->bitrate + 10000;
102 }
103
104 /* try to get the channel header */
105 if ((lseek(fd, chanstart-6, SEEK_SET) < 0)
106 || ((read_bytes = read(fd, buf, 6)) < 6))
107 {
108 return false;
109 }
110
111 /* check channel header */
112 if (memcmp(buf, "(c)CRI", 6) != 0) return false;
113
114 return true;
115}
diff --git a/apps/metadata/aiff.c b/apps/metadata/aiff.c
new file mode 100644
index 0000000000..3b155caa2b
--- /dev/null
+++ b/apps/metadata/aiff.c
@@ -0,0 +1,98 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "id3.h"
27#include "metadata_common.h"
28
29bool get_aiff_metadata(int fd, struct mp3entry* id3)
30{
31 /* Use the trackname part of the id3 structure as a temporary buffer */
32 unsigned char* buf = (unsigned char *)id3->path;
33 unsigned long numChannels = 0;
34 unsigned long numSampleFrames = 0;
35 unsigned long sampleSize = 0;
36 unsigned long sampleRate = 0;
37 unsigned long numbytes = 0;
38 int read_bytes;
39 int i;
40
41 if ((lseek(fd, 0, SEEK_SET) < 0)
42 || ((read_bytes = read(fd, buf, sizeof(id3->path))) < 54))
43 {
44 return false;
45 }
46
47 if ((memcmp(buf, "FORM",4) != 0)
48 || (memcmp(&buf[8], "AIFF", 4) !=0 ))
49 {
50 return false;
51 }
52
53 buf += 12;
54 read_bytes -= 12;
55
56 while ((numbytes == 0) && (read_bytes >= 8))
57 {
58 /* chunkSize */
59 i = get_long_be(&buf[4]);
60
61 if (memcmp(buf, "COMM", 4) == 0)
62 {
63 /* numChannels */
64 numChannels = ((buf[8]<<8)|buf[9]);
65 /* numSampleFrames */
66 numSampleFrames = get_long_be(&buf[10]);
67 /* sampleSize */
68 sampleSize = ((buf[14]<<8)|buf[15]);
69 /* sampleRate */
70 sampleRate = get_long_be(&buf[18]);
71 sampleRate = sampleRate >> (16+14-buf[17]);
72 /* save format infos */
73 id3->bitrate = (sampleSize * numChannels * sampleRate) / 1000;
74 id3->frequency = sampleRate;
75 id3->length = ((int64_t) numSampleFrames * 1000) / id3->frequency;
76
77 id3->vbr = false; /* AIFF files are CBR */
78 id3->filesize = filesize(fd);
79 }
80 else if (memcmp(buf, "SSND", 4) == 0)
81 {
82 numbytes = i - 8;
83 }
84
85 if (i & 0x01)
86 {
87 i++; /* odd chunk sizes must be padded */
88 }
89 buf += i + 8;
90 read_bytes -= i + 8;
91 }
92
93 if ((numbytes == 0) || (numChannels == 0))
94 {
95 return false;
96 }
97 return true;
98}
diff --git a/apps/metadata/ape.c b/apps/metadata/ape.c
new file mode 100644
index 0000000000..ac071be6f7
--- /dev/null
+++ b/apps/metadata/ape.c
@@ -0,0 +1,132 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "id3.h"
27#include "metadata_common.h"
28#include "structec.h"
29
30#define APETAG_HEADER_LENGTH 32
31#define APETAG_HEADER_FORMAT "8llll8"
32#define APETAG_ITEM_HEADER_FORMAT "ll"
33#define APETAG_ITEM_TYPE_MASK 3
34
35struct apetag_header
36{
37 char id[8];
38 long version;
39 long length;
40 long item_count;
41 long flags;
42 char reserved[8];
43};
44
45struct apetag_item_header
46{
47 long length;
48 long flags;
49};
50
51/* Read the items in an APEV2 tag. Only looks for a tag at the end of a
52 * file. Returns true if a tag was found and fully read, false otherwise.
53 */
54bool read_ape_tags(int fd, struct mp3entry* id3)
55{
56 struct apetag_header header;
57
58 if ((lseek(fd, -APETAG_HEADER_LENGTH, SEEK_END) < 0)
59 || (ecread(fd, &header, 1, APETAG_HEADER_FORMAT, IS_BIG_ENDIAN) != APETAG_HEADER_LENGTH)
60 || (memcmp(header.id, "APETAGEX", sizeof(header.id))))
61 {
62 return false;
63 }
64
65 if ((header.version == 2000) && (header.item_count > 0)
66 && (header.length > APETAG_HEADER_LENGTH))
67 {
68 char *buf = id3->id3v2buf;
69 unsigned int buf_remaining = sizeof(id3->id3v2buf)
70 + sizeof(id3->id3v1buf);
71 unsigned int tag_remaining = header.length - APETAG_HEADER_LENGTH;
72 int i;
73
74 if (lseek(fd, -header.length, SEEK_END) < 0)
75 {
76 return false;
77 }
78
79 for (i = 0; i < header.item_count; i++)
80 {
81 struct apetag_item_header item;
82 char name[TAG_NAME_LENGTH];
83 char value[TAG_VALUE_LENGTH];
84 long r;
85
86 if (tag_remaining < sizeof(item))
87 {
88 break;
89 }
90
91 if (ecread(fd, &item, 1, APETAG_ITEM_HEADER_FORMAT, IS_BIG_ENDIAN) < (long) sizeof(item))
92 {
93 return false;
94 }
95
96 tag_remaining -= sizeof(item);
97 r = read_string(fd, name, sizeof(name), 0, tag_remaining);
98
99 if (r == -1)
100 {
101 return false;
102 }
103
104 tag_remaining -= r + item.length;
105
106 if ((item.flags & APETAG_ITEM_TYPE_MASK) == 0)
107 {
108 long len;
109
110 if (read_string(fd, value, sizeof(value), -1, item.length)
111 != item.length)
112 {
113 return false;
114 }
115
116 len = parse_tag(name, value, id3, buf, buf_remaining,
117 TAGTYPE_APE);
118 buf += len;
119 buf_remaining -= len;
120 }
121 else
122 {
123 if (lseek(fd, item.length, SEEK_CUR) < 0)
124 {
125 return false;
126 }
127 }
128 }
129 }
130
131 return true;
132}
diff --git a/apps/metadata/flac.c b/apps/metadata/flac.c
new file mode 100644
index 0000000000..5b3644ede2
--- /dev/null
+++ b/apps/metadata/flac.c
@@ -0,0 +1,122 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "id3.h"
27#include "metadata_common.h"
28#include "logf.h"
29
30bool get_flac_metadata(int fd, struct mp3entry* id3)
31{
32 /* A simple parser to read vital metadata from a FLAC file - length,
33 * frequency, bitrate etc. This code should either be moved to a
34 * seperate file, or discarded in favour of the libFLAC code.
35 * The FLAC stream specification can be found at
36 * http://flac.sourceforge.net/format.html#stream
37 */
38
39 /* Use the trackname part of the id3 structure as a temporary buffer */
40 unsigned char* buf = (unsigned char *)id3->path;
41 bool rc = false;
42
43 if (!skip_id3v2(fd, id3) || (read(fd, buf, 4) < 4))
44 {
45 return rc;
46 }
47
48 if (memcmp(buf, "fLaC", 4) != 0)
49 {
50 return rc;
51 }
52
53 while (true)
54 {
55 long i;
56
57 if (read(fd, buf, 4) < 0)
58 {
59 return rc;
60 }
61
62 /* The length of the block */
63 i = (buf[1] << 16) | (buf[2] << 8) | buf[3];
64
65 if ((buf[0] & 0x7f) == 0) /* 0 is the STREAMINFO block */
66 {
67 unsigned long totalsamples;
68
69 /* FIXME: Don't trust the value of i */
70 if (read(fd, buf, i) < 0)
71 {
72 return rc;
73 }
74
75 id3->vbr = true; /* All FLAC files are VBR */
76 id3->filesize = filesize(fd);
77 id3->frequency = (buf[10] << 12) | (buf[11] << 4)
78 | ((buf[12] & 0xf0) >> 4);
79 rc = true; /* Got vital metadata */
80
81 /* totalsamples is a 36-bit field, but we assume <= 32 bits are used */
82 totalsamples = get_long_be(&buf[14]);
83
84 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
85 id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
86
87 if (id3->length <= 0)
88 {
89 logf("flac length invalid!");
90 return false;
91 }
92
93 id3->bitrate = (id3->filesize * 8) / id3->length;
94 }
95 else if ((buf[0] & 0x7f) == 4) /* 4 is the VORBIS_COMMENT block */
96 {
97 /* The next i bytes of the file contain the VORBIS COMMENTS. */
98 if (!read_vorbis_tags(fd, id3, i))
99 {
100 return rc;
101 }
102 }
103 else
104 {
105 if (buf[0] & 0x80)
106 {
107 /* If we have reached the last metadata block, abort. */
108 break;
109 }
110 else
111 {
112 /* Skip to next metadata block */
113 if (lseek(fd, i, SEEK_CUR) < 0)
114 {
115 return rc;
116 }
117 }
118 }
119 }
120
121 return true;
122}
diff --git a/apps/metadata/metadata_common.c b/apps/metadata/metadata_common.c
new file mode 100644
index 0000000000..00b03841f9
--- /dev/null
+++ b/apps/metadata/metadata_common.c
@@ -0,0 +1,273 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "id3.h"
27#include "metadata_common.h"
28#include "replaygain.h"
29#include "atoi.h"
30
31/* Skip an ID3v2 tag if it can be found. We assume the tag is located at the
32 * start of the file, which should be true in all cases where we need to skip it.
33 * Returns true if successfully skipped or not skipped, and false if
34 * something went wrong while skipping.
35 */
36bool skip_id3v2(int fd, struct mp3entry *id3)
37{
38 char buf[4];
39
40 read(fd, buf, 4);
41 if (memcmp(buf, "ID3", 3) == 0)
42 {
43 /* We have found an ID3v2 tag at the start of the file - find its
44 length and then skip it. */
45 if ((id3->first_frame_offset = getid3v2len(fd)) == 0)
46 return false;
47
48 if ((lseek(fd, id3->first_frame_offset, SEEK_SET) < 0))
49 return false;
50
51 return true;
52 } else {
53 lseek(fd, 0, SEEK_SET);
54 id3->first_frame_offset = 0;
55 return true;
56 }
57}
58
59
60/* Read a string from the file. Read up to size bytes, or, if eos != -1,
61 * until the eos character is found (eos is not stored in buf, unless it is
62 * nil). Writes up to buf_size chars to buf, always terminating with a nil.
63 * Returns number of chars read or -1 on read error.
64 */
65long read_string(int fd, char* buf, long buf_size, int eos, long size)
66{
67 long read_bytes = 0;
68 char c;
69
70 while (size != 0)
71 {
72 if (read(fd, &c, 1) != 1)
73 {
74 read_bytes = -1;
75 break;
76 }
77
78 read_bytes++;
79 size--;
80
81 if ((eos != -1) && (eos == (unsigned char) c))
82 {
83 break;
84 }
85
86 if (buf_size > 1)
87 {
88 *buf++ = c;
89 buf_size--;
90 }
91 }
92
93 *buf = 0;
94 return read_bytes;
95}
96
97/* Read an unsigned 32-bit integer from a big-endian file. */
98#ifdef ROCKBOX_BIG_ENDIAN
99#define read_uint32be(fd,buf) read((fd), (buf), 4)
100#else
101int read_uint32be(int fd, unsigned int* buf)
102{
103 size_t n;
104
105 n = read(fd, (char*) buf, 4);
106 *buf = betoh32(*buf);
107 return n;
108}
109#endif
110
111/* Read an unaligned 32-bit little endian long from buffer. */
112unsigned long get_long_le(void* buf)
113{
114 unsigned char* p = (unsigned char*) buf;
115
116 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
117}
118
119/* Read an unaligned 16-bit little endian short from buffer. */
120unsigned short get_short_le(void* buf)
121{
122 unsigned char* p = (unsigned char*) buf;
123
124 return p[0] | (p[1] << 8);
125}
126
127/* Read an unaligned 32-bit big endian long from buffer. */
128unsigned long get_long_be(void* buf)
129{
130 unsigned char* p = (unsigned char*) buf;
131
132 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
133}
134
135/* Read an unaligned 32-bit little endian long from buffer. */
136long get_slong(void* buf)
137{
138 unsigned char* p = (unsigned char*) buf;
139
140 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
141}
142
143static char* skip_space(char* str)
144{
145 while (isspace(*str))
146 {
147 str++;
148 }
149
150 return str;
151}
152
153unsigned long get_itunes_int32(char* value, int count)
154{
155 static const char hexdigits[] = "0123456789ABCDEF";
156 const char* c;
157 int r = 0;
158
159 while (count-- > 0)
160 {
161 value = skip_space(value);
162
163 while (*value && !isspace(*value))
164 {
165 value++;
166 }
167 }
168
169 value = skip_space(value);
170
171 while (*value && ((c = strchr(hexdigits, toupper(*value))) != NULL))
172 {
173 r = (r << 4) | (c - hexdigits);
174 value++;
175 }
176
177 return r;
178}
179
180/* Parse the tag (the name-value pair) and fill id3 and buffer accordingly.
181 * String values to keep are written to buf. Returns number of bytes written
182 * to buf (including end nil).
183 */
184long parse_tag(const char* name, char* value, struct mp3entry* id3,
185 char* buf, long buf_remaining, enum tagtype type)
186{
187 long len = 0;
188 char** p;
189
190 if ((((strcasecmp(name, "track") == 0) && (type == TAGTYPE_APE)))
191 || ((strcasecmp(name, "tracknumber") == 0) && (type == TAGTYPE_VORBIS)))
192 {
193 id3->tracknum = atoi(value);
194 p = &(id3->track_string);
195 }
196 else if (((strcasecmp(name, "year") == 0) && (type == TAGTYPE_APE))
197 || ((strcasecmp(name, "date") == 0) && (type == TAGTYPE_VORBIS)))
198 {
199 /* Date's can be in any format in Vorbis. However most of them
200 * are in ISO8601 format so if we try and parse the first part
201 * of the tag as a number, we should get the year. If we get crap,
202 * then act like we never parsed it.
203 */
204 id3->year = atoi(value);
205 if (id3->year < 1900)
206 { /* yeah, not likely */
207 id3->year = 0;
208 }
209 p = &(id3->year_string);
210 }
211 else if (strcasecmp(name, "title") == 0)
212 {
213 p = &(id3->title);
214 }
215 else if (strcasecmp(name, "artist") == 0)
216 {
217 p = &(id3->artist);
218 }
219 else if (strcasecmp(name, "album") == 0)
220 {
221 p = &(id3->album);
222 }
223 else if (strcasecmp(name, "genre") == 0)
224 {
225 p = &(id3->genre_string);
226 }
227 else if (strcasecmp(name, "composer") == 0)
228 {
229 p = &(id3->composer);
230 }
231 else if (strcasecmp(name, "comment") == 0)
232 {
233 p = &(id3->comment);
234 }
235 else if (strcasecmp(name, "albumartist") == 0)
236 {
237 p = &(id3->albumartist);
238 }
239 else if (strcasecmp(name, "album artist") == 0)
240 {
241 p = &(id3->albumartist);
242 }
243 else if (strcasecmp(name, "ensemble") == 0)
244 {
245 p = &(id3->albumartist);
246 }
247 else
248 {
249 len = parse_replaygain(name, value, id3, buf, buf_remaining);
250 p = NULL;
251 }
252
253 if (p)
254 {
255 len = strlen(value);
256 len = MIN(len, buf_remaining - 1);
257
258 if (len > 0)
259 {
260 strncpy(buf, value, len);
261 buf[len] = 0;
262 *p = buf;
263 len++;
264 }
265 else
266 {
267 len = 0;
268 }
269 }
270
271 return len;
272}
273
diff --git a/apps/metadata/metadata_common.h b/apps/metadata/metadata_common.h
new file mode 100644
index 0000000000..70e708010d
--- /dev/null
+++ b/apps/metadata/metadata_common.h
@@ -0,0 +1,45 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "id3.h"
20
21#ifdef ROCKBOX_BIG_ENDIAN
22#define IS_BIG_ENDIAN 1
23#else
24#define IS_BIG_ENDIAN 0
25#endif
26
27#define TAG_NAME_LENGTH 32
28#define TAG_VALUE_LENGTH 128
29
30enum tagtype { TAGTYPE_APE = 1, TAGTYPE_VORBIS };
31
32bool read_ape_tags(int fd, struct mp3entry* id3);
33bool read_vorbis_tags(int fd, struct mp3entry *id3,
34 long tag_remaining);
35
36bool skip_id3v2(int fd, struct mp3entry *id3);
37long read_string(int fd, char* buf, long buf_size, int eos, long size);
38int read_uint32be(int fd, unsigned int* buf);
39unsigned long get_long_le(void* buf);
40unsigned short get_short_le(void* buf);
41unsigned long get_long_be(void* buf);
42long get_slong(void* buf);
43unsigned long get_itunes_int32(char* value, int count);
44long parse_tag(const char* name, char* value, struct mp3entry* id3,
45 char* buf, long buf_remaining, enum tagtype type);
diff --git a/apps/metadata/metadata_parsers.h b/apps/metadata/metadata_parsers.h
new file mode 100644
index 0000000000..f52ce69dd2
--- /dev/null
+++ b/apps/metadata/metadata_parsers.h
@@ -0,0 +1,31 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "id3.h"
20
21bool get_adx_metadata(int fd, struct mp3entry* id3);
22bool get_aiff_metadata(int fd, struct mp3entry* id3);
23bool get_flac_metadata(int fd, struct mp3entry* id3);
24bool get_mp4_metadata(int fd, struct mp3entry* id3);
25bool get_monkeys_metadata(int fd, struct mp3entry* id3);
26bool get_musepack_metadata(int fd, struct mp3entry *id3);
27bool get_sid_metadata(int fd, struct mp3entry* id3);
28bool get_spc_metadata(int fd, struct mp3entry* id3);
29bool get_speex_metadata(int fd, struct mp3entry* id3);
30bool get_vorbis_metadata(int fd, struct mp3entry* id3);
31bool get_wave_metadata(int fd, struct mp3entry* id3);
diff --git a/apps/metadata/monkeys.c b/apps/metadata/monkeys.c
new file mode 100644
index 0000000000..bda3a01643
--- /dev/null
+++ b/apps/metadata/monkeys.c
@@ -0,0 +1,92 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "id3.h"
27#include "metadata_common.h"
28
29bool get_monkeys_metadata(int fd, struct mp3entry* id3)
30{
31 /* Use the trackname part of the id3 structure as a temporary buffer */
32 unsigned char* buf = (unsigned char *)id3->path;
33 unsigned char* header;
34 bool rc = false;
35 uint32_t descriptorlength;
36 uint32_t totalsamples;
37 uint32_t blocksperframe, finalframeblocks, totalframes;
38 int fileversion;
39
40 lseek(fd, 0, SEEK_SET);
41
42 if (read(fd, buf, 4) < 4)
43 {
44 return rc;
45 }
46
47 if (memcmp(buf, "MAC ", 4) != 0)
48 {
49 return rc;
50 }
51
52 read(fd, buf + 4, MAX_PATH - 4);
53
54 fileversion = get_short_le(buf+4);
55 if (fileversion < 3970)
56 {
57 /* Not supported */
58 return false;
59 }
60
61 if (fileversion >= 3980)
62 {
63 descriptorlength = get_long_le(buf+8);
64
65 header = buf + descriptorlength;
66
67 blocksperframe = get_long_le(header+4);
68 finalframeblocks = get_long_le(header+8);
69 totalframes = get_long_le(header+12);
70 id3->frequency = get_long_le(header+20);
71 }
72 else
73 {
74 /* v3.95 and later files all have a fixed framesize */
75 blocksperframe = 73728 * 4;
76
77 finalframeblocks = get_long_le(buf+28);
78 totalframes = get_long_le(buf+24);
79 id3->frequency = get_long_le(buf+12);
80 }
81
82 id3->vbr = true; /* All FLAC files are VBR */
83 id3->filesize = filesize(fd);
84
85 totalsamples = finalframeblocks;
86 if (totalframes > 1)
87 totalsamples += blocksperframe * (totalframes-1);
88
89 id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
90 id3->bitrate = (id3->filesize * 8) / id3->length;
91 return true;
92}
diff --git a/apps/metadata/mp4.c b/apps/metadata/mp4.c
new file mode 100644
index 0000000000..6523bb6551
--- /dev/null
+++ b/apps/metadata/mp4.c
@@ -0,0 +1,669 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "errno.h"
27#include "id3.h"
28#include "metadata_common.h"
29#include "logf.h"
30#include "debug.h"
31#include "replaygain.h"
32
33#define MP4_ID(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
34
35#define MP4_3gp6 MP4_ID('3', 'g', 'p', '6')
36#define MP4_alac MP4_ID('a', 'l', 'a', 'c')
37#define MP4_calb MP4_ID(0xa9, 'a', 'l', 'b')
38#define MP4_cART MP4_ID(0xa9, 'A', 'R', 'T')
39#define MP4_cnam MP4_ID(0xa9, 'n', 'a', 'm')
40#define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't')
41#define MP4_esds MP4_ID('e', 's', 'd', 's')
42#define MP4_ftyp MP4_ID('f', 't', 'y', 'p')
43#define MP4_gnre MP4_ID('g', 'n', 'r', 'e')
44#define MP4_hdlr MP4_ID('h', 'd', 'l', 'r')
45#define MP4_ilst MP4_ID('i', 'l', 's', 't')
46#define MP4_M4A MP4_ID('M', '4', 'A', ' ')
47#define MP4_M4B MP4_ID('M', '4', 'B', ' ')
48#define MP4_mdat MP4_ID('m', 'd', 'a', 't')
49#define MP4_mdia MP4_ID('m', 'd', 'i', 'a')
50#define MP4_mdir MP4_ID('m', 'd', 'i', 'r')
51#define MP4_meta MP4_ID('m', 'e', 't', 'a')
52#define MP4_minf MP4_ID('m', 'i', 'n', 'f')
53#define MP4_moov MP4_ID('m', 'o', 'o', 'v')
54#define MP4_mp4a MP4_ID('m', 'p', '4', 'a')
55#define MP4_mp42 MP4_ID('m', 'p', '4', '2')
56#define MP4_qt MP4_ID('q', 't', ' ', ' ')
57#define MP4_soun MP4_ID('s', 'o', 'u', 'n')
58#define MP4_stbl MP4_ID('s', 't', 'b', 'l')
59#define MP4_stsd MP4_ID('s', 't', 's', 'd')
60#define MP4_stts MP4_ID('s', 't', 't', 's')
61#define MP4_trak MP4_ID('t', 'r', 'a', 'k')
62#define MP4_trkn MP4_ID('t', 'r', 'k', 'n')
63#define MP4_udta MP4_ID('u', 'd', 't', 'a')
64#define MP4_extra MP4_ID('-', '-', '-', '-')
65
66/* Read the tag data from an MP4 file, storing up to buffer_size bytes in
67 * buffer.
68 */
69static unsigned long read_mp4_tag(int fd, unsigned int size_left, char* buffer,
70 unsigned int buffer_left)
71{
72 unsigned int bytes_read = 0;
73
74 if (buffer_left == 0)
75 {
76 lseek(fd, size_left, SEEK_CUR); /* Skip everything */
77 }
78 else
79 {
80 /* Skip the data tag header - maybe we should parse it properly? */
81 lseek(fd, 16, SEEK_CUR);
82 size_left -= 16;
83
84 if (size_left > buffer_left)
85 {
86 read(fd, buffer, buffer_left);
87 lseek(fd, size_left - buffer_left, SEEK_CUR);
88 bytes_read = buffer_left;
89 }
90 else
91 {
92 read(fd, buffer, size_left);
93 bytes_read = size_left;
94 }
95 }
96
97 return bytes_read;
98}
99
100/* Read a string tag from an MP4 file */
101static unsigned int read_mp4_tag_string(int fd, int size_left, char** buffer,
102 unsigned int* buffer_left, char** dest)
103{
104 unsigned int bytes_read = read_mp4_tag(fd, size_left, *buffer,
105 *buffer_left - 1);
106 unsigned int length = 0;
107
108 if (bytes_read)
109 {
110 (*buffer)[bytes_read] = 0;
111 *dest = *buffer;
112 length = strlen(*buffer) + 1;
113 *buffer_left -= length;
114 *buffer += length;
115 }
116 else
117 {
118 *dest = NULL;
119 }
120
121 return length;
122}
123
124static unsigned int read_mp4_atom(int fd, unsigned int* size,
125 unsigned int* type, unsigned int size_left)
126{
127 read_uint32be(fd, size);
128 read_uint32be(fd, type);
129
130 if (*size == 1)
131 {
132 /* FAT32 doesn't support files this big, so something seems to
133 * be wrong. (64-bit sizes should only be used when required.)
134 */
135 errno = EFBIG;
136 *type = 0;
137 return 0;
138 }
139
140 if (*size > 0)
141 {
142 if (*size > size_left)
143 {
144 size_left = 0;
145 }
146 else
147 {
148 size_left -= *size;
149 }
150
151 *size -= 8;
152 }
153 else
154 {
155 *size = size_left;
156 size_left = 0;
157 }
158
159 return size_left;
160}
161
162static unsigned int read_mp4_length(int fd, unsigned int* size)
163{
164 unsigned int length = 0;
165 int bytes = 0;
166 unsigned char c;
167
168 do
169 {
170 read(fd, &c, 1);
171 bytes++;
172 (*size)--;
173 length = (length << 7) | (c & 0x7F);
174 }
175 while ((c & 0x80) && (bytes < 4) && (*size > 0));
176
177 return length;
178}
179
180static bool read_mp4_esds(int fd, struct mp3entry* id3,
181 unsigned int* size)
182{
183 unsigned char buf[8];
184 bool sbr = false;
185
186 lseek(fd, 4, SEEK_CUR); /* Version and flags. */
187 read(fd, buf, 1); /* Verify ES_DescrTag. */
188 *size -= 5;
189
190 if (*buf == 3)
191 {
192 /* read length */
193 if (read_mp4_length(fd, size) < 20)
194 {
195 return sbr;
196 }
197
198 lseek(fd, 3, SEEK_CUR);
199 *size -= 3;
200 }
201 else
202 {
203 lseek(fd, 2, SEEK_CUR);
204 *size -= 2;
205 }
206
207 read(fd, buf, 1); /* Verify DecoderConfigDescrTab. */
208 *size -= 1;
209
210 if (*buf != 4)
211 {
212 return sbr;
213 }
214
215 if (read_mp4_length(fd, size) < 13)
216 {
217 return sbr;
218 }
219
220 lseek(fd, 13, SEEK_CUR); /* Skip audio type, bit rates, etc. */
221 read(fd, buf, 1);
222 *size -= 14;
223
224 if (*buf != 5) /* Verify DecSpecificInfoTag. */
225 {
226 return sbr;
227 }
228
229 {
230 static const int sample_rates[] =
231 {
232 96000, 88200, 64000, 48000, 44100, 32000,
233 24000, 22050, 16000, 12000, 11025, 8000
234 };
235 unsigned long bits;
236 unsigned int length;
237 unsigned int index;
238 unsigned int type;
239
240 /* Read the (leading part of the) decoder config. */
241 length = read_mp4_length(fd, size);
242 length = MIN(length, *size);
243 length = MIN(length, sizeof(buf));
244 memset(buf, 0, sizeof(buf));
245 read(fd, buf, length);
246 *size -= length;
247
248 /* Maybe time to write a simple read_bits function... */
249
250 /* Decoder config format:
251 * Object type - 5 bits
252 * Frequency index - 4 bits
253 * Channel configuration - 4 bits
254 */
255 bits = get_long_be(buf);
256 type = bits >> 27; /* Object type - 5 bits */
257 index = (bits >> 23) & 0xf; /* Frequency index - 4 bits */
258
259 if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
260 {
261 id3->frequency = sample_rates[index];
262 }
263
264 if (type == 5)
265 {
266 DEBUGF("MP4: SBR\n");
267 unsigned int old_index = index;
268
269 sbr = true;
270 index = (bits >> 15) & 0xf; /* Frequency index - 4 bits */
271
272 if (index == 15)
273 {
274 /* 17 bits read so far... */
275 bits = get_long_be(&buf[2]);
276 id3->frequency = (bits >> 7) & 0x00ffffff;
277 }
278 else if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
279 {
280 id3->frequency = sample_rates[index];
281 }
282
283 if (old_index == index)
284 {
285 /* Downsampled SBR */
286 id3->frequency *= 2;
287 }
288 }
289 /* Skip 13 bits from above, plus 3 bits, then read 11 bits */
290 else if ((length >= 4) && (((bits >> 5) & 0x7ff) == 0x2b7))
291 {
292 /* extensionAudioObjectType */
293 DEBUGF("MP4: extensionAudioType\n");
294 type = bits & 0x1f; /* Object type - 5 bits*/
295 bits = get_long_be(&buf[4]);
296
297 if (type == 5)
298 {
299 sbr = bits >> 31;
300
301 if (sbr)
302 {
303 unsigned int old_index = index;
304
305 /* 1 bit read so far */
306 index = (bits >> 27) & 0xf; /* Frequency index - 4 bits */
307
308 if (index == 15)
309 {
310 /* 5 bits read so far */
311 id3->frequency = (bits >> 3) & 0x00ffffff;
312 }
313 else if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
314 {
315 id3->frequency = sample_rates[index];
316 }
317
318 if (old_index == index)
319 {
320 /* Downsampled SBR */
321 id3->frequency *= 2;
322 }
323 }
324 }
325 }
326
327 if (!sbr && (id3->frequency <= 24000) && (length <= 2))
328 {
329 /* Double the frequency for low-frequency files without a "long"
330 * DecSpecificConfig header. The file may or may not contain SBR,
331 * but here we guess it does if the header is short. This can
332 * fail on some files, but it's the best we can do, short of
333 * decoding (parts of) the file.
334 */
335 id3->frequency *= 2;
336 }
337 }
338
339 return sbr;
340}
341
342static bool read_mp4_tags(int fd, struct mp3entry* id3,
343 unsigned int size_left)
344{
345 unsigned int size;
346 unsigned int type;
347 unsigned int buffer_left = sizeof(id3->id3v2buf) + sizeof(id3->id3v1buf);
348 char* buffer = id3->id3v2buf;
349 bool cwrt = false;
350
351 do
352 {
353 size_left = read_mp4_atom(fd, &size, &type, size_left);
354
355 /* DEBUGF("Tag atom: '%c%c%c%c' (%d bytes left)\n", type >> 24 & 0xff,
356 type >> 16 & 0xff, type >> 8 & 0xff, type & 0xff, size); */
357
358 switch (type)
359 {
360 case MP4_cnam:
361 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
362 &id3->title);
363 break;
364
365 case MP4_cART:
366 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
367 &id3->artist);
368 break;
369
370 case MP4_calb:
371 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
372 &id3->album);
373 break;
374
375 case MP4_cwrt:
376 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
377 &id3->composer);
378 cwrt = false;
379 break;
380
381 case MP4_gnre:
382 {
383 unsigned short genre;
384
385 read_mp4_tag(fd, size, (char*) &genre, sizeof(genre));
386 id3->genre_string = id3_get_num_genre(betoh16(genre) - 1);
387 }
388 break;
389
390 case MP4_trkn:
391 {
392 unsigned short n[2];
393
394 read_mp4_tag(fd, size, (char*) &n, sizeof(n));
395 id3->tracknum = betoh16(n[1]);
396 }
397 break;
398
399 case MP4_extra:
400 {
401 char tag_name[TAG_NAME_LENGTH];
402 unsigned int sub_size;
403
404 /* "mean" atom */
405 read_uint32be(fd, &sub_size);
406 size -= sub_size;
407 lseek(fd, sub_size - 4, SEEK_CUR);
408 /* "name" atom */
409 read_uint32be(fd, &sub_size);
410 size -= sub_size;
411 lseek(fd, 8, SEEK_CUR);
412 sub_size -= 12;
413
414 if (sub_size > sizeof(tag_name) - 1)
415 {
416 read(fd, tag_name, sizeof(tag_name) - 1);
417 lseek(fd, sub_size - sizeof(tag_name) - 1, SEEK_CUR);
418 tag_name[sizeof(tag_name) - 1] = 0;
419 }
420 else
421 {
422 read(fd, tag_name, sub_size);
423 tag_name[sub_size] = 0;
424 }
425
426 if ((strcasecmp(tag_name, "composer") == 0) && !cwrt)
427 {
428 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
429 &id3->composer);
430 }
431 else if (strcasecmp(tag_name, "iTunSMPB") == 0)
432 {
433 char value[TAG_VALUE_LENGTH];
434 char* value_p = value;
435 char* any;
436 unsigned int length = sizeof(value);
437
438 read_mp4_tag_string(fd, size, &value_p, &length, &any);
439 id3->lead_trim = get_itunes_int32(value, 1);
440 id3->tail_trim = get_itunes_int32(value, 2);
441 DEBUGF("AAC: lead_trim %d, tail_trim %d\n",
442 id3->lead_trim, id3->tail_trim);
443 }
444 else
445 {
446 char* any;
447 unsigned int length = read_mp4_tag_string(fd, size,
448 &buffer, &buffer_left, &any);
449
450 if (length > 0)
451 {
452 /* Re-use the read buffer as the dest buffer... */
453 buffer -= length;
454 buffer_left += length;
455
456 if (parse_replaygain(tag_name, buffer, id3,
457 buffer, buffer_left) > 0)
458 {
459 /* Data used, keep it. */
460 buffer += length;
461 buffer_left -= length;
462 }
463 }
464 }
465 }
466 break;
467
468 default:
469 lseek(fd, size, SEEK_CUR);
470 break;
471 }
472 }
473 while ((size_left > 0) && (errno == 0));
474
475 return true;
476}
477
478static bool read_mp4_container(int fd, struct mp3entry* id3,
479 unsigned int size_left)
480{
481 unsigned int size;
482 unsigned int type;
483 unsigned int handler = 0;
484 bool rc = true;
485
486 do
487 {
488 size_left = read_mp4_atom(fd, &size, &type, size_left);
489
490 /* DEBUGF("Atom: '%c%c%c%c' (0x%08x, %d bytes left)\n",
491 (type >> 24) & 0xff, (type >> 16) & 0xff, (type >> 8) & 0xff,
492 type & 0xff, type, size); */
493
494 switch (type)
495 {
496 case MP4_ftyp:
497 {
498 unsigned int id;
499
500 read_uint32be(fd, &id);
501 size -= 4;
502
503 if ((id != MP4_M4A) && (id != MP4_M4B) && (id != MP4_mp42)
504 && (id != MP4_qt) && (id != MP4_3gp6))
505 {
506 DEBUGF("Unknown MP4 file type: '%c%c%c%c'\n",
507 id >> 24 & 0xff, id >> 16 & 0xff, id >> 8 & 0xff,
508 id & 0xff);
509 return false;
510 }
511 }
512 break;
513
514 case MP4_meta:
515 lseek(fd, 4, SEEK_CUR); /* Skip version */
516 size -= 4;
517 /* Fall through */
518
519 case MP4_moov:
520 case MP4_udta:
521 case MP4_mdia:
522 case MP4_stbl:
523 case MP4_trak:
524 rc = read_mp4_container(fd, id3, size);
525 size = 0;
526 break;
527
528 case MP4_ilst:
529 if (handler == MP4_mdir)
530 {
531 rc = read_mp4_tags(fd, id3, size);
532 size = 0;
533 }
534 break;
535
536 case MP4_minf:
537 if (handler == MP4_soun)
538 {
539 rc = read_mp4_container(fd, id3, size);
540 size = 0;
541 }
542 break;
543
544 case MP4_stsd:
545 lseek(fd, 8, SEEK_CUR);
546 size -= 8;
547 rc = read_mp4_container(fd, id3, size);
548 size = 0;
549 break;
550
551 case MP4_hdlr:
552 lseek(fd, 8, SEEK_CUR);
553 read_uint32be(fd, &handler);
554 size -= 12;
555 /* DEBUGF(" Handler '%c%c%c%c'\n", handler >> 24 & 0xff,
556 handler >> 16 & 0xff, handler >> 8 & 0xff,handler & 0xff); */
557 break;
558
559 case MP4_stts:
560 {
561 unsigned int entries;
562 unsigned int i;
563
564 lseek(fd, 4, SEEK_CUR);
565 read_uint32be(fd, &entries);
566 id3->samples = 0;
567
568 for (i = 0; i < entries; i++)
569 {
570 unsigned int n;
571 unsigned int l;
572
573 read_uint32be(fd, &n);
574 read_uint32be(fd, &l);
575 id3->samples += n * l;
576 }
577
578 size = 0;
579 }
580 break;
581
582 case MP4_mp4a:
583 case MP4_alac:
584 {
585 unsigned int frequency;
586
587 id3->codectype = (type == MP4_mp4a) ? AFMT_AAC : AFMT_ALAC;
588 lseek(fd, 22, SEEK_CUR);
589 read_uint32be(fd, &frequency);
590 size -= 26;
591 id3->frequency = frequency;
592
593 if (type == MP4_mp4a)
594 {
595 unsigned int subsize;
596 unsigned int subtype;
597
598 /* Get frequency from the decoder info tag, if possible. */
599 lseek(fd, 2, SEEK_CUR);
600 /* The esds atom is a part of the mp4a atom, so ignore
601 * the returned size (it's already accounted for).
602 */
603 read_mp4_atom(fd, &subsize, &subtype, size);
604 size -= 10;
605
606 if (subtype == MP4_esds)
607 {
608 read_mp4_esds(fd, id3, &size);
609 }
610 }
611 }
612 break;
613
614 case MP4_mdat:
615 id3->filesize = size;
616 break;
617
618 default:
619 break;
620 }
621
622 lseek(fd, size, SEEK_CUR);
623 }
624 while (rc && (size_left > 0) && (errno == 0) && (id3->filesize == 0));
625 /* Break on non-zero filesize, since Rockbox currently doesn't support
626 * metadata after the mdat atom (which sets the filesize field).
627 */
628
629 return rc;
630}
631
632bool get_mp4_metadata(int fd, struct mp3entry* id3)
633{
634 id3->codectype = AFMT_UNKNOWN;
635 id3->filesize = 0;
636 errno = 0;
637
638 if (read_mp4_container(fd, id3, filesize(fd)) && (errno == 0)
639 && (id3->samples > 0) && (id3->frequency > 0)
640 && (id3->filesize > 0))
641 {
642 if (id3->codectype == AFMT_UNKNOWN)
643 {
644 logf("Not an ALAC or AAC file");
645 return false;
646 }
647
648 id3->length = ((int64_t) id3->samples * 1000) / id3->frequency;
649
650 if (id3->length <= 0)
651 {
652 logf("mp4 length invalid!");
653 return false;
654 }
655
656 id3->bitrate = ((int64_t) id3->filesize * 8) / id3->length;
657 DEBUGF("MP4 bitrate %d, frequency %ld Hz, length %ld ms\n",
658 id3->bitrate, id3->frequency, id3->length);
659 }
660 else
661 {
662 logf("MP4 metadata error");
663 DEBUGF("MP4 metadata error. errno %d, length %ld, frequency %ld, filesize %ld\n",
664 errno, id3->length, id3->frequency, id3->filesize);
665 return false;
666 }
667
668 return true;
669}
diff --git a/apps/metadata/mpc.c b/apps/metadata/mpc.c
new file mode 100644
index 0000000000..60e8202ff5
--- /dev/null
+++ b/apps/metadata/mpc.c
@@ -0,0 +1,118 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "id3.h"
27#include "metadata_common.h"
28#include "logf.h"
29#include "replaygain.h"
30
31bool get_musepack_metadata(int fd, struct mp3entry *id3)
32{
33 const int32_t sfreqs_sv7[4] = { 44100, 48000, 37800, 32000 };
34 uint32_t header[8];
35 uint64_t samples = 0;
36 int i;
37
38 if (!skip_id3v2(fd, id3))
39 return false;
40 if (read(fd, header, 4*8) != 4*8) return false;
41 /* Musepack files are little endian, might need swapping */
42 for (i = 1; i < 8; i++)
43 header[i] = letoh32(header[i]);
44 if (!memcmp(header, "MP+", 3)) { /* Compare to sig "MP+" */
45 unsigned int streamversion;
46
47 header[0] = letoh32(header[0]);
48 streamversion = (header[0] >> 24) & 15;
49 if (streamversion >= 8) {
50 return false; /* SV8 or higher don't exist yet, so no support */
51 } else if (streamversion == 7) {
52 unsigned int gapless = (header[5] >> 31) & 0x0001;
53 unsigned int last_frame_samples = (header[5] >> 20) & 0x07ff;
54 int track_gain, album_gain;
55 unsigned int bufused;
56
57 id3->frequency = sfreqs_sv7[(header[2] >> 16) & 0x0003];
58 samples = (uint64_t)header[1]*1152; /* 1152 is mpc frame size */
59 if (gapless)
60 samples -= 1152 - last_frame_samples;
61 else
62 samples -= 481; /* Musepack subband synth filter delay */
63
64 /* Extract ReplayGain data from header */
65 track_gain = (int16_t)((header[3] >> 16) & 0xffff);
66 id3->track_gain = get_replaygain_int(track_gain);
67 id3->track_peak = ((uint16_t)(header[3] & 0xffff)) << 9;
68
69 album_gain = (int16_t)((header[4] >> 16) & 0xffff);
70 id3->album_gain = get_replaygain_int(album_gain);
71 id3->album_peak = ((uint16_t)(header[4] & 0xffff)) << 9;
72
73 /* Write replaygain values to strings for use in id3 screen. We use
74 the XING header as buffer space since Musepack files shouldn't
75 need to use it in any other way */
76 id3->track_gain_string = (char *)id3->toc;
77 bufused = snprintf(id3->track_gain_string, 45,
78 "%d.%d dB", track_gain/100, abs(track_gain)%100);
79 id3->album_gain_string = (char *)id3->toc + bufused + 1;
80 bufused = snprintf(id3->album_gain_string, 45,
81 "%d.%d dB", album_gain/100, abs(album_gain)%100);
82 }
83 } else {
84 header[0] = letoh32(header[0]);
85 unsigned int streamversion = (header[0] >> 11) & 0x03FF;
86 if (streamversion != 4 && streamversion != 5 && streamversion != 6)
87 return false;
88 id3->frequency = 44100;
89 id3->track_gain = 0;
90 id3->track_peak = 0;
91 id3->album_gain = 0;
92 id3->album_peak = 0;
93
94 if (streamversion >= 5)
95 samples = (uint64_t)header[1]*1152; // 32 bit
96 else
97 samples = (uint64_t)(header[1] >> 16)*1152; // 16 bit
98
99 samples -= 576;
100 if (streamversion < 6)
101 samples -= 1152;
102 }
103
104 id3->vbr = true;
105 /* Estimate bitrate, we should probably subtract the various header sizes
106 here for super-accurate results */
107 id3->length = ((int64_t) samples * 1000) / id3->frequency;
108
109 if (id3->length <= 0)
110 {
111 logf("mpc length invalid!");
112 return false;
113 }
114
115 id3->filesize = filesize(fd);
116 id3->bitrate = id3->filesize * 8 / id3->length;
117 return true;
118}
diff --git a/apps/metadata/sid.c b/apps/metadata/sid.c
new file mode 100644
index 0000000000..0dff5f6268
--- /dev/null
+++ b/apps/metadata/sid.c
@@ -0,0 +1,88 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "id3.h"
27#include "metadata_common.h"
28#include "atoi.h"
29#include "rbunicode.h"
30
31/* PSID metadata info is available here:
32 http://www.unusedino.de/ec64/technical/formats/sidplay.html */
33bool get_sid_metadata(int fd, struct mp3entry* id3)
34{
35 /* Use the trackname part of the id3 structure as a temporary buffer */
36 unsigned char* buf = (unsigned char *)id3->path;
37 int read_bytes;
38 char *p;
39
40
41 if ((lseek(fd, 0, SEEK_SET) < 0)
42 || ((read_bytes = read(fd, buf, 0x80)) < 0x80))
43 {
44 return false;
45 }
46
47 if ((memcmp(buf, "PSID",4) != 0))
48 {
49 return false;
50 }
51
52 p = id3->id3v2buf;
53
54 /* Copy Title (assumed max 0x1f letters + 1 zero byte) */
55 id3->title = p;
56 buf[0x16+0x1f] = 0;
57 p = iso_decode(&buf[0x16], p, 0, strlen(&buf[0x16])+1);
58
59 /* Copy Artist (assumed max 0x1f letters + 1 zero byte) */
60 id3->artist = p;
61 buf[0x36+0x1f] = 0;
62 p = iso_decode(&buf[0x36], p, 0, strlen(&buf[0x36])+1);
63
64 /* Copy Year (assumed max 4 letters + 1 zero byte) */
65 buf[0x56+0x4] = 0;
66 id3->year = atoi(&buf[0x56]);
67
68 /* Copy Album (assumed max 0x1f-0x05 letters + 1 zero byte) */
69 id3->album = p;
70 buf[0x56+0x1f] = 0;
71 p = iso_decode(&buf[0x5b], p, 0, strlen(&buf[0x5b])+1);
72
73 id3->bitrate = 706;
74 id3->frequency = 44100;
75 /* New idea as posted by Marco Alanen (ravon):
76 * Set the songlength in seconds to the number of subsongs
77 * so every second represents a subsong.
78 * Users can then skip the current subsong by seeking
79 *
80 * Note: the number of songs is a 16bit value at 0xE, so this code only
81 * uses the lower 8 bits of the counter.
82 */
83 id3->length = (buf[0xf]-1)*1000;
84 id3->vbr = false;
85 id3->filesize = filesize(fd);
86
87 return true;
88}
diff --git a/apps/metadata/spc.c b/apps/metadata/spc.c
new file mode 100644
index 0000000000..8d85518714
--- /dev/null
+++ b/apps/metadata/spc.c
@@ -0,0 +1,126 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "id3.h"
27#include "metadata_common.h"
28#include "debug.h"
29#include "atoi.h"
30#include "rbunicode.h"
31
32bool get_spc_metadata(int fd, struct mp3entry* id3)
33{
34 /* Use the trackname part of the id3 structure as a temporary buffer */
35 unsigned char * buf = (unsigned char *)id3->path;
36 int read_bytes;
37 char * p;
38
39 unsigned long length;
40 unsigned long fade;
41 bool isbinary = true;
42 int i;
43
44 /* try to get the ID666 tag */
45 if ((lseek(fd, 0x2e, SEEK_SET) < 0)
46 || ((read_bytes = read(fd, buf, 0xD2)) < 0xD2))
47 {
48 DEBUGF("lseek or read failed\n");
49 return false;
50 }
51
52 p = id3->id3v2buf;
53
54 id3->title = p;
55 buf[31] = 0;
56 p = iso_decode(buf, p, 0, 32);
57 buf += 32;
58
59 id3->album = p;
60 buf[31] = 0;
61 p = iso_decode(buf, p, 0, 32);
62 buf += 48;
63
64 id3->comment = p;
65 buf[31] = 0;
66 p = iso_decode(buf, p, 0, 32);
67 buf += 32;
68
69 /* Date check */
70 if(buf[2] == '/' && buf[5] == '/')
71 isbinary = false;
72
73 /* Reserved bytes check */
74 if(buf[0xD2 - 0x2E - 112] >= '0' &&
75 buf[0xD2 - 0x2E - 112] <= '9' &&
76 buf[0xD3 - 0x2E - 112] == 0x00)
77 isbinary = false;
78
79 /* is length & fade only digits? */
80 for (i=0;i<8 && (
81 (buf[0xA9 - 0x2E - 112+i]>='0'&&buf[0xA9 - 0x2E - 112+i]<='9') ||
82 buf[0xA9 - 0x2E - 112+i]=='\0');
83 i++);
84 if (i==8) isbinary = false;
85
86 if(isbinary) {
87 id3->year = buf[0] | (buf[1]<<8);
88 buf += 11;
89
90 length = (buf[0] | (buf[1]<<8) | (buf[2]<<16)) * 1000;
91 buf += 3;
92
93 fade = (buf[0] | (buf[1]<<8) | (buf[2]<<16) | (buf[3]<<24));
94 buf += 4;
95 } else {
96 char tbuf[6];
97
98 buf += 6;
99 buf[4] = 0;
100 id3->year = atoi(buf);
101 buf += 5;
102
103 memcpy(tbuf, buf, 3);
104 tbuf[3] = 0;
105 length = atoi(tbuf) * 1000;
106 buf += 3;
107
108 memcpy(tbuf, buf, 5);
109 tbuf[5] = 0;
110 fade = atoi(tbuf);
111 buf += 5;
112 }
113
114 id3->artist = p;
115 buf[31] = 0;
116 p = iso_decode(buf, p, 0, 32);
117
118 if (length==0) {
119 length=3*60*1000; /* 3 minutes */
120 fade=5*1000; /* 5 seconds */
121 }
122
123 id3->length = length+fade;
124
125 return true;
126}
diff --git a/apps/metadata/speex.c b/apps/metadata/speex.c
new file mode 100644
index 0000000000..e5f6a127ae
--- /dev/null
+++ b/apps/metadata/speex.c
@@ -0,0 +1,212 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "id3.h"
27#include "metadata_common.h"
28#include "logf.h"
29
30/* A simple parser to read vital metadata from an Ogg Speex file. Returns
31 * false if metadata needed by the Speex codec couldn't be read.
32 */
33
34bool get_speex_metadata(int fd, struct mp3entry* id3)
35{
36 /* An Ogg File is split into pages, each starting with the string
37 * "OggS". Each page has a timestamp (in PCM samples) referred to as
38 * the "granule position".
39 *
40 * An Ogg Speex has the following structure:
41 * 1) Identification header (containing samplerate, numchannels, etc)
42 Described in this page: (http://www.speex.org/manual2/node7.html)
43 * 2) Comment header - containing the Vorbis Comments
44 * 3) Many audio packets...
45 */
46
47 /* Use the path name of the id3 structure as a temporary buffer. */
48 unsigned char* buf = (unsigned char*)id3->path;
49 long comment_size;
50 long remaining = 0;
51 long last_serial = 0;
52 long serial, r;
53 int segments;
54 int i;
55 bool eof = false;
56
57 if ((lseek(fd, 0, SEEK_SET) < 0) || (read(fd, buf, 58) < 33))
58 {
59 return false;
60 }
61
62 if ((memcmp(buf, "OggS", 4) != 0) || (memcmp(&buf[28], "Speex", 5) != 0))
63 {
64 return false;
65 }
66
67 /* We need to ensure the serial number from this page is the same as the
68 * one from the last page (since we only support a single bitstream).
69 */
70 serial = get_long_le(&buf[14]);
71 if ((lseek(fd, 33, SEEK_SET) < 0)||(read(fd, buf, 58) < 4))
72 {
73 return false;
74 }
75
76 id3->frequency = get_slong(&buf[31]);
77 last_serial = get_long_le(&buf[27]);/*temporary, header size*/
78 id3->bitrate = get_long_le(&buf[47]);
79 id3->vbr = get_long_le(&buf[55]);
80 id3->filesize = filesize(fd);
81 /* Comments are in second Ogg page */
82 if (lseek(fd, 28+last_serial/*(temporary for header size)*/, SEEK_SET) < 0)
83 {
84 return false;
85 }
86
87 /* Minimum header length for Ogg pages is 27. */
88 if (read(fd, buf, 27) < 27)
89 {
90 return false;
91 }
92
93 if (memcmp(buf, "OggS", 4) !=0 )
94 {
95 return false;
96 }
97
98 segments = buf[26];
99 /* read in segment table */
100 if (read(fd, buf, segments) < segments)
101 {
102 return false;
103 }
104
105 /* The second packet in a vorbis stream is the comment packet. It *may*
106 * extend beyond the second page, but usually does not. Here we find the
107 * length of the comment packet (or the rest of the page if the comment
108 * packet extends to the third page).
109 */
110 for (i = 0; i < segments; i++)
111 {
112 remaining += buf[i];
113 /* The last segment of a packet is always < 255 bytes */
114 if (buf[i] < 255)
115 {
116 break;
117 }
118 }
119
120 comment_size = remaining;
121
122 /* Failure to read the tags isn't fatal. */
123 read_vorbis_tags(fd, id3, remaining);
124
125 /* We now need to search for the last page in the file - identified by
126 * by ('O','g','g','S',0) and retrieve totalsamples.
127 */
128
129 /* A page is always < 64 kB */
130 if (lseek(fd, -(MIN(64 * 1024, id3->filesize)), SEEK_END) < 0)
131 {
132 return false;
133 }
134
135 remaining = 0;
136
137 while (!eof)
138 {
139 r = read(fd, &buf[remaining], MAX_PATH - remaining);
140
141 if (r <= 0)
142 {
143 eof = true;
144 }
145 else
146 {
147 remaining += r;
148 }
149
150 /* Inefficient (but simple) search */
151 i = 0;
152
153 while (i < (remaining - 3))
154 {
155 if ((buf[i] == 'O') && (memcmp(&buf[i], "OggS", 4) == 0))
156 {
157 if (i < (remaining - 17))
158 {
159 /* Note that this only reads the low 32 bits of a
160 * 64 bit value.
161 */
162 id3->samples = get_long_le(&buf[i + 6]);
163 last_serial = get_long_le(&buf[i + 14]);
164
165 /* If this page is very small the beginning of the next
166 * header could be in buffer. Jump near end of this header
167 * and continue */
168 i += 27;
169 }
170 else
171 {
172 break;
173 }
174 }
175 else
176 {
177 i++;
178 }
179 }
180
181 if (i < remaining)
182 {
183 /* Move the remaining bytes to start of buffer.
184 * Reuse var 'segments' as it is no longer needed */
185 segments = 0;
186 while (i < remaining)
187 {
188 buf[segments++] = buf[i++];
189 }
190 remaining = segments;
191 }
192 else
193 {
194 /* Discard the rest of the buffer */
195 remaining = 0;
196 }
197 }
198
199 /* This file has mutiple vorbis bitstreams (or is corrupt). */
200 /* FIXME we should display an error here. */
201 if (serial != last_serial)
202 {
203 logf("serialno mismatch");
204 logf("%ld", serial);
205 logf("%ld", last_serial);
206 return false;
207 }
208
209 id3->length = (id3->samples / id3->frequency) * 1000;
210 id3->bitrate = (((int64_t) id3->filesize - comment_size) * 8) / id3->length;
211 return true;
212}
diff --git a/apps/metadata/vorbis.c b/apps/metadata/vorbis.c
new file mode 100644
index 0000000000..5112615e47
--- /dev/null
+++ b/apps/metadata/vorbis.c
@@ -0,0 +1,330 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "id3.h"
27#include "metadata_common.h"
28#include "metadata_parsers.h"
29#include "structec.h"
30#include "logf.h"
31
32/* Read the items in a Vorbis comment packet. Returns true the items were
33 * fully read, false otherwise.
34 */
35bool read_vorbis_tags(int fd, struct mp3entry *id3,
36 long tag_remaining)
37{
38 char *buf = id3->id3v2buf;
39 int32_t comment_count;
40 int32_t len;
41 int buf_remaining = sizeof(id3->id3v2buf) + sizeof(id3->id3v1buf);
42 int i;
43
44 if (ecread(fd, &len, 1, "l", IS_BIG_ENDIAN) < (long) sizeof(len))
45 {
46 return false;
47 }
48
49 if ((lseek(fd, len, SEEK_CUR) < 0)
50 || (ecread(fd, &comment_count, 1, "l", IS_BIG_ENDIAN)
51 < (long) sizeof(comment_count)))
52 {
53 return false;
54 }
55
56 tag_remaining -= len + sizeof(len) + sizeof(comment_count);
57
58 if (tag_remaining <= 0)
59 {
60 return true;
61 }
62
63 for (i = 0; i < comment_count; i++)
64 {
65 char name[TAG_NAME_LENGTH];
66 char value[TAG_VALUE_LENGTH];
67 int32_t read_len;
68
69 if (tag_remaining < 4)
70 {
71 break;
72 }
73
74 if (ecread(fd, &len, 1, "l", IS_BIG_ENDIAN) < (long) sizeof(len))
75 {
76 return false;
77 }
78
79 tag_remaining -= 4;
80
81 /* Quit if we've passed the end of the page */
82 if (tag_remaining < len)
83 {
84 break;
85 }
86
87 tag_remaining -= len;
88 read_len = read_string(fd, name, sizeof(name), '=', len);
89
90 if (read_len < 0)
91 {
92 return false;
93 }
94
95 len -= read_len;
96
97 if (read_string(fd, value, sizeof(value), -1, len) < 0)
98 {
99 return false;
100 }
101
102 len = parse_tag(name, value, id3, buf, buf_remaining,
103 TAGTYPE_VORBIS);
104 buf += len;
105 buf_remaining -= len;
106 }
107
108 /* Skip to the end of the block */
109 if (tag_remaining)
110 {
111 if (lseek(fd, tag_remaining, SEEK_CUR) < 0)
112 {
113 return false;
114 }
115 }
116
117 return true;
118}
119
120/* A simple parser to read vital metadata from an Ogg Vorbis file.
121 * Calls get_speex_metadata if a speex file is identified. Returns
122 * false if metadata needed by the Vorbis codec couldn't be read.
123 */
124bool get_vorbis_metadata(int fd, struct mp3entry* id3)
125{
126 /* An Ogg File is split into pages, each starting with the string
127 * "OggS". Each page has a timestamp (in PCM samples) referred to as
128 * the "granule position".
129 *
130 * An Ogg Vorbis has the following structure:
131 * 1) Identification header (containing samplerate, numchannels, etc)
132 * 2) Comment header - containing the Vorbis Comments
133 * 3) Setup header - containing codec setup information
134 * 4) Many audio packets...
135 */
136
137 /* Use the path name of the id3 structure as a temporary buffer. */
138 unsigned char* buf = (unsigned char *)id3->path;
139 long comment_size;
140 long remaining = 0;
141 long last_serial = 0;
142 long serial, r;
143 int segments;
144 int i;
145 bool eof = false;
146
147 if ((lseek(fd, 0, SEEK_SET) < 0) || (read(fd, buf, 58) < 4))
148 {
149 return false;
150 }
151
152 if ((memcmp(buf, "OggS", 4) != 0) || (memcmp(&buf[29], "vorbis", 6) != 0))
153 {
154 if ((memcmp(buf, "OggS", 4) != 0) || (memcmp(&buf[28], "Speex", 5) != 0))
155 {
156 return false;
157 }
158 else
159 {
160 id3->codectype = AFMT_SPEEX;
161 return get_speex_metadata(fd, id3);
162 }
163 }
164
165 /* We need to ensure the serial number from this page is the same as the
166 * one from the last page (since we only support a single bitstream).
167 */
168 serial = get_long_le(&buf[14]);
169 id3->frequency = get_long_le(&buf[40]);
170 id3->filesize = filesize(fd);
171
172 /* Comments are in second Ogg page */
173 if (lseek(fd, 58, SEEK_SET) < 0)
174 {
175 return false;
176 }
177
178 /* Minimum header length for Ogg pages is 27. */
179 if (read(fd, buf, 27) < 27)
180 {
181 return false;
182 }
183
184 if (memcmp(buf, "OggS", 4) !=0 )
185 {
186 return false;
187 }
188
189 segments = buf[26];
190
191 /* read in segment table */
192 if (read(fd, buf, segments) < segments)
193 {
194 return false;
195 }
196
197 /* The second packet in a vorbis stream is the comment packet. It *may*
198 * extend beyond the second page, but usually does not. Here we find the
199 * length of the comment packet (or the rest of the page if the comment
200 * packet extends to the third page).
201 */
202 for (i = 0; i < segments; i++)
203 {
204 remaining += buf[i];
205
206 /* The last segment of a packet is always < 255 bytes */
207 if (buf[i] < 255)
208 {
209 break;
210 }
211 }
212
213 /* Now read in packet header (type and id string) */
214 if (read(fd, buf, 7) < 7)
215 {
216 return false;
217 }
218
219 comment_size = remaining;
220 remaining -= 7;
221
222 /* The first byte of a packet is the packet type; comment packets are
223 * type 3.
224 */
225 if ((buf[0] != 3) || (memcmp(buf + 1, "vorbis", 6) !=0))
226 {
227 return false;
228 }
229
230 /* Failure to read the tags isn't fatal. */
231 read_vorbis_tags(fd, id3, remaining);
232
233 /* We now need to search for the last page in the file - identified by
234 * by ('O','g','g','S',0) and retrieve totalsamples.
235 */
236
237 /* A page is always < 64 kB */
238 if (lseek(fd, -(MIN(64 * 1024, id3->filesize)), SEEK_END) < 0)
239 {
240 return false;
241 }
242
243 remaining = 0;
244
245 while (!eof)
246 {
247 r = read(fd, &buf[remaining], MAX_PATH - remaining);
248
249 if (r <= 0)
250 {
251 eof = true;
252 }
253 else
254 {
255 remaining += r;
256 }
257
258 /* Inefficient (but simple) search */
259 i = 0;
260
261 while (i < (remaining - 3))
262 {
263 if ((buf[i] == 'O') && (memcmp(&buf[i], "OggS", 4) == 0))
264 {
265 if (i < (remaining - 17))
266 {
267 /* Note that this only reads the low 32 bits of a
268 * 64 bit value.
269 */
270 id3->samples = get_long_le(&buf[i + 6]);
271 last_serial = get_long_le(&buf[i + 14]);
272
273 /* If this page is very small the beginning of the next
274 * header could be in buffer. Jump near end of this header
275 * and continue */
276 i += 27;
277 }
278 else
279 {
280 break;
281 }
282 }
283 else
284 {
285 i++;
286 }
287 }
288
289 if (i < remaining)
290 {
291 /* Move the remaining bytes to start of buffer.
292 * Reuse var 'segments' as it is no longer needed */
293 segments = 0;
294 while (i < remaining)
295 {
296 buf[segments++] = buf[i++];
297 }
298 remaining = segments;
299 }
300 else
301 {
302 /* Discard the rest of the buffer */
303 remaining = 0;
304 }
305 }
306
307 /* This file has mutiple vorbis bitstreams (or is corrupt). */
308 /* FIXME we should display an error here. */
309 if (serial != last_serial)
310 {
311 logf("serialno mismatch");
312 logf("%ld", serial);
313 logf("%ld", last_serial);
314 return false;
315 }
316
317 id3->length = ((int64_t) id3->samples * 1000) / id3->frequency;
318
319 if (id3->length <= 0)
320 {
321 logf("ogg length invalid!");
322 return false;
323 }
324
325 id3->bitrate = (((int64_t) id3->filesize - comment_size) * 8) / id3->length;
326 id3->vbr = true;
327
328 return true;
329}
330
diff --git a/apps/metadata/wave.c b/apps/metadata/wave.c
new file mode 100644
index 0000000000..d29f9f5363
--- /dev/null
+++ b/apps/metadata/wave.c
@@ -0,0 +1,128 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <ctype.h>
23#include <inttypes.h>
24
25#include "system.h"
26#include "id3.h"
27#include "metadata_common.h"
28
29bool get_wave_metadata(int fd, struct mp3entry* id3)
30{
31 /* Use the trackname part of the id3 structure as a temporary buffer */
32 unsigned char* buf = (unsigned char *)id3->path;
33 unsigned long totalsamples = 0;
34 unsigned long channels = 0;
35 unsigned long bitspersample = 0;
36 unsigned long numbytes = 0;
37 int read_bytes;
38 int i;
39
40 /* get RIFF chunk header */
41 if ((lseek(fd, 0, SEEK_SET) < 0)
42 || ((read_bytes = read(fd, buf, 12)) < 12))
43 {
44 return false;
45 }
46
47 if ((memcmp(buf, "RIFF",4) != 0)
48 || (memcmp(&buf[8], "WAVE", 4) !=0 ))
49 {
50 return false;
51 }
52
53 /* iterate over WAVE chunks until 'data' chunk */
54 while (true)
55 {
56 /* get chunk header */
57 if ((read_bytes = read(fd, buf, 8)) < 8)
58 return false;
59
60 /* chunkSize */
61 i = get_long_le(&buf[4]);
62
63 if (memcmp(buf, "fmt ", 4) == 0)
64 {
65 /* get rest of chunk */
66 if ((read_bytes = read(fd, buf, 16)) < 16)
67 return false;
68
69 i -= 16;
70
71 /* skipping wFormatTag */
72 /* wChannels */
73 channels = buf[2] | (buf[3] << 8);
74 /* dwSamplesPerSec */
75 id3->frequency = get_long_le(&buf[4]);
76 /* dwAvgBytesPerSec */
77 id3->bitrate = (get_long_le(&buf[8]) * 8) / 1000;
78 /* skipping wBlockAlign */
79 /* wBitsPerSample */
80 bitspersample = buf[14] | (buf[15] << 8);
81 }
82 else if (memcmp(buf, "data", 4) == 0)
83 {
84 numbytes = i;
85 break;
86 }
87 else if (memcmp(buf, "fact", 4) == 0)
88 {
89 /* dwSampleLength */
90 if (i >= 4)
91 {
92 /* get rest of chunk */
93 if ((read_bytes = read(fd, buf, 4)) < 4)
94 return false;
95
96 i -= 4;
97 totalsamples = get_long_le(buf);
98 }
99 }
100
101 /* seek to next chunk (even chunk sizes must be padded) */
102 if (i & 0x01)
103 i++;
104
105 if(lseek(fd, i, SEEK_CUR) < 0)
106 return false;
107 }
108
109 if ((numbytes == 0) || (channels == 0))
110 {
111 return false;
112 }
113
114 if (totalsamples == 0)
115 {
116 /* for PCM only */
117 totalsamples = numbytes
118 / ((((bitspersample - 1) / 8) + 1) * channels);
119 }
120
121 id3->vbr = false; /* All WAV files are CBR */
122 id3->filesize = filesize(fd);
123
124 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
125 id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
126
127 return true;
128}