/****************************************************************************** * sigproc.cpp * *-------------* * *------------------------------------------------------------------------------ * Copyright (C) 1999 Entropic, Inc * Copyright (C) 2000 Microsoft Corporation Date: 03/02/00 * All Rights Reserved * ********************************************************************* PACOG ***/ #include "sigprocInt.h" #define PREEMP_FACTOR 0.97F /***************************************************************************** * Cepstrum * *----------* * Description: * compute lpc ceptrum form lpc coefficients * ******************************************************************* PACOG ***/ double* Cepstrum(double *pdData, int iNumData, int iLpcOrder, int iCepOrder) { double* pdCepCoef = 0; double* pdWindow = 0; double* pdLpcCoef = 0; assert(iLpcOrder > 0); assert(iCepOrder > 0); // get lpc coef pdWindow = ComputeWindow (WINDOW_HAMM, iNumData, false); if (!pdWindow) { return 0; } for (int i=1; i<iNumData; i++) { pdWindow[i] *= pdData[i] - PREEMP_FACTOR * pdData[i-1]; } pdLpcCoef = GetDurbinCoef (pdWindow , iNumData, iLpcOrder, LPC_ALFA, NULL); if ((pdCepCoef = new double[iCepOrder]) == 0) { return 0; } Alfa2Cepstrum (pdLpcCoef, iLpcOrder, pdCepCoef, iCepOrder); delete[] pdWindow; delete[] pdLpcCoef; return pdCepCoef; } /***************************************************************************** * Alfa2Cepstrum * *---------------* * Description: * compute lpc cepstrum from lpc coefficients * a = alfa (lpc) coefs, input * p = order of lpc analysis * c = cepstrum coefs, output * n = order of cepstral analysis ******************************************************************* PACOG ***/ void Alfa2Cepstrum (double* pdAlfa, int iNumAlfa, double* pdCepstrum, int iNumCepstrum) { double dAux; int k; pdCepstrum[0] = -pdAlfa[0]; for (int i = 1; i < iNumCepstrum; i++) { if (i<iNumAlfa) { pdCepstrum[i] = -pdAlfa[i]; } else { pdCepstrum[i] = 0.0; } dAux = 0.0; for (k = 1; k<=i && k<=iNumAlfa; k++) { dAux += ((double)(i+1-k)/(double)(i+1)) * pdCepstrum[i-k] * pdAlfa[k-1]; } pdCepstrum[i] -= dAux; } } /***************************************************************************** * EuclideanDist * *---------------* * Description: * ******************************************************************* PACOG ***/ double EuclideanDist (double c1[], double c2[], int iLen) { double dDist = 0.0; for (int i = 0; i < iLen; i++) { dDist += (c1[i] - c2[i]) * (c1[i] - c2[i]); } return dDist; } /***************************************************************************** * Energy * *--------* * Description: * Compute the time-weighted RMS of a size segment of data. The data * is weighted by a window of type w_type before RMS computation. w_type * is decoded above in window(). ******************************************************************* PACOG ***/ double Energy (double* pdData, int iNumData, int iWindType) { static int iWindLen = 0; static double *pdWindow = 0; double dWData; double dSum = 0.0; assert (pdData); if (iWindLen != iNumData) { if (pdWindow) { delete[] pdWindow; } pdWindow = ComputeWindow (iWindType, iNumData, false); if (!pdWindow) { fprintf (stderr, "Memory error in Energy\n"); return(0.0); } iWindLen = iNumData; } for (int i=0; i<iNumData; i++) { dWData = pdData[i] * pdWindow[i]; dSum += dWData * dWData; } return (double)sqrt((double)(dSum/iNumData)); } /***************************************************************************** * RemoveDc * *----------* * Description: * ******************************************************************* PACOG ***/ int RemoveDc (double* pdSamples, int iNumSamples) { double dDc = 0.0; assert (pdSamples); assert (iNumSamples>0); for (int i=0; i<iNumSamples; i++) { dDc += pdSamples[i]; } dDc /= iNumSamples; for (i=0; i<iNumSamples; i++) { pdSamples[i] -= dDc; } return (int) dDc; }