2 Copyright (C) 2003 Paul Brossier
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "aubio_priv.h"
22 #include "mathutils.h"
26 #define fftw_malloc fftwf_malloc
27 #define fftw_free fftwf_free
28 #define fftw_execute fftwf_execute
29 #define fftw_plan_dft_r2c_1d fftwf_plan_dft_r2c_1d
30 #define fftw_plan_dft_c2r_1d fftwf_plan_dft_c2r_1d
31 #define fftw_plan fftwf_plan
32 #define fftw_destroy_plan fftwf_destroy_plan
49 static aubio_fft_t * aubio_fft_alloc(uint_t size);
50 static void aubio_fft_free(aubio_fft_t *s);
52 static aubio_fft_t * aubio_fft_alloc(uint_t size) {
53 aubio_fft_t * s = AUBIO_NEW(aubio_fft_t);
55 s->in = AUBIO_ARRAY(real_t,size);
56 s->out = AUBIO_ARRAY(real_t,size);
57 s->specdata = (fft_data_t*)fftw_malloc(sizeof(fft_data_t)*size);
61 static void aubio_fft_free(aubio_fft_t * s) {
63 fftw_destroy_plan(s->pfw);
64 fftw_destroy_plan(s->pbw);
65 if (s->specdata) fftw_free(s->specdata);
66 if (s->out) AUBIO_FREE(s->out);
67 if (s->in ) AUBIO_FREE(s->in );
70 aubio_fft_t * new_aubio_fft(uint_t size) {
71 aubio_fft_t * s =(aubio_fft_t *)aubio_fft_alloc(size);
73 s->pfw = fftw_plan_dft_r2c_1d(size, s->in, s->specdata, FFTW_ESTIMATE);
74 s->pbw = fftw_plan_dft_c2r_1d(size, s->specdata, s->out, FFTW_ESTIMATE);
78 void del_aubio_fft(aubio_fft_t * s) {
83 void aubio_fft_do(const aubio_fft_t * s,
84 const smpl_t * data, fft_data_t * spectrum,
87 for (i=0;i<size;i++) s->in[i] = data[i];
89 for (i=0;i<size;i++) spectrum[i] = s->specdata[i];
92 void aubio_fft_rdo(const aubio_fft_t * s,
93 const fft_data_t * spectrum,
97 const smpl_t renorm = 1./(smpl_t)size;
98 for (i=0;i<size;i++) s->specdata[i] = spectrum[i];
100 for (i=0;i<size;i++) data[i] = s->out[i]*renorm;
104 void aubio_fft_getnorm(smpl_t * norm, fft_data_t * spectrum, uint_t size) {
106 for (i=0;i<size;i++) norm[i] = ABSC(spectrum[i]);
109 void aubio_fft_getphas(smpl_t * phas, fft_data_t * spectrum, uint_t size) {
111 for (i=0;i<size;i++) phas[i] = ARGC(spectrum[i]);
115 /* new interface aubio_mfft */
116 struct _aubio_mfft_t {
117 aubio_fft_t * fft; /* fftw interface */
118 fft_data_t ** spec; /* complex spectral data */
123 aubio_mfft_t * new_aubio_mfft(uint_t winsize, uint_t channels){
125 aubio_mfft_t * fft = AUBIO_NEW(aubio_mfft_t);
126 fft->winsize = winsize;
127 fft->channels = channels;
128 fft->fft = new_aubio_fft(winsize);
129 fft->spec = AUBIO_ARRAY(fft_data_t*,channels);
130 for (i=0; i < channels; i++)
131 fft->spec[i] = AUBIO_ARRAY(fft_data_t,winsize);
136 void aubio_mfft_do (aubio_mfft_t * fft,fvec_t * in,cvec_t * fftgrain){
139 for (i=0; i < fft->channels; i++) {
140 aubio_fft_do (fft->fft,in->data[i],fft->spec[i],fft->winsize);
141 /* put norm and phase into fftgrain */
142 aubio_fft_getnorm(fftgrain->norm[i], fft->spec[i], fft->winsize/2+1);
143 aubio_fft_getphas(fftgrain->phas[i], fft->spec[i], fft->winsize/2+1);
147 /* execute inverse fourier transform */
148 void aubio_mfft_rdo(aubio_mfft_t * fft,cvec_t * fftgrain, fvec_t * out){
150 for (i=0; i < fft->channels; i++) {
151 for (j=0; j<fft->winsize/2+1; j++) {
152 fft->spec[i][j] = CEXPC(I*aubio_unwrap2pi(fftgrain->phas[i][j]));
153 fft->spec[i][j] *= fftgrain->norm[i][j];
155 aubio_fft_rdo(fft->fft,fft->spec[i],out->data[i],fft->winsize);
159 void del_aubio_mfft(aubio_mfft_t * fft) {
161 for (i=0; i < fft->channels; i++)
162 AUBIO_FREE(fft->spec[i]);
163 AUBIO_FREE(fft->spec);
164 aubio_fft_free(fft->fft);