1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Daniel Stenberg
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
21 * Parts of this code has been stolen from the Ample project and was written
22 * by David Härdeman. It has since been extended and enhanced pretty much by
23 * all sorts of friendly Rockbox people.
25 * A nice reference for MPEG header info:
26 * http://rockbox.haxx.se/docs/mpeghdr.html
41 #define UNSYNC(b0,b1,b2,b3) (((b0 & 0x7F) << (3*7)) | \
42 ((b1 & 0x7F) << (2*7)) | \
43 ((b2 & 0x7F) << (1*7)) | \
44 ((b3 & 0x7F) << (0*7)))
46 #define BYTES2INT(b0,b1,b2,b3) (((b0 & 0xFF) << (3*8)) | \
47 ((b1 & 0xFF) << (2*8)) | \
48 ((b2 & 0xFF) << (1*8)) | \
49 ((b3 & 0xFF) << (0*8)))
51 /* Table of bitrates for MP3 files, all values in kilo.
52 * Indexed by version, layer and value of bit 15-12 in header.
54 const int bitrate_table
[2][3][16] =
57 {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
58 {0,32,48,56, 64,80, 96, 112,128,160,192,224,256,320,384,0},
59 {0,32,40,48, 56,64, 80, 96, 112,128,160,192,224,256,320,0}
62 {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0},
63 {0, 8,16,24,32,40,48, 56, 64, 80, 96,112,128,144,160,0},
64 {0, 8,16,24,32,40,48, 56, 64, 80, 96,112,128,144,160,0}
68 /* Table of samples per frame for MP3 files.
69 * Indexed by layer. Multiplied with 1000.
71 const int bs
[4] = {0, 384000, 1152000, 1152000};
73 /* Table of sample frequency for MP3 files.
74 * Indexed by version and layer.
76 const int freqtab
[][4] =
78 {11025, 12000, 8000, 0}, /* MPEG version 2.5 */
79 {44100, 48000, 32000, 0}, /* MPEG Version 1 */
80 {22050, 24000, 16000, 0}, /* MPEG version 2 */
83 #define UNICODE_BOM_1 0xfffe
84 #define UNICODE_BOM_2 0xfeff
86 /* Checks to see if the passed in string is a 16-bit wide Unicode v2
87 string. If it is, we attempt to convert it to a 8-bit ASCII string
88 (for valid 8-bit ASCII characters). If it's not unicode, we leave
89 it alone. At some point we should fully support unicode strings */
90 static int unicode_munge(char** string
, int *len
) {
95 char *outstr
= *string
;
98 /* Plain old string */
102 /* Type 0x00 is ordinary ISO 8859-1 */
105 (*string
)++; /* Skip the encoding type byte */
109 /* Unicode with or without BOM */
110 if(str
[0] == 0x01 || str
[0] == 0x02) {
112 tmp
= BYTES2INT(0, 0, str
[1], str
[2]);
114 if(tmp
== UNICODE_BOM_2
) { /* Little endian? */
119 if(tmp
== UNICODE_BOM_1
) /* Big endian? */
129 outstr
[i
++] = str
[0];
134 outstr
[i
++] = str
[1];
136 } while(str
[0] || str
[1]);
139 (*string
)++; /* Skip the encoding type byte */
143 /* If we come here, the string was of an unsupported type */
150 * Removes trailing spaces from a string.
152 * Arguments: buffer - the string to process
157 stripspaces(char *buffer
)
160 while(*(buffer
+ i
) != '\0')
164 if(*(buffer
+ i
) == ' ')
165 *(buffer
+ i
) = '\0';
166 else if(*(buffer
+ i
) == '\0')
174 * Sets the title of an MP3 entry based on its ID3v1 tag.
176 * Arguments: file - the MP3 file to scen for a ID3v1 tag
177 * entry - the entry to set the title in
179 * Returns: true if a title was found and created, else false
181 static bool setid3v1title(int fd
, struct mp3entry
*entry
)
183 unsigned char buffer
[31];
184 int offsets
[4] = {-95,-65,-125,-31};
188 if (-1 == lseek(fd
, offsets
[i
], SEEK_END
))
192 read(fd
, buffer
, 30);
195 if (buffer
[0] || i
== 3) {
198 strcpy(entry
->id3v1buf
[0], buffer
);
199 entry
->artist
= entry
->id3v1buf
[0];
202 strcpy(entry
->id3v1buf
[1], buffer
);
203 entry
->album
= entry
->id3v1buf
[1];
206 strcpy(entry
->id3v1buf
[2], buffer
);
207 entry
->title
= entry
->id3v1buf
[2];
210 /* id3v1.1 uses last two bytes of comment field for track
211 number: first must be 0 and second is track num */
213 entry
->tracknum
= buffer
[29];
224 * Sets the title of an MP3 entry based on its ID3v2 tag.
226 * Arguments: file - the MP3 file to scen for a ID3v2 tag
227 * entry - the entry to set the title in
229 * Returns: true if a title was found and created, else false
231 static void setid3v2title(int fd
, struct mp3entry
*entry
)
235 int readsize
= 0, headerlen
;
239 char *tracknum
= NULL
;
241 unsigned short int version
;
242 int titlen
=0, artistn
=0, albumn
=0, tracknumn
=0;
243 char *buffer
= entry
->id3v2buf
;
245 /* 10 = headerlength */
246 if(entry
->id3v2len
< 10)
250 lseek(fd
, 0, SEEK_SET
);
251 if(10 != read(fd
, header
, 10))
254 version
= (unsigned short int)header
[3];
256 /* Read all frames in the tag */
257 size
= entry
->id3v2len
- 10;
259 if(size
>= (int)sizeof(entry
->id3v2buf
))
260 size
= sizeof(entry
->id3v2buf
)-1;
262 if(size
!= read(fd
, buffer
, size
))
265 *(buffer
+ size
) = '\0';
267 /* Set minimum frame size according to ID3v2 version */
274 * We must have at least minframesize bytes left for the
275 * remaining frames to be interesting
277 while(size
- readsize
> minframesize
) {
279 /* Read frame header and check length */
281 memcpy(header
, (buffer
+ readsize
), 10);
284 headerlen
= UNSYNC(header
[4], header
[5],
285 header
[6], header
[7]);
287 /* version .3 files don't use synchsafe ints for
289 headerlen
= BYTES2INT(header
[4], header
[5],
290 header
[6], header
[7]);
293 memcpy(header
, (buffer
+ readsize
), 6);
295 headerlen
= (header
[3] << 16) +
300 /* Get only the part of the header that is within our buffer */
301 if(headerlen
> (size
-readsize
))
302 headerlen
= (size
- readsize
);
304 /* Check for certain frame headers */
305 if(!strncmp(header
, "TPE1", strlen("TPE1")) ||
306 !strncmp(header
, "TP1", strlen("TP1"))) {
309 artist
= buffer
+ readsize
;
311 unicode_munge(&artist
, &artistn
);
313 else if(!strncmp(header
, "TIT2", strlen("TIT2")) ||
314 !strncmp(header
, "TT2", strlen("TT2"))) {
317 title
= buffer
+ readsize
;
319 unicode_munge(&title
, &titlen
);
321 else if(!strncmp(header
, "TALB", strlen("TALB"))) {
324 album
= buffer
+ readsize
;
326 unicode_munge(&album
, &albumn
);
328 else if(!strncmp(header
, "TRCK", strlen("TRCK"))) {
331 tracknum
= buffer
+ readsize
;
332 tracknumn
= headerlen
;
333 unicode_munge(&tracknum
, &tracknumn
);
336 readsize
+= headerlen
;
340 entry
->artist
= artist
;
345 entry
->title
= title
;
350 entry
->album
= album
;
355 tracknum
[tracknumn
] = 0;
356 entry
->tracknum
= atoi(tracknum
);
361 * Calculates the size of the ID3v2 tag.
363 * Arguments: file - the file to search for a tag.
365 * Returns: the size of the tag or 0 if none was found
367 static int getid3v2len(int fd
)
372 /* Make sure file has a ID3 tag */
373 if((-1 == lseek(fd
, 0, SEEK_SET
)) ||
374 (read(fd
, buf
, 6) != 6) ||
375 (strncmp(buf
, "ID3", strlen("ID3")) != 0))
378 /* Now check what the ID3v2 size field says */
379 else if(read(fd
, buf
, 4) != 4)
382 offset
= UNSYNC(buf
[0], buf
[1], buf
[2], buf
[3]) + 10;
387 static int getfilesize(int fd
)
391 /* seek to the end of it */
392 size
= lseek(fd
, 0, SEEK_END
);
394 return 0; /* unknown */
400 * Calculates the size of the ID3v1 tag.
402 * Arguments: file - the file to search for a tag.
404 * Returns: the size of the tag or 0 if none was found
406 static int getid3v1len(int fd
)
411 /* Check if we find "TAG" 128 bytes from EOF */
412 if((lseek(fd
, -128, SEEK_END
) == -1) ||
413 (read(fd
, buf
, 3) != 3) ||
414 (strncmp(buf
, "TAG", 3) != 0))
422 /* check if 'head' is a valid mp3 frame header */
423 static bool mp3frameheader(unsigned long head
)
425 if ((head
& 0xffe00000) != 0xffe00000) /* bad sync? */
427 if (!((head
>> 17) & 3)) /* no layer? */
429 if (((head
>> 12) & 0xf) == 0xf) /* bad bitrate? */
431 if (!((head
>> 12) & 0xf)) /* no bitrate? */
433 if (((head
>> 10) & 0x3) == 0x3) /* bad sample rate? */
435 if (((head
>> 19) & 1) == 1 &&
436 ((head
>> 17) & 3) == 3 &&
437 ((head
>> 16) & 1) == 1)
439 if ((head
& 0xffff0000) == 0xfffe0000)
446 * Calculates the length (in milliseconds) of an MP3 file.
448 * Modified to only use integers.
450 * Arguments: file - the file to calculate the length upon
451 * entry - the entry to update with the length
453 * Returns: the song length in milliseconds,
454 * 0 means that it couldn't be calculated
456 static int getsonglength(int fd
, struct mp3entry
*entry
)
458 unsigned int filetime
= 0;
459 unsigned long header
=0;
461 unsigned char frame
[156];
477 int bittable
; /* which bitrate table to use */
478 bool header_found
= false;
483 /* Start searching after ID3v2 header */
484 if(-1 == lseek(fd
, entry
->id3v2len
, SEEK_SET
))
487 /* Fill up header with first 24 bits */
488 for(version
= 0; version
< 3; version
++) {
490 if(!read(fd
, &tmp
, 1))
495 /* Loop trough file until we find a frame header */
496 bytecount
= entry
->id3v2len
- 1;
497 bytelimit
= entry
->id3v2len
+ 0x20000;
501 if(!read(fd
, &tmp
, 1))
505 /* Quit if we haven't found a valid header within 128K */
507 if(bytecount
> bytelimit
)
509 } while(!mp3frameheader(header
));
512 * Some files are filled with garbage in the beginning,
513 * if the bitrate index of the header is binary 1111
514 * that is a good indicator
516 if((header
& 0xF000) == 0xF000)
519 /* MPEG Audio Version */
520 switch((header
& 0x180000) >> 19) {
522 /* MPEG version 2.5 is not an official standard */
523 version
= MPEG_VERSION2_5
;
524 bittable
= MPEG_VERSION2
; /* use the V2 bit rate table */
528 /* MPEG version 2 (ISO/IEC 13818-3) */
529 version
= MPEG_VERSION2
;
530 bittable
= MPEG_VERSION2
;
534 /* MPEG version 1 (ISO/IEC 11172-3) */
535 version
= MPEG_VERSION1
;
536 bittable
= MPEG_VERSION1
;
543 switch((header
& 0x060000) >> 17) {
558 bitindex
= (header
& 0xF000) >> 12;
559 bitrate
= bitrate_table
[bittable
-1][layer
-1][bitindex
];
563 /* Sampling frequency */
564 freqindex
= (header
& 0x0C00) >> 10;
565 frequency
= freqtab
[version
][freqindex
];
570 DEBUGF( "Version %i, lay %i, biti %i, bitr %i, freqi %i, freq %i, chmode %d\n",
571 version
, layer
, bitindex
, bitrate
, freqindex
, frequency
, chmode
);
573 entry
->version
= version
;
574 entry
->layer
= layer
;
575 entry
->frequency
= frequency
;
577 /* Calculate bytes per frame, calculation depends on layer */
580 bpf
= bitrate_table
[bittable
- 1][layer
- 1][bitindex
];
582 bpf
/= freqtab
[version
][freqindex
] << (bittable
- 1);
586 bpf
= bitrate_table
[bittable
- 1][layer
- 1][bitindex
];
588 bpf
/= freqtab
[version
][freqindex
] << (bittable
- 1);
594 /* Calculate time per frame */
595 tpf
= bs
[layer
] / (freqtab
[version
][freqindex
] << (bittable
- 1));
600 /* OK, we have found a frame. Let's see if it has a Xing header */
601 if(read(fd
, frame
, sizeof frame
) < 0)
604 /* Channel mode (stereo/mono) */
605 chmode
= (header
& 0xc0) >> 6;
607 /* calculate position of Xing VBR header */
608 if ( version
== 1 ) {
609 if ( chmode
== 3 ) /* mono */
615 if ( chmode
== 3 ) /* mono */
621 if (xing
[0] == 'X' &&
626 int i
= 8; /* Where to start parsing info */
628 /* Yes, it is a VBR file */
630 entry
->vbrflags
= xing
[7];
632 if (entry
->vbrflags
& VBR_FRAMES_FLAG
) /* Is the frame count there? */
634 int framecount
= (xing
[i
] << 24) | (xing
[i
+1] << 16) |
635 (xing
[i
+2] << 8) | xing
[i
+3];
637 filetime
= framecount
* tpf
;
641 if (entry
->vbrflags
& VBR_BYTES_FLAG
) /* is byte count there? */
643 int bytecount
= (xing
[i
] << 24) | (xing
[i
+1] << 16) |
644 (xing
[i
+2] << 8) | xing
[i
+3];
646 bitrate
= bytecount
* 8 / filetime
;
650 if (entry
->vbrflags
& VBR_TOC_FLAG
) /* is table-of-contents there? */
652 memcpy( entry
->toc
, xing
+i
, 100 );
655 /* Make sure we skip this frame in playback */
661 if (xing
[0] == 'V' &&
669 /* Yes, it is a FhG VBR file */
673 bytecount
= (xing
[10] << 24) | (xing
[11] << 16) |
674 (xing
[12] << 8) | xing
[13];
676 framecount
= (xing
[14] << 24) | (xing
[15] << 16) |
677 (xing
[16] << 8) | xing
[17];
679 filetime
= framecount
* tpf
;
680 bitrate
= bytecount
* 8 / filetime
;
682 /* We don't parse the TOC, since we don't yet know how to (FIXME) */
684 /* Make sure we skip this frame in playback */
690 /* Is it a LAME Info frame? */
691 if (xing
[0] == 'I' &&
696 /* Make sure we skip this frame in playback */
703 entry
->bitrate
= bitrate
;
705 /* If the file time hasn't been established, this may be a fixed
706 rate MP3, so just use the default formula */
711 * ((filesize)/(bytes per frame))*(time per frame)
713 filetime
= entry
->filesize
/bpf
*tpf
;
716 DEBUGF("Old ID3V2 length: %x\n", entry
->id3v2len
);
717 /* Adjust the tag length only if there is a tag present */
718 if(entry
->id3v2len
|| header_found
)
719 entry
->id3v2len
= bytecount
;
720 DEBUGF("New ID3V2 length: %x\n", bytecount
);
727 * Checks all relevant information (such as ID3v1 tag, ID3v2 tag, length etc)
728 * about an MP3 file and updates it's entry accordingly.
730 * Arguments: entry - the entry to check and update with the new information
734 bool mp3info(struct mp3entry
*entry
, char *filename
)
737 fd
= open(filename
, O_RDONLY
);
741 memset(entry
, 0, sizeof(struct mp3entry
));
743 strncpy(entry
->path
, filename
, sizeof(entry
->path
));
746 entry
->filesize
= getfilesize(fd
);
747 entry
->id3v2len
= getid3v2len(fd
);
751 setid3v2title(fd
, entry
);
752 entry
->length
= getsonglength(fd
, entry
);
754 entry
->id3v1len
= getid3v1len(fd
);
755 if(entry
->id3v1len
&& !entry
->title
)
756 setid3v1title(fd
, entry
);
760 if(!entry
->length
|| (entry
->filesize
< 8 ))
761 /* no song length or less than 8 bytes is hereby considered to be an
762 invalid mp3 and won't be played by us! */
768 #ifdef DEBUG_STANDALONE
770 char *secs2str(int ms
)
772 static char buffer
[32];
775 snprintf(buffer
, sizeof(buffer
), "%d:%02d.%d", secs
/60, secs
%60, ms
/100);
779 int main(int argc
, char **argv
)
782 for(i
=1; i
<argc
; i
++) {
784 if(mp3info(&mp3
, argv
[i
])) {
785 printf("Failed to get %s\n", argv
[i
]);
789 printf("****** File: %s\n"
793 " Length: %s / %d s\n"
797 mp3
.title
?mp3
.title
:"<blank>",
798 mp3
.artist
?mp3
.artist
:"<blank>",
799 mp3
.album
?mp3
.album
:"<blank>",
800 secs2str(mp3
.length
),
811 /* -----------------------------------------------------------------
813 * eval: (load-file "rockbox-mode.el")