/* * 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.*; /** * Computes the delta and double delta of input cepstrum (or plp or ...). The delta is the first order derivative and * the double delta (a.k.a. delta delta) is the second order derivative of the original cepstrum. They help model the * speech signal dynamics. The output data is a {@link FloatData} object with a float array of size three times the * original cepstrum. * <p> * The format of the outputted feature is: * <p> * 12 cepstra (c[1] through c[12]) <br>followed by delta cepstra (delta c[1] through delta c[12]) <br>followed by c[0], * delta c[0] <br>followed by delta delta c[0] through delta delta c[12] */ public class S3FeatureExtractor extends AbstractFeatureExtractor { /** * Computes the next feature. Advances the pointers as well. * * @return the feature Data computed */ @Override protected Data computeNextFeature() { int jp1 = (currentPosition - 1 + cepstraBufferSize) % cepstraBufferSize; int jp2 = (currentPosition - 2 + cepstraBufferSize) % cepstraBufferSize; int jp3 = (currentPosition - 3 + cepstraBufferSize) % cepstraBufferSize; int jf1 = (currentPosition + 1) % cepstraBufferSize; int jf2 = (currentPosition + 2) % cepstraBufferSize; int jf3 = (currentPosition + 3) % cepstraBufferSize; DoubleData currentCepstrum = cepstraBuffer[currentPosition]; double[] mfc3f = cepstraBuffer[jf3].getValues(); double[] mfc2f = cepstraBuffer[jf2].getValues(); double[] mfc1f = cepstraBuffer[jf1].getValues(); double[] current = currentCepstrum.getValues(); double[] mfc1p = cepstraBuffer[jp1].getValues(); double[] mfc2p = cepstraBuffer[jp2].getValues(); double[] mfc3p = cepstraBuffer[jp3].getValues(); float[] feature = new float[current.length * 3]; currentPosition = (currentPosition + 1)% cepstraBufferSize; // CEP; skip C[0] int j = 0; for (int k = 1; k < current.length; k++) { feature[j++] = (float) current[k]; } // DCEP: mfc[2] - mfc[-2], skip DC[0] for (int k = 1; k < mfc2f.length; k++) { feature[j++] = (float) (mfc2f[k] - mfc2p[k]); } // POW: C0, DC0 feature[j++] = (float) current[0]; feature[j++] = (float) (mfc2f[0] - mfc2p[0]); // D2CEP: (mfc[3] - mfc[-1]) - (mfc[1] - mfc[-3]) for (int k = 0; k < mfc3f.length; k++) { feature[j++] = (float) ((mfc3f[k] - mfc1p[k]) - (mfc1f[k] - mfc3p[k])); } return (new FloatData(feature, currentCepstrum.getSampleRate(), currentCepstrum.getFirstSampleNumber())); } }