aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/init.c84
-rw-r--r--src/vector.c60
-rw-r--r--src/xtract_macros_private.h5
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
diff --git a/src/init.c b/src/init.c
index 35802d0..a0e0b03 100644
--- a/src/init.c
+++ b/src/init.c
@@ -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