195 lines
4.4 KiB
C++
195 lines
4.4 KiB
C++
|
/******************************************************************************
|
||
|
* 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;
|
||
|
}
|
||
|
|