/* * Copyright 1999-2004 Carnegie Mellon University. * Portions Copyright 2002-2004 Sun Microsystems, Inc. * Portions Copyright 2002-2004 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.filter; import edu.cmu.sphinx.frontend.*; import edu.cmu.sphinx.frontend.endpoint.*; import edu.cmu.sphinx.util.props.*; /** * Implements a high-pass filter that compensates for attenuation in the audio data. Speech signals have an attenuation * (a decrease in intensity of a signal) of 20 dB/dec. It increases the relative magnitude of the higher frequencies * with respect to the lower frequencies. * <p> * The Preemphasizer takes a {@link Data}object that usually represents audio data as input, and outputs the same {@link * Data}object, but with preemphasis applied. For each value X[i] in the input Data object X, the following formula is * applied to obtain the output Data object Y: * <p> * <code> Y[i] = X[i] - (X[i-1] * preemphasisFactor) </code> * <p> * where 'i' denotes time. * <p> * The preemphasis factor has a value defined by the field {@link #PROP_PREEMPHASIS_FACTOR} of 0.97. A common value for * this factor is something around 0.97. * <p> * Other {@link Data}objects are passed along unchanged through this Preemphasizer. * <p> * The Preemphasizer emphasizes the high frequency components, because they usually contain much less energy than lower * frequency components, even though they are still important for speech recognition. It is a high-pass filter because * it allows the high frequency components to "pass through", while weakening or filtering out the low frequency * components. */ public class Preemphasizer extends BaseDataProcessor { /** The property for preemphasis factor/alpha. */ @S4Double(defaultValue = 0.97) public static final String PROP_PREEMPHASIS_FACTOR = "factor"; private double preemphasisFactor; private double prior; public Preemphasizer( double preemphasisFactor ) { initLogger(); this.preemphasisFactor = preemphasisFactor; } public Preemphasizer( ) { } /* * (non-Javadoc) * * @see edu.cmu.sphinx.util.props.Configurable#newProperties(edu.cmu.sphinx.util.props.PropertySheet) */ @Override public void newProperties(PropertySheet ps) throws PropertyException { super.newProperties(ps); preemphasisFactor = ps.getDouble(PROP_PREEMPHASIS_FACTOR); } /** * Returns the next Data object being processed by this Preemphasizer, or if it is a Signal, it is returned without * modification. * * @return the next available Data object, returns null if no Data object is available * @throws DataProcessingException if there is a processing error * @see Data */ @Override public Data getData() throws DataProcessingException { Data input = getPredecessor().getData(); if (input != null) { if (input instanceof DoubleData) { applyPreemphasis(((DoubleData) input).getValues()); } else if (input instanceof DataEndSignal || input instanceof SpeechEndSignal) { prior = 0; } } return input; } /** * Applies pre-emphasis filter to the given Audio. The preemphasis is applied in place. * * @param in audio data */ private void applyPreemphasis(double[] in) { // set the prior value for the next Audio double nextPrior = prior; if (in.length > 0) { nextPrior = in[in.length - 1]; } if (in.length > 1 && preemphasisFactor != 0.0) { // do preemphasis double current; double previous = in[0]; in[0] = previous - preemphasisFactor * prior; for (int i = 1; i < in.length; i++) { current = in[i]; in[i] = current - preemphasisFactor * previous; previous = current; } } prior = nextPrior; } }