MP3 Player. You can change fwd/rev speed and skip. see: http://mbed.org/users/okini3939/notebook/lpc4088_madplayer/

Dependencies:   I2SSlave SDFileSystem TLV320 mbed

Committer:
okini3939
Date:
Tue Feb 18 00:22:50 2014 +0000
Revision:
0:8ba6230eefbd
1st build

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 0:8ba6230eefbd 1 /*
okini3939 0:8ba6230eefbd 2 * libmad - MPEG audio decoder library
okini3939 0:8ba6230eefbd 3 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
okini3939 0:8ba6230eefbd 4 *
okini3939 0:8ba6230eefbd 5 * This program is free software; you can redistribute it and/or modify
okini3939 0:8ba6230eefbd 6 * it under the terms of the GNU General Public License as published by
okini3939 0:8ba6230eefbd 7 * the Free Software Foundation; either version 2 of the License, or
okini3939 0:8ba6230eefbd 8 * (at your option) any later version.
okini3939 0:8ba6230eefbd 9 *
okini3939 0:8ba6230eefbd 10 * This program is distributed in the hope that it will be useful,
okini3939 0:8ba6230eefbd 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
okini3939 0:8ba6230eefbd 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
okini3939 0:8ba6230eefbd 13 * GNU General Public License for more details.
okini3939 0:8ba6230eefbd 14 *
okini3939 0:8ba6230eefbd 15 * You should have received a copy of the GNU General Public License
okini3939 0:8ba6230eefbd 16 * along with this program; if not, write to the Free Software
okini3939 0:8ba6230eefbd 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
okini3939 0:8ba6230eefbd 18 *
okini3939 0:8ba6230eefbd 19 * $Id: decoder.c,v 1.1 2010/11/23 20:12:57 andy Exp $
okini3939 0:8ba6230eefbd 20 */
okini3939 0:8ba6230eefbd 21
okini3939 0:8ba6230eefbd 22 # include "config.h"
okini3939 0:8ba6230eefbd 23
okini3939 0:8ba6230eefbd 24 # include "global.h"
okini3939 0:8ba6230eefbd 25
okini3939 0:8ba6230eefbd 26
okini3939 0:8ba6230eefbd 27 # ifdef HAVE_SYS_TYPES_H
okini3939 0:8ba6230eefbd 28 # include <sys/types.h>
okini3939 0:8ba6230eefbd 29 # endif
okini3939 0:8ba6230eefbd 30
okini3939 0:8ba6230eefbd 31 # ifdef HAVE_SYS_WAIT_H
okini3939 0:8ba6230eefbd 32 # include <sys/wait.h>
okini3939 0:8ba6230eefbd 33 # endif
okini3939 0:8ba6230eefbd 34
okini3939 0:8ba6230eefbd 35 # ifdef HAVE_UNISTD_H
okini3939 0:8ba6230eefbd 36 # include <unistd.h>
okini3939 0:8ba6230eefbd 37 # endif
okini3939 0:8ba6230eefbd 38
okini3939 0:8ba6230eefbd 39 # ifdef HAVE_FCNTL_H
okini3939 0:8ba6230eefbd 40 # include <fcntl.h>
okini3939 0:8ba6230eefbd 41 # endif
okini3939 0:8ba6230eefbd 42
okini3939 0:8ba6230eefbd 43 # include <stdlib.h>
okini3939 0:8ba6230eefbd 44
okini3939 0:8ba6230eefbd 45 # ifdef HAVE_ERRNO_H
okini3939 0:8ba6230eefbd 46 # include <errno.h>
okini3939 0:8ba6230eefbd 47 # endif
okini3939 0:8ba6230eefbd 48
okini3939 0:8ba6230eefbd 49 # include "stream.h"
okini3939 0:8ba6230eefbd 50 # include "frame.h"
okini3939 0:8ba6230eefbd 51 # include "synth.h"
okini3939 0:8ba6230eefbd 52 # include "decoder.h"
okini3939 0:8ba6230eefbd 53
okini3939 0:8ba6230eefbd 54 /*
okini3939 0:8ba6230eefbd 55 * NAME: decoder->init()
okini3939 0:8ba6230eefbd 56 * DESCRIPTION: initialize a decoder object with callback routines
okini3939 0:8ba6230eefbd 57 */
okini3939 0:8ba6230eefbd 58 void mad_decoder_init(struct mad_decoder *decoder, void *data,
okini3939 0:8ba6230eefbd 59 enum mad_flow (*input_func)(void *,
okini3939 0:8ba6230eefbd 60 struct mad_stream *),
okini3939 0:8ba6230eefbd 61 enum mad_flow (*header_func)(void *,
okini3939 0:8ba6230eefbd 62 struct mad_header const *),
okini3939 0:8ba6230eefbd 63 enum mad_flow (*filter_func)(void *,
okini3939 0:8ba6230eefbd 64 struct mad_stream const *,
okini3939 0:8ba6230eefbd 65 struct mad_frame *),
okini3939 0:8ba6230eefbd 66 enum mad_flow (*output_func)(void *,
okini3939 0:8ba6230eefbd 67 struct mad_header const *,
okini3939 0:8ba6230eefbd 68 struct mad_pcm *),
okini3939 0:8ba6230eefbd 69 enum mad_flow (*error_func)(void *,
okini3939 0:8ba6230eefbd 70 struct mad_stream *,
okini3939 0:8ba6230eefbd 71 struct mad_frame *),
okini3939 0:8ba6230eefbd 72 enum mad_flow (*message_func)(void *,
okini3939 0:8ba6230eefbd 73 void *, unsigned int *))
okini3939 0:8ba6230eefbd 74 {
okini3939 0:8ba6230eefbd 75 decoder->mode = (enum mad_decoder_mode)-1;
okini3939 0:8ba6230eefbd 76
okini3939 0:8ba6230eefbd 77 decoder->options = 0;
okini3939 0:8ba6230eefbd 78
okini3939 0:8ba6230eefbd 79
okini3939 0:8ba6230eefbd 80 decoder->sync = 0;
okini3939 0:8ba6230eefbd 81
okini3939 0:8ba6230eefbd 82 decoder->cb_data = data;
okini3939 0:8ba6230eefbd 83
okini3939 0:8ba6230eefbd 84 decoder->input_func = input_func;
okini3939 0:8ba6230eefbd 85 decoder->header_func = header_func;
okini3939 0:8ba6230eefbd 86 decoder->filter_func = filter_func;
okini3939 0:8ba6230eefbd 87 decoder->output_func = output_func;
okini3939 0:8ba6230eefbd 88 decoder->error_func = error_func;
okini3939 0:8ba6230eefbd 89 decoder->message_func = message_func;
okini3939 0:8ba6230eefbd 90 }
okini3939 0:8ba6230eefbd 91
okini3939 0:8ba6230eefbd 92 int mad_decoder_finish(struct mad_decoder *decoder)
okini3939 0:8ba6230eefbd 93 {
okini3939 0:8ba6230eefbd 94 return 0;
okini3939 0:8ba6230eefbd 95 }
okini3939 0:8ba6230eefbd 96
okini3939 0:8ba6230eefbd 97
okini3939 0:8ba6230eefbd 98 static
okini3939 0:8ba6230eefbd 99 enum mad_flow error_default(void *data, struct mad_stream *stream,
okini3939 0:8ba6230eefbd 100 struct mad_frame *frame)
okini3939 0:8ba6230eefbd 101 {
okini3939 0:8ba6230eefbd 102 int *bad_last_frame = (int *)data;
okini3939 0:8ba6230eefbd 103
okini3939 0:8ba6230eefbd 104 switch (stream->error) {
okini3939 0:8ba6230eefbd 105 case MAD_ERROR_BADCRC:
okini3939 0:8ba6230eefbd 106 if (*bad_last_frame)
okini3939 0:8ba6230eefbd 107 mad_frame_mute(frame);
okini3939 0:8ba6230eefbd 108 else
okini3939 0:8ba6230eefbd 109 *bad_last_frame = 1;
okini3939 0:8ba6230eefbd 110
okini3939 0:8ba6230eefbd 111 return MAD_FLOW_IGNORE;
okini3939 0:8ba6230eefbd 112
okini3939 0:8ba6230eefbd 113 default:
okini3939 0:8ba6230eefbd 114 return MAD_FLOW_CONTINUE;
okini3939 0:8ba6230eefbd 115 }
okini3939 0:8ba6230eefbd 116 }
okini3939 0:8ba6230eefbd 117
okini3939 0:8ba6230eefbd 118 static
okini3939 0:8ba6230eefbd 119 int run_sync(struct mad_decoder *decoder)
okini3939 0:8ba6230eefbd 120 {
okini3939 0:8ba6230eefbd 121 enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
okini3939 0:8ba6230eefbd 122 void *error_data;
okini3939 0:8ba6230eefbd 123 int bad_last_frame = 0;
okini3939 0:8ba6230eefbd 124 struct mad_stream *stream;
okini3939 0:8ba6230eefbd 125 struct mad_frame *frame;
okini3939 0:8ba6230eefbd 126 struct mad_synth *synth;
okini3939 0:8ba6230eefbd 127 int result = 0;
okini3939 0:8ba6230eefbd 128
okini3939 0:8ba6230eefbd 129 if (decoder->input_func == 0)
okini3939 0:8ba6230eefbd 130 return 0;
okini3939 0:8ba6230eefbd 131
okini3939 0:8ba6230eefbd 132 if (decoder->error_func) {
okini3939 0:8ba6230eefbd 133 error_func = decoder->error_func;
okini3939 0:8ba6230eefbd 134 error_data = decoder->cb_data;
okini3939 0:8ba6230eefbd 135 }
okini3939 0:8ba6230eefbd 136 else {
okini3939 0:8ba6230eefbd 137 error_func = error_default;
okini3939 0:8ba6230eefbd 138 error_data = &bad_last_frame;
okini3939 0:8ba6230eefbd 139 }
okini3939 0:8ba6230eefbd 140
okini3939 0:8ba6230eefbd 141 stream = &decoder->sync->stream;
okini3939 0:8ba6230eefbd 142 frame = &decoder->sync->frame;
okini3939 0:8ba6230eefbd 143 synth = decoder->sync->synth;
okini3939 0:8ba6230eefbd 144
okini3939 0:8ba6230eefbd 145 mad_stream_init(stream);
okini3939 0:8ba6230eefbd 146 mad_frame_init(frame);
okini3939 0:8ba6230eefbd 147 mad_synth_init(synth);
okini3939 0:8ba6230eefbd 148
okini3939 0:8ba6230eefbd 149 mad_stream_options(stream, decoder->options);
okini3939 0:8ba6230eefbd 150
okini3939 0:8ba6230eefbd 151 do {
okini3939 0:8ba6230eefbd 152 switch (decoder->input_func(decoder->cb_data, stream)) {
okini3939 0:8ba6230eefbd 153 case MAD_FLOW_STOP:
okini3939 0:8ba6230eefbd 154 goto done;
okini3939 0:8ba6230eefbd 155 case MAD_FLOW_BREAK:
okini3939 0:8ba6230eefbd 156 goto fail;
okini3939 0:8ba6230eefbd 157 case MAD_FLOW_IGNORE:
okini3939 0:8ba6230eefbd 158 continue;
okini3939 0:8ba6230eefbd 159 case MAD_FLOW_CONTINUE:
okini3939 0:8ba6230eefbd 160 break;
okini3939 0:8ba6230eefbd 161 }
okini3939 0:8ba6230eefbd 162
okini3939 0:8ba6230eefbd 163 while (1) {
okini3939 0:8ba6230eefbd 164 if (decoder->header_func) {
okini3939 0:8ba6230eefbd 165 if (mad_header_decode(&frame->header, stream) == -1) {
okini3939 0:8ba6230eefbd 166 if (!MAD_RECOVERABLE(stream->error))
okini3939 0:8ba6230eefbd 167 break;
okini3939 0:8ba6230eefbd 168
okini3939 0:8ba6230eefbd 169 switch (error_func(error_data, stream, frame)) {
okini3939 0:8ba6230eefbd 170 case MAD_FLOW_STOP:
okini3939 0:8ba6230eefbd 171 goto done;
okini3939 0:8ba6230eefbd 172 case MAD_FLOW_BREAK:
okini3939 0:8ba6230eefbd 173 goto fail;
okini3939 0:8ba6230eefbd 174 case MAD_FLOW_IGNORE:
okini3939 0:8ba6230eefbd 175 case MAD_FLOW_CONTINUE:
okini3939 0:8ba6230eefbd 176 default:
okini3939 0:8ba6230eefbd 177 continue;
okini3939 0:8ba6230eefbd 178 }
okini3939 0:8ba6230eefbd 179 }
okini3939 0:8ba6230eefbd 180
okini3939 0:8ba6230eefbd 181 switch (decoder->header_func(decoder->cb_data, &frame->header)) {
okini3939 0:8ba6230eefbd 182 case MAD_FLOW_STOP:
okini3939 0:8ba6230eefbd 183 goto done;
okini3939 0:8ba6230eefbd 184 case MAD_FLOW_BREAK:
okini3939 0:8ba6230eefbd 185 goto fail;
okini3939 0:8ba6230eefbd 186 case MAD_FLOW_IGNORE:
okini3939 0:8ba6230eefbd 187 continue;
okini3939 0:8ba6230eefbd 188 case MAD_FLOW_CONTINUE:
okini3939 0:8ba6230eefbd 189 break;
okini3939 0:8ba6230eefbd 190 }
okini3939 0:8ba6230eefbd 191 }
okini3939 0:8ba6230eefbd 192
okini3939 0:8ba6230eefbd 193 if (mad_frame_decode(frame, stream) == -1) {
okini3939 0:8ba6230eefbd 194 if (!MAD_RECOVERABLE(stream->error))
okini3939 0:8ba6230eefbd 195 break;
okini3939 0:8ba6230eefbd 196
okini3939 0:8ba6230eefbd 197 switch (error_func(error_data, stream, frame)) {
okini3939 0:8ba6230eefbd 198 case MAD_FLOW_STOP:
okini3939 0:8ba6230eefbd 199 goto done;
okini3939 0:8ba6230eefbd 200 case MAD_FLOW_BREAK:
okini3939 0:8ba6230eefbd 201 goto fail;
okini3939 0:8ba6230eefbd 202 case MAD_FLOW_IGNORE:
okini3939 0:8ba6230eefbd 203 break;
okini3939 0:8ba6230eefbd 204 case MAD_FLOW_CONTINUE:
okini3939 0:8ba6230eefbd 205 default:
okini3939 0:8ba6230eefbd 206 continue;
okini3939 0:8ba6230eefbd 207 }
okini3939 0:8ba6230eefbd 208 }
okini3939 0:8ba6230eefbd 209 else
okini3939 0:8ba6230eefbd 210 bad_last_frame = 0;
okini3939 0:8ba6230eefbd 211
okini3939 0:8ba6230eefbd 212 if (decoder->filter_func) {
okini3939 0:8ba6230eefbd 213 switch (decoder->filter_func(decoder->cb_data, stream, frame)) {
okini3939 0:8ba6230eefbd 214 case MAD_FLOW_STOP:
okini3939 0:8ba6230eefbd 215 goto done;
okini3939 0:8ba6230eefbd 216 case MAD_FLOW_BREAK:
okini3939 0:8ba6230eefbd 217 goto fail;
okini3939 0:8ba6230eefbd 218 case MAD_FLOW_IGNORE:
okini3939 0:8ba6230eefbd 219 continue;
okini3939 0:8ba6230eefbd 220 case MAD_FLOW_CONTINUE:
okini3939 0:8ba6230eefbd 221 break;
okini3939 0:8ba6230eefbd 222 }
okini3939 0:8ba6230eefbd 223 }
okini3939 0:8ba6230eefbd 224
okini3939 0:8ba6230eefbd 225 mad_synth_frame(synth, frame);
okini3939 0:8ba6230eefbd 226
okini3939 0:8ba6230eefbd 227 if (decoder->output_func) {
okini3939 0:8ba6230eefbd 228 switch (decoder->output_func(decoder->cb_data,
okini3939 0:8ba6230eefbd 229 &frame->header, &synth->pcm)) {
okini3939 0:8ba6230eefbd 230 case MAD_FLOW_STOP:
okini3939 0:8ba6230eefbd 231 goto done;
okini3939 0:8ba6230eefbd 232 case MAD_FLOW_BREAK:
okini3939 0:8ba6230eefbd 233 goto fail;
okini3939 0:8ba6230eefbd 234 case MAD_FLOW_IGNORE:
okini3939 0:8ba6230eefbd 235 case MAD_FLOW_CONTINUE:
okini3939 0:8ba6230eefbd 236 break;
okini3939 0:8ba6230eefbd 237 }
okini3939 0:8ba6230eefbd 238 }
okini3939 0:8ba6230eefbd 239 }
okini3939 0:8ba6230eefbd 240 }
okini3939 0:8ba6230eefbd 241 while (stream->error == MAD_ERROR_BUFLEN);
okini3939 0:8ba6230eefbd 242
okini3939 0:8ba6230eefbd 243 fail:
okini3939 0:8ba6230eefbd 244 result = -1;
okini3939 0:8ba6230eefbd 245
okini3939 0:8ba6230eefbd 246 done:
okini3939 0:8ba6230eefbd 247 mad_synth_finish(synth);
okini3939 0:8ba6230eefbd 248 mad_frame_finish(frame);
okini3939 0:8ba6230eefbd 249 mad_stream_finish(stream);
okini3939 0:8ba6230eefbd 250
okini3939 0:8ba6230eefbd 251 return result;
okini3939 0:8ba6230eefbd 252 }
okini3939 0:8ba6230eefbd 253
okini3939 0:8ba6230eefbd 254
okini3939 0:8ba6230eefbd 255 /*
okini3939 0:8ba6230eefbd 256 * NAME: decoder->run()
okini3939 0:8ba6230eefbd 257 * DESCRIPTION: run the decoder thread either synchronously or asynchronously
okini3939 0:8ba6230eefbd 258 */
okini3939 0:8ba6230eefbd 259 int mad_decoder_run(struct mad_decoder *decoder, enum mad_decoder_mode mode)
okini3939 0:8ba6230eefbd 260 {
okini3939 0:8ba6230eefbd 261 int result;
okini3939 0:8ba6230eefbd 262 int (*run)(struct mad_decoder *) = 0;
okini3939 0:8ba6230eefbd 263
okini3939 0:8ba6230eefbd 264 switch (decoder->mode = mode) {
okini3939 0:8ba6230eefbd 265 case MAD_DECODER_MODE_SYNC:
okini3939 0:8ba6230eefbd 266 run = run_sync;
okini3939 0:8ba6230eefbd 267 break;
okini3939 0:8ba6230eefbd 268
okini3939 0:8ba6230eefbd 269 case MAD_DECODER_MODE_ASYNC:
okini3939 0:8ba6230eefbd 270 break;
okini3939 0:8ba6230eefbd 271 }
okini3939 0:8ba6230eefbd 272
okini3939 0:8ba6230eefbd 273 if (run == 0)
okini3939 0:8ba6230eefbd 274 return -1;
okini3939 0:8ba6230eefbd 275 // static struct mad_sync_s sync_mem;
okini3939 0:8ba6230eefbd 276 decoder->sync = (struct mad_sync_s *)malloc(sizeof(*decoder->sync));
okini3939 0:8ba6230eefbd 277 #if defined(TARGET_LPC1768)
okini3939 0:8ba6230eefbd 278 decoder->sync->synth = (struct mad_synth *)mad_malloc(sizeof(struct mad_synth));
okini3939 0:8ba6230eefbd 279 #else
okini3939 0:8ba6230eefbd 280 decoder->sync->synth = (struct mad_synth *)malloc(sizeof(struct mad_synth));
okini3939 0:8ba6230eefbd 281 #endif
okini3939 0:8ba6230eefbd 282 if (decoder->sync == 0)
okini3939 0:8ba6230eefbd 283 return -1;
okini3939 0:8ba6230eefbd 284
okini3939 0:8ba6230eefbd 285 result = run(decoder);
okini3939 0:8ba6230eefbd 286 #if !defined(TARGET_LPC1768)
okini3939 0:8ba6230eefbd 287 free(decoder->sync->synth);
okini3939 0:8ba6230eefbd 288 #endif
okini3939 0:8ba6230eefbd 289 free(decoder->sync);
okini3939 0:8ba6230eefbd 290 decoder->sync = 0;
okini3939 0:8ba6230eefbd 291 #if defined(TARGET_LPC1768)
okini3939 0:8ba6230eefbd 292 reset_ahb_mem();
okini3939 0:8ba6230eefbd 293 #endif
okini3939 0:8ba6230eefbd 294 return result;
okini3939 0:8ba6230eefbd 295 }
okini3939 0:8ba6230eefbd 296
okini3939 0:8ba6230eefbd 297 /*
okini3939 0:8ba6230eefbd 298 * NAME: decoder->message()
okini3939 0:8ba6230eefbd 299 * DESCRIPTION: send a message to and receive a reply from the decoder process
okini3939 0:8ba6230eefbd 300 */
okini3939 0:8ba6230eefbd 301 int mad_decoder_message(struct mad_decoder *decoder,
okini3939 0:8ba6230eefbd 302 void *message, unsigned int *len)
okini3939 0:8ba6230eefbd 303 {
okini3939 0:8ba6230eefbd 304 return -1;
okini3939 0:8ba6230eefbd 305 }