diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/init.c | 84 | ||||
-rw-r--r-- | src/vector.c | 60 | ||||
-rw-r--r-- | src/xtract_macros_private.h | 5 |
4 files changed, 123 insertions, 28 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 8dc7691..bee5c4d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ MAINTAINERCLEANFILES = Makefile.in -SOURCES = libxtract.c descriptors.c scalar.c vector.c delta.c init.c +SOURCES = libxtract.c descriptors.c scalar.c vector.c delta.c init.c fini.c if BUILD_FFT FFT_DEFINE = -DXTRACT_FFT @@ -20,10 +20,24 @@ /* init.c: defines functions that extract a feature as a single value from an input vector */ -#include "xtract/libxtract.h" +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + #include <math.h> #include <stdlib.h> +#include "xtract/libxtract.h" +#include "xtract_globals_private.h" + +#ifdef XTRACT_FFT +#include <fftw3.h> + +#ifndef XTRACT_FFT_OPTIMISATION_LEVEL +/* This should never happen */ +#define XTRACT_FFT_OPTIMISATION_LEVEL 1 +#endif + int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq_max, int freq_bands, float **fft_tables){ int n, i, k, *fft_peak, M, next_peak; @@ -113,6 +127,10 @@ int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq fft_tables[n][k] = 0.f; } + + /* Initialise the fft_plan for the DCT */ + xtract_init_fft(freq_bands, XTRACT_MFCC); + free(mel_peak); free(lin_peak); free(height_norm); @@ -122,6 +140,69 @@ int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq } +int xtract_init_fft(int N, int feature_name){ + + float *input, *output; + int optimisation; + + input = output = NULL; + + fprintf(stderr, "Optimisation level: %d\n", XTRACT_FFT_OPTIMISATION_LEVEL); + + if(XTRACT_FFT_OPTIMISATION_LEVEL == 0) + optimisation = FFTW_ESTIMATE; + else if(XTRACT_FFT_OPTIMISATION_LEVEL == 1) + optimisation = FFTW_MEASURE; + else if(XTRACT_FFT_OPTIMISATION_LEVEL == 2) + optimisation = FFTW_PATIENT; + else + optimisation = FFTW_MEASURE; /* The default */ + + if(feature_name == XTRACT_AUTOCORRELATION_FFT) + N <<= 1; + + input = malloc(N * sizeof(float)); + output = malloc(N * sizeof(float)); + + switch(feature_name){ + case XTRACT_SPECTRUM: + if(spectrum_plan != NULL) + fftwf_destroy_plan(spectrum_plan); + spectrum_plan = + fftwf_plan_r2r_1d(N, input, output, FFTW_R2HC, optimisation); + break; + case XTRACT_AUTOCORRELATION_FFT: + if(autocorrelation_fft_plan_1 != NULL) + fftwf_destroy_plan(autocorrelation_fft_plan_1); + if(autocorrelation_fft_plan_2 != NULL) + fftwf_destroy_plan(autocorrelation_fft_plan_2); + autocorrelation_fft_plan_1 = + fftwf_plan_r2r_1d(N, input, output, FFTW_R2HC, optimisation); + autocorrelation_fft_plan_2 = + fftwf_plan_r2r_1d(N, input, output, FFTW_HC2R, optimisation); + break; + case XTRACT_DCT: + if(dct_plan != NULL) + fftwf_destroy_plan(dct_plan); + dct_plan = + fftwf_plan_r2r_1d(N, input, output, FFTW_REDFT00, optimisation); + case XTRACT_MFCC: + if(dct_plan != NULL) + fftwf_destroy_plan(dct_plan); + dct_plan = + fftwf_plan_r2r_1d(N, output, output, FFTW_REDFT00, optimisation); + break; + } + + free(input); + free(output); + + return XTRACT_SUCCESS; + +} + +#endif + int xtract_init_bark(int N, float sr, int *band_limits){ float edges[] = {0, 100, 200, 300, 400, 510, 630, 770, 920, 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150, 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500, 20500, 27000}; /* Takes us up to sr = 54kHz (CCRMA: JOS)*/ @@ -134,3 +215,4 @@ int xtract_init_bark(int N, float sr, int *band_limits){ return XTRACT_SUCCESS; } + diff --git a/src/vector.c b/src/vector.c index 19596ff..a9c5290 100644 --- a/src/vector.c +++ b/src/vector.c @@ -21,12 +21,13 @@ /* xtract_vector.c: defines functions that extract a feature as a single value from an input vector */ -#include "xtract/libxtract.h" -#include "xtract_macros_private.h" #include <math.h> #include <string.h> #include <stdlib.h> +#include "xtract/libxtract.h" +#include "xtract_macros_private.h" + #ifndef roundf float roundf(float f){ if (f - (int)f >= 0.5) @@ -39,17 +40,20 @@ #ifdef XTRACT_FFT #include <fftw3.h> +#include "xtract_globals_private.h" +#include "xtract_macros_private.h" int xtract_spectrum(const float *data, const int N, const void *argv, float *result){ float *input, *rfft, q, temp; size_t bytes; - int n , NxN, M, vector, withDC; - fftwf_plan plan; + int n , NxN, M, vector, withDC, argc; + //fftwf_plan plan; + + vector = argc = withDC = 0; M = N >> 1; NxN = XTRACT_SQ(N); - withDC = 0; rfft = (float *)fftwf_malloc(N * sizeof(float)); input = (float *)malloc(bytes = N * sizeof(float)); @@ -61,9 +65,16 @@ int xtract_spectrum(const float *data, const int N, const void *argv, float *res XTRACT_CHECK_q; - plan = fftwf_plan_r2r_1d(N, input, rfft, FFTW_R2HC, FFTW_ESTIMATE); - - fftwf_execute(plan); + if(spectrum_plan == NULL){ + /* FIX: Not sure this should really be here. Might introduce + * DEBUG_POST macro, or some kind of error handler, or leave it to the + * caller... */ + fprintf(stderr, + "libxtract: Error: xtract_spectrum() has uninitialised plan\n"); + return XTRACT_NO_RESULT; + } + + fftwf_execute_r2r(spectrum_plan, input, rfft); switch(vector){ @@ -152,11 +163,10 @@ int xtract_spectrum(const float *data, const int N, const void *argv, float *res } else { /* The Nyquist */ - result[M - 1] = XTRACT_SQ(rfft[M]); + result[M - 1] = (float)XTRACT_SQ(rfft[M]); result[N - 1] = q * M; } - fftwf_destroy_plan(plan); fftwf_free(rfft); free(input); @@ -167,7 +177,7 @@ int xtract_autocorrelation_fft(const float *data, const int N, const void *argv, float *freq, *time; int n, M; - fftwf_plan plan; + //fftwf_plan plan; M = N << 1; @@ -176,9 +186,10 @@ int xtract_autocorrelation_fft(const float *data, const int N, const void *argv, time = (float *)calloc(M, sizeof(float)); time = memcpy(time, data, N * sizeof(float)); - plan = fftwf_plan_r2r_1d(M, time, freq, FFTW_R2HC, FFTW_ESTIMATE); + fftwf_execute_r2r(autocorrelation_fft_plan_1, time, freq); + //plan = fftwf_plan_r2r_1d(M, time, freq, FFTW_R2HC, FFTW_ESTIMATE); - fftwf_execute(plan); + //fftwf_execute(plan); for(n = 1; n < N; n++){ freq[n] = XTRACT_SQ(freq[n]) + XTRACT_SQ(freq[M - n]); @@ -188,9 +199,11 @@ int xtract_autocorrelation_fft(const float *data, const int N, const void *argv, freq[0] = XTRACT_SQ(freq[0]); freq[N] = XTRACT_SQ(freq[N]); - plan = fftwf_plan_r2r_1d(M, freq, time, FFTW_HC2R, FFTW_ESTIMATE); + //plan = fftwf_plan_r2r_1d(M, freq, time, FFTW_HC2R, FFTW_ESTIMATE); - fftwf_execute(plan); + //fftwf_execute(plan); + + fftwf_execute_r2r(autocorrelation_fft_plan_2, freq, time); /* Normalisation factor */ M = M * N; @@ -199,7 +212,7 @@ int xtract_autocorrelation_fft(const float *data, const int N, const void *argv, result[n] = time[n] / (float)M; /* result[n] = time[n+1] / (float)M; */ - fftwf_destroy_plan(plan); + //fftwf_destroy_plan(plan); fftwf_free(freq); free(time); @@ -228,13 +241,14 @@ int xtract_mfcc(const float *data, const int N, const void *argv, float *result) int xtract_dct(const float *data, const int N, const void *argv, float *result){ - fftwf_plan plan; + //fftwf_plan plan; - plan = - fftwf_plan_r2r_1d(N, (float *) data, result, FFTW_REDFT00, FFTW_ESTIMATE); + //plan = + // fftwf_plan_r2r_1d(N, (float *) data, result, FFTW_REDFT00, FFTW_ESTIMATE); - fftwf_execute(plan); - fftwf_destroy_plan(plan); + fftwf_execute_r2r(dct_plan, (float *)data, result); + //fftwf_execute(plan); + //fftwf_destroy_plan(plan); return XTRACT_SUCCESS; } @@ -363,7 +377,9 @@ int xtract_peak_spectrum(const float *data, const int N, const void *argv, float XTRACT_CHECK_q; - input = (float *)malloc(bytes = N * sizeof(float)); + input = (float *)calloc(N, sizeof(float)); + + bytes = N * sizeof(float); if(input != NULL) input = memcpy(input, data, bytes); diff --git a/src/xtract_macros_private.h b/src/xtract_macros_private.h index 7f06960..bfe0b63 100644 --- a/src/xtract_macros_private.h +++ b/src/xtract_macros_private.h @@ -49,9 +49,6 @@ (= SR_LOWER_LIMIT / FFT_BANDS_MAX*/ #define XTRACT_SPEC_BW_MAX 12000.0 /* SR_UPPER_LIMIT / FFT_BANDS_MIN */ #define XTRACT_SPEC_BW_DEF 43.066 /* SR_DEFAULT / FFT_BANDS_DEF */ - -#ifdef __cplusplus -} -#endif +#define XTRACT_ARRAY_ELEMENTS(_array) (sizeof(_array)/sizeof(_array[0])) #endif |