/** * Build a PLP filterbank with the parameters given. The center frequencies of the PLP filters will be uniformly * spaced between the minimum and maximum analysis frequencies on the Bark scale. on the Bark scale. * * @throws IllegalArgumentException */ private void BuildCriticalBandFilterbank() { double minBarkFreq; double maxBarkFreq; double deltaBarkFreq; double nyquistFreq; double centerFreq; var numberDFTPoints = (_numberFftPoints >> 1) + 1; double[] DFTFrequencies; /* This is the same class of warper called by PLPFilter.java */ var bark = new FrequencyWarper(); _criticalBandFilter = new PLPFilter[_numberFilters]; if (_numberFftPoints == 0) { throw new ArgumentException("Number of FFT points is zero"); } if (_numberFilters < 1) { throw new ArgumentException("Number of filters illegal: " + _numberFilters); } DFTFrequencies = new double[numberDFTPoints]; nyquistFreq = _sampleRate / 2; for (var i = 0; i < numberDFTPoints; i++) { DFTFrequencies[i] = i * nyquistFreq / (numberDFTPoints - 1); } /** * Find center frequencies of filters in the Bark scale * translate to linear frequency and create PLP filters * with these center frequencies. * * Note that minFreq and maxFreq specify the CENTER FREQUENCIES * of the lowest and highest PLP filters */ minBarkFreq = bark.HertzToBark(_minFreq); maxBarkFreq = bark.HertzToBark(_maxFreq); if (_numberFilters < 1) { throw new ArgumentException("Number of filters illegal: " + _numberFilters); } deltaBarkFreq = (maxBarkFreq - minBarkFreq) / (_numberFilters + 1); for (var i = 0; i < _numberFilters; i++) { centerFreq = bark.BarkToHertz(minBarkFreq + i * deltaBarkFreq); _criticalBandFilter[i] = new PLPFilter(DFTFrequencies, centerFreq); } }
/// <summary> /// Initializes a new instance of the <see cref="PLPFilter"/> class. /// <para> Defines a filter according to the following equation, defined piecewise (all frequencies in the equation are Bark /// frequencies):</para> /// Filter(f) = 0 if f < -2.5 <br> /// = 10^(-(f+0.5)) if -2.5 <= f <= -0.5 <br> /// = 1 if -0.5 <= f <= 0.5 <br> /// = 10^(2.5(f-0.5)) if 0.5 <= f <= 1.3 <br> /// = 0 if f > 1.3 <br> /// The current implementation assumes that the calling routine passes in an array of frequencies, one for each of /// the DFT points in the spectrum of the frame of speech to be filtered. This is used in conjunction with a /// specified center frequency to determine the filter. /// /// </summary> /// <param name="dftFrequenciesInHz">A double array containing the frequencies in Hertz corresponding to each of the DFT points in the spectrum of the signal to be filtered.</param> /// <param name="centerFreqInHz">The filter's center frequency.</param> /// <exception cref="System.ArgumentException">Center frequency for PLP filter out of range</exception> public PLPFilter(double[] dftFrequenciesInHz, double centerFreqInHz) { var bark = new FrequencyWarper(); _numDftPoints = dftFrequenciesInHz.Length; CenterFreqInHz = centerFreqInHz; CenterFreqInBark = bark.HertzToBark(centerFreqInHz); if (centerFreqInHz < dftFrequenciesInHz[0] || centerFreqInHz > dftFrequenciesInHz[_numDftPoints - 1]) { throw new ArgumentException("Center frequency for PLP filter out of range"); } _filterCoefficients = new double[_numDftPoints]; for (var i = 0; i < _numDftPoints; i++) { double barkf = bark.HertzToBark(dftFrequenciesInHz[i]) - CenterFreqInBark; if (barkf < -2.5) { _filterCoefficients[i] = 0.0; } else if (barkf <= -0.5) { _filterCoefficients[i] = Math.Pow(10.0, barkf + 0.5); } else if (barkf <= 0.5) { _filterCoefficients[i] = 1.0; } else if (barkf <= 1.3) { _filterCoefficients[i] = Math.Pow(10.0, -2.5 * (barkf - 0.5)); } else { _filterCoefficients[i] = 0.0; } } }