newpitch_2.c
来自「文件系统在DSP5509上的实现」· C语言 代码 · 共 782 行 · 第 1/2 页
C
782 行
if(fft[j]>a)
{ a=fft[j];
b=j;
}
} //局部极值
if(n<=2)
{
if((abs(b-n*i)<=2)&&(a>=0.2*amax)&&(a>=FFTA))
{
c++;
}
}
if((n>2)&&(n<=5)&&(a>=0.2*amax)&&(a>=FFTA))
{
if(abs(b-n*i)<=3)
{
c++;
}
}
if((n>5)&&(a>=0.2*amax)&&(a>=FFTA))
{
if(abs(b-n*i)<=5)
{
c++;
}
}
}
PitchPre[i-FFTL]=c;
}//for
PitchPreMax=0;
for(i=1;i<(FFTH-FFTL);i++)
{
if(PitchPre[i]>PitchPreMax)
{
PitchPreMax=PitchPre[i];
}
} //求出最大值
MaxInside=0;
for(j=1;j<(FFTH-FFTL);j++)
{
if(PitchPre[j]==PitchPreMax)
{ PitchPre[j]=0;
b=j;
PitchNew1=b+FFTL; //求出基音
sum1=0;
for(n=1;n*PitchNew1+5<190;n++)
{
for(i=n*PitchNew1-2;i<=n*PitchNew1+2;i++)
{
sum1+=fft[i];
}
}
sum2=0;
for(n=1;2*n*PitchNew1+5<190;n++)
{
for(i=2*n*PitchNew1-2;i<=2*n*PitchNew1+2;i++)
{
sum2+=fft[i];
}
}
sum3=0;
for(n=1;3*n*PitchNew1+5<190;n++)
{
for(i=3*n*PitchNew1-2;i<=3*n*PitchNew1+2;i++)
{
sum3+=fft[i];
}
}
sum4=0;
for(n=1;4*n*PitchNew1+5<190;n++)
{
for(i=4*n*PitchNew1-2;i<=4*n*PitchNew1+2;i++)
{
sum4+=fft[i];
}
}
sum5=0;
for(n=1;5*n*PitchNew1+5<190;n++)
{
for(i=5*n*PitchNew1-2;i<=5*n*PitchNew1+2;i++)
{
sum5+=fft[i];
}
}
if(sum2>0.9*sum1) //是2倍基音
{ PitchNew1=2*PitchNew1;
sum1=sum2;
}
if(sum3>0.9*sum1) //是3倍基音
{ PitchNew1=3*PitchNew1;
sum1=sum3;
}
if(sum4>0.9*sum1) //是4倍基音
{ PitchNew1=4*PitchNew1;
sum1=sum4;
}
if(sum5>0.9*sum1) //是5倍基音
{ PitchNew1=5*PitchNew1;
sum1=sum5;
}
SumK=(float)sum1/sum; //瘦不瘦
if((SumK>SUMK)&&(((bmax%PitchNew1)<=4)||((bmax%PitchNew1)>=(PitchNew1-4))))
{
MaxInside=1;
Pig=11;
goto Out;
}
else
{
MaxInside=0; //最大值在不在范围内
// PitchNew1=0;
Pig=0;
}
}//if
}//for
Out:
}
/*------------------------ 时域---频域转换 ------------------------*/
static void PitchCep(void)
{
int i;
//数据输入
for(i=0;i<WindowsLong;i++)
{
fft[i]=PitchDataIn[i];
if(int_flag==1)SoundOut();
}
for(i=0;i<WindowsLong/2;i++)
{
PitchDataIn[i]=0;//PitchDataIn[i+WindowsLong/2];
if(int_flag==1)SoundOut();
}
for(i=0;i<WindowsLong/2;i++)
{
Am[i]=PitchDataIn[i+WindowsLong/2];
if(int_flag==1)SoundOut();
}
//**************** KIll ******************************
IRQ_globalDisable();
rfft(fft,WindowsLong,SCALE); // 求傅立叶变换
IRQ_globalEnable();
//******************************************************
for(i=0;i<WindowsLong;i++) // 扩大16倍
{
fft[i]=16*fft[i];
if(int_flag==1)SoundOut();
}
for(i=0;i<WindowsLong;i++) // 求绝对值
{
if(fft[i]<0)
fft[i]=-(fft[i]);
if(int_flag==1)SoundOut();
}
fft[0]=0;
/*for(i=0;i<WindowsLong/2;i++) // 扩大16倍
{
if(fft[i]>0)
fftfl[i]=log(fft[i]);
else fftfl[i]=0;
// fftfl[i]=fft[i]/fftfl[i];
if(int_flag==1)SoundOut();
}
*/
// FftSubLong(); //减长期误差
FftSubAverge(); //减平均误差
}
////////////////////// 减长期误差 //////////////////////////////////
void FftSubLong(void)
{
int i;float k;
TimeLong++;
if(TimeLong>=AdptiveLength)
TimeLong=AdptiveLength;
//转为浮点数
// IRQ_globalDisable();
q15tofl(&fft[FFTMIN],fftSource,FftLength);
// IRQ_globalEnable();
//保护数据
for(i=FFTMIN;i<FFTMAX;i++)
{
FftLong1[i-FFTMIN]=fftSource[i-FFTMIN];
}
//减区长期噪声数据
for(i=FFTMIN;i<FFTMAX;i++)
{
fftSource[i]-=FftLong[i-FFTMIN];
if(fftSource[i]<0)
fftSource[i]=0;
}
//修改长期噪声数据
k=(float)(TimeLong-1)/TimeLong;
for(i=FFTMIN;i<FFTMAX;i++)
{
FftLong[i-FFTMIN]=FftLong[i-FFTMIN]*k;
}
k=1-k;
for(i=FFTMIN;i<FFTMAX;i++)
{
FftLong1[i-FFTMIN]=FftLong1[i-FFTMIN]*k;
}
for(i=FFTMIN;i<FFTMAX;i++)
{
FftLong[i-FFTMIN]+=FftLong1[i-FFTMIN];
}
// IRQ_globalDisable();
fltoq15(fftSource,&fft[FFTMIN],FftLength);
// IRQ_globalEnable();
}
/////////////////////////////减平均误差///////////////////////////
void FftSubAverge(void)
{
int i;
long unsigned int a=0;
for(i=FFTMIN;i<FFTMAX;i++)
{
a+=fft[i];
}
a/=(FFTMAX-FFTMIN);
for(i=FFTMIN;i<FFTMAX;i++)
{
fft[i]-=3*a;
if(fft[i]<0)
fft[i]=0;
}
}
/////////////////////////////////////////////////////////////////////////
// 1. 计算最大值与平均值之比;
// 2. 200-38及38-15 和的比;
// 3. 200-128与128-18范围内和的比。
//
/////////////////////////////////////////////////////////////////////////////
static void ComputerVar(void)
{
int i;
Averagefft=0;
for(i=20;i<200;i++)
{
Averagefft+=fft[i];
}
Averagefft/=(200-20); //200-20内的平均值
if(int_flag==1)SoundOut();
Maxfft=0;
for(i=15;i<200;i++)
{
if(fft[i]>Maxfft)
Maxfft=fft[i]; //200-15内的最大值
}
AverageNumber=Maxfft/Averagefft; //最大值与平均值之比
if(int_flag==1)SoundOut();
fftL=0;
for(i=15;i<38;i++)
{
fftL+=fft[i];
}
fftH=0;
for(i=38;i<200;i++)
{
fftH+=fft[i];
}
fftNumber=fftH/fftL; //200-38及38-15 和的比
if(int_flag==1)SoundOut();
fftH128=0;
for(i=128;i<200;i++)
{
fftH128+=fft[i];
}
fftL18=0;
for(i=18;i<128;i++)
{
fftL18+=fft[i];
}
if(int_flag==1)SoundOut();
fftHNumber=fftH128/fftL18; //200-128与128-18范围内和的比
}
///////////////////////// 初始化 FftLong[] /////////////////////////
void FftLongInit(void)
{
int i;
for(i=FFTMIN;i<FFTMAX;i++)
{
FftLong[i-FFTMIN]=0;
}
}
/**************************************************************
变量初始化 */
void bianliang_chushihua(void)
{
uint i;
ZhenYi_F=0;
PitchFlag=0;
for(i=0;i<LpcNumber;i++)
{
CEP[i]=0;
ALF[i]=0;
PRECEPD[i]=0;
}
for(i=0;i<WindowsLong;i++)
fft[i]=0;
for(i=0;i<WindowsLong;i++)
{
VoiceIn[i]=0;
VoicePreEmphasisOut[i]=0;
// CanCHa[i]=0;
if(int_flag==1)SoundOut();
}
}
/********************************************************************/
///////////////////////////////END////////////////////////////////////
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?