boo/soxr/src/fft4g_cache.h

93 lines
2.1 KiB
C

/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
static int * LSX_FFT_BR;
static DFT_FLOAT * LSX_FFT_SC;
static int FFT_LEN = -1;
static ccrw2_t FFT_CACHE_CCRW;
void LSX_INIT_FFT_CACHE(void)
{
if (FFT_LEN >= 0)
return;
assert(LSX_FFT_BR == NULL);
assert(LSX_FFT_SC == NULL);
assert(FFT_LEN == -1);
ccrw2_init(FFT_CACHE_CCRW);
FFT_LEN = 0;
}
void LSX_CLEAR_FFT_CACHE(void)
{
assert(FFT_LEN >= 0);
ccrw2_clear(FFT_CACHE_CCRW);
free(LSX_FFT_BR);
free(LSX_FFT_SC);
LSX_FFT_SC = NULL;
LSX_FFT_BR = NULL;
FFT_LEN = -1;
}
static bool UPDATE_FFT_CACHE(int len)
{
LSX_INIT_FFT_CACHE();
assert(lsx_is_power_of_2(len));
assert(FFT_LEN >= 0);
ccrw2_become_reader(FFT_CACHE_CCRW);
if (len > FFT_LEN) {
ccrw2_cease_reading(FFT_CACHE_CCRW);
ccrw2_become_writer(FFT_CACHE_CCRW);
if (len > FFT_LEN) {
int old_n = FFT_LEN;
FFT_LEN = len;
LSX_FFT_BR = realloc(LSX_FFT_BR, dft_br_len(FFT_LEN) * sizeof(*LSX_FFT_BR));
LSX_FFT_SC = realloc(LSX_FFT_SC, dft_sc_len(FFT_LEN) * sizeof(*LSX_FFT_SC));
if (!old_n) {
LSX_FFT_BR[0] = 0;
#if SOXR_LIB
atexit(LSX_CLEAR_FFT_CACHE);
#endif
}
return true;
}
ccrw2_cease_writing(FFT_CACHE_CCRW);
ccrw2_become_reader(FFT_CACHE_CCRW);
}
return false;
}
static void DONE_WITH_FFT_CACHE(bool is_writer)
{
if (is_writer)
ccrw2_cease_writing(FFT_CACHE_CCRW);
else ccrw2_cease_reading(FFT_CACHE_CCRW);
}
void LSX_SAFE_RDFT(int len, int type, DFT_FLOAT * d)
{
bool is_writer = UPDATE_FFT_CACHE(len);
LSX_RDFT(len, type, d, LSX_FFT_BR, LSX_FFT_SC);
DONE_WITH_FFT_CACHE(is_writer);
}
void LSX_SAFE_CDFT(int len, int type, DFT_FLOAT * d)
{
bool is_writer = UPDATE_FFT_CACHE(len);
LSX_CDFT(len, type, d, LSX_FFT_BR, LSX_FFT_SC);
DONE_WITH_FFT_CACHE(is_writer);
}
#undef UPDATE_FFT_CACHE
#undef LSX_SAFE_RDFT
#undef LSX_SAFE_CDFT
#undef LSX_RDFT
#undef LSX_INIT_FFT_CACHE
#undef LSX_FFT_SC
#undef LSX_FFT_BR
#undef LSX_CLEAR_FFT_CACHE
#undef LSX_CDFT
#undef FFT_LEN
#undef FFT_CACHE_CCRW
#undef DONE_WITH_FFT_CACHE
#undef DFT_FLOAT