ref: 334287d880b9248feb636cad2172d18f0b795cc9
parent: 1e097282146bc0eeb0008f970689f9fdb281d141
author: cbagwell <cbagwell>
date: Sat Nov 28 01:09:00 EST 2009
Cleanup ID3 tag support to work with 3.97 lame as much as possible. Send floats to lame for increased percision.
--- a/ChangeLog
+++ b/ChangeLog
@@ -45,9 +45,11 @@
o New Grandstream ring-tone (gsrt) format. (robs)
o CVSD encode/decode speed-ups. (Kimberly Rockwell, P. Chaintreuil)
o Add ability to select MP3 compression parameters. (Jim Harkins)
- o Now writes out ID3-tags in MP3 files. (Doug Cook)
+ o Now writes out ID3-tags in MP3 files with lame supports it. (Doug Cook)
o Also can write VBR Tag ("XING Header") in MP3 files. (Jim Hark /
Doug Cook)
+ o Increase percision of MP3 encoders to use 24-bits instead of
+ 16-bits. (Doug Cook)
o Fix failed writing 24-bit PAF files (and possibly other libsndfile
based formats). (cbagwell)
o Allow libsndfile to be dlopen()'ed at runtime if --enable-dl-sndfile
--- a/INSTALL
+++ b/INSTALL
@@ -238,8 +238,8 @@
o SoX source distribution version 14.0.1
available on [http://sox.sourceforge.net]
-o LAME source distribution version 3.97. 3.98 required for ID3TAG support.
- available on [http://lame.sourceforge.net]
+o LAME source distribution version 3.97. 3.98 required for full ID3 tag
+ support. available on [http://lame.sourceforge.net]
o MAD source distribution version 0.15.1b
available on [http://www.underbit.com/products/mad/]
--- a/configure.ac
+++ b/configure.ac
@@ -337,13 +337,17 @@
AC_DEFINE(DL_LAME, 1, [Define if to dlopen() lame.])
else
AC_CHECK_LIB(mp3lame, lame_init, MP3_LIBS="$MP3_LIBS -lmp3lame",using_lame=no)
- AC_CHECK_LIB(mp3lame, lame_set_VBR_quality)
- if test "$ac_cv_lib_mp3lame_lame_set_VBR_quality" = yes; then
- AC_DEFINE(HAVE_LAME_SET_VBR_QUALITY, 1, [Define to 1 if you have lame_set_VBR_quality.])
+ AC_CHECK_LIB(mp3lame, lame_get_lametag_frame)
+ if test "$ac_cv_lib_mp3lame_lame_get_lametag_frame" = yes; then
+ AC_DEFINE(HAVE_LAME_398, 1, [Define to 1 if you have lame 3.98 or greater.])
fi
+ AC_CHECK_LIB(mp3lame, id3tag_init)
+ if test "$ac_cv_lib_mp3lame_id3tag_init" = yes; then
+ AC_DEFINE(HAVE_LAME_ID3TAG, 1, [Define to 1 if lame supports optional ID3 tags.])
+ fi
AC_CHECK_LIB(mp3lame, id3tag_set_fieldvalue)
if test "$ac_cv_lib_mp3lame_id3tag_set_fieldvalue" = yes; then
- AC_DEFINE(HAVE_ID3TAG_SET_FIELDVALUE, 1, [Define to 1 if you have id3tag_set_fieldvalue.])
+ AC_DEFINE(HAVE_LAME_398_ID3TAG, 1, [Define to 1 if lame 3.98 or newer ID3 tag support.])
fi
if test "$with_lame" = "yes" -a "$using_lame" = "no"; then
AC_MSG_FAILURE([cannot find LAME])
--- a/src/formats.c
+++ b/src/formats.c
@@ -171,8 +171,9 @@
case SOX_ENCODING_CVSD: return bits_per_sample == 1? 16: 0;
case SOX_ENCODING_DPCM: return bits_per_sample; /* ? */
+ case SOX_ENCODING_MP3: return 0; /* Accept the precision returned by the format. */
+
case SOX_ENCODING_GSM:
- case SOX_ENCODING_MP3:
case SOX_ENCODING_VORBIS:
case SOX_ENCODING_AMR_WB:
case SOX_ENCODING_AMR_NB:
@@ -1145,7 +1146,6 @@
static sox_bool plugins_initted = sox_false;
#ifdef HAVE_LIBLTDL /* Plugin format handlers */
- #include <ltdl.h>
#define MAX_DYNAMIC_FORMATS 42
#define MAX_FORMATS (NSTATIC_FORMATS + MAX_DYNAMIC_FORMATS)
#define MAX_FORMATS_1 (MAX_FORMATS + 1)
--- a/src/mp3-util.h
+++ b/src/mp3-util.h
@@ -35,41 +35,41 @@
static void write_comments(sox_format_t * ft)
{
priv_t *p = (priv_t *) ft->priv;
- size_t i;
- char* id3tag_buf = NULL;
- size_t id3tag_size = 0;
const char* comment;
- size_t required_size;
p->id3tag_init(p->gfp);
p->id3tag_set_pad(p->gfp, ID3PADDING);
- for (i = 0; id3tagmap[i][0]; i++)
+ /* Note: id3tag_set_fieldvalue is not present in LAME 3.97, so we're using
+ the 3.97-compatible methods for all of the tags that 3.97 supported. */
+ if (comment = sox_find_comment(ft->oob.comments, "Title"))
+ p->id3tag_set_title(p->gfp, comment);
+ if (comment = sox_find_comment(ft->oob.comments, "Artist"))
+ p->id3tag_set_artist(p->gfp, comment);
+ if (comment = sox_find_comment(ft->oob.comments, "Album"))
+ p->id3tag_set_album(p->gfp, comment);
+ if (comment = sox_find_comment(ft->oob.comments, "Tracknumber"))
+ p->id3tag_set_track(p->gfp, comment);
+ if (comment = sox_find_comment(ft->oob.comments, "Year"))
+ p->id3tag_set_year(p->gfp, comment);
+ if (comment = sox_find_comment(ft->oob.comments, "Comment"))
+ p->id3tag_set_comment(p->gfp, comment);
+ if (comment = sox_find_comment(ft->oob.comments, "Genre"))
{
- comment = sox_find_comment(ft->oob.comments, id3tagmap[i][1]);
- if (comment)
- {
- required_size = strlen(comment) + 6;
- if (id3tag_size < required_size)
- {
- char* id3tag_realloc = lsx_realloc(id3tag_buf, required_size);
- if (id3tag_realloc)
- {
- id3tag_buf = id3tag_realloc;
- id3tag_size = required_size;
- }
- }
+ if (p->id3tag_set_genre(p->gfp, comment))
+ lsx_warn("\"%s\" is not a recognized ID3v1 genre.", comment);
+ }
- if (id3tag_size >= required_size)
- {
- sprintf(id3tag_buf, "%s=%s", id3tagmap[i][0], comment);
- id3tag_buf[id3tag_size - 1] = 0;
- p->id3tag_set_fieldvalue(p->gfp, id3tag_buf);
- }
+ if (comment = sox_find_comment(ft->oob.comments, "Discnumber"))
+ {
+ char* id3tag_buf = lsx_malloc(strlen(comment) + 6);
+ if (id3tag_buf)
+ {
+ sprintf(id3tag_buf, "TPOS=%s", comment);
+ p->id3tag_set_fieldvalue(p->gfp, id3tag_buf);
+ free(id3tag_buf);
}
}
-
- free(id3tag_buf);
}
#endif /* HAVE_LAME */
--- a/src/mp3.c
+++ b/src/mp3.c
@@ -62,6 +62,13 @@
#define MAXFRAMESIZE 2880
#define ID3PADDING 128
+/* LAME takes float values as input. */
+#define MP3_LAME_PRECISION 24
+
+/* MAD returns values with MAD_F_FRACBITS (28) bits of precision, though it's
+ not certain that all of them are meaningful. Let's just make it match LAME. */
+#define MP3_MAD_PRECISION MP3_LAME_PRECISION
+
static const char* const mad_library_names[] =
{
#ifdef DL_MAD
@@ -106,34 +113,54 @@
};
#ifdef DL_LAME
+
+ /* Expected to be present in all builds of LAME. */
#define LAME_FUNC LSX_DLENTRY_DYNAMIC
- #define LAME_FUNC_MSG LSX_DLENTRY_STUB
- #define LAME_FUNC_LAMETAG LSX_DLENTRY_STUB
+
+ /* id3tag support is an optional component of LAME. Use if available. */
#define LAME_FUNC_ID3 LSX_DLENTRY_STUB
-#else
+
+ /* Added in LAME 3.98: lame_get_lametag_frame. Use if available. */
+ #define LAME_FUNC_398 LSX_DLENTRY_STUB
+
+ /* Added in LAME 3.98.1 (optional): id3tag_set_pad, lame_get_id3v2_tag,
+ id3tag_set_fieldvalue. Use if available. */
+ #define LAME_FUNC_398_ID3 LSX_DLENTRY_STUB
+
+#else /* DL_LAME */
+
+ /* Expected to be present in all builds of LAME. */
#define LAME_FUNC LSX_DLENTRY_STATIC
- #ifdef HAVE_LAME_SET_MSGF
- #define LAME_FUNC_MSG LSX_DLENTRY_STATIC
+
+ /* id3tag support is an optional component of LAME. Use if available. */
+ #ifdef HAVE_LAME_ID3TAG
+ #define LAME_FUNC_ID3 LSX_DLENTRY_STATIC
#else
- #define LAME_FUNC_MSG LSX_DLENTRY_STUB
+ #define LAME_FUNC_ID3 LSX_DLENTRY_STUB
#endif
- #ifdef HAVE_LAME_GET_LAMETAG_FRAME
- #define LAME_FUNC_LAMETAG LSX_DLENTRY_STATIC
+
+ /* Added in LAME 3.98: lame_get_lametag_frame. Use if available. */
+ #ifdef HAVE_LAME_398
+ #define LAME_FUNC_398 LSX_DLENTRY_STATIC
#else
- #define LAME_FUNC_LAMETAG LSX_DLENTRY_STUB
+ #define LAME_FUNC_398 LSX_DLENTRY_STUB
#endif
- #ifdef HAVE_ID3TAG_SET_FIELDVALUE
- #define LAME_FUNC_ID3 LSX_DLENTRY_STATIC
+
+ /* Added in LAME 3.98.1 (optional): id3tag_set_pad, lame_get_id3v2_tag,
+ id3tag_set_fieldvalue. Use if available. */
+ #ifdef HAVE_LAME_398_ID3TAG
+ #define LAME_FUNC_398_ID3 LSX_DLENTRY_STATIC
#else
- #define LAME_FUNC_ID3 LSX_DLENTRY_STUB
+ #define LAME_FUNC_398_ID3 LSX_DLENTRY_STUB
#endif
-#endif
+#endif /* DL_LAME */
+
#define LAME_FUNC_ENTRIES(f,x) \
LAME_FUNC(f,x, lame_global_flags*, lame_init, (void)) \
- LAME_FUNC_MSG(f,x, int, lame_set_errorf, (lame_global_flags *, void (*)(const char *, va_list))) \
- LAME_FUNC_MSG(f,x, int, lame_set_debugf, (lame_global_flags *, void (*)(const char *, va_list))) \
- LAME_FUNC_MSG(f,x, int, lame_set_msgf, (lame_global_flags *, void (*)(const char *, va_list))) \
+ LAME_FUNC(f,x, int, lame_set_errorf, (lame_global_flags *, void (*)(const char *, va_list))) \
+ LAME_FUNC(f,x, int, lame_set_debugf, (lame_global_flags *, void (*)(const char *, va_list))) \
+ LAME_FUNC(f,x, int, lame_set_msgf, (lame_global_flags *, void (*)(const char *, va_list))) \
LAME_FUNC(f,x, int, lame_set_num_samples, (lame_global_flags *, unsigned long)) \
LAME_FUNC(f,x, int, lame_get_num_channels, (const lame_global_flags *)) \
LAME_FUNC(f,x, int, lame_set_num_channels, (lame_global_flags *, int)) \
@@ -146,14 +173,21 @@
LAME_FUNC(f,x, int, lame_set_VBR, (lame_global_flags *, vbr_mode)) \
LAME_FUNC(f,x, int, lame_set_VBR_q, (lame_global_flags *, int)) \
LAME_FUNC(f,x, int, lame_init_params, (lame_global_flags *)) \
- LAME_FUNC(f,x, int, lame_encode_buffer, (lame_global_flags *, const short int[], const short int[], const int, unsigned char *, const int)) \
+ LAME_FUNC(f,x, int, lame_encode_buffer_float, (lame_global_flags *, const float[], const float[], const int, unsigned char *, const int)) \
LAME_FUNC(f,x, int, lame_encode_flush, (lame_global_flags *, unsigned char *, int)) \
LAME_FUNC(f,x, int, lame_close, (lame_global_flags *)) \
- LAME_FUNC_LAMETAG(f,x, size_t, lame_get_lametag_frame, (const lame_global_flags *, unsigned char*, size_t)) \
- LAME_FUNC_ID3(f,x, size_t, lame_get_id3v2_tag, (lame_global_flags *, unsigned char*, size_t)) \
LAME_FUNC_ID3(f,x, void, id3tag_init, (lame_global_flags *)) \
- LAME_FUNC_ID3(f,x, void, id3tag_set_pad, (lame_global_flags *, size_t)) \
- LAME_FUNC_ID3(f,x, int, id3tag_set_fieldvalue, (lame_global_flags *, const char *))
+ LAME_FUNC_ID3(f,x, void, id3tag_set_title, (lame_global_flags *, const char* title)) \
+ LAME_FUNC_ID3(f,x, void, id3tag_set_artist, (lame_global_flags *, const char* artist)) \
+ LAME_FUNC_ID3(f,x, void, id3tag_set_album, (lame_global_flags *, const char* album)) \
+ LAME_FUNC_ID3(f,x, void, id3tag_set_year, (lame_global_flags *, const char* year)) \
+ LAME_FUNC_ID3(f,x, void, id3tag_set_comment, (lame_global_flags *, const char* comment)) \
+ LAME_FUNC_ID3(f,x, int, id3tag_set_track, (lame_global_flags *, const char* track)) \
+ LAME_FUNC_ID3(f,x, int, id3tag_set_genre, (lame_global_flags *, const char* genre)) \
+ LAME_FUNC_398(f,x, size_t, lame_get_lametag_frame, (const lame_global_flags *, unsigned char*, size_t)) \
+ LAME_FUNC_398_ID3(f,x, size_t, id3tag_set_pad, (lame_global_flags *, size_t)) \
+ LAME_FUNC_398_ID3(f,x, size_t, lame_get_id3v2_tag, (lame_global_flags *, unsigned char*, size_t)) \
+ LAME_FUNC_398_ID3(f,x, int, id3tag_set_fieldvalue, (lame_global_flags *, const char *))
/* Private data */
typedef struct mp3_priv_t {
@@ -172,7 +206,7 @@
#ifdef HAVE_LAME
lame_global_flags *gfp;
- short *pcm_buffer;
+ float *pcm_buffer;
size_t pcm_buffer_size;
unsigned long num_samples;
int vbr_tag;
@@ -388,6 +422,7 @@
p->mad_timer_add(&p->Timer,p->Frame.header.duration);
p->mad_synth_frame(&p->Synth,&p->Frame);
+ ft->signal.precision = MP3_MAD_PRECISION;
ft->signal.rate=p->Synth.pcm.samplerate;
if (ignore_length)
ft->signal.length = SOX_UNSPEC;
@@ -526,20 +561,30 @@
/* These functions are considered optional. If they aren't present in the
library, the stub versions defined here will be used instead. */
-static int lame_set_errorf_stub(lame_global_flags * gfp UNUSED, void (*func)(const char *, va_list) UNUSED)
+static void id3tag_init_stub(lame_global_flags * gfp UNUSED)
+ { return; }
+static void id3tag_pad_v2_stub(lame_global_flags * gfp UNUSED)
+ { return; }
+static void id3tag_set_title_stub(lame_global_flags * gfp UNUSED, const char* title UNUSED)
+ { return; }
+static void id3tag_set_artist_stub(lame_global_flags * gfp UNUSED, const char* artist UNUSED)
+ { return; }
+static void id3tag_set_album_stub(lame_global_flags * gfp UNUSED, const char* album UNUSED)
+ { return; }
+static void id3tag_set_year_stub(lame_global_flags * gfp UNUSED, const char* year UNUSED)
+ { return; }
+static void id3tag_set_comment_stub(lame_global_flags * gfp UNUSED, const char* comment UNUSED)
+ { return; }
+static void id3tag_set_track_stub(lame_global_flags * gfp UNUSED, const char* track UNUSED)
+ { return; }
+static int id3tag_set_genre_stub(lame_global_flags * gfp UNUSED, const char* genre UNUSED)
{ return 0; }
-static int lame_set_debugf_stub(lame_global_flags * gfp UNUSED, void (*func)(const char *, va_list) UNUSED)
- { return 0; }
-static int lame_set_msgf_stub(lame_global_flags * gfp UNUSED, void (*func)(const char *, va_list) UNUSED)
- { return 0; }
static size_t lame_get_lametag_frame_stub(const lame_global_flags * gfp UNUSED, unsigned char * buffer UNUSED, size_t size UNUSED)
{ return 0; }
+static size_t id3tag_set_pad_stub(lame_global_flags * gfp UNUSED, size_t n UNUSED)
+ { return 0; }
static size_t lame_get_id3v2_tag_stub(lame_global_flags * gfp UNUSED, unsigned char * buffer UNUSED, size_t size UNUSED)
{ return 0; }
-static void id3tag_init_stub(lame_global_flags * gfp UNUSED)
- { return; }
-static void id3tag_set_pad_stub(lame_global_flags * gfp UNUSED, size_t padding UNUSED)
- { return; }
static int id3tag_set_fieldvalue_stub(lame_global_flags * gfp UNUSED, const char *fieldvalue UNUSED)
{ return 0; }
@@ -584,11 +629,21 @@
priv_t *p = (priv_t *)ft->priv;
FILE *fp = ft->fp;
int new_size;
- unsigned char *buffer = lsx_malloc(id3v2_size);
+ unsigned char * buffer;
+ if (LSX_DLFUNC_IS_STUB(p, lame_get_id3v2_tag))
+ {
+ if (p->num_samples)
+ lsx_warn("cannot update track length info - tag update not supported with this version of LAME. Track length will be incorrect.");
+ else
+ lsx_report("cannot update track length info - tag update not supported with this version of LAME. Track length will be unspecified.");
+ return;
+ }
+
+ buffer = lsx_malloc(id3v2_size);
if (!buffer)
{
- lsx_warn("cannot update id3 tag - failed to allocate buffer");
+ lsx_warn("cannot update track length info - failed to allocate buffer");
return;
}
@@ -595,7 +650,6 @@
p->lame_set_num_samples(p->gfp, num_samples);
lsx_debug("updated MP3 TLEN to %lu samples", num_samples);
- p->id3tag_set_pad(p->gfp, ID3PADDING);
new_size = p->lame_get_id3v2_tag(p->gfp, buffer, id3v2_size);
if (new_size != id3v2_size && new_size-ID3PADDING <= id3v2_size) {
@@ -604,7 +658,15 @@
}
if (new_size != id3v2_size) {
- lsx_warn("cannot update id3 tag - new tag too big");
+ if (LSX_DLFUNC_IS_STUB(p, id3tag_set_pad))
+ {
+ if (p->num_samples)
+ lsx_warn("cannot update track length info - tag size adjustment not supported with this version of LAME. Track length will be invalid.");
+ else
+ lsx_report("cannot update track length info - tag size adjustment not supported with this version of LAME. Track length will be unspecified.");
+ }
+ else
+ lsx_warn("cannot update track length info - failed to adjust tag size");
} else {
fseeko(fp, 0, SEEK_SET);
/* Overwrite the Id3v2 tag (this time TLEN should be accurate) */
@@ -694,10 +756,10 @@
ft->encoding.encoding = SOX_ENCODING_MP3;
}
- p->mp3_buffer_size = LAME_BUFFER_SIZE(sox_globals.bufsiz);
+ p->mp3_buffer_size = LAME_BUFFER_SIZE(sox_globals.bufsiz / max(ft->signal.channels, 1));
p->mp3_buffer = lsx_malloc(p->mp3_buffer_size);
- p->pcm_buffer_size = sox_globals.bufsiz * sizeof(short signed int);
+ p->pcm_buffer_size = sox_globals.bufsiz * sizeof(float);
p->pcm_buffer = lsx_malloc(p->pcm_buffer_size);
p->gfp = p->lame_init();
@@ -715,6 +777,8 @@
p->num_samples = ft->signal.length == SOX_IGNORE_LENGTH ? 0 : ft->signal.length / max(ft->signal.channels, 1);
p->lame_set_num_samples(p->gfp, p->num_samples);
+ ft->signal.precision = MP3_LAME_PRECISION;
+
if (ft->signal.channels != SOX_ENCODING_UNKNOWN) {
if ( (p->lame_set_num_channels(p->gfp,(int)ft->signal.channels)) < 0) {
lsx_fail_errno(ft,SOX_EOF,"Unsupported number of channels");
@@ -786,11 +850,10 @@
p->lame_set_VBR(p->gfp, vbr_default);
if (ft->seekable) {
- if (!LSX_DLFUNC_IS_STUB(p, lame_get_id3v2_tag) &&
- !LSX_DLFUNC_IS_STUB(p, lame_get_lametag_frame)) {
+ if (!LSX_DLFUNC_IS_STUB(p, lame_get_lametag_frame)) {
p->vbr_tag = 1;
} else {
- lsx_warn("unable to write VBR tag because lametag support is not present");
+ lsx_report("unable to write VBR tag because lametag update is not supported with this version of LAME");
}
} else {
lsx_warn("unable to write VBR tag because we can't seek");
@@ -838,19 +901,22 @@
return(SOX_SUCCESS);
}
+#define MP3_SAMPLE_TO_FLOAT(d,clips) ((float)(32768*SOX_SAMPLE_TO_FLOAT_32BIT(d,clips)))
+
static size_t sox_mp3write(sox_format_t * ft, const sox_sample_t *buf, size_t samp)
{
priv_t *p = (priv_t *)ft->priv;
size_t new_buffer_size;
- short signed int *buffer_l, *buffer_r = NULL;
+ float *buffer_l, *buffer_r;
int nsamples = samp/ft->signal.channels;
int i,j;
size_t written;
+ int clips = 0;
SOX_SAMPLE_LOCALS;
- new_buffer_size = samp * sizeof(short signed int);
+ new_buffer_size = samp * sizeof(float);
if (p->pcm_buffer_size < new_buffer_size) {
- short *new_buffer = lsx_realloc(p->pcm_buffer, new_buffer_size);
+ float *new_buffer = lsx_realloc(p->pcm_buffer, new_buffer_size);
if (!new_buffer) {
lsx_fail_errno(ft, SOX_ENOMEM, "Out of memory");
return 0;
@@ -859,45 +925,30 @@
p->pcm_buffer = new_buffer;
}
- /* NOTE: This logic assumes that "short int" is 16-bits
- * on all platforms. It happens to be for all that I know
- * about.
- *
- * Lame ultimately wants data scaled to 16-bit samples
- * and assumes for the majority of cases that your passing
- * in something scaled based on passed in datatype
- * (16, 32, 64, and float).
- *
- * If we used long buffers then this means it expects
- * different scalling between 32-bit and 64-bit CPU's.
- *
- * We might as well scale it ourselfs to 16-bit to allow
- * lsx_malloc()'ing a smaller buffer and call a consistent
- * interface.
- */
buffer_l = p->pcm_buffer;
if (ft->signal.channels == 2)
{
- /* lame doesn't support iterleaved samples so we must break
+ /* lame doesn't support interleaved samples for floats so we must break
* them out into seperate buffers.
*/
buffer_r = p->pcm_buffer + nsamples;
j=0;
- for (i=0; i<nsamples; i++)
+ for (i = 0; i < nsamples; i++)
{
- buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++], ft->clips);
- buffer_r[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++], ft->clips);
+ buffer_l[i] = MP3_SAMPLE_TO_FLOAT(buf[j++], clips);
+ buffer_r[i] = MP3_SAMPLE_TO_FLOAT(buf[j++], clips);
}
}
else
{
j=0;
- for (i=0; i<nsamples; i++)
- buffer_l[i]=SOX_SAMPLE_TO_SIGNED_16BIT(buf[j++], ft->clips);
+ for (i = 0; i < nsamples; i++) {
+ buffer_l[i] = MP3_SAMPLE_TO_FLOAT(buf[j++], clips);
+ }
}
- new_buffer_size = LAME_BUFFER_SIZE(samp);
+ new_buffer_size = LAME_BUFFER_SIZE(nsamples);
if (p->mp3_buffer_size < new_buffer_size) {
unsigned char *new_buffer = lsx_realloc(p->mp3_buffer, new_buffer_size);
if (!new_buffer) {
@@ -909,7 +960,7 @@
}
if ((written =
- p->lame_encode_buffer(p->gfp,buffer_l, buffer_r,
+ p->lame_encode_buffer_float(p->gfp, buffer_l, buffer_r,
nsamples, p->mp3_buffer,
(int)p->mp3_buffer_size)) > p->mp3_buffer_size){
lsx_fail_errno(ft,SOX_EOF,"Encoding failed");