Ignore:
Timestamp:
Sep 17, 2009, 1:20:54 AM (15 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/autosink, feature/cnn, feature/cnn_org, feature/constantq, feature/crepe, feature/crepe_org, feature/pitchshift, feature/pydocstrings, feature/timestretch, fix/ffmpeg5, master, pitchshift, sampler, timestretch, yinfft+
Children:
3b3b03e
Parents:
7bf3dcb
Message:

src/spectral/filterbank.c: refactorise filter bank, split mel frequency coefficients to src/spectral/filterbank_mel.c, start bumping license to GPLv3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/spectral/filterbank.c

    r7bf3dcb r06cae6c  
    11/*
    2    Copyright (C) 2007 Amaury Hazan <ahazan@iua.upf.edu>
    3                   and Paul Brossier <piem@piem.org>
     2  Copyright (C) 2007-2009 Paul Brossier <piem@aubio.org>
     3                      and Amaury Hazan <ahazan@iua.upf.edu>
    44
    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.
     5  This file is part of Aubio.
    96
    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.
     7  Aubio 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 3 of the License, or
     10  (at your option) any later version.
    1411
    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.
     12  Aubio 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 Aubio.  If not, see <http://www.gnu.org/licenses/>.
    1819
    1920*/
    20 
    2121
    2222#include "aubio_priv.h"
     
    3232    uint_t win_s;
    3333    uint_t n_filters;
    34     fvec_t **filters;
     34    fvec_t *filters;
    3535};
    3636
    3737aubio_filterbank_t * new_aubio_filterbank(uint_t n_filters, uint_t win_s){
    38   /** allocating space for filterbank object */
     38  /* allocate space for filterbank object */
    3939  aubio_filterbank_t * fb = AUBIO_NEW(aubio_filterbank_t);
    40   uint_t filter_cnt;
    4140  fb->win_s=win_s;
    4241  fb->n_filters=n_filters;
    4342
    44   /** allocating filter tables */
    45   fb->filters=AUBIO_ARRAY(fvec_t*,n_filters);
    46   for (filter_cnt=0; filter_cnt<n_filters; filter_cnt++)
    47     /* considering one-channel filters */
    48     fb->filters[filter_cnt]=new_fvec(win_s, 1);
     43  /* allocate filter tables, an fvec of length win_s and of filter_cnt channel */
     44  fb->filters = new_fvec(win_s, n_filters);
    4945
    5046  return fb;
    5147}
    5248
    53 /*
    54 FB initialization based on Slaney's auditory toolbox
    55 TODO:
    56   *solve memory leak problems while
    57   *solve quantization issues when constructing signal:
    58     *bug for win_s=512
    59     *corrections for win_s=1024 -> why even filters with smaller amplitude
    60 
    61 */
    62 
    63 aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, uint_t samplerate, smpl_t freq_min, smpl_t freq_max){
    64  
    65   aubio_filterbank_t * fb = new_aubio_filterbank(n_filters, win_s);
    66  
    67  
    68   //slaney params
    69   smpl_t lowestFrequency = 133.3333;
    70   smpl_t linearSpacing = 66.66666666;
    71   smpl_t logSpacing = 1.0711703;
    72 
    73   uint_t linearFilters = 13;
    74   uint_t logFilters = 27;
    75   uint_t allFilters = linearFilters + logFilters;
    76  
    77   //buffers for computing filter frequencies
    78   fvec_t * freqs=new_fvec(allFilters+2 , 1);
    79  
    80   fvec_t * lower_freqs=new_fvec( allFilters, 1);
    81   fvec_t * upper_freqs=new_fvec( allFilters, 1);
    82   fvec_t * center_freqs=new_fvec( allFilters, 1);
    83 
    84   fvec_t * triangle_heights=new_fvec( allFilters, 1);
    85   //lookup table of each bin frequency in hz
    86   fvec_t * fft_freqs=new_fvec(win_s, 1);
    87 
    88   uint_t filter_cnt, bin_cnt;
    89  
    90   //first step: filling all the linear filter frequencies
    91   for(filter_cnt=0; filter_cnt<linearFilters; filter_cnt++){
    92     freqs->data[0][filter_cnt]=lowestFrequency+ filter_cnt*linearSpacing;
    93   }
    94   smpl_t lastlinearCF=freqs->data[0][filter_cnt-1];
    95  
    96   //second step: filling all the log filter frequencies
    97   for(filter_cnt=0; filter_cnt<logFilters+2; filter_cnt++){
    98     freqs->data[0][filter_cnt+linearFilters] =
    99       lastlinearCF*(pow(logSpacing,filter_cnt+1));
    100   }
    101 
    102   //Option 1. copying interesting values to lower_freqs, center_freqs and upper freqs arrays
    103   //TODO: would be nicer to have a reference to freqs->data, anyway we do not care in this init step
    104    
    105   for(filter_cnt=0; filter_cnt<allFilters; filter_cnt++){
    106     lower_freqs->data[0][filter_cnt]=freqs->data[0][filter_cnt];
    107     center_freqs->data[0][filter_cnt]=freqs->data[0][filter_cnt+1];
    108     upper_freqs->data[0][filter_cnt]=freqs->data[0][filter_cnt+2];
    109   }
    110 
    111   //computing triangle heights so that each triangle has unit area
    112   for(filter_cnt=0; filter_cnt<allFilters; filter_cnt++){
    113     triangle_heights->data[0][filter_cnt] = 2./(upper_freqs->data[0][filter_cnt]
    114       - lower_freqs->data[0][filter_cnt]);
    115   }
    116  
    117   //AUBIO_DBG("filter tables frequencies\n");
    118   //for(filter_cnt=0; filter_cnt<allFilters; filter_cnt++)
    119   //  AUBIO_DBG("filter n. %d %f %f %f %f\n",
    120   //    filter_cnt, lower_freqs->data[0][filter_cnt],
    121   //    center_freqs->data[0][filter_cnt], upper_freqs->data[0][filter_cnt],
    122   //    triangle_heights->data[0][filter_cnt]);
    123 
    124   //filling the fft_freqs lookup table, which assigns the frequency in hz to each bin
    125   for(bin_cnt=0; bin_cnt<win_s; bin_cnt++){
    126     fft_freqs->data[0][bin_cnt]= aubio_bintofreq(bin_cnt, samplerate, win_s);
    127   }
    128 
    129   //building each filter table
    130   for(filter_cnt=0; filter_cnt<allFilters; filter_cnt++){
    131 
    132     //TODO:check special case : lower freq =0
    133     //calculating rise increment in mag/Hz
    134     smpl_t riseInc= triangle_heights->data[0][filter_cnt]/(center_freqs->data[0][filter_cnt]-lower_freqs->data[0][filter_cnt]);
    135    
    136     //zeroing begining of filter
    137     for(bin_cnt=0; bin_cnt<win_s-1; bin_cnt++){
    138       fb->filters[filter_cnt]->data[0][bin_cnt]=0.f;
    139       if( fft_freqs->data[0][bin_cnt]  <= lower_freqs->data[0][filter_cnt] &&
    140           fft_freqs->data[0][bin_cnt+1] > lower_freqs->data[0][filter_cnt]) {
    141         break;
    142       }
    143     }
    144     bin_cnt++;
    145    
    146     //positive slope
    147     for(; bin_cnt<win_s-1; bin_cnt++){
    148       fb->filters[filter_cnt]->data[0][bin_cnt]=(fft_freqs->data[0][bin_cnt]-lower_freqs->data[0][filter_cnt])*riseInc;
    149       //if(fft_freqs->data[0][bin_cnt]<= center_freqs->data[0][filter_cnt] && fft_freqs->data[0][bin_cnt+1]> center_freqs->data[0][filter_cnt])
    150       if(fft_freqs->data[0][bin_cnt+1]> center_freqs->data[0][filter_cnt])
    151         break;
    152     }
    153     //bin_cnt++;
    154    
    155     //negative slope
    156     for(; bin_cnt<win_s-1; bin_cnt++){
    157      
    158       //checking whether last value is less than 0...
    159       smpl_t val=triangle_heights->data[0][filter_cnt]-(fft_freqs->data[0][bin_cnt]-center_freqs->data[0][filter_cnt])*riseInc;
    160       if(val>=0)
    161         fb->filters[filter_cnt]->data[0][bin_cnt]=val;
    162       else fb->filters[filter_cnt]->data[0][bin_cnt]=0.f;
    163      
    164       //if(fft_freqs->data[0][bin_cnt]<= upper_freqs->data[0][bin_cnt] && fft_freqs->data[0][bin_cnt+1]> upper_freqs->data[0][filter_cnt])
    165       //TODO: CHECK whether bugfix correct
    166       if(fft_freqs->data[0][bin_cnt+1]> upper_freqs->data[0][filter_cnt])
    167         break;
    168     }
    169     //bin_cnt++;
    170    
    171     //zeroing tail
    172     for(; bin_cnt<win_s; bin_cnt++)
    173       fb->filters[filter_cnt]->data[0][bin_cnt]=0.f;
    174 
    175   }
    176  
    177  
    178   del_fvec(freqs);
    179   del_fvec(lower_freqs);
    180   del_fvec(upper_freqs);
    181   del_fvec(center_freqs);
    182 
    183   del_fvec(triangle_heights);
    184   del_fvec(fft_freqs);
    185 
    186   return fb;
    187 
    188 }
    189 
    19049void del_aubio_filterbank(aubio_filterbank_t * fb){
    191   uint_t filter_cnt;
    192   /** deleting filter tables first */
    193   for (filter_cnt=0; filter_cnt<fb->n_filters; filter_cnt++)
    194     del_fvec(fb->filters[filter_cnt]);
    195   AUBIO_FREE(fb->filters);
     50  del_fvec(fb->filters);
    19651  AUBIO_FREE(fb);
    19752}
    19853
    19954void aubio_filterbank_do(aubio_filterbank_t * f, cvec_t * in, fvec_t *out) {
    200   uint_t n, filter_cnt;
    201   for(filter_cnt = 0; (filter_cnt < f->n_filters)
    202     && (filter_cnt < out->length); filter_cnt++){
    203       out->data[0][filter_cnt] = 0.f;
    204       for(n = 0; n < in->length; n++){
    205           out->data[0][filter_cnt] += in->norm[0][n]
    206             * f->filters[filter_cnt]->data[0][n];
     55  uint_t i, j, fn;
     56
     57  /* apply filter to all input channel, provided out has enough channels */
     58  uint_t max_channels = MIN(in->channels, out->channels);
     59  uint_t max_filters  = MIN(f->n_filters, out->length);
     60
     61  /* reset all values in output vector */
     62  fvec_zeros(out);
     63
     64  /* apply filters on all channels */
     65  for (i = 0; i < max_channels; i++) {
     66
     67    /* for each filter */
     68    for(fn = 0; fn < max_filters; fn++) {
     69
     70      /* for each sample */
     71      for(j = 0; j < in->length; j++) {
     72          out->data[i][fn] += in->norm[i][j] * f->filters->data[fn][j];
    20773      }
    208       out->data[0][filter_cnt] =
    209         LOG(out->data[0][filter_cnt] < VERY_SMALL_NUMBER ?
    210             VERY_SMALL_NUMBER : out->data[0][filter_cnt]);
     74
     75      /* threshold to VERY_SMALL_NUMBER to avoid log oveflow */
     76      out->data[i][fn] = MAX(VERY_SMALL_NUMBER, out->data[i][fn]);
     77
     78      /* compute logarithm */
     79      out->data[i][fn] = LOG(out->data[i][fn]);
     80    }
    21181  }
    21282
     
    21484}
    21585
    216 fvec_t * aubio_filterbank_getchannel(aubio_filterbank_t * f, uint_t channel) {
    217   if ( (channel < f->n_filters) ) { return f->filters[channel]; }
    218   else { return NULL; }
     86fvec_t * aubio_filterbank_get_coeffs(aubio_filterbank_t * f) {
     87  return f->filters;
    21988}
Note: See TracChangeset for help on using the changeset viewer.