source: src/filterbank.c @ 7a46bf6

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

merged from piem, corrected mffcs coefs/filter number
added some scripts to visualize filterbank and mfccs

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2   Copyright (C) 2007 Amaury Hazan <ahazan@iua.upf.edu>
3                  and Paul Brossier <piem@piem.org>
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19*/
20
21/* part of this mfcc implementation were inspired from LibXtract
22   http://libxtract.sourceforge.net/
23*/
24
25#include "aubio_priv.h"
26#include "sample.h"
27#include "filterbank.h"
28
29#include "stdio.h"
30
31#define USE_EQUAL_GAIN 1
32#define VERY_SMALL_NUMBER 2e-42
33
34/** \brief A structure to store a set of n_filters filters of lenghts win_s */
35struct aubio_filterbank_t_ {
36    uint_t win_s;
37    uint_t n_filters;
38    fvec_t **filters;
39};
40
41aubio_filterbank_t * new_aubio_filterbank(uint_t n_filters, uint_t win_s){
42  /** allocating space for filterbank object */
43  aubio_filterbank_t * fb = AUBIO_NEW(aubio_filterbank_t);
44  uint_t filter_cnt;
45  fb->win_s=win_s;
46  fb->n_filters=n_filters;
47
48  /** allocating filter tables */
49  fb->filters=AUBIO_ARRAY(fvec_t*,n_filters);
50  for (filter_cnt=0; filter_cnt<n_filters; filter_cnt++)
51    /* considering one-channel filters */
52    fb->filters[filter_cnt]=new_fvec(win_s, 1);
53
54  return fb;
55}
56
57aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, smpl_t samplerate, smpl_t freq_min, smpl_t freq_max){
58 
59  uint_t writelog=1;
60
61  FILE * mlog;
62  if(writelog==1) mlog=fopen("filterbank.txt","w");
63 
64
65  smpl_t nyquist = samplerate/2.;
66  uint_t style = 1;
67  aubio_filterbank_t * fb = new_aubio_filterbank(n_filters, win_s);
68
69  uint_t n, i, k, *fft_peak, M, next_peak; 
70  smpl_t norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val, 
71         freq_bw_mel, *mel_peak, *height_norm, *lin_peak;
72
73  mel_peak = height_norm = lin_peak = NULL;
74  fft_peak = NULL;
75  norm = 1; 
76
77  mel_freq_max = 1127 * log(1 + freq_max / 700);
78  mel_freq_min = 1127 * log(1 + freq_min / 700);
79  freq_bw_mel = (mel_freq_max - mel_freq_min) / fb->n_filters;
80
81  mel_peak = (smpl_t *)malloc((fb->n_filters + 2) * sizeof(smpl_t)); 
82  /* +2 for zeros at start and end */
83  lin_peak = (smpl_t *)malloc((fb->n_filters + 2) * sizeof(smpl_t));
84  fft_peak = (uint_t *)malloc((fb->n_filters + 2) * sizeof(uint_t));
85  height_norm = (smpl_t *)malloc(fb->n_filters * sizeof(smpl_t));
86
87  if(mel_peak == NULL || height_norm == NULL || 
88      lin_peak == NULL || fft_peak == NULL)
89    return NULL;
90
91  M = fb->win_s >> 1;
92
93  mel_peak[0] = mel_freq_min;
94  lin_peak[0] = 700 * (exp(mel_peak[0] / 1127) - 1);
95  fft_peak[0] = lin_peak[0] / nyquist * M;
96
97  for (n = 1; n <= fb->n_filters; n++){ 
98    /*roll out peak locations - mel, linear and linear on fft window scale */
99    mel_peak[n] = mel_peak[n - 1] + freq_bw_mel;
100    lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1);
101    fft_peak[n] = lin_peak[n] / nyquist * M;
102  }
103
104  for (n = 0; n < fb->n_filters; n++){
105    /*roll out normalised gain of each peak*/
106    if (style == USE_EQUAL_GAIN){
107      height = 1; 
108      norm_fact = norm;
109    }
110    else{
111      height = 2 / (lin_peak[n + 2] - lin_peak[n]);
112      norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0]));
113    }
114    height_norm[n] = height * norm_fact;
115  }
116
117  i = 0;
118
119  for(n = 0; n < fb->n_filters; n++){
120
121    /*calculate the rise increment*/
122    if(n > 0)
123      inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]);
124    else
125      inc = height_norm[n] / fft_peak[n];
126    val = 0; 
127
128    /*zero the start of the array*/
129    for(k = 0; k < i; k++)
130      fb->filters[n]->data[0][k]=0.f;
131
132    /*fill in the rise */
133    for(; i <= fft_peak[n]; i++){ 
134      fb->filters[n]->data[0][k]=val;
135      val += inc;
136    }
137
138    /*calculate the fall increment */
139    inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]);
140
141    val = 0;
142    next_peak = fft_peak[n + 1];
143
144    /*reverse fill the 'fall' */
145    for(i = next_peak; i > fft_peak[n]; i--){ 
146      fb->filters[n]->data[0][k]=val;
147      val += inc;
148    }
149
150    /*zero the rest of the array*/
151    for(k = next_peak + 1; k < fb->win_s; k++)
152      fb->filters[n]->data[0][k]=0.f;
153
154    if(writelog){
155      //dumping filter values
156      smpl_t area_tmp=0.f;
157      for(k = 0; k < fb->win_s; k++){
158        fprintf(mlog,"%f ",fb->filters[n]->data[0][k]);
159      }
160      fprintf(mlog,"\n");
161    }
162
163  }
164
165  free(mel_peak);
166  free(lin_peak);
167  free(height_norm);
168  free(fft_peak);
169
170  if(mlog) fclose(mlog);
171
172  return fb;
173
174}
175
176
177void del_aubio_filterbank(aubio_filterbank_t * fb){
178  uint_t filter_cnt;
179  /** deleting filter tables first */
180  for (filter_cnt=0; filter_cnt<fb->n_filters; filter_cnt++)
181    del_fvec(fb->filters[filter_cnt]);
182  AUBIO_FREE(fb->filters);
183  AUBIO_FREE(fb);
184}
185
186void aubio_filterbank_do(aubio_filterbank_t * f, cvec_t * in, fvec_t *out) {
187  uint_t n, filter_cnt;
188  for(filter_cnt = 0; (filter_cnt < f->n_filters)
189    && (filter_cnt < out->length); filter_cnt++){
190      out->data[0][filter_cnt] = 0.f;
191      for(n = 0; n < in->length; n++){
192          out->data[0][filter_cnt] += in->norm[0][n] 
193            * f->filters[filter_cnt]->data[0][n];
194      }
195      out->data[0][filter_cnt] =
196        LOG(out->data[0][filter_cnt] < VERY_SMALL_NUMBER ? 
197            VERY_SMALL_NUMBER : out->data[0][filter_cnt]);
198  }
199
200  return;
201}
Note: See TracBrowser for help on using the repository browser.