MP3 Player without external hardware MP3 Player without external hardware. A software based MP3 player based on a modified version of libmad. Mono output (at the moment) via AnalogOut. Files are read from an USB drive. This is a demo program, it plays only one file at the moment. Documentation is in "main.cpp" and "config.h"

Dependencies:   mbed

Committer:
Gruenfrosch
Date:
Sat Nov 27 17:27:33 2010 +0000
Revision:
2:f28cf0afd021
Parent:
0:7627c79db971
Version 3:
* moved another memory block into AHB RAM, giving more room for
* stereo buffer.
* moved content of decode() to main()
* decoding is now safe to be called multiple times (bug in older versions)
* Output routine now fills stereo buffer, DAC output sums channels,
* just for demonstration that stereo output could go here

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Gruenfrosch 0:7627c79db971 1 /*
Gruenfrosch 0:7627c79db971 2 * libmad - MPEG audio decoder library
Gruenfrosch 0:7627c79db971 3 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
Gruenfrosch 0:7627c79db971 4 *
Gruenfrosch 0:7627c79db971 5 * This program is free software; you can redistribute it and/or modify
Gruenfrosch 0:7627c79db971 6 * it under the terms of the GNU General Public License as published by
Gruenfrosch 0:7627c79db971 7 * the Free Software Foundation; either version 2 of the License, or
Gruenfrosch 0:7627c79db971 8 * (at your option) any later version.
Gruenfrosch 0:7627c79db971 9 *
Gruenfrosch 0:7627c79db971 10 * This program is distributed in the hope that it will be useful,
Gruenfrosch 0:7627c79db971 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Gruenfrosch 0:7627c79db971 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Gruenfrosch 0:7627c79db971 13 * GNU General Public License for more details.
Gruenfrosch 0:7627c79db971 14 *
Gruenfrosch 0:7627c79db971 15 * You should have received a copy of the GNU General Public License
Gruenfrosch 0:7627c79db971 16 * along with this program; if not, write to the Free Software
Gruenfrosch 0:7627c79db971 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Gruenfrosch 0:7627c79db971 18 *
Gruenfrosch 0:7627c79db971 19 * $Id: frame.c,v 1.1 2010/11/23 20:12:57 andy Exp $
Gruenfrosch 0:7627c79db971 20 */
Gruenfrosch 0:7627c79db971 21
Gruenfrosch 0:7627c79db971 22 # include "config.h"
Gruenfrosch 0:7627c79db971 23
Gruenfrosch 0:7627c79db971 24 # include "global.h"
Gruenfrosch 0:7627c79db971 25
Gruenfrosch 0:7627c79db971 26 # include <stdlib.h>
Gruenfrosch 0:7627c79db971 27
Gruenfrosch 0:7627c79db971 28 # include "bit.h"
Gruenfrosch 0:7627c79db971 29 # include "stream.h"
Gruenfrosch 0:7627c79db971 30 # include "frame.h"
Gruenfrosch 0:7627c79db971 31 # include "timer.h"
Gruenfrosch 0:7627c79db971 32 # include "layer12.h"
Gruenfrosch 0:7627c79db971 33 # include "layer3.h"
Gruenfrosch 0:7627c79db971 34
Gruenfrosch 0:7627c79db971 35 static
Gruenfrosch 0:7627c79db971 36 unsigned long const bitrate_table[5][15] = {
Gruenfrosch 0:7627c79db971 37 /* MPEG-1 */
Gruenfrosch 0:7627c79db971 38 { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */
Gruenfrosch 0:7627c79db971 39 256000, 288000, 320000, 352000, 384000, 416000, 448000 },
Gruenfrosch 0:7627c79db971 40 { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */
Gruenfrosch 0:7627c79db971 41 128000, 160000, 192000, 224000, 256000, 320000, 384000 },
Gruenfrosch 0:7627c79db971 42 { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */
Gruenfrosch 0:7627c79db971 43 112000, 128000, 160000, 192000, 224000, 256000, 320000 },
Gruenfrosch 0:7627c79db971 44
Gruenfrosch 0:7627c79db971 45 /* MPEG-2 LSF */
Gruenfrosch 0:7627c79db971 46 { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */
Gruenfrosch 0:7627c79db971 47 128000, 144000, 160000, 176000, 192000, 224000, 256000 },
Gruenfrosch 0:7627c79db971 48 { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */
Gruenfrosch 0:7627c79db971 49 64000, 80000, 96000, 112000, 128000, 144000, 160000 } /* II & III */
Gruenfrosch 0:7627c79db971 50 };
Gruenfrosch 0:7627c79db971 51
Gruenfrosch 0:7627c79db971 52 static
Gruenfrosch 0:7627c79db971 53 unsigned int const samplerate_table[3] = { 44100, 48000, 32000 };
Gruenfrosch 0:7627c79db971 54
Gruenfrosch 0:7627c79db971 55 static
Gruenfrosch 0:7627c79db971 56 int (*const decoder_table[3])(struct mad_stream *, struct mad_frame *) = {
Gruenfrosch 0:7627c79db971 57 mad_layer_I,
Gruenfrosch 0:7627c79db971 58 mad_layer_II,
Gruenfrosch 0:7627c79db971 59 mad_layer_III
Gruenfrosch 0:7627c79db971 60 };
Gruenfrosch 0:7627c79db971 61
Gruenfrosch 0:7627c79db971 62 /*
Gruenfrosch 0:7627c79db971 63 * NAME: header->init()
Gruenfrosch 0:7627c79db971 64 * DESCRIPTION: initialize header struct
Gruenfrosch 0:7627c79db971 65 */
Gruenfrosch 0:7627c79db971 66 void mad_header_init(struct mad_header *header)
Gruenfrosch 0:7627c79db971 67 {
Gruenfrosch 0:7627c79db971 68 header->layer = (enum mad_layer)0;
Gruenfrosch 0:7627c79db971 69 header->mode = (enum mad_mode)0;
Gruenfrosch 0:7627c79db971 70 header->mode_extension = 0;
Gruenfrosch 0:7627c79db971 71 header->emphasis = (enum mad_emphasis)0;
Gruenfrosch 0:7627c79db971 72
Gruenfrosch 0:7627c79db971 73 header->bitrate = 0;
Gruenfrosch 0:7627c79db971 74 header->samplerate = 0;
Gruenfrosch 0:7627c79db971 75
Gruenfrosch 0:7627c79db971 76 header->crc_check = 0;
Gruenfrosch 0:7627c79db971 77 header->crc_target = 0;
Gruenfrosch 0:7627c79db971 78
Gruenfrosch 0:7627c79db971 79 header->flags = 0;
Gruenfrosch 0:7627c79db971 80 header->private_bits = 0;
Gruenfrosch 0:7627c79db971 81
Gruenfrosch 0:7627c79db971 82 header->duration = mad_timer_zero;
Gruenfrosch 0:7627c79db971 83 }
Gruenfrosch 0:7627c79db971 84
Gruenfrosch 0:7627c79db971 85 /*
Gruenfrosch 0:7627c79db971 86 * NAME: frame->init()
Gruenfrosch 0:7627c79db971 87 * DESCRIPTION: initialize frame struct
Gruenfrosch 0:7627c79db971 88 */
Gruenfrosch 0:7627c79db971 89 void mad_frame_init(struct mad_frame *frame)
Gruenfrosch 0:7627c79db971 90 {
Gruenfrosch 0:7627c79db971 91 mad_header_init(&frame->header);
Gruenfrosch 0:7627c79db971 92
Gruenfrosch 0:7627c79db971 93 frame->options = 0;
Gruenfrosch 0:7627c79db971 94
Gruenfrosch 2:f28cf0afd021 95 //### frame->overlap = 0;
Gruenfrosch 0:7627c79db971 96 mad_frame_mute(frame);
Gruenfrosch 0:7627c79db971 97 }
Gruenfrosch 0:7627c79db971 98
Gruenfrosch 0:7627c79db971 99 /*
Gruenfrosch 0:7627c79db971 100 * NAME: frame->finish()
Gruenfrosch 0:7627c79db971 101 * DESCRIPTION: deallocate any dynamic memory associated with frame
Gruenfrosch 0:7627c79db971 102 */
Gruenfrosch 0:7627c79db971 103 void mad_frame_finish(struct mad_frame *frame)
Gruenfrosch 0:7627c79db971 104 {
Gruenfrosch 0:7627c79db971 105 mad_header_finish(&frame->header);
Gruenfrosch 2:f28cf0afd021 106 /* ###
Gruenfrosch 0:7627c79db971 107 if (frame->overlap) {
Gruenfrosch 0:7627c79db971 108 free(frame->overlap);
Gruenfrosch 0:7627c79db971 109 frame->overlap = 0;
Gruenfrosch 0:7627c79db971 110 }
Gruenfrosch 2:f28cf0afd021 111 */
Gruenfrosch 0:7627c79db971 112 }
Gruenfrosch 0:7627c79db971 113
Gruenfrosch 0:7627c79db971 114 /*
Gruenfrosch 0:7627c79db971 115 * NAME: decode_header()
Gruenfrosch 0:7627c79db971 116 * DESCRIPTION: read header data and following CRC word
Gruenfrosch 0:7627c79db971 117 */
Gruenfrosch 0:7627c79db971 118 static
Gruenfrosch 0:7627c79db971 119 int decode_header(struct mad_header *header, struct mad_stream *stream)
Gruenfrosch 0:7627c79db971 120 {
Gruenfrosch 0:7627c79db971 121 unsigned int index;
Gruenfrosch 0:7627c79db971 122
Gruenfrosch 0:7627c79db971 123 header->flags = 0;
Gruenfrosch 0:7627c79db971 124 header->private_bits = 0;
Gruenfrosch 0:7627c79db971 125
Gruenfrosch 0:7627c79db971 126 /* header() */
Gruenfrosch 0:7627c79db971 127
Gruenfrosch 0:7627c79db971 128 /* syncword */
Gruenfrosch 0:7627c79db971 129 mad_bit_skip(&stream->ptr, 11);
Gruenfrosch 0:7627c79db971 130
Gruenfrosch 0:7627c79db971 131 /* MPEG 2.5 indicator (really part of syncword) */
Gruenfrosch 0:7627c79db971 132 if (mad_bit_read(&stream->ptr, 1) == 0)
Gruenfrosch 0:7627c79db971 133 header->flags |= MAD_FLAG_MPEG_2_5_EXT;
Gruenfrosch 0:7627c79db971 134
Gruenfrosch 0:7627c79db971 135 /* ID */
Gruenfrosch 0:7627c79db971 136 if (mad_bit_read(&stream->ptr, 1) == 0)
Gruenfrosch 0:7627c79db971 137 header->flags |= MAD_FLAG_LSF_EXT;
Gruenfrosch 0:7627c79db971 138 else if (header->flags & MAD_FLAG_MPEG_2_5_EXT) {
Gruenfrosch 0:7627c79db971 139 stream->error = MAD_ERROR_LOSTSYNC;
Gruenfrosch 0:7627c79db971 140 return -1;
Gruenfrosch 0:7627c79db971 141 }
Gruenfrosch 0:7627c79db971 142
Gruenfrosch 0:7627c79db971 143 /* layer */
Gruenfrosch 0:7627c79db971 144 header->layer = (enum mad_layer)(4 - mad_bit_read(&stream->ptr, 2));
Gruenfrosch 0:7627c79db971 145
Gruenfrosch 0:7627c79db971 146 if (header->layer == 4) {
Gruenfrosch 0:7627c79db971 147 stream->error = MAD_ERROR_BADLAYER;
Gruenfrosch 0:7627c79db971 148 return -1;
Gruenfrosch 0:7627c79db971 149 }
Gruenfrosch 0:7627c79db971 150
Gruenfrosch 0:7627c79db971 151 /* protection_bit */
Gruenfrosch 0:7627c79db971 152 if (mad_bit_read(&stream->ptr, 1) == 0) {
Gruenfrosch 0:7627c79db971 153 header->flags |= MAD_FLAG_PROTECTION;
Gruenfrosch 0:7627c79db971 154 header->crc_check = mad_bit_crc(stream->ptr, 16, 0xffff);
Gruenfrosch 0:7627c79db971 155 }
Gruenfrosch 0:7627c79db971 156
Gruenfrosch 0:7627c79db971 157 /* bitrate_index */
Gruenfrosch 0:7627c79db971 158 index = mad_bit_read(&stream->ptr, 4);
Gruenfrosch 0:7627c79db971 159
Gruenfrosch 0:7627c79db971 160 if (index == 15) {
Gruenfrosch 0:7627c79db971 161 stream->error = MAD_ERROR_BADBITRATE;
Gruenfrosch 0:7627c79db971 162 return -1;
Gruenfrosch 0:7627c79db971 163 }
Gruenfrosch 0:7627c79db971 164
Gruenfrosch 0:7627c79db971 165 if (header->flags & MAD_FLAG_LSF_EXT)
Gruenfrosch 0:7627c79db971 166 header->bitrate = bitrate_table[3 + (header->layer >> 1)][index];
Gruenfrosch 0:7627c79db971 167 else
Gruenfrosch 0:7627c79db971 168 header->bitrate = bitrate_table[header->layer - 1][index];
Gruenfrosch 0:7627c79db971 169
Gruenfrosch 0:7627c79db971 170 /* sampling_frequency */
Gruenfrosch 0:7627c79db971 171 index = mad_bit_read(&stream->ptr, 2);
Gruenfrosch 0:7627c79db971 172
Gruenfrosch 0:7627c79db971 173 if (index == 3) {
Gruenfrosch 0:7627c79db971 174 stream->error = MAD_ERROR_BADSAMPLERATE;
Gruenfrosch 0:7627c79db971 175 return -1;
Gruenfrosch 0:7627c79db971 176 }
Gruenfrosch 0:7627c79db971 177
Gruenfrosch 0:7627c79db971 178 header->samplerate = samplerate_table[index];
Gruenfrosch 0:7627c79db971 179
Gruenfrosch 0:7627c79db971 180 if (header->flags & MAD_FLAG_LSF_EXT) {
Gruenfrosch 0:7627c79db971 181 header->samplerate /= 2;
Gruenfrosch 0:7627c79db971 182
Gruenfrosch 0:7627c79db971 183 if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
Gruenfrosch 0:7627c79db971 184 header->samplerate /= 2;
Gruenfrosch 0:7627c79db971 185 }
Gruenfrosch 0:7627c79db971 186
Gruenfrosch 0:7627c79db971 187 /* padding_bit */
Gruenfrosch 0:7627c79db971 188 if (mad_bit_read(&stream->ptr, 1))
Gruenfrosch 0:7627c79db971 189 header->flags |= MAD_FLAG_PADDING;
Gruenfrosch 0:7627c79db971 190
Gruenfrosch 0:7627c79db971 191 /* private_bit */
Gruenfrosch 0:7627c79db971 192 if (mad_bit_read(&stream->ptr, 1))
Gruenfrosch 0:7627c79db971 193 header->private_bits |= MAD_PRIVATE_HEADER;
Gruenfrosch 0:7627c79db971 194
Gruenfrosch 0:7627c79db971 195 /* mode */
Gruenfrosch 0:7627c79db971 196 header->mode = (enum mad_mode)(3 - mad_bit_read(&stream->ptr, 2));
Gruenfrosch 0:7627c79db971 197
Gruenfrosch 0:7627c79db971 198 /* mode_extension */
Gruenfrosch 0:7627c79db971 199 header->mode_extension = mad_bit_read(&stream->ptr, 2);
Gruenfrosch 0:7627c79db971 200
Gruenfrosch 0:7627c79db971 201 /* copyright */
Gruenfrosch 0:7627c79db971 202 if (mad_bit_read(&stream->ptr, 1))
Gruenfrosch 0:7627c79db971 203 header->flags |= MAD_FLAG_COPYRIGHT;
Gruenfrosch 0:7627c79db971 204
Gruenfrosch 0:7627c79db971 205 /* original/copy */
Gruenfrosch 0:7627c79db971 206 if (mad_bit_read(&stream->ptr, 1))
Gruenfrosch 0:7627c79db971 207 header->flags |= MAD_FLAG_ORIGINAL;
Gruenfrosch 0:7627c79db971 208
Gruenfrosch 0:7627c79db971 209 /* emphasis */
Gruenfrosch 0:7627c79db971 210 header->emphasis = (enum mad_emphasis)mad_bit_read(&stream->ptr, 2);
Gruenfrosch 0:7627c79db971 211
Gruenfrosch 0:7627c79db971 212 # if defined(OPT_STRICT)
Gruenfrosch 0:7627c79db971 213 /*
Gruenfrosch 0:7627c79db971 214 * ISO/IEC 11172-3 says this is a reserved emphasis value, but
Gruenfrosch 0:7627c79db971 215 * streams exist which use it anyway. Since the value is not important
Gruenfrosch 0:7627c79db971 216 * to the decoder proper, we allow it unless OPT_STRICT is defined.
Gruenfrosch 0:7627c79db971 217 */
Gruenfrosch 0:7627c79db971 218 if (header->emphasis == MAD_EMPHASIS_RESERVED) {
Gruenfrosch 0:7627c79db971 219 stream->error = MAD_ERROR_BADEMPHASIS;
Gruenfrosch 0:7627c79db971 220 return -1;
Gruenfrosch 0:7627c79db971 221 }
Gruenfrosch 0:7627c79db971 222 # endif
Gruenfrosch 0:7627c79db971 223
Gruenfrosch 0:7627c79db971 224 /* error_check() */
Gruenfrosch 0:7627c79db971 225
Gruenfrosch 0:7627c79db971 226 /* crc_check */
Gruenfrosch 0:7627c79db971 227 if (header->flags & MAD_FLAG_PROTECTION)
Gruenfrosch 0:7627c79db971 228 header->crc_target = mad_bit_read(&stream->ptr, 16);
Gruenfrosch 0:7627c79db971 229
Gruenfrosch 0:7627c79db971 230 return 0;
Gruenfrosch 0:7627c79db971 231 }
Gruenfrosch 0:7627c79db971 232
Gruenfrosch 0:7627c79db971 233 /*
Gruenfrosch 0:7627c79db971 234 * NAME: free_bitrate()
Gruenfrosch 0:7627c79db971 235 * DESCRIPTION: attempt to discover the bitstream's free bitrate
Gruenfrosch 0:7627c79db971 236 */
Gruenfrosch 0:7627c79db971 237 static
Gruenfrosch 0:7627c79db971 238 int free_bitrate(struct mad_stream *stream, struct mad_header const *header)
Gruenfrosch 0:7627c79db971 239 {
Gruenfrosch 0:7627c79db971 240 struct mad_bitptr keep_ptr;
Gruenfrosch 0:7627c79db971 241 unsigned long rate = 0;
Gruenfrosch 0:7627c79db971 242 unsigned int pad_slot, slots_per_frame;
Gruenfrosch 0:7627c79db971 243 unsigned char const *ptr = 0;
Gruenfrosch 0:7627c79db971 244
Gruenfrosch 0:7627c79db971 245 keep_ptr = stream->ptr;
Gruenfrosch 0:7627c79db971 246
Gruenfrosch 0:7627c79db971 247 pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0;
Gruenfrosch 0:7627c79db971 248 slots_per_frame = (header->layer == MAD_LAYER_III &&
Gruenfrosch 0:7627c79db971 249 (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144;
Gruenfrosch 0:7627c79db971 250
Gruenfrosch 0:7627c79db971 251 while (mad_stream_sync(stream) == 0) {
Gruenfrosch 0:7627c79db971 252 struct mad_stream peek_stream;
Gruenfrosch 0:7627c79db971 253 struct mad_header peek_header;
Gruenfrosch 0:7627c79db971 254
Gruenfrosch 0:7627c79db971 255 peek_stream = *stream;
Gruenfrosch 0:7627c79db971 256 peek_header = *header;
Gruenfrosch 0:7627c79db971 257
Gruenfrosch 0:7627c79db971 258 if (decode_header(&peek_header, &peek_stream) == 0 &&
Gruenfrosch 0:7627c79db971 259 peek_header.layer == header->layer &&
Gruenfrosch 0:7627c79db971 260 peek_header.samplerate == header->samplerate) {
Gruenfrosch 0:7627c79db971 261 unsigned int N;
Gruenfrosch 0:7627c79db971 262
Gruenfrosch 0:7627c79db971 263 ptr = mad_bit_nextbyte(&stream->ptr);
Gruenfrosch 0:7627c79db971 264
Gruenfrosch 0:7627c79db971 265 N = ptr - stream->this_frame;
Gruenfrosch 0:7627c79db971 266
Gruenfrosch 0:7627c79db971 267 if (header->layer == MAD_LAYER_I) {
Gruenfrosch 0:7627c79db971 268 rate = (unsigned long) header->samplerate *
Gruenfrosch 0:7627c79db971 269 (N - 4 * pad_slot + 4) / 48 / 1000;
Gruenfrosch 0:7627c79db971 270 }
Gruenfrosch 0:7627c79db971 271 else {
Gruenfrosch 0:7627c79db971 272 rate = (unsigned long) header->samplerate *
Gruenfrosch 0:7627c79db971 273 (N - pad_slot + 1) / slots_per_frame / 1000;
Gruenfrosch 0:7627c79db971 274 }
Gruenfrosch 0:7627c79db971 275
Gruenfrosch 0:7627c79db971 276 if (rate >= 8)
Gruenfrosch 0:7627c79db971 277 break;
Gruenfrosch 0:7627c79db971 278 }
Gruenfrosch 0:7627c79db971 279
Gruenfrosch 0:7627c79db971 280 mad_bit_skip(&stream->ptr, 8);
Gruenfrosch 0:7627c79db971 281 }
Gruenfrosch 0:7627c79db971 282
Gruenfrosch 0:7627c79db971 283 stream->ptr = keep_ptr;
Gruenfrosch 0:7627c79db971 284
Gruenfrosch 0:7627c79db971 285 if (rate < 8 || (header->layer == MAD_LAYER_III && rate > 640)) {
Gruenfrosch 0:7627c79db971 286 stream->error = MAD_ERROR_LOSTSYNC;
Gruenfrosch 0:7627c79db971 287 return -1;
Gruenfrosch 0:7627c79db971 288 }
Gruenfrosch 0:7627c79db971 289
Gruenfrosch 0:7627c79db971 290 stream->freerate = rate * 1000;
Gruenfrosch 0:7627c79db971 291
Gruenfrosch 0:7627c79db971 292 return 0;
Gruenfrosch 0:7627c79db971 293 }
Gruenfrosch 0:7627c79db971 294
Gruenfrosch 0:7627c79db971 295 /*
Gruenfrosch 0:7627c79db971 296 * NAME: header->decode()
Gruenfrosch 0:7627c79db971 297 * DESCRIPTION: read the next frame header from the stream
Gruenfrosch 0:7627c79db971 298 */
Gruenfrosch 0:7627c79db971 299 int mad_header_decode(struct mad_header *header, struct mad_stream *stream)
Gruenfrosch 0:7627c79db971 300 {
Gruenfrosch 0:7627c79db971 301 register unsigned char const *ptr, *end;
Gruenfrosch 0:7627c79db971 302 unsigned int pad_slot, N;
Gruenfrosch 0:7627c79db971 303
Gruenfrosch 0:7627c79db971 304 ptr = stream->next_frame;
Gruenfrosch 0:7627c79db971 305 end = stream->bufend;
Gruenfrosch 0:7627c79db971 306
Gruenfrosch 0:7627c79db971 307 if (ptr == 0) {
Gruenfrosch 0:7627c79db971 308 stream->error = MAD_ERROR_BUFPTR;
Gruenfrosch 0:7627c79db971 309 goto fail;
Gruenfrosch 0:7627c79db971 310 }
Gruenfrosch 0:7627c79db971 311
Gruenfrosch 0:7627c79db971 312 /* stream skip */
Gruenfrosch 0:7627c79db971 313 if (stream->skiplen) {
Gruenfrosch 0:7627c79db971 314 if (!stream->sync)
Gruenfrosch 0:7627c79db971 315 ptr = stream->this_frame;
Gruenfrosch 0:7627c79db971 316
Gruenfrosch 0:7627c79db971 317 if (end - ptr < stream->skiplen) {
Gruenfrosch 0:7627c79db971 318 stream->skiplen -= end - ptr;
Gruenfrosch 0:7627c79db971 319 stream->next_frame = end;
Gruenfrosch 0:7627c79db971 320
Gruenfrosch 0:7627c79db971 321 stream->error = MAD_ERROR_BUFLEN;
Gruenfrosch 0:7627c79db971 322 goto fail;
Gruenfrosch 0:7627c79db971 323 }
Gruenfrosch 0:7627c79db971 324
Gruenfrosch 0:7627c79db971 325 ptr += stream->skiplen;
Gruenfrosch 0:7627c79db971 326 stream->skiplen = 0;
Gruenfrosch 0:7627c79db971 327
Gruenfrosch 0:7627c79db971 328 stream->sync = 1;
Gruenfrosch 0:7627c79db971 329 }
Gruenfrosch 0:7627c79db971 330
Gruenfrosch 0:7627c79db971 331 sync:
Gruenfrosch 0:7627c79db971 332 /* synchronize */
Gruenfrosch 0:7627c79db971 333 if (stream->sync) {
Gruenfrosch 0:7627c79db971 334 if (end - ptr < MAD_BUFFER_GUARD) {
Gruenfrosch 0:7627c79db971 335 stream->next_frame = ptr;
Gruenfrosch 0:7627c79db971 336
Gruenfrosch 0:7627c79db971 337 stream->error = MAD_ERROR_BUFLEN;
Gruenfrosch 0:7627c79db971 338 goto fail;
Gruenfrosch 0:7627c79db971 339 }
Gruenfrosch 0:7627c79db971 340 else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
Gruenfrosch 0:7627c79db971 341 /* mark point where frame sync word was expected */
Gruenfrosch 0:7627c79db971 342 stream->this_frame = ptr;
Gruenfrosch 0:7627c79db971 343 stream->next_frame = ptr + 1;
Gruenfrosch 0:7627c79db971 344
Gruenfrosch 0:7627c79db971 345 stream->error = MAD_ERROR_LOSTSYNC;
Gruenfrosch 0:7627c79db971 346 goto fail;
Gruenfrosch 0:7627c79db971 347 }
Gruenfrosch 0:7627c79db971 348 }
Gruenfrosch 0:7627c79db971 349 else {
Gruenfrosch 0:7627c79db971 350 mad_bit_init(&stream->ptr, ptr);
Gruenfrosch 0:7627c79db971 351
Gruenfrosch 0:7627c79db971 352 if (mad_stream_sync(stream) == -1) {
Gruenfrosch 0:7627c79db971 353 if (end - stream->next_frame >= MAD_BUFFER_GUARD)
Gruenfrosch 0:7627c79db971 354 stream->next_frame = end - MAD_BUFFER_GUARD;
Gruenfrosch 0:7627c79db971 355
Gruenfrosch 0:7627c79db971 356 stream->error = MAD_ERROR_BUFLEN;
Gruenfrosch 0:7627c79db971 357 goto fail;
Gruenfrosch 0:7627c79db971 358 }
Gruenfrosch 0:7627c79db971 359
Gruenfrosch 0:7627c79db971 360 ptr = mad_bit_nextbyte(&stream->ptr);
Gruenfrosch 0:7627c79db971 361 }
Gruenfrosch 0:7627c79db971 362
Gruenfrosch 0:7627c79db971 363 /* begin processing */
Gruenfrosch 0:7627c79db971 364 stream->this_frame = ptr;
Gruenfrosch 0:7627c79db971 365 stream->next_frame = ptr + 1; /* possibly bogus sync word */
Gruenfrosch 0:7627c79db971 366
Gruenfrosch 0:7627c79db971 367 mad_bit_init(&stream->ptr, stream->this_frame);
Gruenfrosch 0:7627c79db971 368
Gruenfrosch 0:7627c79db971 369 if (decode_header(header, stream) == -1)
Gruenfrosch 0:7627c79db971 370 goto fail;
Gruenfrosch 0:7627c79db971 371
Gruenfrosch 0:7627c79db971 372 /* calculate frame duration */
Gruenfrosch 0:7627c79db971 373 mad_timer_set(&header->duration, 0,
Gruenfrosch 0:7627c79db971 374 32 * MAD_NSBSAMPLES(header), header->samplerate);
Gruenfrosch 0:7627c79db971 375
Gruenfrosch 0:7627c79db971 376 /* calculate free bit rate */
Gruenfrosch 0:7627c79db971 377 if (header->bitrate == 0) {
Gruenfrosch 0:7627c79db971 378 if ((stream->freerate == 0 || !stream->sync ||
Gruenfrosch 0:7627c79db971 379 (header->layer == MAD_LAYER_III && stream->freerate > 640000)) &&
Gruenfrosch 0:7627c79db971 380 free_bitrate(stream, header) == -1)
Gruenfrosch 0:7627c79db971 381 goto fail;
Gruenfrosch 0:7627c79db971 382
Gruenfrosch 0:7627c79db971 383 header->bitrate = stream->freerate;
Gruenfrosch 0:7627c79db971 384 header->flags |= MAD_FLAG_FREEFORMAT;
Gruenfrosch 0:7627c79db971 385 }
Gruenfrosch 0:7627c79db971 386
Gruenfrosch 0:7627c79db971 387 /* calculate beginning of next frame */
Gruenfrosch 0:7627c79db971 388 pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0;
Gruenfrosch 0:7627c79db971 389
Gruenfrosch 0:7627c79db971 390 if (header->layer == MAD_LAYER_I)
Gruenfrosch 0:7627c79db971 391 N = ((12 * header->bitrate / header->samplerate) + pad_slot) * 4;
Gruenfrosch 0:7627c79db971 392 else {
Gruenfrosch 0:7627c79db971 393 unsigned int slots_per_frame;
Gruenfrosch 0:7627c79db971 394
Gruenfrosch 0:7627c79db971 395 slots_per_frame = (header->layer == MAD_LAYER_III &&
Gruenfrosch 0:7627c79db971 396 (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144;
Gruenfrosch 0:7627c79db971 397
Gruenfrosch 0:7627c79db971 398 N = (slots_per_frame * header->bitrate / header->samplerate) + pad_slot;
Gruenfrosch 0:7627c79db971 399 }
Gruenfrosch 0:7627c79db971 400
Gruenfrosch 0:7627c79db971 401 /* verify there is enough data left in buffer to decode this frame */
Gruenfrosch 0:7627c79db971 402 if (N + MAD_BUFFER_GUARD > end - stream->this_frame) {
Gruenfrosch 0:7627c79db971 403 stream->next_frame = stream->this_frame;
Gruenfrosch 0:7627c79db971 404
Gruenfrosch 0:7627c79db971 405 stream->error = MAD_ERROR_BUFLEN;
Gruenfrosch 0:7627c79db971 406 goto fail;
Gruenfrosch 0:7627c79db971 407 }
Gruenfrosch 0:7627c79db971 408
Gruenfrosch 0:7627c79db971 409 stream->next_frame = stream->this_frame + N;
Gruenfrosch 0:7627c79db971 410
Gruenfrosch 0:7627c79db971 411 if (!stream->sync) {
Gruenfrosch 0:7627c79db971 412 /* check that a valid frame header follows this frame */
Gruenfrosch 0:7627c79db971 413
Gruenfrosch 0:7627c79db971 414 ptr = stream->next_frame;
Gruenfrosch 0:7627c79db971 415 if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
Gruenfrosch 0:7627c79db971 416 ptr = stream->next_frame = stream->this_frame + 1;
Gruenfrosch 0:7627c79db971 417 goto sync;
Gruenfrosch 0:7627c79db971 418 }
Gruenfrosch 0:7627c79db971 419
Gruenfrosch 0:7627c79db971 420 stream->sync = 1;
Gruenfrosch 0:7627c79db971 421 }
Gruenfrosch 0:7627c79db971 422
Gruenfrosch 0:7627c79db971 423 header->flags |= MAD_FLAG_INCOMPLETE;
Gruenfrosch 0:7627c79db971 424
Gruenfrosch 0:7627c79db971 425 return 0;
Gruenfrosch 0:7627c79db971 426
Gruenfrosch 0:7627c79db971 427 fail:
Gruenfrosch 0:7627c79db971 428 stream->sync = 0;
Gruenfrosch 0:7627c79db971 429
Gruenfrosch 0:7627c79db971 430 return -1;
Gruenfrosch 0:7627c79db971 431 }
Gruenfrosch 0:7627c79db971 432
Gruenfrosch 0:7627c79db971 433 /*
Gruenfrosch 0:7627c79db971 434 * NAME: frame->decode()
Gruenfrosch 0:7627c79db971 435 * DESCRIPTION: decode a single frame from a bitstream
Gruenfrosch 0:7627c79db971 436 */
Gruenfrosch 0:7627c79db971 437 int mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream)
Gruenfrosch 0:7627c79db971 438 {
Gruenfrosch 0:7627c79db971 439 frame->options = stream->options;
Gruenfrosch 0:7627c79db971 440
Gruenfrosch 0:7627c79db971 441 /* header() */
Gruenfrosch 0:7627c79db971 442 /* error_check() */
Gruenfrosch 0:7627c79db971 443
Gruenfrosch 0:7627c79db971 444 if (!(frame->header.flags & MAD_FLAG_INCOMPLETE) &&
Gruenfrosch 0:7627c79db971 445 mad_header_decode(&frame->header, stream) == -1)
Gruenfrosch 0:7627c79db971 446 goto fail;
Gruenfrosch 0:7627c79db971 447
Gruenfrosch 0:7627c79db971 448 /* audio_data() */
Gruenfrosch 0:7627c79db971 449
Gruenfrosch 0:7627c79db971 450 frame->header.flags &= ~MAD_FLAG_INCOMPLETE;
Gruenfrosch 0:7627c79db971 451
Gruenfrosch 0:7627c79db971 452 if (decoder_table[frame->header.layer - 1](stream, frame) == -1) {
Gruenfrosch 0:7627c79db971 453 if (!MAD_RECOVERABLE(stream->error))
Gruenfrosch 0:7627c79db971 454 stream->next_frame = stream->this_frame;
Gruenfrosch 0:7627c79db971 455
Gruenfrosch 0:7627c79db971 456 goto fail;
Gruenfrosch 0:7627c79db971 457 }
Gruenfrosch 0:7627c79db971 458
Gruenfrosch 0:7627c79db971 459 /* ancillary_data() */
Gruenfrosch 0:7627c79db971 460
Gruenfrosch 0:7627c79db971 461 if (frame->header.layer != MAD_LAYER_III) {
Gruenfrosch 0:7627c79db971 462 struct mad_bitptr next_frame;
Gruenfrosch 0:7627c79db971 463
Gruenfrosch 0:7627c79db971 464 mad_bit_init(&next_frame, stream->next_frame);
Gruenfrosch 0:7627c79db971 465
Gruenfrosch 0:7627c79db971 466 stream->anc_ptr = stream->ptr;
Gruenfrosch 0:7627c79db971 467 stream->anc_bitlen = mad_bit_length(&stream->ptr, &next_frame);
Gruenfrosch 0:7627c79db971 468
Gruenfrosch 0:7627c79db971 469 mad_bit_finish(&next_frame);
Gruenfrosch 0:7627c79db971 470 }
Gruenfrosch 0:7627c79db971 471
Gruenfrosch 0:7627c79db971 472 return 0;
Gruenfrosch 0:7627c79db971 473
Gruenfrosch 0:7627c79db971 474 fail:
Gruenfrosch 0:7627c79db971 475 stream->anc_bitlen = 0;
Gruenfrosch 0:7627c79db971 476 return -1;
Gruenfrosch 0:7627c79db971 477 }
Gruenfrosch 0:7627c79db971 478
Gruenfrosch 0:7627c79db971 479 /*
Gruenfrosch 0:7627c79db971 480 * NAME: frame->mute()
Gruenfrosch 0:7627c79db971 481 * DESCRIPTION: zero all subband values so the frame becomes silent
Gruenfrosch 0:7627c79db971 482 */
Gruenfrosch 0:7627c79db971 483 void mad_frame_mute(struct mad_frame *frame)
Gruenfrosch 0:7627c79db971 484 {
Gruenfrosch 0:7627c79db971 485 unsigned int s, sb;
Gruenfrosch 0:7627c79db971 486
Gruenfrosch 0:7627c79db971 487 for (s = 0; s < 36; ++s) {
Gruenfrosch 0:7627c79db971 488 for (sb = 0; sb < 32; ++sb) {
Gruenfrosch 0:7627c79db971 489 frame->sbsample[0][s][sb] =
Gruenfrosch 0:7627c79db971 490 frame->sbsample[1][s][sb] = 0;
Gruenfrosch 0:7627c79db971 491 }
Gruenfrosch 0:7627c79db971 492 }
Gruenfrosch 0:7627c79db971 493
Gruenfrosch 0:7627c79db971 494 if (frame->overlap) {
Gruenfrosch 0:7627c79db971 495 for (s = 0; s < 18; ++s) {
Gruenfrosch 0:7627c79db971 496 for (sb = 0; sb < 32; ++sb) {
Gruenfrosch 2:f28cf0afd021 497 (frame->overlap)[0][sb][s] =
Gruenfrosch 2:f28cf0afd021 498 (frame->overlap)[1][sb][s] = 0;
Gruenfrosch 0:7627c79db971 499 }
Gruenfrosch 0:7627c79db971 500 }
Gruenfrosch 0:7627c79db971 501 }
Gruenfrosch 0:7627c79db971 502 }