diff options
Diffstat (limited to 'apps/metadata.c')
-rw-r--r-- | apps/metadata.c | 2154 |
1 files changed, 6 insertions, 2148 deletions
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 | |||
37 | enum 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 | |||
86 | struct 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 | ||
96 | struct 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 | ||
103 | static const unsigned short a52_bitrates[] = | 36 | static 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 | */ | ||
132 | static 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 | ||
168 | static 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. */ | ||
179 | static 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. */ | ||
187 | static 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. */ | ||
195 | static 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. */ | ||
203 | static 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 | |||
210 | static char* skip_space(char* str) | ||
211 | { | ||
212 | while (isspace(*str)) | ||
213 | { | ||
214 | str++; | ||
215 | } | ||
216 | |||
217 | return str; | ||
218 | } | ||
219 | |||
220 | static 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 | */ | ||
251 | static 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 | */ | ||
344 | static 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 | */ | ||
427 | static 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 | */ | ||
517 | static 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 | |||
544 | static 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 | */ | ||
729 | static 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 | |||
936 | static 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 | |||
1030 | static 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 | |||
1095 | static 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 | */ | ||
1199 | static 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 */ | ||
1231 | static 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 | |||
1254 | static 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 | |||
1292 | static 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 | |||
1310 | static 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 | |||
1472 | static 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 | |||
1608 | static 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 | |||
1762 | static 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 | |||
1801 | static 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 */ | ||
1892 | static 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 | |||
1949 | static 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 | |||
2036 | static 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 | |||
2132 | static 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 | ||