1 /* This file is a subset of the debian source tarball of mpg321-0.2.10.3/mad.c
2 - see http://mpg321.sourceforge.net/ */
5 mpg321 - a fully free clone of mpg123.
6 Copyright (C) 2001 Joe Drew
8 Originally based heavily upon:
9 plaympeg - Sample MPEG player using the SMPEG library
10 Copyright (C) 1999 Loki Entertainment Software
12 Also uses some code from
13 mad - MPEG audio decoder
14 Copyright (C) 2000-2001 Robert Leslie
16 Original playlist code contributed by Tobias Bengtsson <tobbe@tobbe.nu>
18 This program is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or
21 (at your option) any later version.
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, write to the Free Software
30 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 #include <sys/types.h>
40 /* XING parsing is from the MAD winamp input plugin */
46 unsigned char toc[100];
57 # define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
60 int parse_xing(struct xing *xing, struct mad_bitptr ptr, unsigned int bitlen)
62 if (bitlen < 64 || mad_bit_read(&ptr, 32) != XING_MAGIC)
65 xing->flags = mad_bit_read(&ptr, 32);
68 if (xing->flags & XING_FRAMES) {
72 xing->frames = mad_bit_read(&ptr, 32);
76 if (xing->flags & XING_BYTES) {
80 xing->bytes = mad_bit_read(&ptr, 32);
84 if (xing->flags & XING_TOC) {
90 for (i = 0; i < 100; ++i)
91 xing->toc[i] = mad_bit_read(&ptr, 8);
96 if (xing->flags & XING_SCALE) {
100 xing->scale = mad_bit_read(&ptr, 32);
111 /* Following two functions are adapted from mad_timer, from the
112 libmad distribution */
113 void scan_mp3(void const *ptr, ssize_t len, buffer *buf)
115 struct mad_stream stream;
116 struct mad_header header;
119 unsigned long bitrate = 0;
123 memset(&xing, 0, sizeof xing);
125 mad_stream_init(&stream);
126 mad_header_init(&header);
128 mad_stream_buffer(&stream, ptr, len);
132 /* There are three ways of calculating the length of an mp3:
133 1) Constant bitrate: One frame can provide the information
134 needed: # of frames and duration. Just see how long it
135 is and do the division.
136 2) Variable bitrate: Xing tag. It provides the number of
137 frames. Each frame has the same number of samples, so
139 3) All: Count up the frames and duration of each frames
140 by decoding each one. We do this if we've no other
141 choice, i.e. if it's a VBR file with no Xing tag.
146 if (mad_header_decode(&header, &stream) == -1)
148 if (MAD_RECOVERABLE(stream.error))
154 /* Limit xing testing to the first frame header */
155 if (!buf->num_frames++)
157 if(parse_xing(&xing, stream.anc_ptr, stream.anc_bitlen))
161 if (xing.flags & XING_FRAMES)
163 /* We use the Xing tag only for frames. If it doesn't have that
164 information, it's useless to us and we have to treat it as a
167 buf->num_frames = xing.frames;
173 /* Test the first n frames to see if this is a VBR file */
174 if (!is_vbr && !(buf->num_frames > 20))
176 if (bitrate && header.bitrate != bitrate)
183 bitrate = header.bitrate;
187 /* We have to assume it's not a VBR file if it hasn't already been
188 marked as one and we've checked n frames for different bitrates */
194 mad_timer_add(&buf->duration, header.duration);
199 double time = (len * 8.0) / (header.bitrate); /* time in seconds */
200 double timefrac = (double)time - ((long)(time));
201 long nsamples = 32 * MAD_NSBSAMPLES(&header); /* samples per frame */
203 /* samplerate is a constant */
204 buf->num_frames = (long) (time * header.samplerate / nsamples);
206 mad_timer_set(&buf->duration, (long)time, (long)(timefrac*100), 100);
211 /* modify header.duration since we don't need it anymore */
212 mad_timer_multiply(&header.duration, buf->num_frames);
213 buf->duration = header.duration;
218 /* the durations have been added up, and the number of frames
219 counted. We do nothing here. */
222 mad_header_finish(&header);
223 mad_stream_finish(&stream);