Christian Weisgerber <[EMAIL PROTECTED]> wrote:

> > I run stable.
> > I built a new amd64 4.3 machine yesterday, and installed sox and lame.
> > When I attempted convert a wav file to mp3 format, it dumped core.
> 
> I cannot reproduce this on -current.

Don send me his wav file.  Turns out that a mono file triggers a hidden
assumption that long is always 32 bits.  *Sigh*

The whole section has since been rewritten upstream.  Corresponding patch
below.  Please test.

Index: Makefile
===================================================================
RCS file: /cvs/ports/audio/sox/Makefile,v
retrieving revision 1.36
diff -u -r1.36 Makefile
--- Makefile    15 Sep 2007 21:26:03 -0000      1.36
+++ Makefile    30 Jun 2008 14:50:39 -0000
@@ -3,6 +3,7 @@
 COMMENT=       SOund eXchange - universal sound sample translator
 
 DISTNAME=      sox-12.18.2
+PKGNAME=       ${DISTNAME}     # also see below
 CATEGORIES=    audio
 HOMEPAGE=      http://sox.sourceforge.net/
 
@@ -34,6 +35,7 @@
 .endif
 
 .if ${FLAVOR:L:Mmp3}
+PKGNAME=       ${DISTNAME}p0
 LIB_DEPENDS+=  mad.>=2::audio/libmad mp3lame::audio/lame
 .else
 CONFIGURE_ARGS+= --disable-mad --disable-lame
Index: patches/patch-src_mp3_c
===================================================================
RCS file: patches/patch-src_mp3_c
diff -N patches/patch-src_mp3_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_mp3_c     30 Jun 2008 14:50:39 -0000
@@ -0,0 +1,97 @@
+$OpenBSD$
+--- src/mp3.c.orig     Sun Jun 29 18:37:31 2008
++++ src/mp3.c  Sun Jun 29 18:51:20 2008
+@@ -423,31 +423,56 @@ st_ssize_t st_mp3write(ft_t ft, st_sample_t *buf, st_s
+   struct mp3priv *p = (struct mp3priv *) ft->priv;
+   char *mp3buffer;
+   int mp3buffer_size;
+-  long *buffer_l, *buffer_r;
++  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){
++  /* 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){
++  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]=(long)buf[j++];   /* Should we paranoically check whether 
long is actually 32 bits? */
+-      buffer_r[i]=(long)buf[j++];
++    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++]);
+     }
+   }
+   else{
+-    buffer_l=(long*)buf;
+-    memset(buffer_r,0,nsamples*sizeof(long));
++    j=0;
++    for (i=0; i<nsamples; i++)
++      buffer_l[i]=ST_SAMPLE_TO_SIGNED_WORD(buf[j++]);
+   }
+ 
+   mp3buffer_size=1.25*nsamples + 7200;
+@@ -456,12 +481,9 @@ st_ssize_t st_mp3write(ft_t ft, st_sample_t *buf, st_s
+     goto end2;
+   }
+  
+-  if ( (written = lame_encode_buffer_long2(p->gfp,
+-                                           buffer_l,
+-                                           buffer_r,
+-                                           nsamples,
+-                                           (unsigned char *)mp3buffer,
+-                                           mp3buffer_size)) < 0){
++  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;
+   }
+@@ -477,9 +499,9 @@ st_ssize_t st_mp3write(ft_t ft, st_sample_t *buf, st_s
+   free(mp3buffer);
+  end2:
+   if (ft->info.channels == 2)
+-    free(buffer_l);
++    free(buffer_r);
+  end3:
+-  free(buffer_r);
++  free(buffer_l);
+  end4:
+   return done;
+ }
-- 
Christian "naddy" Weisgerber                          [EMAIL PROTECTED]

Reply via email to