shithub: sox

Download patch

ref: 3913916c634913a624461fc48fd0344983367b00
parent: 459c39dbd7d0eef09c5dbcbd8f2653162647d669
author: cbagwell <cbagwell>
date: Fri Mar 3 21:50:05 EST 2000

Fix adpcm support for stereo files.  Better error checking for
resample effect.

--- a/src/resample.c
+++ b/src/resample.c
@@ -143,7 +143,7 @@
 		}
 	}
 
-	if ((n >= 1) && !sscanf(argv[0], "%lf", &r->rolloff))
+	if ((n >= 1) && (sscanf(argv[0], "%lf", &r->rolloff) != 1))
 	{
 	  fail("Usage: resample [ rolloff [ beta ] ]");
 	  return (ST_EOF);
--- a/src/wav.c
+++ b/src/wav.c
@@ -459,11 +459,6 @@
     ULONG    bytesPerBlock = 0;
     ULONG    bytespersample;	    /* bytes per sample (per channel */
 
-    /* This is needed for rawread(), st_readw, etc */
-    rc = st_rawstartread(ft);
-    if (rc)
-	return rc;
-
     endptr = (char *) &littlendian;
     if (!*endptr) ft->swap = ft->swap ? 0 : 1;
 
@@ -510,6 +505,12 @@
 	if (ft->info.encoding != -1 && ft->info.encoding != ST_ENCODING_UNSIGNED &&
 	    ft->info.encoding != ST_ENCODING_SIGN2)
 	    warn("User options overriding encoding read in .wav header");
+
+	/* Needed by rawread() functions */
+        rc = st_rawstartread(ft);
+        if (rc)
+	    return rc;
+
 	break;
 	
     case WAVE_FORMAT_IMA_ADPCM:
@@ -906,8 +907,6 @@
 	wav_t	wav = (wav_t) ft->priv;
 	LONG	done;
 	
-	if (len > wav->numSamples) len = wav->numSamples;
-
 	/* If file is in ADPCM encoding then read in multiple blocks else */
 	/* read as much as possible and return quickly. */
 	switch (ft->info.encoding)
@@ -914,6 +913,14 @@
 	{
 	case ST_ENCODING_IMA_ADPCM:
 	case ST_ENCODING_ADPCM:
+
+	    /* FIXME: numSamples is not used consistently in
+	     * wav handler.  Sometimes it accounts for stereo,
+	     * sometimes it does not.
+	     */
+	    if (len > (wav->numSamples*ft->info.channels)) 
+	        len = (wav->numSamples*ft->info.channels);
+
 	    done = 0;
 	    while (done < len) { /* Still want data? */
 		/* See if need to read more from disk */
@@ -928,7 +935,6 @@
 			wav->numSamples = 0;
 			return done;
 		    }
-		    wav->blockSamplesRemaining *= ft->info.channels;
 		    wav->samplePtr = wav->samples;
 		}
 
@@ -937,11 +943,11 @@
 		    short *p, *top;
 		    int ct;
 		    ct = len-done;
-		    if (ct > wav->blockSamplesRemaining)
-			ct = wav->blockSamplesRemaining;
+		    if (ct > (wav->blockSamplesRemaining*ft->info.channels))
+			ct = (wav->blockSamplesRemaining*ft->info.channels);
 
 		    done += ct;
-		    wav->blockSamplesRemaining -= ct;
+		    wav->blockSamplesRemaining -= (ct/ft->info.channels);
 		    p = wav->samplePtr;
 		    top = p+ct;
 		    /* Output is already signed */
@@ -951,10 +957,19 @@
 		    wav->samplePtr = p;
 		}
 	    }
+	    /* "done" for ADPCM equals total data processed and not
+	     * total samples procesed.  The only way to take care of that
+	     * is to return here and not fall thru.
+	     */
+	    wav->numSamples -= (done / ft->info.channels);
+	    return done;
 	    break;
 
 #ifdef HAVE_LIBGSM
 	case ST_ENCODING_GSM:
+	    if (len > wav->numSamples) 
+	        len = wav->numSamples;
+
 	    done = wavgsmread(ft, buf, len);
 	    if (done == 0 && wav->numSamples != 0)
 		warn("Premature EOF on .wav input file");
@@ -961,6 +976,9 @@
 	break;
 #endif
 	default: /* assume PCM encoding */
+	    if (len > wav->numSamples) 
+	        len = wav->numSamples;
+
 	    done = st_rawread(ft, buf, len);
 	    /* If software thinks there are more samples but I/O */
 	    /* says otherwise, let the user know about this.     */