shithub: sox

Download patch

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;
 }