Package: sox
Version: 12.17.9-1
Followup-For: Bug #382275
Sorry, I forgot to attach the patch before.
-- System Information:
Debian Release: testing/unstable
APT prefers testing
APT policy: (500, 'testing')
Architecture: i386 (i686)
Shell: /bin/sh linked to /bin/bash
Kernel: Linux 2.6.17-2-686
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Versions of packages sox depends on:
ii libasound2 1.0.13-1 ALSA library
ii libc6 2.3.6.ds1-7 GNU C Library: Shared libraries
ii libmad0 0.15.1b-2.1 MPEG audio decoder library
ii libogg0 1.1.3-2 Ogg Bitstream Library
ii libvorbis0a 1.1.2.dfsg-1.2 The Vorbis General Audio Compressi
ii libvorbisenc2 1.1.2.dfsg-1.2 The Vorbis General Audio Compressi
ii libvorbisfile3 1.1.2.dfsg-1.2 The Vorbis General Audio Compressi
sox recommends no packages.
-- no debconf information
--- sox-12.18.2/src/mp3.c 2006-11-06 05:59:08.000000000 +0000
+++ sox-12.18.2/src/mp3.c 2006-11-06 07:28:10.000000000 +0000
@@ -13,6 +13,7 @@
#include "st_i.h"
#include <string.h>
+#include <dlfcn.h>
#if defined(HAVE_LIBMAD) || defined(HAVE_LAME)
@@ -47,6 +48,121 @@
#endif /*HAVE_LAME*/
};
+#if defined(HAVE_LIBMAD)
+static void (*dl_mad_frame_init)(struct mad_frame *);
+static void (*dl_mad_frame_finish)(struct mad_frame *);
+static int (*dl_mad_frame_decode)(struct mad_frame *, struct mad_stream *);
+static void (*dl_mad_stream_init)(struct mad_stream *);
+static void (*dl_mad_stream_finish)(struct mad_stream *);
+static void (*dl_mad_stream_buffer)(struct mad_stream *, unsigned char const *, unsigned long);
+static char const *(*dl_mad_stream_errorstr)(struct mad_stream const *);
+static void (*dl_mad_stream_skip)(struct mad_stream *, unsigned long);
+static void (*dl_mad_synth_init)(struct mad_synth *);
+static void (*dl_mad_synth_frame)(struct mad_synth *, struct mad_frame const *);
+static void (*dl_mad_timer_add)(mad_timer_t *, mad_timer_t);
+
+#define dl_mad_timer_reset(timer) ((void) (*(timer) = *dl_mad_timer_zero))
+static mad_timer_t const *dl_mad_timer_zero;
+
+#define dl_mad_synth_finish(synth) /* nothing */
+
+static int load_mad(void) {
+ static int loaded=0;
+ void *library;
+
+ if (loaded) return 0;
+
+ library = dlopen("libmad.so",RTLD_NOW);
+
+ if (!(dl_mad_frame_decode = dlsym(library,"mad_frame_decode")))
+ return -1;
+ if (!(dl_mad_frame_finish = dlsym(library,"mad_frame_finish")))
+ return -1;
+ if (!(dl_mad_frame_init = dlsym(library,"mad_frame_init")))
+ return -1;
+ if (!(dl_mad_stream_buffer = dlsym(library,"mad_stream_buffer")))
+ return -1;
+ if (!(dl_mad_stream_errorstr = dlsym(library,"mad_stream_errorstr")))
+ return -1;
+ if (!(dl_mad_stream_finish = dlsym(library,"mad_stream_finish")))
+ return -1;
+ if (!(dl_mad_stream_init = dlsym(library,"mad_stream_init")))
+ return -1;
+ if (!(dl_mad_stream_skip = dlsym(library,"mad_stream_skip")))
+ return -1;
+ if (!(dl_mad_synth_frame = dlsym(library,"mad_synth_frame")))
+ return -1;
+ if (!(dl_mad_synth_init = dlsym(library,"mad_synth_init")))
+ return -1;
+ if (!(dl_mad_timer_add = dlsym(library,"mad_timer_add")))
+ return -1;
+ if (!(dl_mad_timer_zero = dlsym(library,"mad_timer_zero")))
+ return -1;
+
+ loaded++;
+ return 0;
+}
+#endif
+
+#if defined(HAVE_LAME)
+static int (*dl_lame_close)(lame_global_flags *);
+static int (*dl_lame_encode_buffer_long2)(
+ lame_global_flags*,
+ const long buffer_l [],
+ const long buffer_r [],
+ const int ,
+ unsigned char* ,
+ const int );
+static int (*dl_lame_encode_flush)(lame_global_flags *, unsigned char* , int);
+static lame_global_flags *(*dl_lame_init)(void);
+static int (*dl_lame_init_params)(lame_global_flags * const );
+static int (*dl_lame_set_bWriteVbrTag)(lame_global_flags *, int);
+static int (*dl_lame_set_errorf)(lame_global_flags *, void (*func)(const char *, va_list));
+static int (*dl_lame_set_debugf)(lame_global_flags *, void (*func)(const char *, va_list));
+static int (*dl_lame_set_msgf)(lame_global_flags *, void (*func)(const char *, va_list));
+static int (*dl_lame_set_in_samplerate)(lame_global_flags *, int);
+static int (*dl_lame_get_num_channels)(const lame_global_flags *);
+static int (*dl_lame_set_num_channels)(lame_global_flags *, int);
+
+static int load_lame(void)
+{
+ static int loaded=0;
+ void *library;
+
+ if (loaded) return 0;
+
+ library = dlopen("libmp3lame.so",RTLD_NOW);
+
+ if (!(dl_lame_close = dlsym (library, "lame_close")))
+ return -1;
+ if (!(dl_lame_encode_buffer_long2 = dlsym (library, "lame_encode_buffer_long2")))
+ return -1;
+ if (!(dl_lame_encode_flush = dlsym (library, "lame_encode_flush")))
+ return -1;
+ if (!(dl_lame_get_num_channels = dlsym (library, "lame_get_num_channels")))
+ return -1;
+ if (!(dl_lame_init = dlsym (library, "lame_init")))
+ return -1;
+ if (!(dl_lame_init_params = dlsym (library, "lame_init_params")))
+ return -1;
+ if (!(dl_lame_set_bWriteVbrTag = dlsym (library, "lame_set_bWriteVbrTag")))
+ return -1;
+ if (!(dl_lame_set_debugf = dlsym (library, "lame_set_debugf")))
+ return -1;
+ if (!(dl_lame_set_errorf = dlsym (library, "lame_set_errorf")))
+ return -1;
+ if (!(dl_lame_set_in_samplerate = dlsym (library, "lame_set_in_samplerate")))
+ return -1;
+ if (!(dl_lame_set_msgf = dlsym (library, "lame_set_msgf")))
+ return -1;
+ if (!(dl_lame_set_num_channels = dlsym (library, "lame_set_num_channels")))
+ return -1;
+
+ loaded++;
+ return 0;
+}
+#endif /*HAVE_LAME*/
+
#if defined(HAVE_LIBMAD)
/* This function merges the functions tagtype() and id3_tag_query()
@@ -82,6 +198,11 @@
struct mp3priv *p = (struct mp3priv *) ft->priv;
size_t ReadSize;
+ if (load_mad()) {
+ st_fail_errno(ft,ST_EOF,"SoX was compiled without MP3 decoding support");
+ return ST_EOF;
+ }
+
p->Stream=(struct mad_stream *)malloc(sizeof(struct mad_stream));
if (p->Stream == NULL){
st_fail_errno(ft, ST_ENOMEM, "Could not allocate memory");
@@ -122,10 +243,10 @@
return ST_EOF;
}
- mad_stream_init(p->Stream);
- mad_frame_init(p->Frame);
- mad_synth_init(p->Synth);
- mad_timer_reset(p->Timer);
+ dl_mad_stream_init(p->Stream);
+ dl_mad_frame_init(p->Frame);
+ dl_mad_synth_init(p->Synth);
+ dl_mad_timer_reset(p->Timer);
ft->info.encoding = ST_ENCODING_MP3;
ft->info.size = ST_SIZE_WORD;
@@ -143,14 +264,14 @@
return(ST_EOF);
}
- mad_stream_buffer(p->Stream,p->InputBuffer,ReadSize);
+ dl_mad_stream_buffer(p->Stream,p->InputBuffer,ReadSize);
p->Stream->error = 0;
/* Find a valid frame before starting up. This makes sure
* that we have a valid MP3 and also skips past ID3v2 tags
* at the beginning of the audio file.
*/
- while(mad_frame_decode(p->Frame,p->Stream)) {
+ while(dl_mad_frame_decode(p->Frame,p->Stream)) {
int tagsize;
size_t remaining;
@@ -166,7 +287,7 @@
}
remaining+=ReadSize;
- mad_stream_buffer(p->Stream, p->InputBuffer, remaining);
+ dl_mad_stream_buffer(p->Stream, p->InputBuffer, remaining);
p->Stream->error = 0;
}
@@ -200,7 +321,7 @@
goto more_data;
}
- mad_stream_skip(p->Stream, tagsize);
+ dl_mad_stream_skip(p->Stream, tagsize);
}
/* TODO: It would be nice to look for Xing VBR headers
@@ -226,8 +347,8 @@
p->FrameCount=1;
ft->info.rate=p->Frame->header.samplerate;
- mad_timer_add(p->Timer,p->Frame->header.duration);
- mad_synth_frame(p->Synth,p->Frame);
+ dl_mad_timer_add(p->Timer,p->Frame->header.duration);
+ dl_mad_synth_frame(p->Synth,p->Frame);
p->cursamp = 0;
p->eof = 0;
@@ -248,6 +369,11 @@
mad_fixed_t sample;
int chan;
+ if (load_mad()) {
+ st_fail_errno(ft,ST_EOF,"SoX was compiled without MP3 decoding support");
+ return ST_EOF;
+ }
+
do{
donow=MIN(len,(p->Synth->pcm.length - p->cursamp)*ft->info.channels);
i=0;
@@ -297,20 +423,20 @@
ReadSize=MAD_BUFFER_GUARD;
}
- mad_stream_buffer(p->Stream,p->InputBuffer,ReadSize+Remaining);
+ dl_mad_stream_buffer(p->Stream,p->InputBuffer,ReadSize+Remaining);
p->Stream->error = 0;
}
- if(mad_frame_decode(p->Frame,p->Stream)){
+ if(dl_mad_frame_decode(p->Frame,p->Stream)){
if(MAD_RECOVERABLE(p->Stream->error))
{
int tagsize;
if ( (tagsize=tagtype(p->Stream->this_frame, p->Stream->bufend - p->Stream->this_frame)) == 0){
if (!p->eof)
st_report("recoverable frame level error (%s).\n",
- mad_stream_errorstr(p->Stream));
+ dl_mad_stream_errorstr(p->Stream));
}
- else mad_stream_skip(p->Stream,tagsize);
+ else dl_mad_stream_skip(p->Stream,tagsize);
continue;
}
else
@@ -320,14 +446,14 @@
else
{
st_report("unrecoverable frame level error (%s).\n",
- mad_stream_errorstr(p->Stream));
+ dl_mad_stream_errorstr(p->Stream));
return done;
}
}
}
p->FrameCount++;
- mad_timer_add(p->Timer,p->Frame->header.duration);
- mad_synth_frame(p->Synth,p->Frame);
+ dl_mad_timer_add(p->Timer,p->Frame->header.duration);
+ dl_mad_synth_frame(p->Synth,p->Frame);
p->cursamp=0;
}while(1);
@@ -338,9 +464,14 @@
{
struct mp3priv *p=(struct mp3priv*) ft->priv;
- mad_synth_finish(p->Synth);
- mad_frame_finish(p->Frame);
- mad_stream_finish(p->Stream);
+ if (load_mad()) {
+ st_fail_errno(ft,ST_EOF,"SoX was compiled without MP3 decoding support");
+ return ST_EOF;
+ }
+
+ dl_mad_synth_finish(p->Synth);
+ dl_mad_frame_finish(p->Frame);
+ dl_mad_stream_finish(p->Stream);
free(p->Stream);
free(p->Frame);
@@ -378,6 +509,11 @@
int st_mp3startwrite(ft_t ft)
{
struct mp3priv *p = (struct mp3priv *) ft->priv;
+
+ if (load_lame()) {
+ st_fail_errno(ft,ST_EOF,"Sorry, no MP3 encoding support");
+ return ST_EOF;
+ }
if (ft->info.encoding != ST_ENCODING_MP3){
if(ft->info.encoding != -1)
@@ -385,35 +521,35 @@
ft->info.encoding = ST_ENCODING_MP3;
}
- p->gfp = lame_init();
+ p->gfp = dl_lame_init();
if (p->gfp == NULL){
st_fail_errno(ft,ST_EOF,"Initialization of LAME library failed");
return(ST_EOF);
}
if (ft->info.channels != -1){
- if ( (lame_set_num_channels(p->gfp,ft->info.channels)) < 0) {
+ if ( (dl_lame_set_num_channels(p->gfp,ft->info.channels)) < 0) {
st_fail_errno(ft,ST_EOF,"Unsupported number of channels");
return(ST_EOF);
}
}
else
- ft->info.channels = lame_get_num_channels(p->gfp); /* LAME default */
+ ft->info.channels = dl_lame_get_num_channels(p->gfp); /* LAME default */
- lame_set_in_samplerate(p->gfp,ft->info.rate);
+ dl_lame_set_in_samplerate(p->gfp,ft->info.rate);
- lame_set_bWriteVbrTag(p->gfp, 0); /* disable writing VBR tag */
+ dl_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 */
- if (lame_init_params(p->gfp) < 0){
+ if (dl_lame_init_params(p->gfp) < 0){
st_fail_errno(ft,ST_EOF,"LAME initialization failed");
return(ST_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);
+ dl_lame_set_errorf(p->gfp,null_error_func);
+ dl_lame_set_debugf(p->gfp,null_error_func);
+ dl_lame_set_msgf (p->gfp,null_error_func);
return(ST_SUCCESS);
}
@@ -429,6 +565,11 @@
st_ssize_t done = 0;
int written;
+ if (load_lame()) {
+ st_fail_errno(ft,ST_EOF,"Sorry, no MP3 encoding support");
+ return ST_EOF;
+ }
+
if ( (buffer_r=(long*)malloc(nsamples*sizeof(long))) == NULL){
st_fail_errno(ft,ST_ENOMEM,"Memory allocation failed");
goto end4;
@@ -456,7 +597,7 @@
goto end2;
}
- if ( (written = lame_encode_buffer_long2(p->gfp,
+ if ( (written = dl_lame_encode_buffer_long2(p->gfp,
buffer_l,
buffer_r,
nsamples,
@@ -489,15 +630,20 @@
struct mp3priv *p = (struct mp3priv *) ft->priv;
char mp3buffer[7200];
int written;
+
+ if (load_lame()) {
+ st_fail_errno(ft,ST_EOF,"Sorry, no MP3 encoding support");
+ return ST_EOF;
+ }
- if ( (written=lame_encode_flush(p->gfp, (unsigned char *)mp3buffer, 7200)) <0){
+ if ( (written=dl_lame_encode_flush(p->gfp, (unsigned char *)mp3buffer, 7200)) <0){
st_fail_errno(ft,ST_EOF,"Encoding failed");
}
else if (st_writebuf(ft, mp3buffer, 1, written) < written){
st_fail_errno(ft,ST_EOF,"File write failed");
}
- lame_close(p->gfp);
+ dl_lame_close(p->gfp);
return ST_SUCCESS;
}