/* * 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.feature; import edu.cmu.sphinx.frontend.*; import edu.cmu.sphinx.util.props.PropertyException; import edu.cmu.sphinx.util.props.PropertySheet; import edu.cmu.sphinx.util.props.S4Boolean; import edu.cmu.sphinx.util.props.S4Integer; /** * Drops certain feature frames, usually to speed up decoding. For example, if you 'dropEveryNthFrame' is set to 2, it * will drop every other feature frame. If you set 'replaceNthWithPrevious' to 3, then you replace with 3rd frame with * the 2nd frame, the 6th frame with the 5th frame, etc.. */ public class FrameDropper extends BaseDataProcessor { /** * The property that specifies dropping one in every Nth frame. If N=2, we drop every other frame. If N=3, we * drop every third frame, etc.. */ @S4Integer(defaultValue = -1) public static final String PROP_DROP_EVERY_NTH_FRAME = "dropEveryNthFrame"; /** The property that specifies whether to replace the Nth frame with the previous frame. */ @S4Boolean(defaultValue = false) public static final String PROP_REPLACE_NTH_WITH_PREVIOUS = "replaceNthWithPrevious"; private Data lastFeature; private boolean replaceNthWithPrevious; private int dropEveryNthFrame; private int id; // first frame has ID "0", second "1", etc. /** * @param dropEveryNthFrame frame count to drop * @param replaceNthWithPrevious replace each nth frame with previous */ public FrameDropper( int dropEveryNthFrame, boolean replaceNthWithPrevious ) { initLogger(); initVars( dropEveryNthFrame, replaceNthWithPrevious); } public FrameDropper( ) { } /* * (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); initVars( ps.getInt(PROP_DROP_EVERY_NTH_FRAME), ps.getBoolean(PROP_REPLACE_NTH_WITH_PREVIOUS)); } protected void initVars( int dropEveryNthFrame, boolean replaceNthWithPrevious ) { this.dropEveryNthFrame = dropEveryNthFrame; if (dropEveryNthFrame <= 1) { throw new IllegalArgumentException(PROP_DROP_EVERY_NTH_FRAME + "must be greater than one"); } this.replaceNthWithPrevious = replaceNthWithPrevious; } /** Initializes this FrameDropper. */ @Override public void initialize() { super.initialize(); this.id = -1; } /** * Returns the next Data object from this FrameDropper. The Data objects belonging to a single Utterance should be * preceded by a DataStartSignal and ended by a DataEndSignal. * * @return the next available Data object, returns null if no Data object is available * @throws DataProcessingException if a data processing error occurs */ @Override public Data getData() throws DataProcessingException { Data feature = readData(); if (feature != null) { if (!(feature instanceof Signal)) { if ((id % dropEveryNthFrame) == (dropEveryNthFrame - 1)) { // should drop the feature if (replaceNthWithPrevious) { // replace the feature if (feature instanceof FloatData) { FloatData floatLastFeature = (FloatData) lastFeature; feature = new FloatData (floatLastFeature.getValues(), floatLastFeature.getSampleRate(), floatLastFeature.getFirstSampleNumber()); } else { DoubleData doubleLastFeature = (DoubleData) lastFeature; feature = new DoubleData (doubleLastFeature.getValues(), doubleLastFeature.getSampleRate(), doubleLastFeature.getFirstSampleNumber()); } } else { // read the next feature feature = readData(); } } } if (feature != null) { if (feature instanceof DataEndSignal) { id = -1; } if (feature instanceof FloatData) { lastFeature = feature; } else { lastFeature = null; } } else { lastFeature = null; } } return feature; } /** * Read a Data object from the predecessor DataProcessor, and increment the ID count appropriately. * * @return the read Data object * @throws edu.cmu.sphinx.frontend.DataProcessingException */ private Data readData() throws DataProcessingException { Data frame = getPredecessor().getData(); if (frame != null) { id++; } return frame; } }