shithub: sox

Download patch

ref: 8d912d4b1daafe11a73c01dfb43d65bf0acbb1f8
parent: aaa8932887e11d0b6b90462a15ba05237ecd306a
author: idigdoug <idigdoug>
date: Thu Jan 7 06:31:05 EST 2010

Fix incorrect direct use of FFT cache (used without lock and without previously
checking for sufficient buffer in the cache). Also fix applications that were exiting without clearing the cache first.

--- a/src/dft_filter.c
+++ b/src/dft_filter.c
@@ -63,7 +63,7 @@
     fifo_trim_by(&p->output_fifo, overlap);
     memcpy(output, input, f->dft_length * sizeof(*output));
 
-    lsx_rdft(f->dft_length, 1, output, lsx_fft_br, lsx_fft_sc);
+    lsx_safe_rdft(f->dft_length, 1, output);
     output[0] *= f->coefs[0];
     output[1] *= f->coefs[1];
     for (i = 2; i < f->dft_length; i += 2) {
@@ -71,7 +71,7 @@
       output[i  ] = f->coefs[i  ] * tmp - f->coefs[i+1] * output[i+1];
       output[i+1] = f->coefs[i+1] * tmp + f->coefs[i  ] * output[i+1];
     }
-    lsx_rdft(f->dft_length, -1, output, lsx_fft_br, lsx_fft_sc);
+    lsx_safe_rdft(f->dft_length, -1, output);
   }
 }
 
--- a/src/effects_i_dsp.c
+++ b/src/effects_i_dsp.c
@@ -97,9 +97,9 @@
 }
 
 #include "fft4g.h"
-int    * lsx_fft_br;
-double * lsx_fft_sc;
-static int fft_len;
+static int * lsx_fft_br;
+static double * lsx_fft_sc;
+static int fft_len = -1;
 #ifdef HAVE_OPENMP
 static omp_lock_t fft_cache_lock;
 #endif
@@ -106,21 +106,33 @@
 
 void init_fft_cache(void)
 {
+  assert(lsx_fft_br == NULL);
+  assert(lsx_fft_sc == NULL);
+  assert(fft_len == -1);
   omp_init_lock(&fft_cache_lock);
+  fft_len = 0;
 }
 
 void clear_fft_cache(void)
 {
+  assert(fft_len >= 0);
   omp_destroy_lock(&fft_cache_lock);
   free(lsx_fft_br);
   free(lsx_fft_sc);
   lsx_fft_sc = NULL;
   lsx_fft_br = NULL;
-  fft_len = 0;
+  fft_len = -1;
 }
 
+static sox_bool is_power_of_2(int x)
+{
+  return !(x < 2 || (x & (x - 1)));
+}
+
 static void update_fft_cache(int len)
 {
+  assert(is_power_of_2(len));
+  assert(fft_len >= 0);
   omp_set_lock(&fft_cache_lock);
   if (len > fft_len) {
     int old_n = fft_len;
@@ -132,14 +144,8 @@
   }
 }
 
-static sox_bool is_power_of_2(int x)
-{
-  return !(x < 2 || (x & (x - 1)));
-}
-
 void lsx_safe_rdft(int len, int type, double * d)
 {
-  assert(is_power_of_2(len));
   update_fft_cache(len);
   lsx_rdft(len, type, d, lsx_fft_br, lsx_fft_sc);
   omp_unset_lock(&fft_cache_lock);
@@ -147,7 +153,6 @@
 
 void lsx_safe_cdft(int len, int type, double * d)
 {
-  assert(is_power_of_2(len));
   update_fft_cache(len);
   lsx_cdft(len, type, d, lsx_fft_br, lsx_fft_sc);
   omp_unset_lock(&fft_cache_lock);
--- a/src/example0.c
+++ b/src/example0.c
@@ -87,6 +87,6 @@
   sox_delete_effects_chain(chain);
   sox_close(out);
   sox_close(in);
-  sox_format_quit();
+  sox_quit();
   return 0;
 }
--- a/src/example1.c
+++ b/src/example1.c
@@ -157,6 +157,6 @@
   sox_delete_effects_chain(chain);
   sox_close(out);
   sox_close(in);
-  sox_format_quit();
+  sox_quit();
   return 0;
 }
--- a/src/example2.c
+++ b/src/example2.c
@@ -113,6 +113,6 @@
   /* All done; tidy up: */
   free(buf);
   sox_close(in);
-  sox_format_quit();
+  sox_quit();
   return 0;
 }
--- a/src/example3.c
+++ b/src/example3.c
@@ -87,7 +87,7 @@
   sox_delete_effects_chain(chain);
   sox_close(out);
   sox_close(in);
-  sox_format_quit();
+  sox_quit();
 
   return 0;
 }
--- a/src/rate.c
+++ b/src/rate.c
@@ -136,7 +136,7 @@
     fifo_trim_by(output_fifo, (f->dft_length + overlap) >> 1);
     memcpy(output, input, f->dft_length * sizeof(*output));
 
-    lsx_rdft(f->dft_length, 1, output, lsx_fft_br, lsx_fft_sc);
+    lsx_safe_rdft(f->dft_length, 1, output);
     output[0] *= f->coefs[0];
     output[1] *= f->coefs[1];
     for (i = 2; i < f->dft_length; i += 2) {
@@ -144,7 +144,7 @@
       output[i  ] = f->coefs[i  ] * tmp - f->coefs[i+1] * output[i+1];
       output[i+1] = f->coefs[i+1] * tmp + f->coefs[i  ] * output[i+1];
     }
-    lsx_rdft(f->dft_length, -1, output, lsx_fft_br, lsx_fft_sc);
+    lsx_safe_rdft(f->dft_length, -1, output);
 
     for (j = 1, i = 2; i < f->dft_length - overlap; ++j, i += 2)
       output[j] = output[i];
@@ -169,7 +169,7 @@
     for (j = i = 0; i < f->dft_length; ++j, i += 2)
       output[i] = input[j], output[i+1] = 0;
 
-    lsx_rdft(f->dft_length, 1, output, lsx_fft_br, lsx_fft_sc);
+    lsx_safe_rdft(f->dft_length, 1, output);
     output[0] *= f->coefs[0];
     output[1] *= f->coefs[1];
     for (i = 2; i < f->dft_length; i += 2) {
@@ -177,7 +177,7 @@
       output[i  ] = f->coefs[i  ] * tmp - f->coefs[i+1] * output[i+1];
       output[i+1] = f->coefs[i+1] * tmp + f->coefs[i  ] * output[i+1];
     }
-    lsx_rdft(f->dft_length, -1, output, lsx_fft_br, lsx_fft_sc);
+    lsx_safe_rdft(f->dft_length, -1, output);
   }
 }
 
--- a/src/sox.c
+++ b/src/sox.c
@@ -248,7 +248,7 @@
     tcsetattr(fileno(stdin), TCSANOW, &original_termios);
 #endif
 
-  sox_format_quit();
+  sox_quit();
 }
 
 static char const * str_time(double seconds)
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -90,8 +90,6 @@
 
 double lsx_bessel_I_0(double x);
 int lsx_set_dft_length(int num_taps);
-extern int * lsx_fft_br;
-extern double * lsx_fft_sc;
 void init_fft_cache(void);
 void clear_fft_cache(void);
 void lsx_safe_rdft(int len, int type, double * d);
--- a/src/spectrogram.c
+++ b/src/spectrogram.c
@@ -301,7 +301,7 @@
       make_window(p, p->last_end = p->end);
     for (i = 0; i < p->dft_size; ++i) p->dft_buf[i] = p->buf[i] * p->window[i];
     if (is_p2(p->dft_size)) {
-      lsx_rdft(p->dft_size, 1, p->dft_buf, lsx_fft_br, lsx_fft_sc);
+      lsx_safe_rdft(p->dft_size, 1, p->dft_buf);
       p->magnitudes[0] += sqr(p->dft_buf[0]);
       for (i = 1; i < p->dft_size >> 1; ++i)
         p->magnitudes[i] += sqr(p->dft_buf[2*i]) + sqr(p->dft_buf[2*i+1]);