source: src/filterbank.c @ 8708556

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 8708556 was 8708556, checked in by Amaury Hazan <mahmoudax@gmail.com>, 17 years ago

80% wrapped-up filterbank and mfcc

  • Property mode set to 100644
File size: 7.9 KB
Line 
1/*
2   Copyright (C) 2007 Amaury Hazan
3   Ported to aubio from LibXtract
4   http://libxtract.sourceforge.net/
5   
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#include "aubio_priv.h"
24#include "filterbank.h"
25
26
27// Struct Declaration
28
29/** \brief A structure to store a set of n_filters filters of lenghts win_s */
30struct aubio_filterbank_t_ {
31    uint_t win_s;
32    uint_t n_filters;
33    fvec_t *filters;
34};
35
36aubio_filterbank_t * new_aubio_filterbank(uint_t n_filters, uint_t win_s){
37 
38  int filter_cnt;
39  /** allocating space for filterbank object */
40  aubio_filterbank_t * fb = AUBIO_NEW(aubio_filterbank_t);
41  fb->win_s=win_s;
42  fb->n_filters=n_filters;
43
44  /** allocating filter tables */
45  fb->filters=AUBIO_ARRAY(n_filters,f_vec_t);
46  for (filter_cnt=0; filter_cnt<n_filters; filter_cnt++)
47    /* considering one-channel filters */
48    filters[filter_cnt]=new_fvec(win_s, 1);
49
50}
51
52void del_aubio_filterbank(aubio_filterbank_t * fb){
53 
54  int filter_cnt;
55  /** deleting filter tables first */
56  for (filter_cnt=0; filter_cnt<fb->n_filters; filter_cnt++)
57    del_fvec(fb->filters[filter_cnt]);
58  AUBIO_FREE(fb->filters);
59  AUBIO_FREE(fb);
60
61}
62
63// Initialization
64
65void aubio_filterbank_mfcc_init(aubio_filterbank_t * fb, smpl_t nyquist, int style, smpl_t freq_min, smpl_t freq_max){
66
67    int n, i, k, *fft_peak, M, next_peak; 
68    smpl_t norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val, 
69        freq_bw_mel, *mel_peak, *height_norm, *lin_peak;
70
71    mel_peak = height_norm = lin_peak = NULL;
72    fft_peak = NULL;
73    norm = 1; 
74
75    mel_freq_max = 1127 * log(1 + freq_max / 700);
76    mel_freq_min = 1127 * log(1 + freq_min / 700);
77    freq_bw_mel = (mel_freq_max - mel_freq_min) / fb->n_filters;
78
79    mel_peak = (smpl_t *)malloc((fb->n_filters + 2) * sizeof(smpl_t)); 
80    /* +2 for zeros at start and end */
81    lin_peak = (smpl_t *)malloc((fb->n_filters + 2) * sizeof(smpl_t));
82    fft_peak = (int *)malloc((fb->n_filters + 2) * sizeof(int));
83    height_norm = (smpl_t *)malloc(fb->n_filters * sizeof(smpl_t));
84
85    if(mel_peak == NULL || height_norm == NULL || 
86                    lin_peak == NULL || fft_peak == NULL)
87                    return XTRACT_MALLOC_FAILED;
88   
89    M = fb->win_s >> 1;
90
91    mel_peak[0] = mel_freq_min;
92    lin_peak[0] = 700 * (exp(mel_peak[0] / 1127) - 1);
93    fft_peak[0] = lin_peak[0] / nyquist * M;
94
95
96    for (n = 1; n <= fb->n_filters; n++){ 
97    /*roll out peak locations - mel, linear and linear on fft window scale */
98        mel_peak[n] = mel_peak[n - 1] + freq_bw_mel;
99        lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1);
100        fft_peak[n] = lin_peak[n] / nyquist * M;
101    }
102
103    for (n = 0; n < fb->n_filters; n++){
104        /*roll out normalised gain of each peak*/
105        if (style == XTRACT_EQUAL_GAIN){
106            height = 1; 
107            norm_fact = norm;
108        }
109        else{
110            height = 2 / (lin_peak[n + 2] - lin_peak[n]);
111            norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0]));
112        }
113        height_norm[n] = height * norm_fact;
114    }
115
116    i = 0;
117   
118    for(n = 0; n < fb->n_filters; n++){
119 
120  /*calculate the rise increment*/
121        if(n > 0)
122            inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]);
123        else
124            inc = height_norm[n] / fft_peak[n];
125        val = 0; 
126 
127  /*zero the start of the array*/
128  for(k = 0; k < i; k++)
129     //fft_tables[n][k] = 0.f;
130     fb->filters[n]->data[0][k]=0.f;
131 
132  /*fill in the rise */
133        for(; i <= fft_peak[n]; i++){ 
134         // fft_tables[n][i] = val;
135            fb->filters[n]->data[0][k]=val;
136            val += inc;
137        }
138 
139        /*calculate the fall increment */
140        inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]);
141 
142        val = 0;
143  next_peak = fft_peak[n + 1];
144 
145  /*reverse fill the 'fall' */
146        for(i = next_peak; i > fft_peak[n]; i--){ 
147            //fft_tables[n][i] = val;
148            fb->filters[n]->data[0][k]=val;
149            val += inc;
150        }
151
152  /*zero the rest of the array*/
153  for(k = next_peak + 1; k < fb->win_s; k++)
154      //fft_tables[n][k] = 0.f;
155      fb->filters[n]->data[0][k]=0.f;
156    }
157
158    free(mel_peak);
159    free(lin_peak);
160    free(height_norm);
161    free(fft_peak);
162
163    //return XTRACT_SUCCESS;
164
165}
166
167//to be deleted code
168
169
170// int aubio_mfcc_init(int N, smpl_t nyquist, int style, smpl_t freq_min, smpl_t freq_max, int freq_bands, smpl_t **fft_tables){
171//
172//     int n, i, k, *fft_peak, M, next_peak;
173//     smpl_t norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val,
174//         freq_bw_mel, *mel_peak, *height_norm, *lin_peak;
175//
176//     mel_peak = height_norm = lin_peak = NULL;
177//     fft_peak = NULL;
178//     norm = 1;
179//
180//     mel_freq_max = 1127 * log(1 + freq_max / 700);
181//     mel_freq_min = 1127 * log(1 + freq_min / 700);
182//     freq_bw_mel = (mel_freq_max - mel_freq_min) / freq_bands;
183//
184//     mel_peak = (smpl_t *)malloc((freq_bands + 2) * sizeof(smpl_t));
185//     /* +2 for zeros at start and end */
186//     lin_peak = (smpl_t *)malloc((freq_bands + 2) * sizeof(smpl_t));
187//     fft_peak = (int *)malloc((freq_bands + 2) * sizeof(int));
188//     height_norm = (smpl_t *)malloc(freq_bands * sizeof(smpl_t));
189//
190//     if(mel_peak == NULL || height_norm == NULL ||
191//                     lin_peak == NULL || fft_peak == NULL)
192//                     return XTRACT_MALLOC_FAILED;
193//     
194//     M = N >> 1;
195//
196//     mel_peak[0] = mel_freq_min;
197//     lin_peak[0] = 700 * (exp(mel_peak[0] / 1127) - 1);
198//     fft_peak[0] = lin_peak[0] / nyquist * M;
199//
200//
201//     for (n = 1; n <= freq_bands; n++){ 
202//     /*roll out peak locations - mel, linear and linear on fft window scale */
203//         mel_peak[n] = mel_peak[n - 1] + freq_bw_mel;
204//         lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1);
205//         fft_peak[n] = lin_peak[n] / nyquist * M;
206//     }
207//
208//     for (n = 0; n < freq_bands; n++){
209//         /*roll out normalised gain of each peak*/
210//         if (style == XTRACT_EQUAL_GAIN){
211//             height = 1;
212//             norm_fact = norm;
213//         }
214//         else{
215//             height = 2 / (lin_peak[n + 2] - lin_peak[n]);
216//             norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0]));
217//         }
218//         height_norm[n] = height * norm_fact;
219//     }
220//
221//     i = 0;
222//   
223//     for(n = 0; n < freq_bands; n++){
224//   
225//   /*calculate the rise increment*/
226//         if(n > 0)
227//             inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]);
228//         else
229//             inc = height_norm[n] / fft_peak[n];
230//         val = 0; 
231//   
232//   /*zero the start of the array*/
233//   for(k = 0; k < i; k++)
234//      fft_tables[n][k] = 0.f;
235//   
236//   /*fill in the rise */
237//         for(; i <= fft_peak[n]; i++){
238//             fft_tables[n][i] = val;
239//             val += inc;
240//         }
241//   
242//         /*calculate the fall increment */
243//         inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]);
244//   
245//         val = 0;
246//   next_peak = fft_peak[n + 1];
247//   
248//   /*reverse fill the 'fall' */
249//         for(i = next_peak; i > fft_peak[n]; i--){
250//             fft_tables[n][i] = val;
251//             val += inc;
252//         }
253//
254//   /*zero the rest of the array*/
255//   for(k = next_peak + 1; k < N; k++)
256//       fft_tables[n][k] = 0.f;
257//     }
258//
259//     free(mel_peak);
260//     free(lin_peak);
261//     free(height_norm);
262//     free(fft_peak);
263//
264//     return XTRACT_SUCCESS;
265//
266// }
Note: See TracBrowser for help on using the repository browser.