streo mp3 player see: http://mbed.org/users/okini3939/notebook/I2S_AUDIO
Dependencies: FatFileSystemCpp I2SSlave TLV320 mbed
Fork of madplayer by
frame.cpp@0:7627c79db971, 2010-11-26 (annotated)
- Committer:
- Gruenfrosch
- Date:
- Fri Nov 26 12:18:30 2010 +0000
- Revision:
- 0:7627c79db971
- Child:
- 2:f28cf0afd021
First Version
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 | 0:7627c79db971 | 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 | 0:7627c79db971 | 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 | 0:7627c79db971 | 111 | } |
Gruenfrosch | 0:7627c79db971 | 112 | |
Gruenfrosch | 0:7627c79db971 | 113 | /* |
Gruenfrosch | 0:7627c79db971 | 114 | * NAME: decode_header() |
Gruenfrosch | 0:7627c79db971 | 115 | * DESCRIPTION: read header data and following CRC word |
Gruenfrosch | 0:7627c79db971 | 116 | */ |
Gruenfrosch | 0:7627c79db971 | 117 | static |
Gruenfrosch | 0:7627c79db971 | 118 | int decode_header(struct mad_header *header, struct mad_stream *stream) |
Gruenfrosch | 0:7627c79db971 | 119 | { |
Gruenfrosch | 0:7627c79db971 | 120 | unsigned int index; |
Gruenfrosch | 0:7627c79db971 | 121 | |
Gruenfrosch | 0:7627c79db971 | 122 | header->flags = 0; |
Gruenfrosch | 0:7627c79db971 | 123 | header->private_bits = 0; |
Gruenfrosch | 0:7627c79db971 | 124 | |
Gruenfrosch | 0:7627c79db971 | 125 | /* header() */ |
Gruenfrosch | 0:7627c79db971 | 126 | |
Gruenfrosch | 0:7627c79db971 | 127 | /* syncword */ |
Gruenfrosch | 0:7627c79db971 | 128 | mad_bit_skip(&stream->ptr, 11); |
Gruenfrosch | 0:7627c79db971 | 129 | |
Gruenfrosch | 0:7627c79db971 | 130 | /* MPEG 2.5 indicator (really part of syncword) */ |
Gruenfrosch | 0:7627c79db971 | 131 | if (mad_bit_read(&stream->ptr, 1) == 0) |
Gruenfrosch | 0:7627c79db971 | 132 | header->flags |= MAD_FLAG_MPEG_2_5_EXT; |
Gruenfrosch | 0:7627c79db971 | 133 | |
Gruenfrosch | 0:7627c79db971 | 134 | /* ID */ |
Gruenfrosch | 0:7627c79db971 | 135 | if (mad_bit_read(&stream->ptr, 1) == 0) |
Gruenfrosch | 0:7627c79db971 | 136 | header->flags |= MAD_FLAG_LSF_EXT; |
Gruenfrosch | 0:7627c79db971 | 137 | else if (header->flags & MAD_FLAG_MPEG_2_5_EXT) { |
Gruenfrosch | 0:7627c79db971 | 138 | stream->error = MAD_ERROR_LOSTSYNC; |
Gruenfrosch | 0:7627c79db971 | 139 | return -1; |
Gruenfrosch | 0:7627c79db971 | 140 | } |
Gruenfrosch | 0:7627c79db971 | 141 | |
Gruenfrosch | 0:7627c79db971 | 142 | /* layer */ |
Gruenfrosch | 0:7627c79db971 | 143 | header->layer = (enum mad_layer)(4 - mad_bit_read(&stream->ptr, 2)); |
Gruenfrosch | 0:7627c79db971 | 144 | |
Gruenfrosch | 0:7627c79db971 | 145 | if (header->layer == 4) { |
Gruenfrosch | 0:7627c79db971 | 146 | stream->error = MAD_ERROR_BADLAYER; |
Gruenfrosch | 0:7627c79db971 | 147 | return -1; |
Gruenfrosch | 0:7627c79db971 | 148 | } |
Gruenfrosch | 0:7627c79db971 | 149 | |
Gruenfrosch | 0:7627c79db971 | 150 | /* protection_bit */ |
Gruenfrosch | 0:7627c79db971 | 151 | if (mad_bit_read(&stream->ptr, 1) == 0) { |
Gruenfrosch | 0:7627c79db971 | 152 | header->flags |= MAD_FLAG_PROTECTION; |
Gruenfrosch | 0:7627c79db971 | 153 | header->crc_check = mad_bit_crc(stream->ptr, 16, 0xffff); |
Gruenfrosch | 0:7627c79db971 | 154 | } |
Gruenfrosch | 0:7627c79db971 | 155 | |
Gruenfrosch | 0:7627c79db971 | 156 | /* bitrate_index */ |
Gruenfrosch | 0:7627c79db971 | 157 | index = mad_bit_read(&stream->ptr, 4); |
Gruenfrosch | 0:7627c79db971 | 158 | |
Gruenfrosch | 0:7627c79db971 | 159 | if (index == 15) { |
Gruenfrosch | 0:7627c79db971 | 160 | stream->error = MAD_ERROR_BADBITRATE; |
Gruenfrosch | 0:7627c79db971 | 161 | return -1; |
Gruenfrosch | 0:7627c79db971 | 162 | } |
Gruenfrosch | 0:7627c79db971 | 163 | |
Gruenfrosch | 0:7627c79db971 | 164 | if (header->flags & MAD_FLAG_LSF_EXT) |
Gruenfrosch | 0:7627c79db971 | 165 | header->bitrate = bitrate_table[3 + (header->layer >> 1)][index]; |
Gruenfrosch | 0:7627c79db971 | 166 | else |
Gruenfrosch | 0:7627c79db971 | 167 | header->bitrate = bitrate_table[header->layer - 1][index]; |
Gruenfrosch | 0:7627c79db971 | 168 | |
Gruenfrosch | 0:7627c79db971 | 169 | /* sampling_frequency */ |
Gruenfrosch | 0:7627c79db971 | 170 | index = mad_bit_read(&stream->ptr, 2); |
Gruenfrosch | 0:7627c79db971 | 171 | |
Gruenfrosch | 0:7627c79db971 | 172 | if (index == 3) { |
Gruenfrosch | 0:7627c79db971 | 173 | stream->error = MAD_ERROR_BADSAMPLERATE; |
Gruenfrosch | 0:7627c79db971 | 174 | return -1; |
Gruenfrosch | 0:7627c79db971 | 175 | } |
Gruenfrosch | 0:7627c79db971 | 176 | |
Gruenfrosch | 0:7627c79db971 | 177 | header->samplerate = samplerate_table[index]; |
Gruenfrosch | 0:7627c79db971 | 178 | |
Gruenfrosch | 0:7627c79db971 | 179 | if (header->flags & MAD_FLAG_LSF_EXT) { |
Gruenfrosch | 0:7627c79db971 | 180 | header->samplerate /= 2; |
Gruenfrosch | 0:7627c79db971 | 181 | |
Gruenfrosch | 0:7627c79db971 | 182 | if (header->flags & MAD_FLAG_MPEG_2_5_EXT) |
Gruenfrosch | 0:7627c79db971 | 183 | header->samplerate /= 2; |
Gruenfrosch | 0:7627c79db971 | 184 | } |
Gruenfrosch | 0:7627c79db971 | 185 | |
Gruenfrosch | 0:7627c79db971 | 186 | /* padding_bit */ |
Gruenfrosch | 0:7627c79db971 | 187 | if (mad_bit_read(&stream->ptr, 1)) |
Gruenfrosch | 0:7627c79db971 | 188 | header->flags |= MAD_FLAG_PADDING; |
Gruenfrosch | 0:7627c79db971 | 189 | |
Gruenfrosch | 0:7627c79db971 | 190 | /* private_bit */ |
Gruenfrosch | 0:7627c79db971 | 191 | if (mad_bit_read(&stream->ptr, 1)) |
Gruenfrosch | 0:7627c79db971 | 192 | header->private_bits |= MAD_PRIVATE_HEADER; |
Gruenfrosch | 0:7627c79db971 | 193 | |
Gruenfrosch | 0:7627c79db971 | 194 | /* mode */ |
Gruenfrosch | 0:7627c79db971 | 195 | header->mode = (enum mad_mode)(3 - mad_bit_read(&stream->ptr, 2)); |
Gruenfrosch | 0:7627c79db971 | 196 | |
Gruenfrosch | 0:7627c79db971 | 197 | /* mode_extension */ |
Gruenfrosch | 0:7627c79db971 | 198 | header->mode_extension = mad_bit_read(&stream->ptr, 2); |
Gruenfrosch | 0:7627c79db971 | 199 | |
Gruenfrosch | 0:7627c79db971 | 200 | /* copyright */ |
Gruenfrosch | 0:7627c79db971 | 201 | if (mad_bit_read(&stream->ptr, 1)) |
Gruenfrosch | 0:7627c79db971 | 202 | header->flags |= MAD_FLAG_COPYRIGHT; |
Gruenfrosch | 0:7627c79db971 | 203 | |
Gruenfrosch | 0:7627c79db971 | 204 | /* original/copy */ |
Gruenfrosch | 0:7627c79db971 | 205 | if (mad_bit_read(&stream->ptr, 1)) |
Gruenfrosch | 0:7627c79db971 | 206 | header->flags |= MAD_FLAG_ORIGINAL; |
Gruenfrosch | 0:7627c79db971 | 207 | |
Gruenfrosch | 0:7627c79db971 | 208 | /* emphasis */ |
Gruenfrosch | 0:7627c79db971 | 209 | header->emphasis = (enum mad_emphasis)mad_bit_read(&stream->ptr, 2); |
Gruenfrosch | 0:7627c79db971 | 210 | |
Gruenfrosch | 0:7627c79db971 | 211 | # if defined(OPT_STRICT) |
Gruenfrosch | 0:7627c79db971 | 212 | /* |
Gruenfrosch | 0:7627c79db971 | 213 | * ISO/IEC 11172-3 says this is a reserved emphasis value, but |
Gruenfrosch | 0:7627c79db971 | 214 | * streams exist which use it anyway. Since the value is not important |
Gruenfrosch | 0:7627c79db971 | 215 | * to the decoder proper, we allow it unless OPT_STRICT is defined. |
Gruenfrosch | 0:7627c79db971 | 216 | */ |
Gruenfrosch | 0:7627c79db971 | 217 | if (header->emphasis == MAD_EMPHASIS_RESERVED) { |
Gruenfrosch | 0:7627c79db971 | 218 | stream->error = MAD_ERROR_BADEMPHASIS; |
Gruenfrosch | 0:7627c79db971 | 219 | return -1; |
Gruenfrosch | 0:7627c79db971 | 220 | } |
Gruenfrosch | 0:7627c79db971 | 221 | # endif |
Gruenfrosch | 0:7627c79db971 | 222 | |
Gruenfrosch | 0:7627c79db971 | 223 | /* error_check() */ |
Gruenfrosch | 0:7627c79db971 | 224 | |
Gruenfrosch | 0:7627c79db971 | 225 | /* crc_check */ |
Gruenfrosch | 0:7627c79db971 | 226 | if (header->flags & MAD_FLAG_PROTECTION) |
Gruenfrosch | 0:7627c79db971 | 227 | header->crc_target = mad_bit_read(&stream->ptr, 16); |
Gruenfrosch | 0:7627c79db971 | 228 | |
Gruenfrosch | 0:7627c79db971 | 229 | return 0; |
Gruenfrosch | 0:7627c79db971 | 230 | } |
Gruenfrosch | 0:7627c79db971 | 231 | |
Gruenfrosch | 0:7627c79db971 | 232 | /* |
Gruenfrosch | 0:7627c79db971 | 233 | * NAME: free_bitrate() |
Gruenfrosch | 0:7627c79db971 | 234 | * DESCRIPTION: attempt to discover the bitstream's free bitrate |
Gruenfrosch | 0:7627c79db971 | 235 | */ |
Gruenfrosch | 0:7627c79db971 | 236 | static |
Gruenfrosch | 0:7627c79db971 | 237 | int free_bitrate(struct mad_stream *stream, struct mad_header const *header) |
Gruenfrosch | 0:7627c79db971 | 238 | { |
Gruenfrosch | 0:7627c79db971 | 239 | struct mad_bitptr keep_ptr; |
Gruenfrosch | 0:7627c79db971 | 240 | unsigned long rate = 0; |
Gruenfrosch | 0:7627c79db971 | 241 | unsigned int pad_slot, slots_per_frame; |
Gruenfrosch | 0:7627c79db971 | 242 | unsigned char const *ptr = 0; |
Gruenfrosch | 0:7627c79db971 | 243 | |
Gruenfrosch | 0:7627c79db971 | 244 | keep_ptr = stream->ptr; |
Gruenfrosch | 0:7627c79db971 | 245 | |
Gruenfrosch | 0:7627c79db971 | 246 | pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0; |
Gruenfrosch | 0:7627c79db971 | 247 | slots_per_frame = (header->layer == MAD_LAYER_III && |
Gruenfrosch | 0:7627c79db971 | 248 | (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144; |
Gruenfrosch | 0:7627c79db971 | 249 | |
Gruenfrosch | 0:7627c79db971 | 250 | while (mad_stream_sync(stream) == 0) { |
Gruenfrosch | 0:7627c79db971 | 251 | struct mad_stream peek_stream; |
Gruenfrosch | 0:7627c79db971 | 252 | struct mad_header peek_header; |
Gruenfrosch | 0:7627c79db971 | 253 | |
Gruenfrosch | 0:7627c79db971 | 254 | peek_stream = *stream; |
Gruenfrosch | 0:7627c79db971 | 255 | peek_header = *header; |
Gruenfrosch | 0:7627c79db971 | 256 | |
Gruenfrosch | 0:7627c79db971 | 257 | if (decode_header(&peek_header, &peek_stream) == 0 && |
Gruenfrosch | 0:7627c79db971 | 258 | peek_header.layer == header->layer && |
Gruenfrosch | 0:7627c79db971 | 259 | peek_header.samplerate == header->samplerate) { |
Gruenfrosch | 0:7627c79db971 | 260 | unsigned int N; |
Gruenfrosch | 0:7627c79db971 | 261 | |
Gruenfrosch | 0:7627c79db971 | 262 | ptr = mad_bit_nextbyte(&stream->ptr); |
Gruenfrosch | 0:7627c79db971 | 263 | |
Gruenfrosch | 0:7627c79db971 | 264 | N = ptr - stream->this_frame; |
Gruenfrosch | 0:7627c79db971 | 265 | |
Gruenfrosch | 0:7627c79db971 | 266 | if (header->layer == MAD_LAYER_I) { |
Gruenfrosch | 0:7627c79db971 | 267 | rate = (unsigned long) header->samplerate * |
Gruenfrosch | 0:7627c79db971 | 268 | (N - 4 * pad_slot + 4) / 48 / 1000; |
Gruenfrosch | 0:7627c79db971 | 269 | } |
Gruenfrosch | 0:7627c79db971 | 270 | else { |
Gruenfrosch | 0:7627c79db971 | 271 | rate = (unsigned long) header->samplerate * |
Gruenfrosch | 0:7627c79db971 | 272 | (N - pad_slot + 1) / slots_per_frame / 1000; |
Gruenfrosch | 0:7627c79db971 | 273 | } |
Gruenfrosch | 0:7627c79db971 | 274 | |
Gruenfrosch | 0:7627c79db971 | 275 | if (rate >= 8) |
Gruenfrosch | 0:7627c79db971 | 276 | break; |
Gruenfrosch | 0:7627c79db971 | 277 | } |
Gruenfrosch | 0:7627c79db971 | 278 | |
Gruenfrosch | 0:7627c79db971 | 279 | mad_bit_skip(&stream->ptr, 8); |
Gruenfrosch | 0:7627c79db971 | 280 | } |
Gruenfrosch | 0:7627c79db971 | 281 | |
Gruenfrosch | 0:7627c79db971 | 282 | stream->ptr = keep_ptr; |
Gruenfrosch | 0:7627c79db971 | 283 | |
Gruenfrosch | 0:7627c79db971 | 284 | if (rate < 8 || (header->layer == MAD_LAYER_III && rate > 640)) { |
Gruenfrosch | 0:7627c79db971 | 285 | stream->error = MAD_ERROR_LOSTSYNC; |
Gruenfrosch | 0:7627c79db971 | 286 | return -1; |
Gruenfrosch | 0:7627c79db971 | 287 | } |
Gruenfrosch | 0:7627c79db971 | 288 | |
Gruenfrosch | 0:7627c79db971 | 289 | stream->freerate = rate * 1000; |
Gruenfrosch | 0:7627c79db971 | 290 | |
Gruenfrosch | 0:7627c79db971 | 291 | return 0; |
Gruenfrosch | 0:7627c79db971 | 292 | } |
Gruenfrosch | 0:7627c79db971 | 293 | |
Gruenfrosch | 0:7627c79db971 | 294 | /* |
Gruenfrosch | 0:7627c79db971 | 295 | * NAME: header->decode() |
Gruenfrosch | 0:7627c79db971 | 296 | * DESCRIPTION: read the next frame header from the stream |
Gruenfrosch | 0:7627c79db971 | 297 | */ |
Gruenfrosch | 0:7627c79db971 | 298 | int mad_header_decode(struct mad_header *header, struct mad_stream *stream) |
Gruenfrosch | 0:7627c79db971 | 299 | { |
Gruenfrosch | 0:7627c79db971 | 300 | register unsigned char const *ptr, *end; |
Gruenfrosch | 0:7627c79db971 | 301 | unsigned int pad_slot, N; |
Gruenfrosch | 0:7627c79db971 | 302 | |
Gruenfrosch | 0:7627c79db971 | 303 | ptr = stream->next_frame; |
Gruenfrosch | 0:7627c79db971 | 304 | end = stream->bufend; |
Gruenfrosch | 0:7627c79db971 | 305 | |
Gruenfrosch | 0:7627c79db971 | 306 | if (ptr == 0) { |
Gruenfrosch | 0:7627c79db971 | 307 | stream->error = MAD_ERROR_BUFPTR; |
Gruenfrosch | 0:7627c79db971 | 308 | goto fail; |
Gruenfrosch | 0:7627c79db971 | 309 | } |
Gruenfrosch | 0:7627c79db971 | 310 | |
Gruenfrosch | 0:7627c79db971 | 311 | /* stream skip */ |
Gruenfrosch | 0:7627c79db971 | 312 | if (stream->skiplen) { |
Gruenfrosch | 0:7627c79db971 | 313 | if (!stream->sync) |
Gruenfrosch | 0:7627c79db971 | 314 | ptr = stream->this_frame; |
Gruenfrosch | 0:7627c79db971 | 315 | |
Gruenfrosch | 0:7627c79db971 | 316 | if (end - ptr < stream->skiplen) { |
Gruenfrosch | 0:7627c79db971 | 317 | stream->skiplen -= end - ptr; |
Gruenfrosch | 0:7627c79db971 | 318 | stream->next_frame = end; |
Gruenfrosch | 0:7627c79db971 | 319 | |
Gruenfrosch | 0:7627c79db971 | 320 | stream->error = MAD_ERROR_BUFLEN; |
Gruenfrosch | 0:7627c79db971 | 321 | goto fail; |
Gruenfrosch | 0:7627c79db971 | 322 | } |
Gruenfrosch | 0:7627c79db971 | 323 | |
Gruenfrosch | 0:7627c79db971 | 324 | ptr += stream->skiplen; |
Gruenfrosch | 0:7627c79db971 | 325 | stream->skiplen = 0; |
Gruenfrosch | 0:7627c79db971 | 326 | |
Gruenfrosch | 0:7627c79db971 | 327 | stream->sync = 1; |
Gruenfrosch | 0:7627c79db971 | 328 | } |
Gruenfrosch | 0:7627c79db971 | 329 | |
Gruenfrosch | 0:7627c79db971 | 330 | sync: |
Gruenfrosch | 0:7627c79db971 | 331 | /* synchronize */ |
Gruenfrosch | 0:7627c79db971 | 332 | if (stream->sync) { |
Gruenfrosch | 0:7627c79db971 | 333 | if (end - ptr < MAD_BUFFER_GUARD) { |
Gruenfrosch | 0:7627c79db971 | 334 | stream->next_frame = ptr; |
Gruenfrosch | 0:7627c79db971 | 335 | |
Gruenfrosch | 0:7627c79db971 | 336 | stream->error = MAD_ERROR_BUFLEN; |
Gruenfrosch | 0:7627c79db971 | 337 | goto fail; |
Gruenfrosch | 0:7627c79db971 | 338 | } |
Gruenfrosch | 0:7627c79db971 | 339 | else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { |
Gruenfrosch | 0:7627c79db971 | 340 | /* mark point where frame sync word was expected */ |
Gruenfrosch | 0:7627c79db971 | 341 | stream->this_frame = ptr; |
Gruenfrosch | 0:7627c79db971 | 342 | stream->next_frame = ptr + 1; |
Gruenfrosch | 0:7627c79db971 | 343 | |
Gruenfrosch | 0:7627c79db971 | 344 | stream->error = MAD_ERROR_LOSTSYNC; |
Gruenfrosch | 0:7627c79db971 | 345 | goto fail; |
Gruenfrosch | 0:7627c79db971 | 346 | } |
Gruenfrosch | 0:7627c79db971 | 347 | } |
Gruenfrosch | 0:7627c79db971 | 348 | else { |
Gruenfrosch | 0:7627c79db971 | 349 | mad_bit_init(&stream->ptr, ptr); |
Gruenfrosch | 0:7627c79db971 | 350 | |
Gruenfrosch | 0:7627c79db971 | 351 | if (mad_stream_sync(stream) == -1) { |
Gruenfrosch | 0:7627c79db971 | 352 | if (end - stream->next_frame >= MAD_BUFFER_GUARD) |
Gruenfrosch | 0:7627c79db971 | 353 | stream->next_frame = end - MAD_BUFFER_GUARD; |
Gruenfrosch | 0:7627c79db971 | 354 | |
Gruenfrosch | 0:7627c79db971 | 355 | stream->error = MAD_ERROR_BUFLEN; |
Gruenfrosch | 0:7627c79db971 | 356 | goto fail; |
Gruenfrosch | 0:7627c79db971 | 357 | } |
Gruenfrosch | 0:7627c79db971 | 358 | |
Gruenfrosch | 0:7627c79db971 | 359 | ptr = mad_bit_nextbyte(&stream->ptr); |
Gruenfrosch | 0:7627c79db971 | 360 | } |
Gruenfrosch | 0:7627c79db971 | 361 | |
Gruenfrosch | 0:7627c79db971 | 362 | /* begin processing */ |
Gruenfrosch | 0:7627c79db971 | 363 | stream->this_frame = ptr; |
Gruenfrosch | 0:7627c79db971 | 364 | stream->next_frame = ptr + 1; /* possibly bogus sync word */ |
Gruenfrosch | 0:7627c79db971 | 365 | |
Gruenfrosch | 0:7627c79db971 | 366 | mad_bit_init(&stream->ptr, stream->this_frame); |
Gruenfrosch | 0:7627c79db971 | 367 | |
Gruenfrosch | 0:7627c79db971 | 368 | if (decode_header(header, stream) == -1) |
Gruenfrosch | 0:7627c79db971 | 369 | goto fail; |
Gruenfrosch | 0:7627c79db971 | 370 | |
Gruenfrosch | 0:7627c79db971 | 371 | /* calculate frame duration */ |
Gruenfrosch | 0:7627c79db971 | 372 | mad_timer_set(&header->duration, 0, |
Gruenfrosch | 0:7627c79db971 | 373 | 32 * MAD_NSBSAMPLES(header), header->samplerate); |
Gruenfrosch | 0:7627c79db971 | 374 | |
Gruenfrosch | 0:7627c79db971 | 375 | /* calculate free bit rate */ |
Gruenfrosch | 0:7627c79db971 | 376 | if (header->bitrate == 0) { |
Gruenfrosch | 0:7627c79db971 | 377 | if ((stream->freerate == 0 || !stream->sync || |
Gruenfrosch | 0:7627c79db971 | 378 | (header->layer == MAD_LAYER_III && stream->freerate > 640000)) && |
Gruenfrosch | 0:7627c79db971 | 379 | free_bitrate(stream, header) == -1) |
Gruenfrosch | 0:7627c79db971 | 380 | goto fail; |
Gruenfrosch | 0:7627c79db971 | 381 | |
Gruenfrosch | 0:7627c79db971 | 382 | header->bitrate = stream->freerate; |
Gruenfrosch | 0:7627c79db971 | 383 | header->flags |= MAD_FLAG_FREEFORMAT; |
Gruenfrosch | 0:7627c79db971 | 384 | } |
Gruenfrosch | 0:7627c79db971 | 385 | |
Gruenfrosch | 0:7627c79db971 | 386 | /* calculate beginning of next frame */ |
Gruenfrosch | 0:7627c79db971 | 387 | pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0; |
Gruenfrosch | 0:7627c79db971 | 388 | |
Gruenfrosch | 0:7627c79db971 | 389 | if (header->layer == MAD_LAYER_I) |
Gruenfrosch | 0:7627c79db971 | 390 | N = ((12 * header->bitrate / header->samplerate) + pad_slot) * 4; |
Gruenfrosch | 0:7627c79db971 | 391 | else { |
Gruenfrosch | 0:7627c79db971 | 392 | unsigned int slots_per_frame; |
Gruenfrosch | 0:7627c79db971 | 393 | |
Gruenfrosch | 0:7627c79db971 | 394 | slots_per_frame = (header->layer == MAD_LAYER_III && |
Gruenfrosch | 0:7627c79db971 | 395 | (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144; |
Gruenfrosch | 0:7627c79db971 | 396 | |
Gruenfrosch | 0:7627c79db971 | 397 | N = (slots_per_frame * header->bitrate / header->samplerate) + pad_slot; |
Gruenfrosch | 0:7627c79db971 | 398 | } |
Gruenfrosch | 0:7627c79db971 | 399 | |
Gruenfrosch | 0:7627c79db971 | 400 | /* verify there is enough data left in buffer to decode this frame */ |
Gruenfrosch | 0:7627c79db971 | 401 | if (N + MAD_BUFFER_GUARD > end - stream->this_frame) { |
Gruenfrosch | 0:7627c79db971 | 402 | stream->next_frame = stream->this_frame; |
Gruenfrosch | 0:7627c79db971 | 403 | |
Gruenfrosch | 0:7627c79db971 | 404 | stream->error = MAD_ERROR_BUFLEN; |
Gruenfrosch | 0:7627c79db971 | 405 | goto fail; |
Gruenfrosch | 0:7627c79db971 | 406 | } |
Gruenfrosch | 0:7627c79db971 | 407 | |
Gruenfrosch | 0:7627c79db971 | 408 | stream->next_frame = stream->this_frame + N; |
Gruenfrosch | 0:7627c79db971 | 409 | |
Gruenfrosch | 0:7627c79db971 | 410 | if (!stream->sync) { |
Gruenfrosch | 0:7627c79db971 | 411 | /* check that a valid frame header follows this frame */ |
Gruenfrosch | 0:7627c79db971 | 412 | |
Gruenfrosch | 0:7627c79db971 | 413 | ptr = stream->next_frame; |
Gruenfrosch | 0:7627c79db971 | 414 | if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { |
Gruenfrosch | 0:7627c79db971 | 415 | ptr = stream->next_frame = stream->this_frame + 1; |
Gruenfrosch | 0:7627c79db971 | 416 | goto sync; |
Gruenfrosch | 0:7627c79db971 | 417 | } |
Gruenfrosch | 0:7627c79db971 | 418 | |
Gruenfrosch | 0:7627c79db971 | 419 | stream->sync = 1; |
Gruenfrosch | 0:7627c79db971 | 420 | } |
Gruenfrosch | 0:7627c79db971 | 421 | |
Gruenfrosch | 0:7627c79db971 | 422 | header->flags |= MAD_FLAG_INCOMPLETE; |
Gruenfrosch | 0:7627c79db971 | 423 | |
Gruenfrosch | 0:7627c79db971 | 424 | return 0; |
Gruenfrosch | 0:7627c79db971 | 425 | |
Gruenfrosch | 0:7627c79db971 | 426 | fail: |
Gruenfrosch | 0:7627c79db971 | 427 | stream->sync = 0; |
Gruenfrosch | 0:7627c79db971 | 428 | |
Gruenfrosch | 0:7627c79db971 | 429 | return -1; |
Gruenfrosch | 0:7627c79db971 | 430 | } |
Gruenfrosch | 0:7627c79db971 | 431 | |
Gruenfrosch | 0:7627c79db971 | 432 | /* |
Gruenfrosch | 0:7627c79db971 | 433 | * NAME: frame->decode() |
Gruenfrosch | 0:7627c79db971 | 434 | * DESCRIPTION: decode a single frame from a bitstream |
Gruenfrosch | 0:7627c79db971 | 435 | */ |
Gruenfrosch | 0:7627c79db971 | 436 | int mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream) |
Gruenfrosch | 0:7627c79db971 | 437 | { |
Gruenfrosch | 0:7627c79db971 | 438 | frame->options = stream->options; |
Gruenfrosch | 0:7627c79db971 | 439 | |
Gruenfrosch | 0:7627c79db971 | 440 | /* header() */ |
Gruenfrosch | 0:7627c79db971 | 441 | /* error_check() */ |
Gruenfrosch | 0:7627c79db971 | 442 | |
Gruenfrosch | 0:7627c79db971 | 443 | if (!(frame->header.flags & MAD_FLAG_INCOMPLETE) && |
Gruenfrosch | 0:7627c79db971 | 444 | mad_header_decode(&frame->header, stream) == -1) |
Gruenfrosch | 0:7627c79db971 | 445 | goto fail; |
Gruenfrosch | 0:7627c79db971 | 446 | |
Gruenfrosch | 0:7627c79db971 | 447 | /* audio_data() */ |
Gruenfrosch | 0:7627c79db971 | 448 | |
Gruenfrosch | 0:7627c79db971 | 449 | frame->header.flags &= ~MAD_FLAG_INCOMPLETE; |
Gruenfrosch | 0:7627c79db971 | 450 | |
Gruenfrosch | 0:7627c79db971 | 451 | if (decoder_table[frame->header.layer - 1](stream, frame) == -1) { |
Gruenfrosch | 0:7627c79db971 | 452 | if (!MAD_RECOVERABLE(stream->error)) |
Gruenfrosch | 0:7627c79db971 | 453 | stream->next_frame = stream->this_frame; |
Gruenfrosch | 0:7627c79db971 | 454 | |
Gruenfrosch | 0:7627c79db971 | 455 | goto fail; |
Gruenfrosch | 0:7627c79db971 | 456 | } |
Gruenfrosch | 0:7627c79db971 | 457 | |
Gruenfrosch | 0:7627c79db971 | 458 | /* ancillary_data() */ |
Gruenfrosch | 0:7627c79db971 | 459 | |
Gruenfrosch | 0:7627c79db971 | 460 | if (frame->header.layer != MAD_LAYER_III) { |
Gruenfrosch | 0:7627c79db971 | 461 | struct mad_bitptr next_frame; |
Gruenfrosch | 0:7627c79db971 | 462 | |
Gruenfrosch | 0:7627c79db971 | 463 | mad_bit_init(&next_frame, stream->next_frame); |
Gruenfrosch | 0:7627c79db971 | 464 | |
Gruenfrosch | 0:7627c79db971 | 465 | stream->anc_ptr = stream->ptr; |
Gruenfrosch | 0:7627c79db971 | 466 | stream->anc_bitlen = mad_bit_length(&stream->ptr, &next_frame); |
Gruenfrosch | 0:7627c79db971 | 467 | |
Gruenfrosch | 0:7627c79db971 | 468 | mad_bit_finish(&next_frame); |
Gruenfrosch | 0:7627c79db971 | 469 | } |
Gruenfrosch | 0:7627c79db971 | 470 | |
Gruenfrosch | 0:7627c79db971 | 471 | return 0; |
Gruenfrosch | 0:7627c79db971 | 472 | |
Gruenfrosch | 0:7627c79db971 | 473 | fail: |
Gruenfrosch | 0:7627c79db971 | 474 | stream->anc_bitlen = 0; |
Gruenfrosch | 0:7627c79db971 | 475 | return -1; |
Gruenfrosch | 0:7627c79db971 | 476 | } |
Gruenfrosch | 0:7627c79db971 | 477 | |
Gruenfrosch | 0:7627c79db971 | 478 | /* |
Gruenfrosch | 0:7627c79db971 | 479 | * NAME: frame->mute() |
Gruenfrosch | 0:7627c79db971 | 480 | * DESCRIPTION: zero all subband values so the frame becomes silent |
Gruenfrosch | 0:7627c79db971 | 481 | */ |
Gruenfrosch | 0:7627c79db971 | 482 | void mad_frame_mute(struct mad_frame *frame) |
Gruenfrosch | 0:7627c79db971 | 483 | { |
Gruenfrosch | 0:7627c79db971 | 484 | unsigned int s, sb; |
Gruenfrosch | 0:7627c79db971 | 485 | |
Gruenfrosch | 0:7627c79db971 | 486 | for (s = 0; s < 36; ++s) { |
Gruenfrosch | 0:7627c79db971 | 487 | for (sb = 0; sb < 32; ++sb) { |
Gruenfrosch | 0:7627c79db971 | 488 | frame->sbsample[0][s][sb] = |
Gruenfrosch | 0:7627c79db971 | 489 | frame->sbsample[1][s][sb] = 0; |
Gruenfrosch | 0:7627c79db971 | 490 | } |
Gruenfrosch | 0:7627c79db971 | 491 | } |
Gruenfrosch | 0:7627c79db971 | 492 | |
Gruenfrosch | 0:7627c79db971 | 493 | if (frame->overlap) { |
Gruenfrosch | 0:7627c79db971 | 494 | for (s = 0; s < 18; ++s) { |
Gruenfrosch | 0:7627c79db971 | 495 | for (sb = 0; sb < 32; ++sb) { |
Gruenfrosch | 0:7627c79db971 | 496 | (*frame->overlap)[0][sb][s] = |
Gruenfrosch | 0:7627c79db971 | 497 | (*frame->overlap)[1][sb][s] = 0; |
Gruenfrosch | 0:7627c79db971 | 498 | } |
Gruenfrosch | 0:7627c79db971 | 499 | } |
Gruenfrosch | 0:7627c79db971 | 500 | } |
Gruenfrosch | 0:7627c79db971 | 501 | } |