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 + -
显示快捷键?