1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Daniel Stenberg
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 * Parts of this code has been stolen from the Ample project and was written
23 * by David H�deman. It has since been extended and enhanced pretty much by
24 * all sorts of friendly Rockbox people.
28 /* tagResolver and associated code copyright 2003 Thomas Paul Diffenbach
35 #include "string-extra.h"
43 #include "metadata_common.h"
44 #include "metadata_parsers.h"
47 * Calculates the length (in milliseconds) of an MP3 file.
49 * Modified to only use integers.
51 * Arguments: file - the file to calculate the length upon
52 * entry - the entry to update with the length
54 * Returns: the song length in milliseconds,
55 * 0 means that it couldn't be calculated
57 static int getsonglength(int fd
, struct mp3entry
*entry
)
59 unsigned long filetime
= 0;
63 /* Start searching after ID3v2 header */
64 if(-1 == lseek(fd
, entry
->id3v2len
, SEEK_SET
))
67 bytecount
= get_mp3file_info(fd
, &info
);
69 logf("Space between ID3V2 tag and first audio frame: 0x%lx bytes",
75 bytecount
+= entry
->id3v2len
;
77 /* Validate byte count, in case the file has been edited without
78 * updating the header.
82 const unsigned long expected
= entry
->filesize
- entry
->id3v1len
84 const unsigned long diff
= MAX(10240, info
.byte_count
/ 20);
86 if ((info
.byte_count
> expected
+ diff
)
87 || (info
.byte_count
< expected
- diff
))
89 logf("Note: info.byte_count differs from expected value by "
90 "%ld bytes", labs((long) (expected
- info
.byte_count
)));
96 /* Even if the bitrate was based on "known bad" values, it
97 * should still be better for VBR files than using the bitrate
98 * of the first audio frame.
103 entry
->bitrate
= info
.bitrate
;
104 entry
->frequency
= info
.frequency
;
105 entry
->version
= info
.version
;
106 entry
->layer
= info
.layer
;
107 switch(entry
->layer
) {
108 #if CONFIG_CODEC==SWCODEC
110 entry
->codectype
=AFMT_MPA_L1
;
114 entry
->codectype
=AFMT_MPA_L2
;
117 entry
->codectype
=AFMT_MPA_L3
;
121 /* If the file time hasn't been established, this may be a fixed
122 rate MP3, so just use the default formula */
124 filetime
= info
.file_time
;
128 /* Prevent a division by zero */
129 if (info
.bitrate
< 8)
132 filetime
= (entry
->filesize
- bytecount
) / (info
.bitrate
/ 8);
133 /* bitrate is in kbps so this delivers milliseconds. Doing bitrate / 8
134 * instead of filesize * 8 is exact, because mpeg audio bitrates are
135 * always multiples of 8, and it avoids overflows. */
138 entry
->frame_count
= info
.frame_count
;
140 entry
->vbr
= info
.is_vbr
;
141 entry
->has_toc
= info
.has_toc
;
143 #if CONFIG_CODEC==SWCODEC
144 if (!entry
->lead_trim
)
145 entry
->lead_trim
= info
.enc_delay
;
146 if (!entry
->tail_trim
)
147 entry
->tail_trim
= info
.enc_padding
;
150 memcpy(entry
->toc
, info
.toc
, sizeof(info
.toc
));
152 entry
->vbr_header_pos
= info
.vbr_header_pos
;
154 /* Update the seek point for the first playable frame */
155 entry
->first_frame_offset
= bytecount
;
156 logf("First frame is at %lx", entry
->first_frame_offset
);
162 * Checks all relevant information (such as ID3v1 tag, ID3v2 tag, length etc)
163 * about an MP3 file and updates it's entry accordingly.
165 Note, that this returns true for successful, false for error! */
166 bool get_mp3_metadata(int fd
, struct mp3entry
*entry
)
169 entry
->filesize
= filesize(fd
);
170 entry
->id3v2len
= getid3v2len(fd
);
175 setid3v2title(fd
, entry
);
176 int len
= getsonglength(fd
, entry
);
181 /* Subtract the meta information from the file size to get
182 the true size of the MP3 stream */
183 entry
->filesize
-= entry
->first_frame_offset
;
185 /* only seek to end of file if no id3v2 tags were found */
186 if (!entry
->id3v2len
) {
187 setid3v1title(fd
, entry
);
190 if(!entry
->length
|| (entry
->filesize
< 8 ))
191 /* no song length or less than 8 bytes is hereby considered to be an
192 invalid mp3 and won't be played by us! */