So you can enable the mp3 decoder with the appropriate library. I'm not going to add this as a default option for probably some time to come.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@926 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
d7bb31a516
commit
36b239f0cf
1 changed files with 246 additions and 0 deletions
246
engine/client/mymad.c
Normal file
246
engine/client/mymad.c
Normal file
|
@ -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 <sys/types.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef HAVE_SYS_WAIT_H
|
||||||
|
# include <sys/wait.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef HAVE_FCNTL_H
|
||||||
|
# include <fcntl.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# include <stdlib.h>
|
||||||
|
|
||||||
|
# ifdef HAVE_ERRNO_H
|
||||||
|
# include <errno.h>
|
||||||
|
# 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
|
Loading…
Reference in a new issue