1 /** @file plugins/mad.c
2 * @brief MP3 Length calculation
4 * This file is a subset of the debian source tarball of
5 * mpg321-0.2.10.3/mad.c - see http://mpg321.sourceforge.net/
9 mpg321 - a fully free clone of mpg123.
10 Copyright (C) 2001 Joe Drew
12 Originally based heavily upon:
13 plaympeg - Sample MPEG player using the SMPEG library
14 Copyright (C) 1999 Loki Entertainment Software
16 Also uses some code from
17 mad - MPEG audio decoder
18 Copyright (C) 2000-2001 Robert Leslie
20 Original playlist code contributed by Tobias Bengtsson <tobbe@tobbe.nu>
22 This program is free software; you can redistribute it and/or modify
23 it under the terms of the GNU General Public License as published by
24 the Free Software Foundation; either version 2 of the License, or
25 (at your option) any later version.
27 This program is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
32 You should have received a copy of the GNU General Public License
33 along with this program; if not, write to the Free Software
34 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 #include <sys/types.h>
44 /* XING parsing is from the MAD winamp input plugin */
50 unsigned char toc[100];
61 # define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
64 int parse_xing(struct xing *xing, struct mad_bitptr ptr, unsigned int bitlen)
66 if (bitlen < 64 || mad_bit_read(&ptr, 32) != XING_MAGIC)
69 xing->flags = mad_bit_read(&ptr, 32);
72 if (xing->flags & XING_FRAMES) {
76 xing->frames = mad_bit_read(&ptr, 32);
80 if (xing->flags & XING_BYTES) {
84 xing->bytes = mad_bit_read(&ptr, 32);
88 if (xing->flags & XING_TOC) {
94 for (i = 0; i < 100; ++i)
95 xing->toc[i] = mad_bit_read(&ptr, 8);
100 if (xing->flags & XING_SCALE) {
104 xing->scale = mad_bit_read(&ptr, 32);
115 /* Following two functions are adapted from mad_timer, from the
116 libmad distribution */
117 void scan_mp3(void const *ptr, ssize_t len, buffer *buf)
119 struct mad_stream stream;
120 struct mad_header header;
123 unsigned long bitrate = 0;
127 memset(&xing, 0, sizeof xing);
129 mad_stream_init(&stream);
130 mad_header_init(&header);
132 mad_stream_buffer(&stream, ptr, len);
136 /* There are three ways of calculating the length of an mp3:
137 1) Constant bitrate: One frame can provide the information
138 needed: # of frames and duration. Just see how long it
139 is and do the division.
140 2) Variable bitrate: Xing tag. It provides the number of
141 frames. Each frame has the same number of samples, so
143 3) All: Count up the frames and duration of each frames
144 by decoding each one. We do this if we've no other
145 choice, i.e. if it's a VBR file with no Xing tag.
150 if (mad_header_decode(&header, &stream) == -1)
152 if (MAD_RECOVERABLE(stream.error))
158 /* Limit xing testing to the first frame header */
159 if (!buf->num_frames++)
161 if(parse_xing(&xing, stream.anc_ptr, stream.anc_bitlen))
165 if (xing.flags & XING_FRAMES)
167 /* We use the Xing tag only for frames. If it doesn't have that
168 information, it's useless to us and we have to treat it as a
171 buf->num_frames = xing.frames;
177 /* Test the first n frames to see if this is a VBR file */
178 if (!is_vbr && !(buf->num_frames > 20))
180 if (bitrate && header.bitrate != bitrate)
187 bitrate = header.bitrate;
191 /* We have to assume it's not a VBR file if it hasn't already been
192 marked as one and we've checked n frames for different bitrates */
198 mad_timer_add(&buf->duration, header.duration);
203 double time = (len * 8.0) / (header.bitrate); /* time in seconds */
204 double timefrac = (double)time - ((long)(time));
205 long nsamples = 32 * MAD_NSBSAMPLES(&header); /* samples per frame */
207 /* samplerate is a constant */
208 buf->num_frames = (long) (time * header.samplerate / nsamples);
210 mad_timer_set(&buf->duration, (long)time, (long)(timefrac*100), 100);
215 /* modify header.duration since we don't need it anymore */
216 mad_timer_multiply(&header.duration, buf->num_frames);
217 buf->duration = header.duration;
222 /* the durations have been added up, and the number of frames
223 counted. We do nothing here. */
226 mad_header_finish(&header);
227 mad_stream_finish(&stream);