ref: bd8e1c93d7c4803c0d00b3d58a983cf928c510da
parent: abdc7c28939886d3c81b74bc16cc0a42fe9a37dd
author: cbagwell <cbagwell>
date: Mon Sep 4 22:37:28 EDT 2006
Fix writing MP3s on AMD64s
--- a/Changelog
+++ b/Changelog
@@ -4,6 +4,10 @@
This file contains a list of all changes starting after the release of
sox-11gamma.
+sox-12.18.3
+-----------
+ o Fix writing MP3 files on AMD64 processors.
+
sox-12.18.2
-----------
o Adding in debain's disk full fix (#313206).
--- a/src/mp3.c
+++ b/src/mp3.c
@@ -39,7 +39,7 @@
mad_timer_t *Timer;
unsigned char *InputBuffer;
st_ssize_t cursamp;
- unsigned long FrameCount;
+ st_size_t FrameCount;
int eof;
#endif /*HAVE_LIBMAD*/
#if defined(HAVE_LAME)
@@ -420,68 +420,99 @@
st_ssize_t st_mp3write(ft_t ft, st_sample_t *buf, st_ssize_t samp)
{
- struct mp3priv *p = (struct mp3priv *) ft->priv;
- char *mp3buffer;
- int mp3buffer_size;
- long *buffer_l, *buffer_r;
- int nsamples = samp/ft->info.channels;
- int i,j;
- st_ssize_t done = 0;
- int written;
+ struct mp3priv *p = (struct mp3priv *)ft->priv;
+ char *mp3buffer;
+ int mp3buffer_size;
+ short signed int *buffer_l, *buffer_r = NULL;
+ int nsamples = samp/ft->info.channels;
+ int i,j;
+ st_ssize_t done = 0;
+ int written;
- if ( (buffer_r=(long*)malloc(nsamples*sizeof(long))) == NULL){
- st_fail_errno(ft,ST_ENOMEM,"Memory allocation failed");
- goto end4;
- }
+ /* 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
+ * malloc()'ing a smaller buffer and call a consistent
+ * interface.
+ */
+ if ((buffer_l =
+ (short signed int *)malloc(nsamples*
+ sizeof(short signed int))) == NULL)
+ {
+ st_fail_errno(ft, ST_ENOMEM, "Memory allocation failed");
+ goto end4;
+ }
- if (ft->info.channels==2){ /* Why isn't there a lame_encode_buffer_long_interleaved? */
- if ( (buffer_l=(long*)malloc(nsamples*sizeof(long))) == NULL){
- st_fail_errno(ft,ST_ENOMEM,"Memory allocation failed");
- goto end3;
+ if (ft->info.channels == 2)
+ {
+ /* lame doesn't support iterleaved samples so we must break
+ * them out into seperate buffers.
+ */
+ if ((buffer_r =
+ (short signed int *)malloc(nsamples*
+ sizeof(short signed int))) == NULL)
+ {
+ st_fail_errno(ft,ST_ENOMEM,"Memory allocation failed");
+ goto end3;
+ }
+
+ j=0;
+ for (i=0; i<nsamples; i++)
+ {
+ buffer_l[i]=ST_SAMPLE_TO_SIGNED_WORD(buf[j++]);
+ buffer_r[i]=ST_SAMPLE_TO_SIGNED_WORD(buf[j++]);
+ }
}
- j=0;
- for (i=0;i<nsamples;i++){
- buffer_l[i]=(long)buf[j++]; /* Should we paranoically check whether long is actually 32 bits? */
- buffer_r[i]=(long)buf[j++];
+ else
+ {
+ j=0;
+ for (i=0; i<nsamples; i++)
+ {
+ buffer_l[i]=ST_SAMPLE_TO_SIGNED_WORD(buf[j++]);
+ }
}
- }
- else{
- buffer_l=(long*)buf;
- memset(buffer_r,0,nsamples*sizeof(long));
- }
- mp3buffer_size=1.25*nsamples + 7200;
- if ( (mp3buffer=(char *)malloc(mp3buffer_size)) == NULL){
- st_fail_errno(ft,ST_ENOMEM,"Memory allocation failed");
- goto end2;
- }
-
- if ( (written = lame_encode_buffer_long2(p->gfp,
- buffer_l,
- buffer_r,
- nsamples,
- (unsigned char *)mp3buffer,
- mp3buffer_size)) < 0){
- st_fail_errno(ft,ST_EOF,"Encoding failed");
- goto end;
- }
+ mp3buffer_size = 1.25 * nsamples + 7200;
+ if ((mp3buffer=(char *)malloc(mp3buffer_size)) == NULL)
+ {
+ st_fail_errno(ft,ST_ENOMEM,"Memory allocation failed");
+ goto end2;
+ }
- if (st_writebuf(ft, mp3buffer, 1, written) < written){
- st_fail_errno(ft,ST_EOF,"File write failed");
- goto end;
- }
+ if ((written = lame_encode_buffer(p->gfp,buffer_l, buffer_r,
+ nsamples, (unsigned char *)mp3buffer,
+ mp3buffer_size)) < 0){
+ st_fail_errno(ft,ST_EOF,"Encoding failed");
+ goto end;
+ }
- done = nsamples*ft->info.channels;
+ if (st_writebuf(ft, mp3buffer, 1, written) < written)
+ {
+ st_fail_errno(ft,ST_EOF,"File write failed");
+ goto end;
+ }
- end:
- free(mp3buffer);
- end2:
- if (ft->info.channels == 2)
+ done = nsamples*ft->info.channels;
+
+end:
+ free(mp3buffer);
+end2:
+ if (ft->info.channels == 2)
+ free(buffer_r);
+end3:
free(buffer_l);
- end3:
- free(buffer_r);
- end4:
- return done;
+end4:
+ return done;
}
int st_mp3stopwrite(ft_t ft)