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]);