diff options
author | Jamie Bullock <jamie@jamiebullock.com> | 2013-01-07 16:27:15 +0000 |
---|---|---|
committer | Jamie Bullock <jamie@jamiebullock.com> | 2013-01-07 16:39:29 +0000 |
commit | 144e7f8668166ee1779ad304cc5ac94d8e525529 (patch) | |
tree | 089b2bbbcf15ee8bdde390a4d270e4812e7e2228 /src/init.c | |
parent | 0f46938156dedf13032bdb1fc914a63d46bae558 (diff) | |
download | LibXtract-144e7f8668166ee1779ad304cc5ac94d8e525529.tar.gz LibXtract-144e7f8668166ee1779ad304cc5ac94d8e525529.tar.bz2 LibXtract-144e7f8668166ee1779ad304cc5ac94d8e525529.zip |
added Ooura implementation to repository
Diffstat (limited to 'src/init.c')
-rw-r--r-- | src/init.c | 281 |
1 files changed, 149 insertions, 132 deletions
@@ -1,5 +1,5 @@ /* libxtract feature extraction library - * + * * Copyright (C) 2006 Jamie Bullock * * This program is free software; you can redistribute it and/or modify @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ @@ -26,41 +26,38 @@ #include <math.h> #include <stdlib.h> +#include <stdio.h> + +#include "fftsg.h" #include "xtract/libxtract.h" #include "xtract_window_private.h" #define DEFINE_GLOBALS #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 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; - float norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val, + int n, i, k, *fft_peak, M, next_peak; + float norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val, freq_bw_mel, *mel_peak, *height_norm, *lin_peak; mel_peak = height_norm = lin_peak = NULL; fft_peak = NULL; - norm = 1; + norm = 1; mel_freq_max = 1127 * log(1 + freq_max / 700); mel_freq_min = 1127 * log(1 + freq_min / 700); freq_bw_mel = (mel_freq_max - mel_freq_min) / freq_bands; - mel_peak = (float *)malloc((freq_bands + 2) * sizeof(float)); + mel_peak = (float *)malloc((freq_bands + 2) * sizeof(float)); /* +2 for zeros at start and end */ lin_peak = (float *)malloc((freq_bands + 2) * sizeof(float)); fft_peak = (int *)malloc((freq_bands + 2) * sizeof(int)); height_norm = (float *)malloc(freq_bands * sizeof(float)); - if(mel_peak == NULL || height_norm == NULL || + if(mel_peak == NULL || height_norm == NULL || lin_peak == NULL || fft_peak == NULL) return XTRACT_MALLOC_FAILED; @@ -71,20 +68,24 @@ int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq fft_peak[0] = lin_peak[0] / nyquist * M; - for (n = 1; n < freq_bands + 2; n++){ - //roll out peak locations - mel, linear and linear on fft window scale + for (n = 1; n < freq_bands + 2; n++) + { + //roll out peak locations - mel, linear and linear on fft window scale mel_peak[n] = mel_peak[n - 1] + freq_bw_mel; lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1); fft_peak[n] = lin_peak[n] / nyquist * M; } - for (n = 0; n < freq_bands; n++){ + for (n = 0; n < freq_bands; n++) + { //roll out normalised gain of each peak - if (style == XTRACT_EQUAL_GAIN){ - height = 1; + if (style == XTRACT_EQUAL_GAIN) + { + height = 1; norm_fact = norm; } - else{ + else + { height = 2 / (lin_peak[n + 2] - lin_peak[n]); norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0])); } @@ -93,21 +94,23 @@ int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq i = 0; - for(n = 0; n < freq_bands; n++){ + for(n = 0; n < freq_bands; n++) + { // calculate the rise increment if(n==0) inc = height_norm[n] / fft_peak[n]; else inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]); - val = 0; + val = 0; // zero the start of the array for(k = 0; k < i; k++) fft_tables[n][k] = 0.f; // fill in the rise - for(; i <= fft_peak[n]; i++){ + for(; i <= fft_peak[n]; i++) + { fft_tables[n][i] = val; val += inc; } @@ -118,8 +121,9 @@ int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq val = 0; next_peak = fft_peak[n + 1]; - // reverse fill the 'fall' - for(i = next_peak; i > fft_peak[n]; i--){ + // reverse fill the 'fall' + for(i = next_peak; i > fft_peak[n]; i--) + { fft_tables[n][i] = val; val += inc; } @@ -131,7 +135,10 @@ int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq /* Initialise the fft_plan for the DCT */ + /* + * Ooura doesn't support non power-of-two DCT xtract_init_fft(freq_bands, XTRACT_MFCC); + */ free(mel_peak); free(lin_peak); @@ -142,82 +149,95 @@ int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq } -int xtract_init_fft(int N, int feature_name){ +void xtract_init_ooura(xtract_ooura_data *ooura_data, unsigned int N) +{ + ooura_data->ooura_ip = (int *)calloc((2 + sqrt(N)), sizeof(int)); + ooura_data->ooura_w = (double *)calloc((N - 1), sizeof(double)); + ooura_data->initialised = true; +} - float *input, *output; - int optimisation; +void xtract_free_ooura(xtract_ooura_data *ooura_data) +{ + free(ooura_data->ooura_ip); + free(ooura_data->ooura_w); + ooura_data->ooura_ip = NULL; + ooura_data->ooura_w = NULL; + ooura_data->initialised = false; +} - input = output = NULL; +int xtract_init_fft(int N, int feature_name) +{ - //fprintf(stderr, "Optimisation level: %d\n", XTRACT_FFT_OPTIMISATION_LEVEL); + int M = N >> 1; - 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(!xtract_is_poweroftwo(N)) + { + fprintf(stderr, + "libxtract: error: only power-of-two FFT sizes are supported.\n"); + exit(EXIT_FAILURE); + } 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(fft_plans.spectrum_plan != NULL) - fftwf_destroy_plan(fft_plans.spectrum_plan); - fft_plans.spectrum_plan = - fftwf_plan_r2r_1d(N, input, output, FFTW_R2HC, optimisation); - break; - case XTRACT_AUTOCORRELATION_FFT: - if(fft_plans.autocorrelation_fft_plan_1 != NULL) - fftwf_destroy_plan(fft_plans.autocorrelation_fft_plan_1); - if(fft_plans.autocorrelation_fft_plan_2 != NULL) - fftwf_destroy_plan(fft_plans.autocorrelation_fft_plan_2); - fft_plans.autocorrelation_fft_plan_1 = - fftwf_plan_r2r_1d(N, input, output, FFTW_R2HC, optimisation); - fft_plans.autocorrelation_fft_plan_2 = - fftwf_plan_r2r_1d(N, input, output, FFTW_HC2R, optimisation); - break; - case XTRACT_DCT: - if(fft_plans.dct_plan != NULL) - fftwf_destroy_plan(fft_plans.dct_plan); - fft_plans.dct_plan = - fftwf_plan_r2r_1d(N, input, output, FFTW_REDFT10, optimisation); - case XTRACT_MFCC: - if(fft_plans.dct_plan != NULL) - fftwf_destroy_plan(fft_plans.dct_plan); - fft_plans.dct_plan = - fftwf_plan_r2r_1d(N, output, output, FFTW_REDFT00, optimisation); - break; + { + M = N; /* allow for zero padding */ } - free(input); - free(output); + switch(feature_name) + { + case XTRACT_SPECTRUM: + if(ooura_data_spectrum.initialised) + { + xtract_free_ooura(&ooura_data_spectrum); + } + xtract_init_ooura(&ooura_data_spectrum, M); + break; + case XTRACT_AUTOCORRELATION_FFT: + if(ooura_data_autocorrelation_fft.initialised) + { + xtract_free_ooura(&ooura_data_autocorrelation_fft); + } + xtract_init_ooura(&ooura_data_autocorrelation_fft, M); + break; + case XTRACT_DCT: + if(ooura_data_dct.initialised) + { + xtract_free_ooura(&ooura_data_dct); + } + xtract_init_ooura(&ooura_data_dct, M); + case XTRACT_MFCC: + if(ooura_data_mfcc.initialised) + { + xtract_free_ooura(&ooura_data_mfcc); + } + xtract_init_ooura(&ooura_data_mfcc, M); + break; + } return XTRACT_SUCCESS; - } -void xtract_free_fft(void){ - if(fft_plans.spectrum_plan != NULL) - fftwf_destroy_plan(fft_plans.spectrum_plan); - if(fft_plans.autocorrelation_fft_plan_1 != NULL) - fftwf_destroy_plan(fft_plans.autocorrelation_fft_plan_1); - if(fft_plans.autocorrelation_fft_plan_2 != NULL) - fftwf_destroy_plan(fft_plans.autocorrelation_fft_plan_2); - if(fft_plans.dct_plan != NULL) - fftwf_destroy_plan(fft_plans.dct_plan); -// fftwf_cleanup(); +void xtract_free_fft(void) +{ + if(ooura_data_spectrum.initialised) + { + xtract_free_ooura(&ooura_data_spectrum); + } + if(ooura_data_autocorrelation_fft.initialised) + { + xtract_free_ooura(&ooura_data_autocorrelation_fft); + } + if(ooura_data_dct.initialised) + { + xtract_free_ooura(&ooura_data_dct); + } + if(ooura_data_mfcc.initialised) + { + xtract_free_ooura(&ooura_data_mfcc); + } } -#endif - -int xtract_init_bark(int N, float sr, int *band_limits){ +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)*/ @@ -230,65 +250,62 @@ int xtract_init_bark(int N, float sr, int *band_limits){ return XTRACT_SUCCESS; } -float *xtract_init_window(const int N, const int type){ - +float *xtract_init_window(const int N, const int type) +{ float *window; window = malloc(N * sizeof(float)); - switch (type) { - case XTRACT_GAUSS: - gauss(window, N, 0.4); - break; - case XTRACT_HAMMING: - hamming(window, N); - break; - case XTRACT_HANN: - hann(window, N); - break; - case XTRACT_BARTLETT: - bartlett(window, N); - break; - case XTRACT_TRIANGULAR: - triangular(window, N); - break; - case XTRACT_BARTLETT_HANN: - bartlett_hann(window, N); - break; - case XTRACT_BLACKMAN: - blackman(window, N); - break; - case XTRACT_KAISER: - kaiser(window, N, 3 * PI); - break; - case XTRACT_BLACKMAN_HARRIS: - blackman_harris(window, N); - break; - default: - hann(window, N); - break; + switch (type) + { + case XTRACT_GAUSS: + gauss(window, N, 0.4); + break; + case XTRACT_HAMMING: + hamming(window, N); + break; + case XTRACT_HANN: + hann(window, N); + break; + case XTRACT_BARTLETT: + bartlett(window, N); + break; + case XTRACT_TRIANGULAR: + triangular(window, N); + break; + case XTRACT_BARTLETT_HANN: + bartlett_hann(window, N); + break; + case XTRACT_BLACKMAN: + blackman(window, N); + break; + case XTRACT_KAISER: + kaiser(window, N, 3 * PI); + break; + case XTRACT_BLACKMAN_HARRIS: + blackman_harris(window, N); + break; + default: + hann(window, N); + break; } return window; - } -void xtract_free_window(float *window){ - +void xtract_free_window(float *window) +{ free(window); - } #ifdef __GNUC__ __attribute__((constructor)) void init() #else - void _init()· +void _init()· #endif { -#ifdef XTRACT_FFT - fft_plans.spectrum_plan = NULL; - fft_plans.autocorrelation_fft_plan_1 = NULL; - fft_plans.autocorrelation_fft_plan_2 = NULL; - fft_plans.dct_plan = NULL; -#endif + ooura_data_dct.initialised = false; + ooura_data_spectrum.initialised = false; + ooura_data_autocorrelation_fft.initialised = false; + ooura_data_mfcc.initialised = false; } |