streo mp3 player see: http://mbed.org/users/okini3939/notebook/I2S_AUDIO
Dependencies: FatFileSystemCpp I2SSlave TLV320 mbed
Fork of madplayer by
frame.cpp@2:f28cf0afd021, 2010-11-27 (annotated)
- 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?
User | Revision | Line number | New 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 | } |