shithub: sox

Download patch

ref: c52b45fa675267acd65b888ae16bff90b731d24b
parent: 3b89cf7fa3d1548b5b91133a11be2d4d88521bb1
author: cbagwell <cbagwell>
date: Sun Jul 8 22:58:53 EDT 2001

Few more updates to silence effect.  Still not working.

--- a/libst.3
+++ b/libst.3
@@ -146,10 +146,9 @@
 actually processed.
 It is under no obligation to read from the input buffer or
 write to the output buffer during the same call.  If the
-call returns 0 for both input and output sizes then this will
-indicate that it no longer expects to process
-samples and the application program can start calling the drain
-operation.
+call returns ST_EOF then this should be used as an indication
+that this effect will no longer read any data and can be used
+to switch to drain mode sooner.
 .TP 20 
 drain
 is called after there are no more input data samples.
--- a/src/silence.c
+++ b/src/silence.c
@@ -40,8 +40,9 @@
     double	trim_threshold;
     char	trim_unit; /* "d" for decibels or "%" for percent. */
     char	stop;
-    double	stop_threshold;
+    int		stop_count;
     ULONG	stop_duration;
+    double	stop_threshold;
     char	stop_unit;
     LONG	*holdoff;
     ULONG	holdoff_count;
@@ -50,33 +51,71 @@
     char	crossings;
 } *silence_t;
 
+/*#define SILENCE_USAGE "Usage: silence count duration thershold [d | %%] [ -notrim ] [ count duration threshold [ d | %% ]]" */
 
+#define SILENCE_USAGE "Usage: silence count duration threshold [d | %%]"
+
 int st_silence_getopts(eff_t effp, int n, char **argv)
 {
 	silence_t	silence = (silence_t) effp->priv;
+	ULONG duration;
 
-	switch (n)
+	if (n < 3)
 	{
-		case 0:	/* No arguments, use defaults given above. */
-		break;
+	    st_fail(SILENCE_USAGE);
+    	    return (ST_EOF);
+	}
 
-		case 1:
-			sscanf(argv[0], "%lf", &silence->trim_threshold);
-		break;
+	silence->trim = FALSE;
+	silence->trim_threshold = 1.0;
+	silence->trim_unit = '%';
 
-		default:
-			sscanf(argv[0], "%lf", &silence->trim_threshold);
-			sscanf(argv[1], "%c", &silence->trim_unit);
-		break;
+	silence->stop = TRUE;
+	if (sscanf(argv[0], "%d", &silence->stop_count) != 1)
+	{
+	    st_fail(SILENCE_USAGE);
+	    return ST_EOF;
 	}
-	/* silence threshold type duration count [-notrim ] [ threshold type duration count ] */
-	if ((silence->trim_unit != '%') && (silence->trim_unit != 'd'))
-		st_fail("Usage: silence [threshold [d | %%]]");
-	if ((silence->trim_unit == '%') && ((silence->trim_threshold < 0.0) || 
-		                             (silence->trim_threshold > 100.0)))
+	if (sscanf(argv[1], "%ld", &duration) != 1)
+	{
+	    st_fail(SILENCE_USAGE);
+	    return ST_EOF;
+	}
+	silence->stop_duration = duration;
+	if (sscanf(argv[2], "%lf", &silence->stop_threshold) != 1)
+	{
+	    st_fail(SILENCE_USAGE);
+	    return ST_EOF;
+	}
+
+	if (n > 3 && strlen(argv[3]) == 1)
+	{
+	    silence->stop_unit = argv[3][0];
+	}
+
+	if (silence->stop_count != 1)
+       	{
+	    st_warn("Only support a stop count of 1 currently");
+	    st_fail(SILENCE_USAGE);
+	    return(ST_EOF);
+	}
+
+	if ((silence->stop_unit != '%') && (silence->stop_unit != 'd'))
+	{
+		st_fail(SILENCE_USAGE);
+		return(ST_EOF);
+	}
+	if ((silence->stop_unit == '%') && ((silence->stop_threshold < 0.0) || 
+					    (silence->stop_threshold > 100.0)))
+	{
 		st_fail("silence threshold should be between 0.0 and 100.0 %%");
-	if ((silence->trim_unit == 'd') && (silence->trim_threshold >= 0.0))
+		return (ST_EOF);
+	}
+	if ((silence->stop_unit == 'd') && (silence->stop_threshold >= 0.0))
+	{
 		st_fail("silence threshold should be less than 0.0 dB");
+		return(ST_EOF);
+	}
 	return(ST_SUCCESS);
 }
 
@@ -84,20 +123,12 @@
 {
 	silence_t	silence = (silence_t) effp->priv;
 
-	silence->trim = TRUE;
-	silence->trim_threshold = 1.0;
-	silence->trim_unit = '%';
+    	silence->mode = SILENCE_START;
 
-	silence->stop = TRUE;
-	silence->stop_threshold = 1.0;
-	silence->stop_duration = 1.8 * effp->ininfo.rate;
-	silence->stop_unit = '%';
 	silence->holdoff = malloc(sizeof(LONG)*silence->stop_duration);
 	silence->holdoff_count = 0;
 	silence->holdoff_offset = 0;
 
-	silence->mode = SILENCE_START;
-
 	silence->crossings = 0;
 
 	if ((effp->outinfo.channels != 1) && (effp->outinfo.channels != 2))
@@ -130,8 +161,15 @@
     switch (silence->mode)
     {
 	case SILENCE_START:
-	    /* Fall through until start is written */
-	    silence->mode = SILENCE_TRIM;
+	    if (!silence->trim)
+	    {
+		/* If no trimming then copy over starting from here */
+		silence->mode = SILENCE_COPY;
+		goto silence_copy;
+	    }
+	    else
+		/* Fall through and trim audio */
+		silence->mode = SILENCE_TRIM;
 
         /* Reads and discards all input data until it detects a
          * sample that is above the specified threshold.  Turns on
@@ -156,6 +194,7 @@
 		nrOfInSamplesRead += effp->ininfo.channels;
 	    }
 	    break;
+	case SILENCE_COPY:
 	    /* Attempts to copy samples into output buffer.  If not
 	     * looking for silence to terminate copy then blindly
 	     * copy data into output buffer.
@@ -172,7 +211,6 @@
 	     * If hold off buffer is full then stop copying data and
 	     * discard data in hold off buffer.
 	     */
-	case SILENCE_COPY:
 silence_copy:
 	    nrOfTicks = min((*isamp-nrOfInSamplesRead), 
 	                    (*osamp-nrOfOutSamplesWritten)) / effp->ininfo.channels;
@@ -184,8 +222,8 @@
 		    for (j = 0; j < effp->ininfo.channels; j++)
 		    {
 		        threshold |= aboveThreshold(ibuf[j], 
-				                    silence->trim_threshold, 
-			                            silence->trim_unit);
+				                    silence->stop_threshold, 
+			                            silence->stop_unit);
 		    }
 		    if (threshold && silence->holdoff_count)
 		    {
@@ -216,6 +254,10 @@
 			{
 			    silence->mode = SILENCE_STOP;
 			    silence->holdoff_count = 0;
+		    	    *isamp = nrOfInSamplesRead;
+			    *osamp = nrOfOutSamplesWritten;
+			    /* Return ST_EOF to indicate no more processing */
+			    return (ST_EOF);
 			    break;
 			}
 		    }
@@ -251,6 +293,7 @@
 	    }
 	    break;
 	case SILENCE_STOP:
+	    nrOfInSamplesRead = *isamp;
 	    break;
 	}