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
);