shithub: sox

Download patch

ref: 834fda64b93fb0e96c2c4bc7b4263cdbe4b5dbf3
parent: 89f56e2cec3a5c82fd524f02799e81a79ad5f429
author: cbagwell <cbagwell>
date: Sun Nov 4 18:49:36 EST 2001

Continued improvements to silence effect.  Change floats to a type of encoding

--- a/Changelog
+++ b/Changelog
@@ -33,6 +33,11 @@
     when EOF was OK.
   o Change libst to use two new data types: st_sample_t and st_size_t.
     This allows for better support and maintaince on 64-bit machines.
+  o Silence effect was broken on stereo files.  Also, made thresholds
+    relative to original bit percision of audio data.  When 16-bit audio
+    is scaled up to 32-bits, a little bit of noise starts to look like a
+    large amplitude of noise.
+  o Changed Floats into a type of encoding instead of a size of audio data.
 
 sox-12.17.2
 -----------
--- a/sox.1
+++ b/sox.1
@@ -107,9 +107,9 @@
 .br
     \fBreverse\fR
 .br
-    \fBsilence\fR \fIabove_periods\fR [ \fIduration threshold\fR[ \fId\fR | \fI%\fR | \fIs\fR]
+    \fBsilence\fR \fIabove_periods\fR [ \fIduration threshold\fR[ \fId\fR | \fI%\fR ]
             [ \fIbelow_periods duration 
-              threshold\fR[ \fId\fR | \fI%\fR | \fIs\fR ]]
+              threshold\fR[ \fId\fR | \fI%\fR ]]
 .br
     \fBspeed\fR [ -c ] \fIfactor\fR
 .br
@@ -234,9 +234,9 @@
 European countries and its gaining popularity because of its
 quality.  It usually is CPU intensive to work with GSM audio data.
 .TP 10
-\fB-b/-w/-l/-f/-d/-D\fR
+\fB-b/-w/-l/-f/-d\fR
 The sample data size is in bytes, 16-bit words, 32-bit longwords,
-32-bit floats, 64-bit double floats, or 80-bit IEEE floats.
+32-bit floats or 64-bit double floats.
 Floats and double floats are in native machine format.
 .TP 10
 \fB-x\fR
@@ -246,7 +246,6 @@
 be swapped according to the word-size given above.
 Only 16-bit and 32-bit integer data may be swapped.
 Machine-format floating-point data is not portable.
-IEEE floats are a fixed, portable format.
 .TP 10
 \fB-c \fIchannels\fR
 The number of sound channels in the data file.
@@ -1039,11 +1038,11 @@
 Reverse the sound sample completely.
 Included for finding Satanic subliminals.
 .TP
-\fBsilence\fR \fIabove_periods\fR [ \fIduration threshold\fR[ \fId\fR | \fI%\fR | \fIs\fR]
+\fBsilence\fR \fIabove_periods\fR [ \fIduration threshold\fR[ \fId\fR | \fI%\fR ]
 .TP
         [ \fIbelow_periods duration 
 .TP 10
-          threshold\fR[ \fId\fR | \fI%\fR | \fIs\fR ]]
+          threshold\fR[ \fId\fR | \fI%\fR ]]
 Removes silence from the beginning or end of a sound file.  Silence is anything below a specified threshold.
 .br
 When trimming silence from the beginning of a sound file, you specify a duration of audio that is above a given silence threshold before audio data is processed.  You can also specify the count of periods of none silence you want to detect before processing audio data.  Specify a period of 0 if you do not want to trim data from the front of the sound file.
@@ -1050,9 +1049,9 @@
 .br
 When optionally trimming silence form the end of a sound file, you specify the duration of audio that must be below a given threshold before stopping to process audio data.  A count of periods that occur below the threshold may also be speficied.  If this options are not specified then data is not trimmed from the end of the audio file.
 .br
-Duration counts may be in the format of time, hh.mm.ss.frac, or in the exact count of samples.
+Duration counts may be in the format of time, hh:mm:ss.frac, or in the exact count of samples.
 .br
-Threshold may be suffixed with d, %, or s to indicated the value is in decibels, percent, or an exact signed long interger sample value.  A value of '0s' will look for total silence.
+Threshold may be suffixed with d, or % to indicated the value is in decibels or a percentage of max value of the sample value.  A value of '0%' will look for total silence.
 .TP 10
 speed [ -c ] \fIfactor\fB
 Speed up or down the sound, as a magnetic tape with a speed control. 
--- a/src/dat.c
+++ b/src/dat.c
@@ -59,8 +59,8 @@
    if (ft->info.channels == -1)
        ft->info.channels = 1;
 
-   ft->info.size = ST_SIZE_DOUBLE;
-   ft->info.encoding = ST_ENCODING_SIGN2;
+   ft->info.size = ST_SIZE_64BIT;
+   ft->info.encoding = ST_ENCODING_FLOAT;
 
    return (ST_SUCCESS);
 }
@@ -78,8 +78,8 @@
 	ft->info.channels = 1;
    }
    
-   ft->info.size = ST_SIZE_DOUBLE;
-   ft->info.encoding = ST_ENCODING_SIGN2;
+   ft->info.size = ST_SIZE_64BIT;
+   ft->info.encoding = ST_ENCODING_FLOAT;
    dat->timevalue = 0.0;
    srate = ft->info.rate;
    dat->deltat = 1.0 / srate;
--- a/src/handlers.c
+++ b/src/handlers.c
@@ -447,7 +447,7 @@
 	{"reverse", 0, 
 		st_reverse_getopts, st_reverse_start, 
 		st_reverse_flow, st_reverse_drain, st_reverse_stop},
-	{"silence", 0, 
+	{"silence", ST_EFF_MCHAN, 
 		st_silence_getopts, st_silence_start, 
 		st_silence_flow, st_silence_drain, st_silence_stop},
 	{"speed", 0, 
--- a/src/oss.c
+++ b/src/oss.c
@@ -87,11 +87,6 @@
 	return(ST_EOF);
     }
 
-    if (ioctl(fileno(ft->fp), SNDCTL_DSP_SYNC, NULL) < 0) {
-	st_fail_errno(ft,ST_EOF,"Unable to sync dsp");
-	return (ST_EOF);
-    }
-
     /* Query the supported formats and find the best match
      */
     rc = ioctl(fileno(ft->fp), SNDCTL_DSP_GETFMTS, &tmp);
@@ -189,6 +184,11 @@
 
     if ((ft->file.buf = malloc (ft->file.size)) == NULL) {
 	st_fail_errno(ft,ST_EOF,"Unable to allocate input/output buffer of size %d", ft->file.size);
+	return (ST_EOF);
+    }
+
+    if (ioctl(fileno(ft->fp), SNDCTL_DSP_SYNC, NULL) < 0) {
+	st_fail_errno(ft,ST_EOF,"Unable to sync dsp");
 	return (ST_EOF);
     }
 
--- a/src/rate.c
+++ b/src/rate.c
@@ -82,8 +82,8 @@
 	    st_fail("rate effect can only handle rates <= 65535");
 	    return (ST_EOF);
 	}
-	if (effp->ininfo.size == ST_SIZE_DWORD ||
-	    effp->ininfo.size == ST_SIZE_FLOAT)
+	if (effp->ininfo.size == ST_SIZE_DWORD || 
+	    effp->ininfo.size == ST_SIZE_DDWORD)
 	{
 	    st_warn("rate effect reduces data to 16 bits");
 	}
--- a/src/raw.c
+++ b/src/raw.c
@@ -47,13 +47,13 @@
 			sample_size = 1;
 		        break;
 		case ST_SIZE_WORD:
-			sample_size = sizeof(short);
+			sample_size = 2;
 		        break;
 		case ST_SIZE_DWORD:
-			sample_size = sizeof(LONG);
+			sample_size = 4;
 		        break;
-		case ST_SIZE_FLOAT:
-			sample_size = sizeof(float);
+		case ST_SIZE_DDWORD:
+			sample_size = 8;
 		        break;
 		default:
 			st_fail_errno(ft,ST_ENOTSUP,"Can't seek this data size");
@@ -295,7 +295,7 @@
 		    copy_buf = st_alaw_copy_buf;
 		    break;
 		default:
-		    st_fail_errno(ft,ST_EFMT,"Do not support this encoding for this data size.");
+		    st_fail_errno(ft,ST_EFMT,"Do not support this encoding for this data size");
 		    return(0);
 	    }
 	    break;
@@ -310,7 +310,7 @@
 		    copy_buf = st_uw_copy_buf;
 		    break;
 		default:
-		    st_fail_errno(ft,ST_EFMT,"Do not support this encoding for this data size.");
+		    st_fail_errno(ft,ST_EFMT,"Do not support this encoding for this data size");
 		    return(0);
 	    }
 	    break;
@@ -324,24 +324,25 @@
 		case ST_ENCODING_UNSIGNED:
 		    copy_buf = st_udw_copy_buf;
 		    break;
+		case ST_ENCODING_FLOAT:
+		    copy_buf = st_f32_copy_buf;
 		default:
-		    st_fail_errno(ft,ST_EFMT,"Do not support this encoding for this data size.");
+		    st_fail_errno(ft,ST_EFMT,"Do not support this encoding for this data size");
 		    return(0);
 	    }
 	    break;
 
-	case ST_SIZE_FLOAT:
-	    copy_buf = st_f32_copy_buf;
-	    /* Hack hack... Encoding should be FLOAT, not the size */
-	    size = 4;
+	case ST_SIZE_DDWORD:
+	    switch(encoding)
+	    {
+		case ST_ENCODING_FLOAT:
+		    copy_buf = st_f64_copy_buf;
+		    break;
+		default:
+		    st_fail_errno(ft,ST_EFMT,"Do not support this encoding for this data size");
+	    }
 	    break;
 
-	case ST_SIZE_DOUBLE:
-	    copy_buf = st_f64_copy_buf;
-	    /* Hack hack... Encoding should be FLOAT, not the size */
-	    size = 8;
-	    break;
-
 	default:
 	    st_fail_errno(ft,ST_EFMT,"Do not support this data size for this handler");
 	    return (0);
@@ -586,17 +587,17 @@
 					done++;
 				}
 				return done;
+			case ST_ENCODING_FLOAT:
+				while(done < nsamp) {
+				    float f;
+				    /* scale signed up to long's range */
+				    f = (float)*buf++ / 0x10000;
+				    blockw(&f, sizeof(float), ft);
+				    done++;
+				}
+				return done;
 		    }
 		    break;
-		case ST_SIZE_FLOAT:
-			while(done < nsamp) {
-				float f;
-				/* scale signed up to long's range */
-				f = (float)*buf++ / 0x10000;
-			 	blockw(&f, sizeof(float), ft);
-				done++;
-			}
-			return done;
 		default:
 			break;
 	}
--- a/src/sf.c
+++ b/src/sf.c
@@ -120,8 +120,8 @@
 			samplesize = ft->info.size;
 			break;
 		case SF_FLOAT:
-			ft->info.size = ST_SIZE_FLOAT;
-			ft->info.encoding = ST_ENCODING_SIGN2;
+			ft->info.size = ST_SIZE_DWORD;
+			ft->info.encoding = ST_ENCODING_FLOAT;
 			samplesize = sizeof(float);
 			break;
 		default:
@@ -175,7 +175,8 @@
 	    sf->info.magic_union._magic_bytes.sf_machine = SF_SUN;
 
 	sf->info.sf_srate = ft->info.rate;
-	if (ft->info.size == ST_SIZE_FLOAT) {
+	if (ft->info.size == ST_SIZE_DWORD && 
+	    ft->info.encoding == ST_ENCODING_FLOAT) {
 		sf->info.sf_packmode = SF_FLOAT;
 	} else {
 		sf->info.sf_packmode = SF_SHORT;
--- a/src/silence.c
+++ b/src/silence.c
@@ -41,25 +41,25 @@
     char	start;
     int		start_periods;
     char	*start_duration_str;
-    ULONG	start_duration;
+    st_size_t	start_duration;
     double	start_threshold;
     char	start_unit; /* "d" for decibels or "%" for percent. */
 
-    LONG	*start_holdoff;
-    ULONG	start_holdoff_offset;
-    ULONG	start_holdoff_end;
+    st_sample_t	*start_holdoff;
+    st_size_t	start_holdoff_offset;
+    st_size_t	start_holdoff_end;
     int		start_found_periods;
 
     char	stop;
     int		stop_periods;
     char	*stop_duration_str;
-    ULONG	stop_duration;
+    st_size_t	stop_duration;
     double	stop_threshold;
     char	stop_unit;
 
-    LONG	*stop_holdoff;
-    ULONG	stop_holdoff_offset;
-    ULONG	stop_holdoff_end;
+    st_sample_t	*stop_holdoff;
+    st_size_t	stop_holdoff_offset;
+    st_size_t	stop_holdoff_end;
     int		stop_found_periods;
 
     /* State Machine */
@@ -66,7 +66,7 @@
     char	mode;
 } *silence_t;
 
-#define SILENCE_USAGE "Usage: silence above_periods [ duration thershold[d | %% | s] ] [ below_periods duration threshold[ d | %% | s ]]"
+#define SILENCE_USAGE "Usage: silence above_periods [ duration thershold[d | %% ] ] [ below_periods duration threshold[ d | %% ]]"
 
 int st_silence_getopts(eff_t effp, int n, char **argv)
 {
@@ -131,16 +131,11 @@
 	    return ST_EOF;
 	}
 	else if (parse_count < 2)
-	    silence->start_unit = 's';
+	    silence->start_unit = '%';
 
 	argv++; argv++;
 	n--; n--;
     }
-    else
-    {
-	st_fail(SILENCE_USAGE);
-	return ST_EOF;
-    }
 
     silence->stop = FALSE;
     /* Parse data needed for trimming of backside */
@@ -193,7 +188,7 @@
 	    return ST_EOF;
 	}
 	else if (parse_count < 2)
-	    silence->stop_unit = 's';
+	    silence->stop_unit = '%';
 
 	argv++; argv++;
 	n--; n--;
@@ -202,8 +197,7 @@
     /* Error checking */
     if (silence->start)
     {
-	if ((silence->start_unit != '%') && (silence->start_unit != 'd') &&
-		(silence->start_unit != 's'))
+	if ((silence->start_unit != '%') && (silence->start_unit != 'd'))
 	{
 	    st_fail("Invalid unit specified");
 	    st_fail(SILENCE_USAGE);
@@ -224,8 +218,7 @@
 
     if (silence->stop)
     {
-	if ((silence->stop_unit != '%') && (silence->stop_unit != 'd') &&
-		(silence->stop_unit != 's'))
+	if ((silence->stop_unit != '%') && (silence->stop_unit != 'd'))
 	{
 	    st_fail("Invalid unit specified");
 	    return(ST_EOF);
@@ -253,7 +246,7 @@
 	if (silence->start)
 	{
 	    if (st_parsesamples(effp->ininfo.rate, silence->start_duration_str,
-			&silence->start_duration,'s') !=
+			        &silence->start_duration, 's') !=
 		    ST_SUCCESS)
 	    {
 		st_fail(SILENCE_USAGE);
@@ -263,7 +256,7 @@
 	if (silence->stop)
 	{
 	    if (st_parsesamples(effp->ininfo.rate,silence->stop_duration_str,
-			&silence->stop_duration,'s') !=
+			        &silence->stop_duration,'s') !=
 		    ST_SUCCESS)
 	    {
 		st_fail(SILENCE_USAGE);
@@ -277,11 +270,21 @@
 	    silence->mode = SILENCE_COPY;
 
 	silence->start_holdoff = malloc(sizeof(LONG)*silence->start_duration);
+	if (!silence->start_holdoff)
+	{
+	    st_fail("Could not allocate memory");
+	    return(ST_EOF);
+	}
 	silence->start_holdoff_offset = 0;
 	silence->start_holdoff_end = 0;
 	silence->start_found_periods = 0;
 
 	silence->stop_holdoff = malloc(sizeof(LONG)*silence->stop_duration);
+	if (!silence->stop_holdoff)
+	{
+	    st_fail("Could not allocate memory");
+	    return(ST_EOF);
+	}
 	silence->stop_holdoff_offset = 0;
 	silence->stop_holdoff_end = 0;
 	silence->stop_found_periods = 0;
@@ -289,26 +292,37 @@
 	return(ST_SUCCESS);
 }
 
-int aboveThreshold(st_sample_t value, double threshold, char unit)
+int aboveThreshold(eff_t effp, st_sample_t value, double threshold, char unit)
 {
     double ratio;
-    int rc = 0;
+    int rc;
 
-    ratio = (double)labs(value) / (double)MAXLONG;
-
-    if (unit == 's')
+    /* When scaling low bit data, noise values got scaled way up */
+    /* Only consider the original bits when looking for silence */
+    switch(effp->ininfo.size)
     {
-	rc = (labs(value) >= threshold);
+	case ST_SIZE_BYTE:
+	    value = ST_SAMPLE_TO_SIGNED_BYTE(value);
+	    ratio = (double)abs(value) / (double)ST_INT8_MAX;
+	    break;
+	case ST_SIZE_WORD:
+	    value = ST_SAMPLE_TO_SIGNED_WORD(value);
+	    ratio = (double)abs(value) / (double)ST_INT16_MAX;
+	    break;
+	case ST_SIZE_DWORD:
+	    value = ST_SAMPLE_TO_SIGNED_DWORD(value);
+	    ratio = (double)labs(value) / (double)ST_INT32_MAX;
+	    break;
+	default:
+	    ratio = 0;
     }
-    else
-    {
-	if (unit == '%')
-	    ratio *= 100.0;
-	else if (unit == 'd')
-	    ratio = log10(ratio) * 20.0;
-    	rc = (ratio >= threshold);
-    }
 
+    if (unit == '%')
+	ratio *= 100.0;
+    else if (unit == 'd')
+	ratio = log10(ratio) * 20.0;
+    rc = (ratio >= threshold);
+
     return rc;
 }
 
@@ -330,6 +344,8 @@
 	    /* Reads and discards all input data until it detects a
 	     * sample that is above the specified threshold.  Turns on
 	     * copy mode when detected.
+	     * Need to make sure and copy input in groups of "channels" to
+	     * prevent getting buffers out of sync.
 	     */
 	    nrOfTicks = min((*isamp), (*osamp)) / effp->ininfo.channels;
 	    for(i = 0; i < nrOfTicks; i++)
@@ -337,10 +353,11 @@
 		threshold = 0;
 		for (j = 0; j < effp->ininfo.channels; j++)
 		{
-		    threshold |= aboveThreshold(ibuf[j], 
-			    silence->start_threshold, 
-			    silence->start_unit);
+		    threshold |= aboveThreshold(effp, ibuf[j], 
+			                        silence->start_threshold, 
+			                        silence->start_unit);
 		}
+
 		if (threshold)
 		{
 		    /* Add to holdoff buffer */
@@ -370,8 +387,8 @@
 		else /* !above Threshold */
 		{
 		    silence->start_holdoff_end = 0;
-		    ibuf += effp->ininfo.channels;
-    		    nrOfInSamplesRead += effp->ininfo.channels;
+		    ibuf += effp->ininfo.channels; 
+		    nrOfInSamplesRead += effp->ininfo.channels;
 		}
 	    } /* for nrOfTicks */
 	    break;
@@ -379,9 +396,8 @@
 	case SILENCE_TRIM_FLUSH:
 silence_trim_flush:
 	    nrOfTicks = min((silence->start_holdoff_end -
-			        silence->start_holdoff_offset), 
-	                    (*osamp-nrOfOutSamplesWritten)) / 
-		            effp->ininfo.channels;
+			     silence->start_holdoff_offset), 
+	                     (*osamp-nrOfOutSamplesWritten)); 
 	    for(i = 0; i < nrOfTicks; i++)
 	    {
 		*obuf++ = silence->start_holdoff[silence->start_holdoff_offset++];
@@ -388,6 +404,7 @@
 		nrOfOutSamplesWritten++;
 	    }
 
+	    /* If fully drained holdoff then switch to copy mode */
 	    if (silence->start_holdoff_offset == silence->start_holdoff_end)
 	    {
 		silence->start_holdoff_offset = 0;
@@ -417,7 +434,7 @@
 silence_copy:
 	    nrOfTicks = min((*isamp-nrOfInSamplesRead), 
 	                    (*osamp-nrOfOutSamplesWritten)) / 
-		            effp->ininfo.channels;
+		           effp->ininfo.channels;
 	    if (silence->stop)
 	    {
 	        for(i = 0; i < nrOfTicks; i++)
@@ -425,13 +442,14 @@
 		    threshold = 1;
 		    for (j = 0; j < effp->ininfo.channels; j++)
 		    {
-		        threshold &= aboveThreshold(ibuf[j], 
+			threshold &= aboveThreshold(effp, ibuf[j], 
 				                    silence->stop_threshold, 
-			                            silence->stop_unit);
+				                    silence->stop_unit);
 		    }
+
 		    /* If above threshold, check to see if we where holding
 		     * off previously.  If so then flush this buffer.
-		     * We haven't incremented any pionters yet so nothing
+		     * We haven't incremented any pointers yet so nothing
 		     * is lost.
 		     */
 		    if (threshold && silence->stop_holdoff_end)
@@ -442,20 +460,23 @@
 		    else if (threshold)
 		    {
 			/* Not holding off so copy into output buffer */
-			memcpy(obuf,ibuf,sizeof(LONG)*effp->ininfo.channels);
-			nrOfInSamplesRead += effp->ininfo.channels;
-			nrOfOutSamplesWritten += effp->ininfo.channels;
-			ibuf += effp->ininfo.channels;
+			for (j = 0; j < effp->ininfo.channels; j++)
+			{
+			    *obuf++ = *ibuf++;
+			    nrOfInSamplesRead++;
+			    nrOfOutSamplesWritten++;
+			}
 		    }
 		    else if (!threshold)
 		    {
 			/* Add to holdoff buffer */
-		        for (j = 0; j < effp->ininfo.channels; j++)
-		        {
+			for (j = 0; j < effp->ininfo.channels; j++)
+			{
 			    silence->stop_holdoff[
-				    silence->stop_holdoff_end++] = *ibuf++;
+				silence->stop_holdoff_end++] = *ibuf++;
 			    nrOfInSamplesRead++;
-		        }
+			}
+
 			/* Check if holdoff buffer is greater than duration 
 			 */
 			if (silence->stop_holdoff_end >= 
@@ -484,15 +505,16 @@
 				goto silence_copy_flush;
 			    }
 			    break;
-			}
-		    }
-	        }
-	    }
+			} /* Filled holdoff buffer */
+		    } /* Detected silence */
+	        } /* For # of samples */
+	    } /* Trimming off backend */
 	    else /* !(silence->stop) */
 	    {
-	        memcpy(obuf, ibuf, sizeof(LONG)*nrOfTicks);
-	        nrOfInSamplesRead += nrOfTicks;
-	        nrOfOutSamplesWritten += nrOfTicks;
+	        memcpy(obuf, ibuf, sizeof(st_sample_t)*nrOfTicks*
+			           effp->ininfo.channels);
+	        nrOfInSamplesRead += (nrOfTicks*effp->ininfo.channels);
+	        nrOfOutSamplesWritten += (nrOfTicks*effp->ininfo.channels);
 	    }
 	    break;
 
@@ -500,7 +522,8 @@
 silence_copy_flush:
 	    nrOfTicks = min((silence->stop_holdoff_end -
 			        silence->stop_holdoff_offset), 
-	                    (*osamp-nrOfOutSamplesWritten)) / effp->ininfo.channels;
+	                    (*osamp-nrOfOutSamplesWritten));
+
 	    for(i = 0; i < nrOfTicks; i++)
 	    {
 		*obuf++ = silence->stop_holdoff[silence->stop_holdoff_offset++];
@@ -507,14 +530,12 @@
 		nrOfOutSamplesWritten++;
 	    }
 
+	    /* If fully drained holdoff then return to copy mode */
 	    if (silence->stop_holdoff_offset == silence->stop_holdoff_end)
 	    {
 		silence->stop_holdoff_offset = 0;
 		silence->stop_holdoff_end = 0;
 		silence->mode = SILENCE_COPY;
-		/* Return to copy mode incase there are is more room in
-		 * output buffer to copy some more data from input buffer.
-		 */
 		goto silence_copy;
 	    }
 	    break;
@@ -539,11 +560,11 @@
     /* Only if in flush mode will there be possible samples to write
      * out during drain() call.
      */
-    if (silence->mode == SILENCE_COPY_FLUSH)
+    if (silence->mode == SILENCE_COPY_FLUSH || 
+	silence->mode == SILENCE_COPY)
     {
         nrOfTicks = min((silence->stop_holdoff_end - 
-		            silence->stop_holdoff_offset), 
-	                *osamp) / effp->ininfo.channels;
+		            silence->stop_holdoff_offset), *osamp);
 	for(i = 0; i < nrOfTicks; i++)
 	{
 	    *obuf++ = silence->stop_holdoff[silence->stop_holdoff_offset++];
@@ -550,6 +571,7 @@
 	    nrOfOutSamplesWritten++;
         }
 
+	/* If fully drained holdoff then stop */
 	if (silence->stop_holdoff_offset == silence->stop_holdoff_end)
 	{
 	    silence->stop_holdoff_offset = 0;
--- a/src/sox.c
+++ b/src/sox.c
@@ -299,7 +299,8 @@
         ft->filetype = "auto";
 
     if ( st_gettype(ft) )
-        st_fail("Unknown input file format for '%s'.  Use -t option to override",ft->filename);
+        st_fail("Unknown input file format for '%s':  %s", 
+		ft->filename, ft->st_errstr);
 
     /* Default the input comment to the filename if not set from
      * command line.
@@ -358,7 +359,8 @@
     if (writing && ft->filename)
     {
         if ( st_gettype(ft) )
-            st_fail("Unknown output file format for '%s'.  Use -t option to override",ft->filename);
+            st_fail("Unknown output file format for '%s': %s",
+		    ft->filename, ft->st_errstr);
 
     }
 
@@ -409,9 +411,9 @@
 }
 
 #ifdef HAVE_GETOPT_H
-static char *getoptstr = "+r:v:t:c:phsuUAaigbwlfdDxV";
+static char *getoptstr = "+r:v:t:c:phsuUAaigbwlfdxV";
 #else
-static char *getoptstr = "r:v:t:c:phsuUAaigbwlfdDxV";
+static char *getoptstr = "r:v:t:c:phsuUAaigbwlfdxV";
 #endif
 
 static void doopts(ft_t ft, int argc, char **argv)
@@ -476,19 +478,6 @@
                         if (! ft) usage("-l");
                         ft->info.size = ST_SIZE_DWORD;
                         break;
-                case 'f':
-                        if (! ft) usage("-f");
-                        ft->info.size = ST_SIZE_FLOAT;
-                        break;
-                case 'd':
-                        if (! ft) usage("-d");
-                        ft->info.size = ST_SIZE_DOUBLE;
-                        break;
-                case 'D':
-                        if (! ft) usage("-D");
-                        ft->info.size = ST_SIZE_IEEE;
-                        break;
-
                 case 's':
                         if (! ft) usage("-s");
                         ft->info.encoding = ST_ENCODING_SIGN2;
@@ -505,6 +494,10 @@
                         if (! ft) usage("-A");
                         ft->info.encoding = ST_ENCODING_ALAW;
                         break;
+                case 'f':
+                        if (! ft) usage("-f");
+                        ft->info.encoding = ST_ENCODING_FLOAT;
+                        break;
                 case 'a':
                         if (! ft) usage("-a");
                         ft->info.encoding = ST_ENCODING_ADPCM;
@@ -641,7 +634,7 @@
     /* Reserve an output buffer for all effects */
     for(e = 0; e < neffects; e++)
     {
-        efftab[e].obuf = (LONG *) malloc(BUFSIZ * sizeof(LONG));
+        efftab[e].obuf = (st_sample_t *) malloc(BUFSIZ * sizeof(st_sample_t));
         if (efftab[e].obuf == NULL)
         {
             st_fail("could not allocate memory");
@@ -648,7 +641,8 @@
         }
         if (efftabR[e].name)
         {
-            efftabR[e].obuf = (LONG *) malloc(BUFSIZ * sizeof(LONG));
+            efftabR[e].obuf = (st_sample_t *) malloc(BUFSIZ * 
+		                                     sizeof(st_sample_t));
             if (efftabR[e].obuf == NULL)
             {
                 st_fail("could not allocate memory");
@@ -659,7 +653,7 @@
 #ifdef SOXMIX
     for (f = 0; f < MAX_INPUT_FILES; f++)
     {
-        ibuf[f] = (LONG *)malloc(BUFSIZ * sizeof(LONG));
+        ibuf[f] = (st_sample_t *)malloc(BUFSIZ * sizeof(st_sample_t));
         if (!ibuf[f])
         {
             st_fail("could not allocate memory");
@@ -680,12 +674,14 @@
 
 #ifndef SOXMIX
         efftab[0].olen = (*informat[0]->h->read)(informat[0],
-                                              efftab[0].obuf, (LONG) BUFSIZ);
+                                                 efftab[0].obuf, 
+						 (st_ssize_t)BUFSIZ);
 #else
         for (f = 0; f < input_count; f++)
         {
             ilen[f] = (*informat[f]->h->read)(informat[f],
-                                              ibuf[f], (LONG)BUFSIZ);
+                                              ibuf[f], 
+					      (st_ssize_t)BUFSIZ);
         }
 
         efftab[0].olen = 0;
@@ -811,8 +807,8 @@
       if (writing&&(efftab[neffects-1].olen>efftab[neffects-1].odone))
       {
           (* outformat->h->write)(outformat,
-                                     efftab[neffects-1].obuf,
-                                     (LONG) efftab[neffects-1].olen);
+                                  efftab[neffects-1].obuf,
+                                  (st_ssize_t)efftab[neffects-1].olen);
           efftab[neffects-1].odone = efftab[neffects-1].olen;
       }
 
@@ -844,8 +840,8 @@
 static int flow_effect(e)
 int e;
 {
-    LONG i, done, idone, odone, idonel, odonel, idoner, odoner;
-    LONG *ibuf, *obuf;
+    st_size_t i, done, idone, odone, idonel, odonel, idoner, odoner;
+    st_sample_t *ibuf, *obuf;
     int effstatus;
 
     /* I have no input data ? */
@@ -859,8 +855,8 @@
         idone = efftab[e-1].olen - efftab[e-1].odone;
         odone = BUFSIZ;
         effstatus = (* efftab[e].h->flow)(&efftab[e],
-                              &efftab[e-1].obuf[efftab[e-1].odone],
-                              efftab[e].obuf, &idone, &odone);
+                                          &efftab[e-1].obuf[efftab[e-1].odone],
+                                          efftab[e].obuf, &idone, &odone);
         efftab[e-1].odone += idone;
         efftab[e].odone = 0;
         efftab[e].olen = odone;
--- a/src/st.h
+++ b/src/st.h
@@ -130,9 +130,9 @@
 typedef struct st_fileinfo 
 {
     char          *buf;                 /* Pointer to data buffer */
-    st_size_t     size;                 /* Size of buffer */
-    st_size_t     count;                /* Count read in to buffer */
-    st_size_t     pos;                  /* Position in buffer */
+    size_t        size;                 /* Size of buffer */
+    size_t        count;                /* Count read in to buffer */
+    size_t        pos;                  /* Position in buffer */
     unsigned char eof;                  /* Marker that EOF has been reached */
 } st_fileinfo_t;
 
@@ -198,7 +198,6 @@
 #define ST_FILE_SEEK    8  /* does file format support seeking? */
 
 /* Size field */
-/* note that the 1st 3 are sometimes used as sizeof(type) */
 #define ST_SIZE_BYTE    1
 #define ST_SIZE_8BIT    1
 #define ST_SIZE_WORD    2
@@ -205,22 +204,20 @@
 #define ST_SIZE_16BIT   2
 #define ST_SIZE_DWORD   4
 #define ST_SIZE_32BIT   4
-#define ST_SIZE_FLOAT   5
-#define ST_SIZE_DOUBLE  6
-#define ST_SIZE_IEEE    7       /* IEEE 80-bit floats. */
+#define ST_SIZE_DDWORD  8
+#define ST_SIZE_64BIT   8
+#define ST_SIZE_MAX     8
 
-#define ST_SIZE_MAX     7
-
 /* Style field */
 #define ST_ENCODING_UNSIGNED    1 /* unsigned linear: Sound Blaster */
 #define ST_ENCODING_SIGN2       2 /* signed linear 2's comp: Mac */
 #define ST_ENCODING_ULAW        3 /* U-law signed logs: US telephony, SPARC */
 #define ST_ENCODING_ALAW        4 /* A-law signed logs: non-US telephony */
-#define ST_ENCODING_ADPCM       5 /* Compressed PCM */
-#define ST_ENCODING_IMA_ADPCM   6 /* Compressed PCM */
-#define ST_ENCODING_GSM         7 /* GSM 6.10 33-byte frame lossy compression */
-
-#define ST_ENCODING_MAX         7
+#define ST_ENCODING_FLOAT       5 /* 32-bit float */
+#define ST_ENCODING_ADPCM       6 /* Compressed PCM */
+#define ST_ENCODING_IMA_ADPCM   7 /* Compressed PCM */
+#define ST_ENCODING_GSM         8 /* GSM 6.10 33byte frame lossy compression */
+#define ST_ENCODING_MAX         8 
 
 /* declared in misc.c */
 extern const char *st_sizes_str[];
--- a/src/st_i.h
+++ b/src/st_i.h
@@ -121,6 +121,11 @@
 #define M_PI_2  1.57079632679489661923  /* pi/2 */
 #endif
 
+#define ST_INT8_MAX (127)
+#define ST_INT16_MAX (32676)
+#define ST_INT32_MAX (2147483647)
+#define ST_INT64_MAX (9223372036854775807)
+
 /*=============================================================================
  * File Handlers
  *=============================================================================
--- a/src/util.c
+++ b/src/util.c
@@ -138,8 +138,7 @@
         if (! formp->filetype){
             st_fail_errno(formp,
                           ST_EFMT,
-                          "Must give file type for %s file, either as suffix or with -t option",
-                          formp->filename);
+                          "Filetype was not specified");
                 return(ST_EFMT);
         }
         for(i = 0; st_formats[i].names; i++) {
@@ -154,20 +153,8 @@
                 formp->h = &st_formats[i];
                 return ST_SUCCESS;
         }
-        if (! strcmpcase(formp->filetype, "snd")) {
-                verbose = 1;
-                st_report("File type '%s' is used to name several different formats.", formp->filetype);
-                st_report("If the file came from a Macintosh, it is probably");
-                st_report("a .ub file with a sample rate of 11025 (or possibly 5012 or 22050).");
-                st_report("Use the sequence '-t .ub -r 11025 file.snd'");
-                st_report("If it came from a PC, it's probably a Soundtool file.");
-                st_report("Use the sequence '-t .sndt file.snd'");
-                st_report("If it came from a NeXT, it's probably a .au file.");
-                st_fail_errno(formp,ST_EFMT,"Use the sequence '-t .au file.snd'\n");
-                return ST_EFMT;
-        }
-        st_fail_errno(formp,ST_EFMT,"File type '%s' of %s file is not known!",
-                formp->filetype, formp->filename);
+        st_fail_errno(formp, ST_EFMT, "File type '%s' is not known",
+                      formp->filetype);
         return ST_EFMT;
 }
 
@@ -428,7 +415,7 @@
                 return ST_EOF;
         }
 
-        if (ft->info.encoding == -1 && ft->info.size != ST_SIZE_FLOAT)
+        if (ft->info.encoding == -1)
         {
                 st_fail_errno(ft,ST_EFMT,"data encoding was not specified");
                 return ST_EOF;