📄 zcpa1.cpp
字号:
// CZCPA.cpp: implementation of the CZCPA class.
//
//////////////////////////////////////////////////////////////////////
#include "zcpa.h"
#include <math.h>
#include <stdlib.h>
CZCPA::CZCPA()
{
int i;
iFreqDimension = 16;
iNumFirTab = 100;
piChannel = new int [iFreqDimension];
piCenterFreq = new int [iFreqDimension];
ppdFirCoeff = new double* [iNumFirTab];
for( i=0 ; i<iNumFirTab ; i++ )
ppdFirCoeff[i] = new double [iFreqDimension];
}
CZCPA::~CZCPA()
{
delete [] piChannel;
delete [] piCenterFreq;
for( int i=0 ; i<iNumFirTab ; i++ )
delete [] ppdFirCoeff[i];
delete [] ppdFirCoeff;
}
void CZCPA::InitZCPA()
{
int i,j;
FILE *fp;
fp = fopen(ZCPA_PARAMETER_FLOATING_FILE,"r");
if( !fp )
{
fprintf(stderr,"ZCPA Floating Parameter Open Error");
exit(1);
}
for( i=0 ; i<iFreqDimension ; i++ )
fscanf(fp,"%d",&piChannel[i]);
for( i=0 ; i<iFreqDimension ; i++ )
fscanf(fp,"%d",&piCenterFreq[i]);
for( i=0 ; i<iNumFirTab ; i++ )
for( j=0 ; j<iFreqDimension ; j++ )
fscanf(fp,"%lf",&ppdFirCoeff[i][j]);
for( i=0 ; i<16 ; i++ )
dBaseMem[i] = 0;
for( i=0 ; i<7 ; i++ )
dMem1[i] = 0;
for( i=0 ; i<4 ; i++ )
dMem2[i] = 0;
for( i=0 ; i<2 ; i++ )
dMem3[i] = 0;
dMem4 = 0;
}
inline int CZCPA::CalCrovPoint(double y1, double y2)
{
return( (int)(-64.*y1/(-y1+y2)) );
}
inline double CZCPA::Nonlinear(double peak)
{
return( log10(1.0+20.0*peak)) ;
}
void CZCPA::TimeNormalize(double **x_in, int len_in, double *x_out, int len_out)
{
int i,j,k;
double *cum_dist, rate0, rate1, deno, delta_dist, dif, tmp;
len_in = len_in-1;
cum_dist = new double [len_in];
for(i=0,cum_dist[0]=0.,tmp=0. ; i<len_in-1 ; i++){
tmp+=GetDist(x_in[i+1],x_in[i+2],iFreqDimension);
cum_dist[i+1]=tmp;
}
delta_dist=cum_dist[len_in-1]/(double)(len_out-1);
for(i=0;i<iFreqDimension;i++) x_out[i]=x_in[1][i];
for(i=1; i<len_out-1;i++){
dif=delta_dist*(double)i;
for(j=0;j<len_in-1;j++)
if(dif>=cum_dist[j]&&dif<cum_dist[j+1]){
deno=cum_dist[j+1]-cum_dist[j];
rate0=(dif-cum_dist[j])/deno;
rate1=(cum_dist[j+1]-dif)/deno;
for(k=0;k<iFreqDimension;k++)
x_out[i*iFreqDimension+k]=(double)(rate0*x_in[j+2][k]+rate1*x_in[j+1][k]);
}
}
for(k=0;k<iFreqDimension;k++)
x_out[(len_out-1)*iFreqDimension+k]=x_in[len_in+1-1][k];
delete [] cum_dist; cum_dist = NULL;
}
void CZCPA::AmpNormalize(double *x_in, int iLen)
{
int i;
double dSum;
for( i=0, dSum=0 ; i<iLen ; i++ )
{
dSum += x_in[i];
}
dSum/=(double)iLen;
for( i=0 ; i<iLen ; i++ )
{
x_in[i]/=dSum;
}
}
double CZCPA::GetDist(double *x, double *y, int dim)
{
int i;
double distance;
for(i=0, distance=0.;i<dim;i++)
if(x[i]>y[i]) distance+=(x[i]-y[i]);
else distance+=(y[i]-x[i]);
return(distance);
}
void CZCPA::CalZCPA(short *input, int iSpeechLen, double *feat)
{
int i,j,k;
double **ppdFilterOut;
int nFrame;
int inCLK;
double max, peak;
int intv;
int dist, freq_bin;
int zcpa_count;
double **zcpa;
short int *speech;
nFrame = (iSpeechLen+99)/110;
for( i=0 ; i<iSpeechLen ; i++ )
input[i] = input[i]>>4;
ppdFilterOut = new double * [iSpeechLen+99];
for( i=0 ; i<iSpeechLen+99 ; i++)
ppdFilterOut[i] = new double [iFreqDimension];
for( i=0 ; i<iSpeechLen+99 ; i++)
for( j=0 ; j<iFreqDimension; j++)
ppdFilterOut[i][j] = 0.;
for( i=0; i<iFreqDimension; i++)
{
for( j=0; j<iSpeechLen+99; j++)
{
for( k=0; k<iNumFirTab; k++)
if( (j-k) >= 0 && (j-k) < iSpeechLen )
ppdFilterOut[j][i] += (double)input[j-k]*ppdFirCoeff[k][i];
}
}
zcpa = new double * [nFrame+5];
for( i=0 ; i<nFrame+5 ; i++)
zcpa[i] = new double [iFreqDimension];
for( i=0; i<nFrame+5; i++)
for( j=0; j<iFreqDimension; j++)
zcpa[i][j] = 0.;
// convolution
// extract ZCPA
for( i=0; i<iFreqDimension; i++)
{
inCLK = 0;
max = 0;
intv = 64;
zcpa_count = 0;
for( j=0; j<iFreqDimension; j++)
{
dBaseMem[j] = 0;
if( j<7)
dMem1[j] = 0;
if( j<4)
dMem2[j] = 0;
if( j<2)
dMem3[j] = 0;
if( j<1)
dMem4 = 0;
}
for( j=0; j<iSpeechLen+99; j++)
{
// zero-crossing detection
if( j != 0 && (ppdFilterOut[j][i] >= 0 && ppdFilterOut[j-1][i] < 0) )
{
dist = CalCrovPoint( ppdFilterOut[j-1][i], ppdFilterOut[j][i]);
intv += dist;
peak = Nonlinear(max);
max = 0.;
if( intv <= 4525 && intv > 174 )
{
for( k=0; k<iFreqDimension; k++)
{
if( k == 15 )
{
if( intv >= piCenterFreq[k] )
freq_bin = k;
}
else if( intv >= piCenterFreq[k] && intv < piCenterFreq[k+1] )
freq_bin = k;
}
if( inCLK <= piChannel[i] )
{
dBaseMem[freq_bin] += peak;
}
if( i > 8 )
{
dMem1[freq_bin-9] += peak;
}
}
intv = -dist;
}
if( ppdFilterOut[j][i] >= 0)
if( ppdFilterOut[j][i] > max )
max = ppdFilterOut[j][i];
if( intv < 6144 )
intv += 64;
if( inCLK == 109 )
inCLK = 0;
else
inCLK++;
if( inCLK == 0 )
{
for( k=0; k<iFreqDimension; k++)
zcpa[zcpa_count][k] += dBaseMem[k];
for( k=0; k<iFreqDimension; k++)
{
if( k > 14 )
{
dBaseMem[k] = dMem4 + dMem3[k-14] + dMem2[k-12] + dMem1[k-9];
dMem4 = dMem3[1];
dMem3[1] = dMem2[3];
dMem2[3] = dMem1[6];
dMem1[6] = 0;
}
else if( k > 13 )
{
dBaseMem[k] = dMem3[k-14] + dMem2[k-12] + dMem1[k-9];
dMem3[k-14] = dMem2[k-12];
dMem2[k-12] = dMem1[k-9];
dMem1[k-9] = 0;
}
else if( k > 11 )
{
dBaseMem[k] = dMem2[k-12] + dMem1[k-9];
dMem2[k-12] = dMem1[k-9];
dMem1[k-9] = 0;
}
else if( k > 8 )
{
dBaseMem[k] = dMem1[k-9];
dMem1[k-9] = 0;
}
else
dBaseMem[k] = 0;
}
zcpa_count++;
}
}
}
for( i=0 ; i<iSpeechLen+99 ; i++ )
delete [] ppdFilterOut[i];
delete [] ppdFilterOut; ppdFilterOut = NULL;
TimeNormalize( zcpa, zcpa_count, feat, 64);
AmpNormalize( feat, 1024);
for( i=0 ; i<nFrame+5 ; i++ )
delete [] zcpa[i];
delete [] zcpa; zcpa = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -