-
Notifications
You must be signed in to change notification settings - Fork 75
Filter banks
Static class FilterBanks
provides methods for obtaining the most widely used frequency bands as well as the general shapes of frequency responses of filters that can be used in various filter bank systems.
The frequency band is essentially the tuple of three values Tuple<double, double, double>
(left frequency, center frequency, right frequency of the band). Center frequencies may be distributed uniformly according to one of the following scales:
- Herz bands
- Mel bands
- Bark bands
- Critical bands
- Octaves (as specified in MPEG-7 standard)
For each scale there's corresponding static method (e.g. MelBands
, OctaveBands
, etc.).
Assumed size of FFT and sampling rate must be given (since methods need to know the spectral frequency resolution in Hz).
Example:
// 12 overlapping mel bands in frequency range [0, 4200] Hz
var melBands = FilterBanks.MelBands(12, fftSize, sampRate, 0, 4000, true);
// 16 non-overlapping bark bands in frequency range [200, 4200] Hz
var barkBands = FilterBanks.BarkBands(16, fftSize, sampRate, 200, 4200, false);
// 10 non-overlapping critical bands in frequency range [1000, 5000] Hz
var criticalBands = FilterBanks.CriticalBands(10, fftSize, sampRate, 1000, 5000);
// 6 non-overlapping bark bands in frequency range [100, samplingRate/2] Hz
var octaveBands = FilterBanks.OctaveBands(6, fftSize, sampRate, 100, overlap: false);
// 3 custom bands - [100,500] Hz, [500, 1500] Hz, [1500, 3500] Hz:
var customBands = new []
{
new Tuple<double, double, double>(100, 300, 500),
new Tuple<double, double, double>(500, 1000, 1500),
new Tuple<double, double, double>(1500, 2500, 3500)
};
Note. CriticalBands
method ignores last parameter (overlap flag). Critical bands are non-overlapping. Actually, all critical band frequencies are pre-computed:
double[] centerFrequencies =
{
50, 150, 250, 350, 450, 570, 700, 840, 1000, 1170, 1370,
//...
};
This method also will ignore the parameter filterCount
if it's greater than the number of actual bands in the given frequency range. The same goes for OctaveBands()
method.
By default low frequency is set to 0 and high frequency is set to samplingRate/2, except for OctaveBands()
, where low frequency is 62.5 Hz by default.
The above-mentioned methods return the array of frequency band tuples (left, center, right). This array itself is not very useful, but it can be passed as a parameter to one of the methods that generate the frequency response of a particular shape:
- Triangular
- Rectangular
- Trapezoidal (slightly overlapping frequency responses of FIR-bandpass filters)
- Overlapping frequency responses of BiQuad-bandpass filters
- ERB
var filterbank1 = FilterBanks.Triangular(fftSize, samplingRate, melBands);
var filterbank2 = FilterBanks.Trapezoidal(fftSize, samplingRate, barkBands);
var filterbank3 = FilterBanks.BiQuad(fftSize, samplingRate, criticalBands);
var filterbank4 = FilterBanks.Rectangular(fftSize, samplingRate, octaveBands);
Gammatone filter bank does not follow the general scheme described above. There's no method for generating frequency ERB-bands. Instead all frequency responses are generated at once like this:
var filterbank = FilterBanks.Erb(filterCount, fftSize, samplingRate, lowFreq, highFreq);
Gammatone filterbank is calculated as described here:
Next, let's see how previously evaluated filter banks can be applied to spectra and spectrograms.
Apply()
method calculates total spectral energy in each frequency band and fills the corresponding array (3rd parameter):
float[] bandEnergies = new float [filterCount];
Filterbanks.Apply(filterbank, spectrum, bandEnergies);
ApplyAndLog()
is very similar method, except that for each total energy it calculates log10(energy):
Filterbanks.ApplyAndLog(filterbank, spectrum, bandEnergies);
This method is used in MFCC-like feature extractors.
Finally, there's overloaded method Apply()
for spectrograms (collections of spectra). Spectrogram is of any type IList<float[]>
.
var bandSpectrogram = Filterbanks.Apply(filterbank, spectrum, spectrogram);
Note, in all cases spectrum must have length fftSize/2 + 1.