shithub: sox

Download patch

ref: 8b07535150c66640c77af3bb97a023b4fc6f25b4
parent: fdc86daca0c63d0ac4d4744e69c41a839977ecb0
author: cbagwell <cbagwell>
date: Sun Mar 5 21:02:12 EST 2006

Bugfixes to silence effect.

--- a/Changelog
+++ b/Changelog
@@ -26,6 +26,11 @@
   o Stop infinite loop when reading MP3's with a tag size of
     exactly 8192 bytes.  (1417511) Hans Fugal
   o Fix typo in stlib.dsp for loading in Visual Studio 6.
+  o Fixed problems in silence effect related to removing multiple
+    periods of silence from the middle of the sound file.
+  o Reduced the window size greatly on the silence effect to
+    prevent leaving in silence that looked like noise still based
+    on RMS values.
 
 sox-12.17.9
 -----------
--- a/src/silence.c
+++ b/src/silence.c
@@ -75,6 +75,19 @@
     char        mode;
 } *silence_t;
 
+static void clear_rms(eff_t effp)
+
+{
+    silence_t silence = (silence_t) effp->priv;
+
+    memset(silence->window, 0, 
+           silence->window_size * sizeof(double));
+
+    silence->window_current = silence->window;
+    silence->window_end = silence->window + silence->window_size;
+    silence->rms_sum = 0;
+}
+
 #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)
@@ -253,7 +266,12 @@
 {
         silence_t       silence = (silence_t) effp->priv;
 
-        silence->window_size = (effp->ininfo.rate / 10) * effp->ininfo.channels;
+        /* When you want to remove silence, small window sizes are
+         * better or else RMS will look like non-silence at
+         * aburpt changes from load to silence.
+         */
+        silence->window_size = (effp->ininfo.rate / 50) * 
+                               effp->ininfo.channels;
         silence->window = (double *)malloc(silence->window_size *
                                            sizeof(double));
 
@@ -263,13 +281,8 @@
             return(ST_EOF);
         }
 
-        memset(silence->window, 0, 
-               silence->window_size * sizeof(double));
+        clear_rms(effp);
 
-        silence->window_current = silence->window;
-        silence->window_end = silence->window + silence->window_size;
-        silence->rms_sum = 0;
-
         /* Now that we now sample rate, reparse duration. */
         if (silence->start)
         {
@@ -354,7 +367,7 @@
     return rc;
 }
 
-st_sample_t compute_rms(eff_t effp, st_sample_t sample)
+static st_sample_t compute_rms(eff_t effp, st_sample_t sample)
 {
     silence_t silence = (silence_t) effp->priv;
     double new_sum;
@@ -369,7 +382,7 @@
     return (rms);
 }
 
-void update_rms(eff_t effp, st_sample_t sample)
+static void update_rms(eff_t effp, st_sample_t sample)
 {
     silence_t silence = (silence_t) effp->priv;
 
@@ -404,7 +417,10 @@
              * 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;
+silence_trim:
+            nrOfTicks = min((*isamp-nrOfInSamplesRead), 
+                            (*osamp-nrOfOutSamplesWritten)) / 
+                           effp->ininfo.channels;
             for(i = 0; i < nrOfTicks; i++)
             {
                 threshold = 0;
@@ -558,16 +574,22 @@
                                 silence->stop_holdoff_end = 0;
                                 if (!silence->restart)
                                 {
-                                    silence->mode = SILENCE_STOP;
                                     *isamp = nrOfInSamplesRead;
                                     *osamp = nrOfOutSamplesWritten;
+                                    silence->mode = SILENCE_STOP;
                                     /* Return ST_EOF since no more processing */
                                     return (ST_EOF);
                                 }
                                 else
                                 {
+                                    silence->stop_found_periods = 0;
+                                    silence->start_found_periods = 0;
+                                    silence->start_holdoff_offset = 0;
+                                    silence->start_holdoff_end = 0;
+                                    clear_rms(effp);
                                     silence->mode = SILENCE_TRIM;
-                                    return (ST_SUCCESS);
+
+                                    goto silence_trim;
                                 }
                             }
                             else