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 scan 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 bufferpos
= 0, totframelen
, framelen
;
237 unsigned short int version
;
238 char *buffer
= entry
->id3v2buf
;
239 char *tracknum
= NULL
;
241 int buffersize
= sizeof(entry
->id3v2buf
);
243 /* Bail out if the tag is shorter than 10 bytes */
244 if(entry
->id3v2len
< 10)
247 /* Read the ID3 tag version from the header */
248 lseek(fd
, 0, SEEK_SET
);
249 if(10 != read(fd
, header
, 10))
252 version
= (unsigned short int)header
[3];
254 /* Get the total ID3 tag size */
255 size
= entry
->id3v2len
- 10;
257 /* Set minimum frame size according to ID3v2 version */
264 * We must have at least minframesize bytes left for the
265 * remaining frames to be interesting
267 while(size
> minframesize
) {
268 /* Read frame header and check length */
270 if(10 != read(fd
, header
, 10))
272 /* Adjust for the 10 bytes we read */
276 framelen
= UNSYNC(header
[4], header
[5],
277 header
[6], header
[7]);
279 /* version .3 files don't use synchsafe ints for
281 framelen
= BYTES2INT(header
[4], header
[5],
282 header
[6], header
[7]);
285 if(6 != read(fd
, header
, 6))
287 /* Adjust for the 6 bytes we read */
290 framelen
= BYTES2INT(0, header
[3], header
[4], header
[5]);
293 /* Keep track of the total size */
294 totframelen
= framelen
;
299 /* If the frame is larger than the remaining buffer space we try
300 to read as much as would fit in the buffer */
301 if(framelen
>= buffersize
- bufferpos
)
302 framelen
= buffersize
- bufferpos
- 1;
304 /* Check for certain frame headers */
305 if(!strncmp(header
, "TPE1", strlen("TPE1")) ||
306 !strncmp(header
, "TP1", strlen("TP1"))) {
307 bytesread
= read(fd
, buffer
+ bufferpos
, framelen
);
308 entry
->artist
= buffer
+ bufferpos
;
309 unicode_munge(&entry
->artist
, &bytesread
);
310 entry
->artist
[bytesread
+ 1] = '\0';
311 bufferpos
+= bytesread
+ 2;
314 else if(!strncmp(header
, "TIT2", strlen("TIT2")) ||
315 !strncmp(header
, "TT2", strlen("TT2"))) {
316 bytesread
= read(fd
, buffer
+ bufferpos
, framelen
);
317 entry
->title
= buffer
+ bufferpos
;
318 unicode_munge(&entry
->title
, &bytesread
);
319 entry
->title
[bytesread
+ 1] = '\0';
320 bufferpos
+= bytesread
+ 2;
323 else if(!strncmp(header
, "TALB", strlen("TALB"))) {
324 bytesread
= read(fd
, buffer
+ bufferpos
, framelen
);
325 entry
->album
= buffer
+ bufferpos
;
326 unicode_munge(&entry
->album
, &bytesread
);
327 entry
->album
[bytesread
+ 1] = '\0';
328 bufferpos
+= bytesread
+ 2;
331 else if(!strncmp(header
, "TRCK", strlen("TRCK"))) {
332 bytesread
= read(fd
, buffer
+ bufferpos
, framelen
);
333 tracknum
= buffer
+ bufferpos
;
334 unicode_munge(&tracknum
, &bytesread
);
335 tracknum
[bytesread
+ 1] = '\0';
336 entry
->tracknum
= atoi(tracknum
);
337 bufferpos
+= bytesread
+ 1;
341 /* Unknown frame, skip it using the total size in case
344 lseek(fd
, totframelen
, SEEK_CUR
);
350 * Calculates the size of the ID3v2 tag.
352 * Arguments: file - the file to search for a tag.
354 * Returns: the size of the tag or 0 if none was found
356 static int getid3v2len(int fd
)
361 /* Make sure file has a ID3 tag */
362 if((-1 == lseek(fd
, 0, SEEK_SET
)) ||
363 (read(fd
, buf
, 6) != 6) ||
364 (strncmp(buf
, "ID3", strlen("ID3")) != 0))
367 /* Now check what the ID3v2 size field says */
368 else if(read(fd
, buf
, 4) != 4)
371 offset
= UNSYNC(buf
[0], buf
[1], buf
[2], buf
[3]) + 10;
376 static int getfilesize(int fd
)
380 /* seek to the end of it */
381 size
= lseek(fd
, 0, SEEK_END
);
383 return 0; /* unknown */
389 * Calculates the size of the ID3v1 tag.
391 * Arguments: file - the file to search for a tag.
393 * Returns: the size of the tag or 0 if none was found
395 static int getid3v1len(int fd
)
400 /* Check if we find "TAG" 128 bytes from EOF */
401 if((lseek(fd
, -128, SEEK_END
) == -1) ||
402 (read(fd
, buf
, 3) != 3) ||
403 (strncmp(buf
, "TAG", 3) != 0))
411 /* check if 'head' is a valid mp3 frame header */
412 static bool mp3frameheader(unsigned long head
)
414 if ((head
& 0xffe00000) != 0xffe00000) /* bad sync? */
416 if (!((head
>> 17) & 3)) /* no layer? */
418 if (((head
>> 12) & 0xf) == 0xf) /* bad bitrate? */
420 if (!((head
>> 12) & 0xf)) /* no bitrate? */
422 if (((head
>> 10) & 0x3) == 0x3) /* bad sample rate? */
424 if (((head
>> 19) & 1) == 1 &&
425 ((head
>> 17) & 3) == 3 &&
426 ((head
>> 16) & 1) == 1)
428 if ((head
& 0xffff0000) == 0xfffe0000)
435 * Calculates the length (in milliseconds) of an MP3 file.
437 * Modified to only use integers.
439 * Arguments: file - the file to calculate the length upon
440 * entry - the entry to update with the length
442 * Returns: the song length in milliseconds,
443 * 0 means that it couldn't be calculated
445 static int getsonglength(int fd
, struct mp3entry
*entry
)
447 unsigned int filetime
= 0;
448 unsigned long header
=0;
450 unsigned char frame
[156];
466 int bittable
; /* which bitrate table to use */
467 bool header_found
= false;
472 /* Start searching after ID3v2 header */
473 if(-1 == lseek(fd
, entry
->id3v2len
, SEEK_SET
))
476 /* Fill up header with first 24 bits */
477 for(version
= 0; version
< 3; version
++) {
479 if(!read(fd
, &tmp
, 1))
484 /* Loop trough file until we find a frame header */
485 bytecount
= entry
->id3v2len
- 1;
486 bytelimit
= entry
->id3v2len
+ 0x20000;
490 if(!read(fd
, &tmp
, 1))
494 /* Quit if we haven't found a valid header within 128K */
496 if(bytecount
> bytelimit
)
498 } while(!mp3frameheader(header
));
501 * Some files are filled with garbage in the beginning,
502 * if the bitrate index of the header is binary 1111
503 * that is a good indicator
505 if((header
& 0xF000) == 0xF000)
508 /* MPEG Audio Version */
509 switch((header
& 0x180000) >> 19) {
511 /* MPEG version 2.5 is not an official standard */
512 version
= MPEG_VERSION2_5
;
513 bittable
= MPEG_VERSION2
; /* use the V2 bit rate table */
517 /* MPEG version 2 (ISO/IEC 13818-3) */
518 version
= MPEG_VERSION2
;
519 bittable
= MPEG_VERSION2
;
523 /* MPEG version 1 (ISO/IEC 11172-3) */
524 version
= MPEG_VERSION1
;
525 bittable
= MPEG_VERSION1
;
532 switch((header
& 0x060000) >> 17) {
547 bitindex
= (header
& 0xF000) >> 12;
548 bitrate
= bitrate_table
[bittable
-1][layer
-1][bitindex
];
552 /* Sampling frequency */
553 freqindex
= (header
& 0x0C00) >> 10;
554 frequency
= freqtab
[version
][freqindex
];
559 DEBUGF( "Version %i, lay %i, biti %i, bitr %i, freqi %i, freq %i, chmode %d\n",
560 version
, layer
, bitindex
, bitrate
, freqindex
, frequency
, chmode
);
562 entry
->version
= version
;
563 entry
->layer
= layer
;
564 entry
->frequency
= frequency
;
566 /* Calculate bytes per frame, calculation depends on layer */
569 bpf
= bitrate_table
[bittable
- 1][layer
- 1][bitindex
];
571 bpf
/= freqtab
[version
][freqindex
] << (bittable
- 1);
575 bpf
= bitrate_table
[bittable
- 1][layer
- 1][bitindex
];
577 bpf
/= freqtab
[version
][freqindex
] << (bittable
- 1);
583 /* Calculate time per frame */
584 tpf
= bs
[layer
] / (freqtab
[version
][freqindex
] << (bittable
- 1));
589 /* OK, we have found a frame. Let's see if it has a Xing header */
590 if(read(fd
, frame
, sizeof frame
) < 0)
593 /* Channel mode (stereo/mono) */
594 chmode
= (header
& 0xc0) >> 6;
596 /* calculate position of Xing VBR header */
597 if ( version
== 1 ) {
598 if ( chmode
== 3 ) /* mono */
604 if ( chmode
== 3 ) /* mono */
610 if (xing
[0] == 'X' &&
615 int i
= 8; /* Where to start parsing info */
617 /* Yes, it is a VBR file */
619 entry
->vbrflags
= xing
[7];
621 if (entry
->vbrflags
& VBR_FRAMES_FLAG
) /* Is the frame count there? */
623 int framecount
= (xing
[i
] << 24) | (xing
[i
+1] << 16) |
624 (xing
[i
+2] << 8) | xing
[i
+3];
626 filetime
= framecount
* tpf
;
630 if (entry
->vbrflags
& VBR_BYTES_FLAG
) /* is byte count there? */
632 int bytecount
= (xing
[i
] << 24) | (xing
[i
+1] << 16) |
633 (xing
[i
+2] << 8) | xing
[i
+3];
635 bitrate
= bytecount
* 8 / filetime
;
639 if (entry
->vbrflags
& VBR_TOC_FLAG
) /* is table-of-contents there? */
641 memcpy( entry
->toc
, xing
+i
, 100 );
644 /* Make sure we skip this frame in playback */
650 if (xing
[0] == 'V' &&
658 /* Yes, it is a FhG VBR file */
662 bytecount
= (xing
[10] << 24) | (xing
[11] << 16) |
663 (xing
[12] << 8) | xing
[13];
665 framecount
= (xing
[14] << 24) | (xing
[15] << 16) |
666 (xing
[16] << 8) | xing
[17];
668 filetime
= framecount
* tpf
;
669 bitrate
= bytecount
* 8 / filetime
;
671 /* We don't parse the TOC, since we don't yet know how to (FIXME) */
673 /* Make sure we skip this frame in playback */
679 /* Is it a LAME Info frame? */
680 if (xing
[0] == 'I' &&
685 /* Make sure we skip this frame in playback */
692 entry
->bitrate
= bitrate
;
694 /* If the file time hasn't been established, this may be a fixed
695 rate MP3, so just use the default formula */
700 * ((filesize)/(bytes per frame))*(time per frame)
702 filetime
= entry
->filesize
/bpf
*tpf
;
705 /* Update the seek point for the first playable frame */
706 entry
->first_frame_offset
= bytecount
;
707 DEBUGF("First frame is at %x\n", entry
->first_frame_offset
);
714 * Checks all relevant information (such as ID3v1 tag, ID3v2 tag, length etc)
715 * about an MP3 file and updates it's entry accordingly.
717 * Arguments: entry - the entry to check and update with the new information
721 bool mp3info(struct mp3entry
*entry
, char *filename
)
724 fd
= open(filename
, O_RDONLY
);
728 memset(entry
, 0, sizeof(struct mp3entry
));
730 strncpy(entry
->path
, filename
, sizeof(entry
->path
));
733 entry
->filesize
= getfilesize(fd
);
734 entry
->id3v2len
= getid3v2len(fd
);
738 setid3v2title(fd
, entry
);
739 entry
->length
= getsonglength(fd
, entry
);
741 entry
->id3v1len
= getid3v1len(fd
);
742 if(entry
->id3v1len
&& !entry
->title
)
743 setid3v1title(fd
, entry
);
747 if(!entry
->length
|| (entry
->filesize
< 8 ))
748 /* no song length or less than 8 bytes is hereby considered to be an
749 invalid mp3 and won't be played by us! */
755 #ifdef DEBUG_STANDALONE
757 char *secs2str(int ms
)
759 static char buffer
[32];
762 snprintf(buffer
, sizeof(buffer
), "%d:%02d.%d", secs
/60, secs
%60, ms
/100);
766 int main(int argc
, char **argv
)
769 for(i
=1; i
<argc
; i
++) {
771 if(mp3info(&mp3
, argv
[i
])) {
772 printf("Failed to get %s\n", argv
[i
]);
776 printf("****** File: %s\n"
780 " Length: %s / %d s\n"
784 mp3
.title
?mp3
.title
:"<blank>",
785 mp3
.artist
?mp3
.artist
:"<blank>",
786 mp3
.album
?mp3
.album
:"<blank>",
787 secs2str(mp3
.length
),
798 /* -----------------------------------------------------------------
800 * eval: (load-file "rockbox-mode.el")