Home | History | Annotate | Download | only in ilbc
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 /******************************************************************
     12 
     13  iLBC Speech Coder ANSI-C Source Code
     14 
     15  WebRtcIlbcfix_Refiner.c
     16 
     17 ******************************************************************/
     18 
     19 #include "defines.h"
     20 #include "constants.h"
     21 #include "enh_upsample.h"
     22 #include "my_corr.h"
     23 
     24 /*----------------------------------------------------------------*
     25  * find segment starting near idata+estSegPos that has highest
     26  * correlation with idata+centerStartPos through
     27  * idata+centerStartPos+ENH_BLOCKL-1 segment is found at a
     28  * resolution of ENH_UPSO times the original of the original
     29  * sampling rate
     30  *---------------------------------------------------------------*/
     31 
     32 void WebRtcIlbcfix_Refiner(
     33     int16_t *updStartPos, /* (o) updated start point (Q-2) */
     34     int16_t *idata,   /* (i) original data buffer */
     35     int16_t idatal,   /* (i) dimension of idata */
     36     int16_t centerStartPos, /* (i) beginning center segment */
     37     int16_t estSegPos,  /* (i) estimated beginning other segment (Q-2) */
     38     int16_t *surround,  /* (i/o) The contribution from this sequence
     39                                            summed with earlier contributions */
     40     int16_t gain    /* (i) Gain to use for this sequence */
     41                            ){
     42   int16_t estSegPosRounded,searchSegStartPos,searchSegEndPos,corrdim;
     43   int16_t tloc,tloc2,i,st,en,fraction;
     44 
     45   int32_t maxtemp, scalefact;
     46   int16_t *filtStatePtr, *polyPtr;
     47   /* Stack based */
     48   int16_t filt[7];
     49   int32_t corrVecUps[ENH_CORRDIM*ENH_UPS0];
     50   int32_t corrVecTemp[ENH_CORRDIM];
     51   int16_t vect[ENH_VECTL];
     52   int16_t corrVec[ENH_CORRDIM];
     53 
     54   /* defining array bounds */
     55 
     56   estSegPosRounded=WEBRTC_SPL_RSHIFT_W16((estSegPos - 2),2);
     57 
     58   searchSegStartPos=estSegPosRounded-ENH_SLOP;
     59 
     60   if (searchSegStartPos<0) {
     61     searchSegStartPos=0;
     62   }
     63   searchSegEndPos=estSegPosRounded+ENH_SLOP;
     64 
     65   if(searchSegEndPos+ENH_BLOCKL >= idatal) {
     66     searchSegEndPos=idatal-ENH_BLOCKL-1;
     67   }
     68   corrdim=searchSegEndPos-searchSegStartPos+1;
     69 
     70   /* compute upsampled correlation and find
     71      location of max */
     72 
     73   WebRtcIlbcfix_MyCorr(corrVecTemp,idata+searchSegStartPos,
     74                        (int16_t)(corrdim+ENH_BLOCKL-1),idata+centerStartPos,ENH_BLOCKL);
     75 
     76   /* Calculate the rescaling factor for the correlation in order to
     77      put the correlation in a int16_t vector instead */
     78   maxtemp=WebRtcSpl_MaxAbsValueW32(corrVecTemp, (int16_t)corrdim);
     79 
     80   scalefact=WebRtcSpl_GetSizeInBits(maxtemp)-15;
     81 
     82   if (scalefact>0) {
     83     for (i=0;i<corrdim;i++) {
     84       corrVec[i]=(int16_t)WEBRTC_SPL_RSHIFT_W32(corrVecTemp[i], scalefact);
     85     }
     86   } else {
     87     for (i=0;i<corrdim;i++) {
     88       corrVec[i]=(int16_t)corrVecTemp[i];
     89     }
     90   }
     91   /* In order to guarantee that all values are initialized */
     92   for (i=corrdim;i<ENH_CORRDIM;i++) {
     93     corrVec[i]=0;
     94   }
     95 
     96   /* Upsample the correlation */
     97   WebRtcIlbcfix_EnhUpsample(corrVecUps,corrVec);
     98 
     99   /* Find maximum */
    100   tloc=WebRtcSpl_MaxIndexW32(corrVecUps, (int16_t) (ENH_UPS0*corrdim));
    101 
    102   /* make vector can be upsampled without ever running outside
    103      bounds */
    104   *updStartPos = (int16_t)WEBRTC_SPL_MUL_16_16(searchSegStartPos,4) + tloc + 4;
    105 
    106   tloc2 = WEBRTC_SPL_RSHIFT_W16((tloc+3), 2);
    107 
    108   st=searchSegStartPos+tloc2-ENH_FL0;
    109 
    110   /* initialize the vector to be filtered, stuff with zeros
    111      when data is outside idata buffer */
    112   if(st<0){
    113     WebRtcSpl_MemSetW16(vect, 0, (int16_t)(-st));
    114     WEBRTC_SPL_MEMCPY_W16(&vect[-st], idata, (ENH_VECTL+st));
    115   }
    116   else{
    117     en=st+ENH_VECTL;
    118 
    119     if(en>idatal){
    120       WEBRTC_SPL_MEMCPY_W16(vect, &idata[st],
    121                             (ENH_VECTL-(en-idatal)));
    122       WebRtcSpl_MemSetW16(&vect[ENH_VECTL-(en-idatal)], 0,
    123                           (int16_t)(en-idatal));
    124     }
    125     else {
    126       WEBRTC_SPL_MEMCPY_W16(vect, &idata[st], ENH_VECTL);
    127     }
    128   }
    129   /* Calculate which of the 4 fractions to use */
    130   fraction=(int16_t)WEBRTC_SPL_MUL_16_16(tloc2,ENH_UPS0)-tloc;
    131 
    132   /* compute the segment (this is actually a convolution) */
    133 
    134   filtStatePtr = filt + 6;
    135   polyPtr = (int16_t*)WebRtcIlbcfix_kEnhPolyPhaser[fraction];
    136   for (i=0;i<7;i++) {
    137     *filtStatePtr-- = *polyPtr++;
    138   }
    139 
    140   WebRtcSpl_FilterMAFastQ12(
    141       &vect[6], vect, filt,
    142       ENH_FLO_MULT2_PLUS1, ENH_BLOCKL);
    143 
    144   /* Add the contribution from this vector (scaled with gain) to the total surround vector */
    145   WebRtcSpl_AddAffineVectorToVector(
    146       surround, vect, gain,
    147       (int32_t)32768, 16, ENH_BLOCKL);
    148 
    149   return;
    150 }
    151