/* * Copyright 1999-2002 Carnegie Mellon University. * Portions Copyright 2002 Sun Microsystems, Inc. * Portions Copyright 2002 Mitsubishi Electric Research Laboratories. * All Rights Reserved. Use is subject to license terms. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ package edu.cmu.sphinx.frontend.frequencywarp; /** * Defines a filter used by the {@link PLPFrequencyFilterBank} class. The filter is defined by a function in the {@link * #PLPFilter Constructor}. A set of equally spaced frequencies in a linear scale is passed to the constructor, which * returns the weights for each of the frequency bins, such that the filter has the shape defined by this piecewise * function in the bark scale. * * @author <a href="mailto:rsingh@cs.cmu.edu">rsingh</a> * @version 1.0 * @see PLPFrequencyFilterBank */ public class PLPFilter { private double[] filterCoefficients; private final int numDFTPoints; /** The center frequency of the filter in Hertz. */ public final double centerFreqInHz; /** The center frequency of the filter in Bark. */ public final double centerFreqInBark; /** * Constructs a PLP filter around a given center frequency. * <p> * Defines a filter according to the following equation, defined piecewise (all frequencies in the equation are Bark * frequencies): * <pre> * 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> * </pre> * 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. * * @param DFTFrequenciesInHz is 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 centerFreqInHz is the filter's center frequency * @throws IllegalArgumentException if center frequency is wrong */ public PLPFilter(double[] DFTFrequenciesInHz, double centerFreqInHz) throws IllegalArgumentException { FrequencyWarper bark = new FrequencyWarper(); numDFTPoints = DFTFrequenciesInHz.length; this.centerFreqInHz = centerFreqInHz; centerFreqInBark = bark.hertzToBark(centerFreqInHz); if (centerFreqInHz < DFTFrequenciesInHz[0] || centerFreqInHz > DFTFrequenciesInHz[numDFTPoints - 1]) { throw new IllegalArgumentException ("Center frequency for PLP filter out of range"); } filterCoefficients = new double[numDFTPoints]; for (int i = 0; i < numDFTPoints; i++) { double barkf; 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; } } /** * Compute the PLP spectrum at the center frequency of this filter for a given power spectrum. * * @param spectrum the input power spectrum to be filtered * @return the PLP spectrum value * @throws IllegalArgumentException if the input spectrum is of a different length than the array of filter * coefficients */ public double filterOutput(double[] spectrum) throws IllegalArgumentException { if (spectrum.length != numDFTPoints) { throw new IllegalArgumentException ("Mismatch in no. of DFT points " + spectrum.length + " in spectrum and in filter " + numDFTPoints); } double output = 0.0; for (int i = 0; i < numDFTPoints; i++) { output += spectrum[i] * filterCoefficients[i]; } return output; } }