📄 raisedcosinewindower.java
字号:
/* * 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.window;import java.util.Arrays;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import edu.cmu.sphinx.frontend.BaseDataProcessor;import edu.cmu.sphinx.frontend.Data;import edu.cmu.sphinx.frontend.DataEndSignal;import edu.cmu.sphinx.frontend.DataProcessingException;import edu.cmu.sphinx.frontend.DataStartSignal;import edu.cmu.sphinx.frontend.DoubleData;import edu.cmu.sphinx.frontend.util.DataUtil;import edu.cmu.sphinx.util.props.PropertyException;import edu.cmu.sphinx.util.props.PropertySheet;import edu.cmu.sphinx.util.props.PropertyType;import edu.cmu.sphinx.util.props.Registry;/** * Slices up a Data object into a number of overlapping windows * (usually refered to as "frames" in the speech world). In order to * minimize the signal discontinuities at the boundaries of each * frame, we multiply each frame with a raised cosine windowing * function. Moreover, the system uses overlapping windows to capture * information that may occur at the window boundaries. These events * would not be well represented if the windows were juxtaposed. * <p> The number of resulting windows depends on the {@link * #PROP_WINDOW_SIZE_MS window size} and the {@link * #PROP_WINDOW_SHIFT_MS window shift} (commonly known as frame shift * in speech world). Figure 1 shows the relationship between the * original data stream, the window size, the window shift, and the * windows returned. * <p> <img src="doc-files/framing.jpg"> <br><b>Figure 1: Relationship * between original data, window size, window shift, and the windows * returned.</b> * <p> The raised cosine windowing function will be applied to each such * window. Since the {@link #getData()} method returns a * window, and multiple windows are created for each Data object, this * is a 1-to-many processor. Also note that the returned windows * should have the same number of data points as the windowing * function. * <p> The applied windowing function, <i>W(n)</i>, of length <i>N</i> * (the window size), is given by the following formula: * <pre> * W(n) = (1-a) - (a * cos((2 * Math.PI * n)/(N - 1))) * </pre> * where <b>a</b> is commonly known as the "alpha" value. This * variable can be set by the user using the property defined by * {@link #PROP_ALPHA}, which has a default value of {@link * #PROP_ALPHA_DEFAULT}. Please follow the links to the see the * constant field values. * Some values of alpha receive special names, since they are used so * often. A value of 0.46 for the alpha results in a window named * Hamming window. A value of 0.5 results in the Hanning window. And a * value of 0 results in the Rectangular window. The default for this * system is the Hamming window, with alpha 0.46 (but check the value * in {@link #PROP_ALPHA_DEFAULT}!). Figure 2 below shows the Hamming * window function (a = 0.46), using our default window size of 25.625 * ms and assuming a sample rate of 16kHz, thus yielding 410 samples * per window. * <p> <img src="doc-files/hamming-window.gif"> <br><b>Figure 2: The * Hamming window function.</b> * * @see Data */public class RaisedCosineWindower extends BaseDataProcessor { /** * The SphinxProperty name for window size in milliseconds. */ public static final String PROP_WINDOW_SIZE_MS = "windowSizeInMs"; /** * The default value for PROP_WINDOW_SIZE_MS. */ public static final float PROP_WINDOW_SIZE_MS_DEFAULT = 25.625f; /** * The SphinxProperty name for window shift in milliseconds, which has a * default value of 10F. */ public static final String PROP_WINDOW_SHIFT_MS = "windowShiftInMs"; /** * The default value for PROP_WINDOW_SHIFT_MS. */ public static final float PROP_WINDOW_SHIFT_MS_DEFAULT = 10; /** * The name of the SphinxProperty for the alpha value of the Window, which * has a default value of 0.46 (double), which is the value for the * RaisedCosineWindow. */ public static final String PROP_ALPHA = "alpha"; /** * The default value for PROP_ALPHA. */ public static final double PROP_ALPHA_DEFAULT = 0.46; private double alpha; // the window alpha value private double[] cosineWindow; // the raised consine window private int windowSize; // size of each window private int windowShift; // the window size private List outputQueue; // cache for output windows private DoubleBuffer overflowBuffer; // cache for overlapped audio regions private long currentCollectTime; private long currentFirstSampleNumber; private float windowSizeInMs; private float windowShiftInMs; private int sampleRate = 0; /* * (non-Javadoc) * * @see edu.cmu.sphinx.util.props.Configurable#register(java.lang.String, * edu.cmu.sphinx.util.props.Registry) */ public void register(String name, Registry registry) throws PropertyException { super.register(name, registry); registry.register(PROP_ALPHA, PropertyType.DOUBLE); registry.register(PROP_WINDOW_SIZE_MS, PropertyType.FLOAT); registry.register(PROP_WINDOW_SHIFT_MS, PropertyType.FLOAT); } /* * (non-Javadoc) * * @see edu.cmu.sphinx.util.props.Configurable#newProperties(edu.cmu.sphinx.util.props.PropertySheet) */ public void newProperties(PropertySheet ps) throws PropertyException { super.newProperties(ps); alpha = ps.getDouble(PROP_ALPHA, PROP_ALPHA_DEFAULT); windowSizeInMs = ps.getFloat(PROP_WINDOW_SIZE_MS, PROP_WINDOW_SIZE_MS_DEFAULT); windowShiftInMs = ps.getFloat(PROP_WINDOW_SHIFT_MS, PROP_WINDOW_SHIFT_MS_DEFAULT); } /* * (non-Javadoc) * * @see edu.cmu.sphinx.frontend.DataProcessor#initialize(edu.cmu.sphinx.frontend.CommonConfig) */ public void initialize() { super.initialize(); // createWindow(); outputQueue = new LinkedList(); } /** * Creates the Hamming Window. */ private void createWindow() { int windowSize = DataUtil.getSamplesPerWindow(sampleRate, windowSizeInMs); windowShift = DataUtil.getSamplesPerShift(sampleRate, windowShiftInMs); this.cosineWindow = new double[windowSize]; if (cosineWindow.length > 1){ double oneMinusAlpha = (1 - alpha); for (int i = 0; i < cosineWindow.length; i++) { cosineWindow[i] = oneMinusAlpha - alpha * Math.cos(2 * Math.PI * i / ((double) cosineWindow.length - 1.0)); } } overflowBuffer = new DoubleBuffer(windowSize); } /** * Returns the next Data object, which is usually a window of the input * Data, with the windowing function applied to it. * * @return the next available Data object, returns null if no * Data object is available * * @throws DataProcessingException if a data processing error occurred * * @see Data */ public Data getData() throws DataProcessingException { if (outputQueue.size() == 0) { Data input = getPredecessor().getData(); getTimer().start(); if (input != null) { if (input instanceof DoubleData) { DoubleData data = (DoubleData) input; if (currentFirstSampleNumber == -1) { currentFirstSampleNumber = data.getFirstSampleNumber(); } if (cosineWindow == null || sampleRate != data.getSampleRate()) { sampleRate = data.getSampleRate(); createWindow(); } // process the Data, and output the windows process(data); } else { if (input instanceof DataStartSignal) { // reset the current first sample number currentFirstSampleNumber = -1; } else if (input instanceof DataEndSignal) { // end of utterance handling processUtteranceEnd(); } outputQueue.add(input); } } getTimer().stop(); } if (outputQueue.size() > 0) { Data output = (Data) outputQueue.remove(0); if (output instanceof DoubleData) { assert ((DoubleData) output).getValues().length == cosineWindow.length; } return output; } else { return null; } } /** * Applies the Windowing to the given Data. The resulting windows * are cached in the outputQueue.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -