diff --git a/engine/client/mymad.c b/engine/client/mymad.c new file mode 100644 index 000000000..7f14ed532 --- /dev/null +++ b/engine/client/mymad.c @@ -0,0 +1,246 @@ +#ifdef USE_MADLIB + +#define HAVE_CONFIG_H +#define ASO_ZEROCHECK +#ifndef _MBCS +#define _MBCS +#endif + + +# ifdef HAVE_CONFIG_H +# include "libmad/mad.h" +//# include "config.h" +# endif + +//# include "global.h" + +# ifdef HAVE_SYS_TYPES_H +# include +# endif + +# ifdef HAVE_SYS_WAIT_H +# include +# endif + +# ifdef HAVE_UNISTD_H +# include +# endif + +# ifdef HAVE_FCNTL_H +# include +# endif + +# include + +# ifdef HAVE_ERRNO_H +# include +# endif + +# include "libmad/stream.h" +# include "libmad/frame.h" +# include "libmad/synth.h" +# include "libmad/decoder.h" + + + + + + + + + +static +enum mad_flow error_default(void *data, struct mad_stream *stream, + struct mad_frame *frame) +{ + int *bad_last_frame = data; + + switch (stream->error) { + case MAD_ERROR_BADCRC: + if (*bad_last_frame) + mad_frame_mute(frame); + else + *bad_last_frame = 1; + + return MAD_FLOW_IGNORE; + + default: + return MAD_FLOW_CONTINUE; + } +} + + + + +int mymad_reset(struct mad_decoder *decoder) +{ +// enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); +// void *error_data; + int bad_last_frame = 0; + struct mad_stream *stream; + struct mad_frame *frame; + struct mad_synth *synth; + int result = 0; + + if (decoder->input_func == 0) + return 0; + + decoder->sync = malloc(sizeof(*decoder->sync)); + if (decoder->sync == 0) + return 0; + + stream = &decoder->sync->stream; + frame = &decoder->sync->frame; + synth = &decoder->sync->synth; + + mad_stream_init(stream); + mad_frame_init(frame); + mad_synth_init(synth); + + mad_stream_options(stream, decoder->options); + + return 1; +} + +int mymad_run(struct mad_decoder *decoder) +{ + enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); + void *error_data; + int bad_last_frame = 0; + struct mad_stream *stream; + struct mad_frame *frame; + struct mad_synth *synth; + + stream = &decoder->sync->stream; + frame = &decoder->sync->frame; + synth = &decoder->sync->synth; + + if (decoder->error_func) { + error_func = decoder->error_func; + error_data = decoder->cb_data; + } + else { + error_func = error_default; + error_data = &bad_last_frame; + } + + if (stream->next_frame >= stream->bufend) + switch (decoder->input_func(decoder->cb_data, stream)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + return 1; + case MAD_FLOW_CONTINUE: + break; + } + +for(;;) +{ + if (decoder->header_func) { + if (mad_header_decode(&frame->header, stream) == -1) { + if (!MAD_RECOVERABLE(stream->error)) + break; + + switch (error_func(error_data, stream, frame)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + case MAD_FLOW_CONTINUE: + default: + return 1; + } + } + + switch (decoder->header_func(decoder->cb_data, &frame->header)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + return 1; + case MAD_FLOW_CONTINUE: + break; + } + } + + if (mad_frame_decode(frame, stream) == -1) { + if (!MAD_RECOVERABLE(stream->error)) + break; + + switch (error_func(error_data, stream, frame)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + break; + case MAD_FLOW_CONTINUE: + default: + return 1; + } + } + else + bad_last_frame = 0; + + if (decoder->filter_func) { + switch (decoder->filter_func(decoder->cb_data, stream, frame)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + return 1; + case MAD_FLOW_CONTINUE: + break; + } + } + + mad_synth_frame(synth, frame); + + if (decoder->output_func) { + switch (decoder->output_func(decoder->cb_data, + &frame->header, &synth->pcm)) { + case MAD_FLOW_STOP: + goto done; + case MAD_FLOW_BREAK: + goto fail; + case MAD_FLOW_IGNORE: + case MAD_FLOW_CONTINUE: + break; + } + } + return 1; + } + + return 0; + +fail: + return 0; + +done: + return 0; +} + +void mymad_finish(struct mad_decoder *decoder) +{ + struct mad_stream *stream; + struct mad_frame *frame; + struct mad_synth *synth; + + stream = &decoder->sync->stream; + frame = &decoder->sync->frame; + synth = &decoder->sync->synth; + + mad_synth_finish(synth); + mad_frame_finish(frame); + mad_stream_finish(stream); + + free(decoder->sync); +} + + +#endif