ref: 7fa7da16022d3d00ce03e4f04d3fa69d82a8267f
parent: f146ff926e672d89f5e8c2db690e65f725b3e464
author: cbagwell <cbagwell>
date: Sun May 10 23:50:41 EDT 2009
Use indirection for MP3 functions to dlopen() possible.
--- a/src/mp3.c
+++ b/src/mp3.c
@@ -40,9 +40,42 @@
unsigned char *InputBuffer;
ptrdiff_t cursamp;
size_t FrameCount;
+
+ void (*mad_stream_buffer)(struct mad_stream *, unsigned char const *,
+ unsigned long);
+ void (*mad_stream_skip)(struct mad_stream *, unsigned long);
+ int (*mad_stream_sync)(struct mad_stream *);
+ void (*mad_stream_init)(struct mad_stream *);
+ void (*mad_frame_init)(struct mad_frame *);
+ void (*mad_synth_init)(struct mad_synth *);
+ int (*mad_frame_decode)(struct mad_frame *, struct mad_stream *);
+ void (*mad_timer_add)(mad_timer_t *, mad_timer_t);
+ void (*mad_synth_frame)(struct mad_synth *, struct mad_frame const *);
+ char const *(*mad_stream_errorstr)(struct mad_stream const *);
+ void (*mad_frame_finish)(struct mad_frame *);
+ void (*mad_stream_finish)(struct mad_stream *);
#endif /*HAVE_MAD_H*/
#ifdef HAVE_LAME_LAME_H
lame_global_flags *gfp;
+
+ lame_global_flags * (*lame_init)(void);
+ int (*lame_set_num_channels)(lame_global_flags *, int);
+ int (*lame_get_num_channels)(const lame_global_flags *);
+ int (*lame_set_in_samplerate)(lame_global_flags *, int);
+ int (*lame_set_bWriteVbrTag)(lame_global_flags *, int);
+ int (*lame_init_params)(lame_global_flags *);
+ int (*lame_set_errorf)(lame_global_flags *,
+ void (*func)(const char *, va_list));
+ int (*lame_set_debugf)(lame_global_flags *,
+ void (*func)(const char *, va_list));
+ int (*lame_set_msgf)(lame_global_flags *,
+ void (*func)(const char *, va_list));
+ int (*lame_encode_buffer)(lame_global_flags *, const short int[],
+ const short int[], const int,
+ unsigned char *, const int);
+ int (*lame_encode_flush)(lame_global_flags *, unsigned char *,
+ int);
+ int (*lame_close)(lame_global_flags *);
#endif /*HAVE_LAME_LAME_H*/
} priv_t;
@@ -143,7 +176,7 @@
remaining = p->Stream.bufend - p->Stream.next_frame;
if ((tagsize = tagtype(p->Stream.this_frame, remaining)))
{
- mad_stream_skip(&p->Stream, tagsize);
+ p->mad_stream_skip(&p->Stream, tagsize);
rc = SOX_SUCCESS;
}
@@ -151,7 +184,7 @@
* so help libmad out and go back into frame seek mode.
* This is true whether an ID3 tag was found or not.
*/
- mad_stream_sync(&p->Stream);
+ p->mad_stream_sync(&p->Stream);
return rc;
}
@@ -162,6 +195,19 @@
size_t ReadSize;
sox_bool ignore_length = ft->signal.length == SOX_IGNORE_LENGTH;
+ p->mad_stream_buffer = mad_stream_buffer;
+ p->mad_stream_skip = mad_stream_skip;
+ p->mad_stream_sync = mad_stream_sync;
+ p->mad_stream_init = mad_stream_init;
+ p->mad_frame_init = mad_frame_init;
+ p->mad_synth_init = mad_synth_init;
+ p->mad_frame_decode = mad_frame_decode;
+ p->mad_timer_add = mad_timer_add;
+ p->mad_synth_frame = mad_synth_frame;
+ p->mad_stream_errorstr = mad_stream_errorstr;
+ p->mad_frame_finish = mad_frame_finish;
+ p->mad_stream_finish = mad_stream_finish;
+
p->InputBuffer = NULL;
p->InputBuffer=lsx_malloc(INPUT_BUFFER_SIZE);
@@ -177,9 +223,9 @@
ft->signal.length = mp3_duration_ms(ft->fp, p->InputBuffer);
}
- mad_stream_init(&p->Stream);
- mad_frame_init(&p->Frame);
- mad_synth_init(&p->Synth);
+ p->mad_stream_init(&p->Stream);
+ p->mad_frame_init(&p->Frame);
+ p->mad_synth_init(&p->Synth);
mad_timer_reset(&p->Timer);
ft->encoding.encoding = SOX_ENCODING_MP3;
@@ -192,7 +238,7 @@
if (ReadSize != INPUT_BUFFER_SIZE && ferror(ft->fp))
return SOX_EOF;
- mad_stream_buffer(&p->Stream, p->InputBuffer, ReadSize);
+ p->mad_stream_buffer(&p->Stream, p->InputBuffer, ReadSize);
/* Find a valid frame before starting up. This makes sure
* that we have a valid MP3 and also skips past ID3v2 tags
@@ -199,7 +245,7 @@
* at the beginning of the audio file.
*/
p->Stream.error = 0;
- while (mad_frame_decode(&p->Frame,&p->Stream))
+ while (p->mad_frame_decode(&p->Frame,&p->Stream))
{
/* check whether input buffer needs a refill */
if (p->Stream.error == MAD_ERROR_BUFLEN)
@@ -242,8 +288,8 @@
p->FrameCount=1;
- mad_timer_add(&p->Timer,p->Frame.header.duration);
- mad_synth_frame(&p->Synth,&p->Frame);
+ p->mad_timer_add(&p->Timer,p->Frame.header.duration);
+ p->mad_synth_frame(&p->Synth,&p->Frame);
ft->signal.rate=p->Synth.pcm.samplerate;
if (ignore_length)
ft->signal.length = SOX_UNSPEC;
@@ -301,7 +347,7 @@
}
}
- if (mad_frame_decode(&p->Frame,&p->Stream))
+ if (p->mad_frame_decode(&p->Frame,&p->Stream))
{
if(MAD_RECOVERABLE(p->Stream.error))
{
@@ -315,14 +361,14 @@
else
{
lsx_report("unrecoverable frame level error (%s).",
- mad_stream_errorstr(&p->Stream));
+ p->mad_stream_errorstr(&p->Stream));
break;
}
}
}
p->FrameCount++;
- mad_timer_add(&p->Timer,p->Frame.header.duration);
- mad_synth_frame(&p->Synth,&p->Frame);
+ p->mad_timer_add(&p->Timer,p->Frame.header.duration);
+ p->mad_synth_frame(&p->Synth,&p->Frame);
p->cursamp=0;
} while(1);
@@ -334,8 +380,8 @@
priv_t *p=(priv_t*) ft->priv;
mad_synth_finish(&p->Synth);
- mad_frame_finish(&p->Frame);
- mad_stream_finish(&p->Stream);
+ p->mad_frame_finish(&p->Frame);
+ p->mad_stream_finish(&p->Stream);
free(p->InputBuffer);
@@ -361,6 +407,19 @@
{
priv_t *p = (priv_t *) ft->priv;
+ p->lame_init = lame_init;
+ p->lame_set_num_channels = lame_set_num_channels;
+ p->lame_get_num_channels = lame_get_num_channels;
+ p->lame_set_in_samplerate = lame_set_in_samplerate;
+ p->lame_set_bWriteVbrTag = lame_set_bWriteVbrTag;
+ p->lame_init_params = lame_init_params;
+ p->lame_set_errorf = lame_set_errorf;
+ p->lame_set_debugf = lame_set_debugf;
+ p->lame_set_msgf = lame_set_msgf;
+ p->lame_encode_buffer = lame_encode_buffer;
+ p->lame_encode_flush = lame_encode_flush;
+ p->lame_close = lame_close;
+
if (ft->encoding.encoding != SOX_ENCODING_MP3) {
if(ft->encoding.encoding != SOX_ENCODING_UNKNOWN)
lsx_report("Encoding forced to MP3");
@@ -367,7 +426,7 @@
ft->encoding.encoding = SOX_ENCODING_MP3;
}
- p->gfp = lame_init();
+ p->gfp = p->lame_init();
if (p->gfp == NULL){
lsx_fail_errno(ft,SOX_EOF,"Initialization of LAME library failed");
return(SOX_EOF);
@@ -374,17 +433,17 @@
}
if (ft->signal.channels != SOX_ENCODING_UNKNOWN) {
- if ( (lame_set_num_channels(p->gfp,(int)ft->signal.channels)) < 0) {
+ if ( (p->lame_set_num_channels(p->gfp,(int)ft->signal.channels)) < 0) {
lsx_fail_errno(ft,SOX_EOF,"Unsupported number of channels");
return(SOX_EOF);
}
}
else
- ft->signal.channels = lame_get_num_channels(p->gfp); /* LAME default */
+ ft->signal.channels = p->lame_get_num_channels(p->gfp); /* LAME default */
- lame_set_in_samplerate(p->gfp,(int)ft->signal.rate);
+ p->lame_set_in_samplerate(p->gfp,(int)ft->signal.rate);
- lame_set_bWriteVbrTag(p->gfp, 0); /* disable writing VBR tag */
+ p->lame_set_bWriteVbrTag(p->gfp, 0); /* disable writing VBR tag */
/* The bitrate, mode, quality and other settings are the default ones,
since SoX's command line options do not allow to set them */
@@ -394,13 +453,13 @@
as a compressed bit-rate. */
if (ft->encoding.compression != HUGE_VAL)
lsx_warn("-C option not supported for mp3; using default compression rate");
- if (lame_init_params(p->gfp) < 0){
+ if (p->lame_init_params(p->gfp) < 0){
lsx_fail_errno(ft,SOX_EOF,"LAME initialization failed");
return(SOX_EOF);
}
- lame_set_errorf(p->gfp,null_error_func);
- lame_set_debugf(p->gfp,null_error_func);
- lame_set_msgf (p->gfp,null_error_func);
+ p->lame_set_errorf(p->gfp,null_error_func);
+ p->lame_set_debugf(p->gfp,null_error_func);
+ p->lame_set_msgf (p->gfp,null_error_func);
return(SOX_SUCCESS);
}
@@ -458,9 +517,10 @@
mp3buffer_size = 1.25 * nsamples + 7200;
mp3buffer = lsx_malloc(mp3buffer_size);
- if ((written = lame_encode_buffer(p->gfp,buffer_l, buffer_r,
- nsamples, mp3buffer,
- (int)mp3buffer_size)) > mp3buffer_size){
+ if ((written =
+ p->lame_encode_buffer(p->gfp,buffer_l, buffer_r,
+ nsamples, mp3buffer,
+ (int)mp3buffer_size)) > mp3buffer_size){
lsx_fail_errno(ft,SOX_EOF,"Encoding failed");
goto end;
}
@@ -486,7 +546,7 @@
{
priv_t *p = (priv_t *) ft->priv;
unsigned char mp3buffer[7200];
- int written = lame_encode_flush(p->gfp, mp3buffer, (int)sizeof(mp3buffer));
+ int written = p->lame_encode_flush(p->gfp, mp3buffer, (int)sizeof(mp3buffer));
if (written < 0)
lsx_fail_errno(ft, SOX_EOF, "Encoding failed");
@@ -493,7 +553,7 @@
else if (lsx_writebuf(ft, mp3buffer, (size_t)written) < (size_t)written)
lsx_fail_errno(ft, SOX_EOF, "File write failed");
- lame_close(p->gfp);
+ p->lame_close(p->gfp);
return SOX_SUCCESS;
}