⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 docplc.c

📁 PA1688网络电话机全部源程序
💻 C
字号:
    
   /****************************************************************** 
    
       iLBC Speech Coder ANSI-C Source Code 
    
       doCPLC.c  
    
       Copyright (c) 2001, 
       Global IP Sound AB. 
       All rights reserved. 
    
   ******************************************************************/ 
    
   #include <math.h> 
   #include <string.h> 
    
   #include "iLBC_define.h" 
    
   /*----------------------------------------------------------------* 
    *  Compute cross correlation and pitch gain for pitch prediction 
    *  of last subframe at given lag. 
    *---------------------------------------------------------------*/ 
    
   void compCorr( 
       float *cc,      /* (o) cross correlation coefficient */ 
       float *gc,      /* (o) gain */ 
       float *pm, 
       float *buffer,  /* (i) signal buffer */ 
       int lag,    /* (i) pitch lag */ 
       int bLen,       /* (i) length of buffer */ 
       int sRange      /* (i) correlation search length */ 
   ){ 
       int i; 
       float ftmp1, ftmp2, ftmp3; 
        
       ftmp1 = 0.0; 
     
    
    
       ftmp2 = 0.0; 
       ftmp3 = 0.0; 
       for (i=0; i<sRange; i++) { 
           ftmp1 += buffer[bLen-sRange+i] * 
               buffer[bLen-sRange+i-lag]; 
           ftmp2 += buffer[bLen-sRange+i-lag] *  
                   buffer[bLen-sRange+i-lag]; 
           ftmp3 += buffer[bLen-sRange+i] *  
                   buffer[bLen-sRange+i]; 
       } 
    
       if (ftmp2 > 0.0) { 
           *cc = ftmp1*ftmp1/ftmp2; 
           *gc = (float)fabs(ftmp1/ftmp2); 
           *pm=(float)fabs(ftmp1)/ 
               ((float)sqrt(ftmp2)*(float)sqrt(ftmp3)); 
       } 
       else { 
           *cc = 0.0; 
           *gc = 0.0; 
           *pm=0.0; 
       } 
   } 
    
   /*----------------------------------------------------------------* 
    *  Packet loss concealment routine. Conceals a residual signal 
    *  and LP parameters. If no packet loss, update state. 
    *---------------------------------------------------------------*/ 
    
   void doThePLC( 
       float *PLCresidual, /* (o) concealed residual */  
       float *PLClpc,      /* (o) concealed LP parameters */   
       int PLI,        /* (i) packet loss indicator  
                                  0 - no PL, 1 = PL */  
       float *decresidual, /* (i) decoded residual */ 
       float *lpc,         /* (i) decoded LPC (only used for no PL) */ 
       int inlag,          /* (i) pitch lag */ 
       iLBC_Dec_Inst_t *iLBCdec_inst  
                           /* (i/o) decoder instance */ 
   ){ 
       int lag=20, randlag; 
       float gain, maxcc; 
       float use_gain; 
       float gain_comp, maxcc_comp, per, max_per; 
       int i, pick; 
       float ftmp, randvec[BLOCKL_MAX], pitchfact, energy; 
                
       /* Packet Loss */ 
    
       if (PLI == 1) { 
            
           iLBCdec_inst->consPLICount += 1; 
            
     
    
    
           /* if previous frame not lost,  
              determine pitch pred. gain */ 
            
           if (iLBCdec_inst->prevPLI != 1) { 
    
               /* Search around the previous lag to find the  
                  best pitch period */ 
                
               lag=20; 
               compCorr(&maxcc, &gain, &max_per,  
                       iLBCdec_inst->prevResidual, 
                       lag, iLBCdec_inst->blockl, 60); 
               for (i=21;i<=120;i++) { 
                   compCorr(&maxcc_comp, &gain_comp, &per, 
                       iLBCdec_inst->prevResidual, 
                       i, iLBCdec_inst->blockl, 60); 
                    
                   if (maxcc_comp>maxcc) { 
                       maxcc=maxcc_comp; 
                       gain=gain_comp; 
                       lag=i; 
                       max_per=per; 
                   } 
               } 
                
           } 
    
           /* previous frame lost, use recorded lag and periodicity */ 
    
           else { 
               lag=iLBCdec_inst->prevLag; 
               max_per=iLBCdec_inst->per; 
           } 
            
           /* downscaling */ 
    
           use_gain=1.0; 
           if (iLBCdec_inst->consPLICount* 
                           iLBCdec_inst->blockl>320) 
               use_gain=(float)0.9; 
           else if (iLBCdec_inst->consPLICount* 
                           iLBCdec_inst->blockl>2*320) 
               use_gain=(float)0.7; 
           else if (iLBCdec_inst->consPLICount* 
                           iLBCdec_inst->blockl>3*320) 
               use_gain=(float)0.5; 
           else if (iLBCdec_inst->consPLICount* 
                           iLBCdec_inst->blockl>4*320) 
               use_gain=(float)0.0; 
    
           /* mix noise and pitch repeatition */ 
           ftmp=(float)sqrt(max_per); 
           if (ftmp>(float)0.7) 
     
    
    
               pitchfact=(float)1.0; 
           else if (ftmp>(float)0.4) 
               pitchfact=(ftmp-(float)0.4)/((float)0.7-(float)0.4); 
           else 
               pitchfact=0.0; 
    
           /* compute concealed residual */ 
    
           energy = 0.0; 
           for (i=0; i<iLBCdec_inst->blockl; i++) { 
    
               /* noise component */ 
    
               iLBCdec_inst->seed=(iLBCdec_inst->seed*69069L+1) &  
                   (0x80000000L-1); 
               randlag = 50 + ((signed long) iLBCdec_inst->seed)%70; 
               pick = i - randlag; 
                
               if (pick < 0) { 
                   randvec[i] =   
                       iLBCdec_inst->prevResidual[iLBCdec_inst->blockl+ 
                                                   pick]; 
               } else { 
                   randvec[i] =  randvec[pick]; 
               } 
    
               /* pitch repeatition component */ 
    
               pick = i - lag; 
                
               if (pick < 0) { 
                   PLCresidual[i] =   
                       iLBCdec_inst->prevResidual[iLBCdec_inst->blockl+ 
                                                   pick]; 
               } else { 
                   PLCresidual[i] = PLCresidual[pick]; 
               } 
    
               /* mix random and periodicity component */ 
    
               if (i<80) 
                   PLCresidual[i] = use_gain*(pitchfact*PLCresidual[i] + 
                       ((float)1.0 - pitchfact) * randvec[i]); 
               else if (i<160) 
                   PLCresidual[i] = (float)0.95*use_gain* 
                       (pitchfact * PLCresidual[i] + 
                       ((float)1.0 - pitchfact) * randvec[i]); 
               else 
                   PLCresidual[i] = (float)0.9*use_gain* 
                       (pitchfact * PLCresidual[i] + 
                       ((float)1.0 - pitchfact) * randvec[i]); 
    
               energy += PLCresidual[i] * PLCresidual[i]; 
     
    
    
           } 
            
           /* less than 30 dB, use only noise */ 
            
           if (sqrt(energy/(float)iLBCdec_inst->blockl) < 30.0) {  
               gain=0.0; 
               for (i=0; i<iLBCdec_inst->blockl; i++) { 
                   PLCresidual[i] = randvec[i]; 
               } 
           } 
    
           /* conceal LPC by bandwidth expansion of old LPC */ 
    
           ftmp=PLC_BWEXPAND; 
           PLClpc[0]=(float)1.0; 
           for (i=1; i<LPC_FILTERORDER+1; i++) { 
               PLClpc[i] = ftmp * iLBCdec_inst->prevLpc[i]; 
               ftmp *= PLC_BWEXPAND; 
           } 
            
       } 
    
       /* no packet loss, copy input */ 
    
       else { 
           memcpy(PLCresidual, decresidual,  
                   iLBCdec_inst->blockl*sizeof(float)); 
           memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float)); 
           iLBCdec_inst->consPLICount = 0; 
       } 
        
       /* update state */ 
    
       if (PLI) { 
           iLBCdec_inst->prevLag = lag; 
           iLBCdec_inst->per=max_per; 
       } 
    
       iLBCdec_inst->prevPLI = PLI; 
       memcpy(iLBCdec_inst->prevLpc, PLClpc,  
           (LPC_FILTERORDER+1)*sizeof(float)); 
       memcpy(iLBCdec_inst->prevResidual, PLCresidual, 
           iLBCdec_inst->blockl*sizeof(float)); 
   } 
    
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -