예제 #1
0
static __inline int16_t Exp2Q10(int16_t x) { // Both in and out in Q10

  int16_t tmp16_1, tmp16_2;

  tmp16_2=(int16_t)(0x0400|(x&0x03FF));
  tmp16_1=-(int16_t)WEBRTC_SPL_RSHIFT_W16(x,10);
  if(tmp16_1>0)
    return (int16_t) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1);
  else
    return (int16_t) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1);

}
예제 #2
0
static __inline WebRtc_Word16  exp2_Q10_T(WebRtc_Word16 x) { // Both in and out in Q10

  WebRtc_Word16 tmp16_1, tmp16_2;

  tmp16_2=(WebRtc_Word16)(0x0400|(x&0x03FF));
  tmp16_1=-(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(x,10);
  if(tmp16_1>0)
    return (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1);
  else
    return (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1);

}
예제 #3
0
WebRtc_Word32 WebRtcVad_GaussianProbability(WebRtc_Word16 in_sample,
                                            WebRtc_Word16 mean,
                                            WebRtc_Word16 std,
                                            WebRtc_Word16 *delta)
{
    WebRtc_Word16 tmp16, tmpDiv, tmpDiv2, expVal, tmp16_1, tmp16_2;
    WebRtc_Word32 tmp32, y32;

    // Calculate tmpDiv=1/std, in Q10
    tmp32 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W16(std,1) + (WebRtc_Word32)131072; // 1 in Q17
    tmpDiv = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32, std); // Q17/Q7 = Q10

    // Calculate tmpDiv2=1/std^2, in Q14
    tmp16 = WEBRTC_SPL_RSHIFT_W16(tmpDiv, 2); // From Q10 to Q8
    tmpDiv2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16, tmp16, 2); // (Q8 * Q8)>>2 = Q14

    tmp16 = WEBRTC_SPL_LSHIFT_W16(in_sample, 3); // Q7
    tmp16 = tmp16 - mean; // Q7 - Q7 = Q7

    // To be used later, when updating noise/speech model
    // delta = (x-m)/std^2, in Q11
    *delta = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmpDiv2, tmp16, 10); //(Q14*Q7)>>10 = Q11

    // Calculate tmp32=(x-m)^2/(2*std^2), in Q10
    tmp32 = (WebRtc_Word32)WEBRTC_SPL_MUL_16_16_RSFT(*delta, tmp16, 9); // One shift for /2

    // Calculate expVal ~= exp(-(x-m)^2/(2*std^2)) ~= exp2(-log2(exp(1))*tmp32)
    if (tmp32 < kCompVar)
    {
        // Calculate tmp16 = log2(exp(1))*tmp32 , in Q10
        tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16)tmp32,
                                                         kLog10Const, 12);
        tmp16 = -tmp16;
        tmp16_2 = (WebRtc_Word16)(0x0400 | (tmp16 & 0x03FF));
        tmp16_1 = (WebRtc_Word16)(tmp16 ^ 0xFFFF);
        tmp16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(tmp16_1, 10);
        tmp16 += 1;
        // Calculate expVal=log2(-tmp32), in Q10
        expVal = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)tmp16_2, tmp16);

    } else
    {
        expVal = 0;
    }

    // Calculate y32=(1/std)*exp(-(x-m)^2/(2*std^2)), in Q20
    y32 = WEBRTC_SPL_MUL_16_16(tmpDiv, expVal); // Q10 * Q10 = Q20

    return y32; // Q20
}
예제 #4
0
void WebRtcVad_SplitFilter(WebRtc_Word16 *in_vector,
                           WebRtc_Word16 *out_vector_hp,
                           WebRtc_Word16 *out_vector_lp,
                           WebRtc_Word16 *upper_state,
                           WebRtc_Word16 *lower_state,
                           int in_vector_length)
{
    WebRtc_Word16 tmpOut;
    int k, halflen;

    // Downsampling by 2 and get two branches
    halflen = WEBRTC_SPL_RSHIFT_W16(in_vector_length, 1);

    // All-pass filtering upper branch
    WebRtcVad_Allpass(&in_vector[0], out_vector_hp, kAllPassCoefsQ15[0], halflen, upper_state);

    // All-pass filtering lower branch
    WebRtcVad_Allpass(&in_vector[1], out_vector_lp, kAllPassCoefsQ15[1], halflen, lower_state);

    // Make LP and HP signals
    for (k = 0; k < halflen; k++)
    {
        tmpOut = *out_vector_hp;
        *out_vector_hp++ -= *out_vector_lp;
        *out_vector_lp++ += tmpOut;
    }
}
예제 #5
0
void WebRtcSpl_ReflCoefToLpc(const int16_t *k, int use_order, int16_t *a)
{
    int16_t any[WEBRTC_SPL_MAX_LPC_ORDER + 1];
    int16_t *aptr, *aptr2, *anyptr;
    const int16_t *kptr;
    int m, i;

    kptr = k;
    *a = 4096; // i.e., (Word16_MAX >> 3)+1.
    *any = *a;
    a[1] = WEBRTC_SPL_RSHIFT_W16((*k), 3);

    for (m = 1; m < use_order; m++)
    {
        kptr++;
        aptr = a;
        aptr++;
        aptr2 = &a[m];
        anyptr = any;
        anyptr++;

        any[m + 1] = WEBRTC_SPL_RSHIFT_W16((*kptr), 3);
        for (i = 0; i < m; i++)
        {
            *anyptr = (*aptr)
                    + (int16_t)WEBRTC_SPL_MUL_16_16_RSFT((*aptr2), (*kptr), 15);
            anyptr++;
            aptr++;
            aptr2--;
        }

        aptr = a;
        anyptr = any;
        for (i = 0; i < (m + 2); i++)
        {
            *aptr = *anyptr;
            aptr++;
            anyptr++;
        }
    }
}
예제 #6
0
/* 1D parabolic interpolation . All input and output values are in Q8 */
static __inline void Intrp1DQ8(int32_t *x, int32_t *fx, int32_t *y, int32_t *fy) {

  int16_t sign1=1, sign2=1;
  int32_t r32, q32, t32, nom32, den32;
  int16_t t16, tmp16, tmp16_1;

  if ((fx[0]>0) && (fx[2]>0)) {
    r32=fx[1]-fx[2];
    q32=fx[0]-fx[1];
    nom32=q32+r32;
    den32=WEBRTC_SPL_MUL_32_16((q32-r32), 2);
    if (nom32<0)
      sign1=-1;
    if (den32<0)
      sign2=-1;

    /* t = (q32+r32)/(2*(q32-r32)) = (fx[0]-fx[1] + fx[1]-fx[2])/(2 * fx[0]-fx[1] - (fx[1]-fx[2]))*/
    /* (Signs are removed because WebRtcSpl_DivResultInQ31 can't handle negative numbers) */
    t32=WebRtcSpl_DivResultInQ31(WEBRTC_SPL_MUL_32_16(nom32, sign1),WEBRTC_SPL_MUL_32_16(den32, sign2)); /* t in Q31, without signs */

    t16=(int16_t)WEBRTC_SPL_RSHIFT_W32(t32, 23);  /* Q8 */
    t16=t16*sign1*sign2;        /* t in Q8 with signs */

    *y = x[0]+t16;          /* Q8 */
    // *y = x[1]+t16;          /* Q8 */

    /* The following code calculates fy in three steps */
    /* fy = 0.5 * t * (t-1) * fx[0] + (1-t*t) * fx[1] + 0.5 * t * (t+1) * fx[2]; */

    /* Part I: 0.5 * t * (t-1) * fx[0] */
    tmp16_1=(int16_t)WEBRTC_SPL_MUL_16_16(t16,t16); /* Q8*Q8=Q16 */
    tmp16_1 = WEBRTC_SPL_RSHIFT_W16(tmp16_1,2);  /* Q16>>2 = Q14 */
    t16 = (int16_t)WEBRTC_SPL_MUL_16_16(t16, 64);           /* Q8<<6 = Q14  */
    tmp16 = tmp16_1-t16;
    *fy = WEBRTC_SPL_MUL_16_32_RSFT15(tmp16, fx[0]); /* (Q14 * Q8 >>15)/2 = Q8 */

    /* Part II: (1-t*t) * fx[1] */
    tmp16 = 16384-tmp16_1;        /* 1 in Q14 - Q14 */
    *fy += WEBRTC_SPL_MUL_16_32_RSFT14(tmp16, fx[1]);/* Q14 * Q8 >> 14 = Q8 */

    /* Part III: 0.5 * t * (t+1) * fx[2] */
    tmp16 = tmp16_1+t16;
    *fy += WEBRTC_SPL_MUL_16_32_RSFT15(tmp16, fx[2]);/* (Q14 * Q8 >>15)/2 = Q8 */
  } else {
    *y = x[0];
    *fy= fx[1];
  }
}
예제 #7
0
// Downsampling filter based on the splitting filter and the allpass functions
// in vad_filterbank.c
void WebRtcVad_Downsampling(WebRtc_Word16* signal_in,
                            WebRtc_Word16* signal_out,
                            WebRtc_Word32* filter_state,
                            int inlen)
{
    WebRtc_Word16 tmp16_1, tmp16_2;
    WebRtc_Word32 tmp32_1, tmp32_2;
    int n, halflen;

    // Downsampling by 2 and get two branches
    halflen = WEBRTC_SPL_RSHIFT_W16(inlen, 1);

    tmp32_1 = filter_state[0];
    tmp32_2 = filter_state[1];

    // Filter coefficients in Q13, filter state in Q0
    for (n = 0; n < halflen; n++)
    {
        // All-pass filtering upper branch
        tmp16_1 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32_1, 1)
                  + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[0]),
                          *signal_in, 14);
        *signal_out = tmp16_1;
        tmp32_1 = (WebRtc_Word32)(*signal_in++)
                  - (WebRtc_Word32)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[0]), tmp16_1, 12);

        // All-pass filtering lower branch
        tmp16_2 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32_2, 1)
                  + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[1]),
                          *signal_in, 14);
        *signal_out++ += tmp16_2;
        tmp32_2 = (WebRtc_Word32)(*signal_in++)
                  - (WebRtc_Word32)WEBRTC_SPL_MUL_16_16_RSFT((kAllPassCoefsQ13[1]), tmp16_2, 12);
    }
    filter_state[0] = tmp32_1;
    filter_state[1] = tmp32_2;
}
예제 #8
0
int32_t WebRtcIlbcfix_Smooth_odata(
    int16_t *odata,
    int16_t *psseq,
    int16_t *surround,
    int16_t C)
{
  int i;

  int16_t err;
  int32_t errs;

  for(i=0;i<80;i++) {
    odata[i]= (int16_t)WEBRTC_SPL_RSHIFT_W32(
        (WEBRTC_SPL_MUL_16_16(C, surround[i])+1024), 11);
  }

  errs=0;
  for(i=0;i<80;i++) {
    err=(int16_t)WEBRTC_SPL_RSHIFT_W16((psseq[i]-odata[i]), 3);
    errs+=WEBRTC_SPL_MUL_16_16(err, err); /* errs in Q-6 */
  }

  return errs;
}
예제 #9
0
void WebRtcIlbcfix_Lsf2Lsp(
    int16_t *lsf, /* (i) lsf in Q13 values between 0 and pi */
    int16_t *lsp, /* (o) lsp in Q15 values between -1 and 1 */
    int16_t m  /* (i) number of coefficients */
                           ) {
  int16_t i, k;
  int16_t diff; /* difference, which is used for the
                           linear approximation (Q8) */
  int16_t freq; /* normalized frequency in Q15 (0..1) */
  int32_t tmpW32;

  for(i=0; i<m; i++)
  {
    freq = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(lsf[i], 20861, 15);
    /* 20861: 1.0/(2.0*PI) in Q17 */
    /*
       Upper 8 bits give the index k and
       Lower 8 bits give the difference, which needs
       to be approximated linearly
    */
    k = WEBRTC_SPL_RSHIFT_W16(freq, 8);
    diff = (freq&0x00ff);

    /* Guard against getting outside table */

    if (k>63) {
      k = 63;
    }

    /* Calculate linear approximation */
    tmpW32 = WEBRTC_SPL_MUL_16_16(WebRtcIlbcfix_kCosDerivative[k], diff);
    lsp[i] = WebRtcIlbcfix_kCos[k]+(int16_t)(WEBRTC_SPL_RSHIFT_W32(tmpW32, 12));
  }

  return;
}
예제 #10
0
WebRtc_Word32 WebRtcIlbcfix_Smooth_odata(
    WebRtc_Word16 *odata,
    WebRtc_Word16 *psseq,
    WebRtc_Word16 *surround,
    WebRtc_Word16 C)
{
  int i;

  WebRtc_Word16 err;
  WebRtc_Word32 errs;

  for(i=0;i<80;i++) {
    odata[i]= (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
        (WEBRTC_SPL_MUL_16_16(C, surround[i])+1024), 11);
  }

  errs=0;
  for(i=0;i<80;i++) {
    err=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16((psseq[i]-odata[i]), 3);
    errs+=WEBRTC_SPL_MUL_16_16(err, err); /* errs in Q-6 */
  }

  return errs;
}
예제 #11
0
WebRtc_Word16 WebRtcVad_get_features(VadInstT *inst,
                                     WebRtc_Word16 *in_vector,
                                     int frame_size,
                                     WebRtc_Word16 *out_vector)
{
    int curlen, filtno;
    WebRtc_Word16 vecHP1[120], vecLP1[120];
    WebRtc_Word16 vecHP2[60], vecLP2[60];
    WebRtc_Word16 *ptin;
    WebRtc_Word16 *hptout, *lptout;
    WebRtc_Word16 power = 0;

    // Split at 2000 Hz and downsample
    filtno = 0;
    ptin = in_vector;
    hptout = vecHP1;
    lptout = vecLP1;
    curlen = frame_size;
    WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno],
                  &inst->lower_state[filtno], curlen);

    // Split at 3000 Hz and downsample
    filtno = 1;
    ptin = vecHP1;
    hptout = vecHP2;
    lptout = vecLP2;
    curlen = WEBRTC_SPL_RSHIFT_W16(frame_size, 1);

    WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno],
                  &inst->lower_state[filtno], curlen);

    // Energy in 3000 Hz - 4000 Hz
    curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1);
    WebRtcVad_LogOfEnergy(vecHP2, &out_vector[5], &power, kOffsetVector[5], curlen);

    // Energy in 2000 Hz - 3000 Hz
    WebRtcVad_LogOfEnergy(vecLP2, &out_vector[4], &power, kOffsetVector[4], curlen);

    // Split at 1000 Hz and downsample
    filtno = 2;
    ptin = vecLP1;
    hptout = vecHP2;
    lptout = vecLP2;
    curlen = WEBRTC_SPL_RSHIFT_W16(frame_size, 1);
    WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno],
                  &inst->lower_state[filtno], curlen);

    // Energy in 1000 Hz - 2000 Hz
    curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1);
    WebRtcVad_LogOfEnergy(vecHP2, &out_vector[3], &power, kOffsetVector[3], curlen);

    // Split at 500 Hz
    filtno = 3;
    ptin = vecLP2;
    hptout = vecHP1;
    lptout = vecLP1;

    WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno],
                  &inst->lower_state[filtno], curlen);

    // Energy in 500 Hz - 1000 Hz
    curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1);
    WebRtcVad_LogOfEnergy(vecHP1, &out_vector[2], &power, kOffsetVector[2], curlen);
    // Split at 250 Hz
    filtno = 4;
    ptin = vecLP1;
    hptout = vecHP2;
    lptout = vecLP2;

    WebRtcVad_SplitFilter(ptin, hptout, lptout, &inst->upper_state[filtno],
                  &inst->lower_state[filtno], curlen);

    // Energy in 250 Hz - 500 Hz
    curlen = WEBRTC_SPL_RSHIFT_W16(curlen, 1);
    WebRtcVad_LogOfEnergy(vecHP2, &out_vector[1], &power, kOffsetVector[1], curlen);

    // Remove DC and LFs
    WebRtcVad_HpOutput(vecLP2, curlen, vecHP1, inst->hp_filter_state);

    // Power in 80 Hz - 250 Hz
    WebRtcVad_LogOfEnergy(vecHP1, &out_vector[0], &power, kOffsetVector[0], curlen);

    return power;
}
예제 #12
0
void WebRtcIlbcfix_GetCbVec(
    int16_t *cbvec,   /* (o) Constructed codebook vector */
    int16_t *mem,   /* (i) Codebook buffer */
    int16_t index,   /* (i) Codebook index */
    int16_t lMem,   /* (i) Length of codebook buffer */
    int16_t cbveclen   /* (i) Codebook vector length */
                            ){
  int16_t k, base_size;
  int16_t lag;
  /* Stack based */
  int16_t tempbuff2[SUBL+5];

  /* Determine size of codebook sections */

  base_size=lMem-cbveclen+1;

  if (cbveclen==SUBL) {
    base_size+=WEBRTC_SPL_RSHIFT_W16(cbveclen,1);
  }

  /* No filter -> First codebook section */

  if (index<lMem-cbveclen+1) {

    /* first non-interpolated vectors */

    k=index+cbveclen;
    /* get vector */
    WEBRTC_SPL_MEMCPY_W16(cbvec, mem+lMem-k, cbveclen);

  } else if (index < base_size) {

    /* Calculate lag */

    k=(int16_t)WEBRTC_SPL_MUL_16_16(2, (index-(lMem-cbveclen+1)))+cbveclen;

    lag=WEBRTC_SPL_RSHIFT_W16(k, 1);

    WebRtcIlbcfix_CreateAugmentedVec(lag, mem+lMem, cbvec);

  }

  /* Higher codebbok section based on filtering */

  else {

    int16_t memIndTest;

    /* first non-interpolated vectors */

    if (index-base_size<lMem-cbveclen+1) {

      /* Set up filter memory, stuff zeros outside memory buffer */

      memIndTest = lMem-(index-base_size+cbveclen);

      WebRtcSpl_MemSetW16(mem-CB_HALFFILTERLEN, 0, CB_HALFFILTERLEN);
      WebRtcSpl_MemSetW16(mem+lMem, 0, CB_HALFFILTERLEN);

      /* do filtering to get the codebook vector */

      WebRtcSpl_FilterMAFastQ12(
          &mem[memIndTest+4], cbvec, (int16_t*)WebRtcIlbcfix_kCbFiltersRev,
          CB_FILTERLEN, cbveclen);
    }

    /* interpolated vectors */

    else {
      /* Stuff zeros outside memory buffer  */
      memIndTest = lMem-cbveclen-CB_FILTERLEN;
      WebRtcSpl_MemSetW16(mem+lMem, 0, CB_HALFFILTERLEN);

      /* do filtering */
      WebRtcSpl_FilterMAFastQ12(
          &mem[memIndTest+7], tempbuff2, (int16_t*)WebRtcIlbcfix_kCbFiltersRev,
          CB_FILTERLEN, (int16_t)(cbveclen+5));

      /* Calculate lag index */
      lag = (cbveclen<<1)-20+index-base_size-lMem-1;

      WebRtcIlbcfix_CreateAugmentedVec(lag, tempbuff2+SUBL+5, cbvec);
    }
  }
}
예제 #13
0
파일: fft.c 프로젝트: 2wce/Signal-Android
/* Uses 16x16 mul, without rounding, which is faster. Uses WEBRTC_SPL_MUL_16_16_RSFT */
int16_t WebRtcIsacfix_FftRadix16Fastest(int16_t RexQx[], int16_t ImxQx[], int16_t iSign) {

  int16_t dd, ee, ff, gg, hh, ii;
  int16_t k0, k1, k2, k3, k4, kk;
  int16_t tmp116, tmp216;

  int16_t ccc1Q14, ccc2Q14, ccc3Q14, sss1Q14, sss2Q14, sss3Q14;
  int16_t sss60Q14, ccc72Q14, sss72Q14;
  int16_t aaQx, ajQx, akQx, ajmQx, ajpQx, akmQx, akpQx;
  int16_t bbQx, bjQx, bkQx, bjmQx, bjpQx, bkmQx, bkpQx;

  int16_t ReDATAQx[240],  ImDATAQx[240];

  sss60Q14 = kCosTabFfftQ14[20];
  ccc72Q14 = kCosTabFfftQ14[48];
  sss72Q14 = kCosTabFfftQ14[12];

  if (iSign < 0) {
    sss72Q14 = -sss72Q14;
    sss60Q14 = -sss60Q14;
  }
  /* Complexity is: 10 cycles */

  /* compute fourier transform */

  // transform for factor of 4
  for (kk=0; kk<60; kk++) {
    k0 = kk;
    k1 = k0 + 60;
    k2 = k1 + 60;
    k3 = k2 + 60;

    akpQx = RexQx[k0] + RexQx[k2];
    akmQx = RexQx[k0] - RexQx[k2];
    ajpQx = RexQx[k1] + RexQx[k3];
    ajmQx = RexQx[k1] - RexQx[k3];
    bkpQx = ImxQx[k0] + ImxQx[k2];
    bkmQx = ImxQx[k0] - ImxQx[k2];
    bjpQx = ImxQx[k1] + ImxQx[k3];
    bjmQx = ImxQx[k1] - ImxQx[k3];

    RexQx[k0] = akpQx + ajpQx;
    ImxQx[k0] = bkpQx + bjpQx;
    ajpQx = akpQx - ajpQx;
    bjpQx = bkpQx - bjpQx;
    if (iSign < 0) {
      akpQx = akmQx + bjmQx;
      bkpQx = bkmQx - ajmQx;
      akmQx -= bjmQx;
      bkmQx += ajmQx;
    } else {
      akpQx = akmQx - bjmQx;
      bkpQx = bkmQx + ajmQx;
      akmQx += bjmQx;
      bkmQx -= ajmQx;
    }

    ccc1Q14 = kCosTabFfftQ14[kk];
    ccc2Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(2, kk)];
    ccc3Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(3, kk)];
    sss1Q14 = kCosTabFfftQ14[kk+60];
    sss2Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(2, kk)+60];
    sss3Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(3, kk)+60];
    if (iSign==1) {
      sss1Q14 = -sss1Q14;
      sss2Q14 = -sss2Q14;
      sss3Q14 = -sss3Q14;
    }

    //Do several multiplications like Q14*Q16>>14 = Q16
    // RexQ16[k1] = akpQ16 * ccc1Q14 - bkpQ16 * sss1Q14;
    // RexQ16[k2] = ajpQ16 * ccc2Q14 - bjpQ16 * sss2Q14;
    // RexQ16[k3] = akmQ16 * ccc3Q14 - bkmQ16 * sss3Q14;
    // ImxQ16[k1] = akpQ16 * sss1Q14 + bkpQ16 * ccc1Q14;
    // ImxQ16[k2] = ajpQ16 * sss2Q14 + bjpQ16 * ccc2Q14;
    // ImxQ16[k3] = akmQ16 * sss3Q14 + bkmQ16 * ccc3Q14;

    RexQx[k1] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc1Q14, akpQx, 14) -
        (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss1Q14, bkpQx, 14); // 6 non-mul + 2 mul cycles, i.e. 8 cycles (6+2*7=20 cycles if 16x32mul)
    RexQx[k2] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, ajpQx, 14) -
        (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bjpQx, 14);
    RexQx[k3] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc3Q14, akmQx, 14) -
        (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss3Q14, bkmQx, 14);
    ImxQx[k1] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss1Q14, akpQx, 14) +
        (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc1Q14, bkpQx, 14);
    ImxQx[k2] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, ajpQx, 14) +
        (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bjpQx, 14);
    ImxQx[k3] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss3Q14, akmQx, 14) +
        (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc3Q14, bkmQx, 14);
    //This mul segment needs 6*8 = 48 cycles for 16x16 muls, but 6*20 = 120 cycles for 16x32 muls


  }
  /* Complexity is: 51+48 = 99 cycles for 16x16 muls, but 51+120 = 171 cycles for 16x32 muls*/

  // transform for factor of 3
  kk=0;
  k1=20;
  k2=40;

  for (hh=0; hh<4; hh++) {
    for (ii=0; ii<20; ii++) {
      akQx = RexQx[kk];
      bkQx = ImxQx[kk];
      ajQx = RexQx[k1] + RexQx[k2];
      bjQx = ImxQx[k1] + ImxQx[k2];
      RexQx[kk] = akQx + ajQx;
      ImxQx[kk] = bkQx + bjQx;
      tmp116 = WEBRTC_SPL_RSHIFT_W16(ajQx, 1);
      tmp216 = WEBRTC_SPL_RSHIFT_W16(bjQx, 1);
      akQx = akQx - tmp116;
      bkQx = bkQx - tmp216;
      tmp116 = RexQx[k1] - RexQx[k2];
      tmp216 = ImxQx[k1] - ImxQx[k2];

      ajQx = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss60Q14, tmp116, 14); // Q14*Qx>>14 = Qx
      bjQx = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss60Q14, tmp216, 14); // Q14*Qx>>14 = Qx
      RexQx[k1] = akQx - bjQx;
      RexQx[k2] = akQx + bjQx;
      ImxQx[k1] = bkQx + ajQx;
      ImxQx[k2] = bkQx - ajQx;

      kk++;
      k1++;
      k2++;
    }
    /* Complexity : (31+6)*20 = 740 cycles for 16x16 muls, but (31+18)*20 = 980 cycles for 16x32 muls*/
    kk=kk+40;
    k1=k1+40;
    k2=k2+40;
  }
  /* Complexity : 4*(740+3) = 2972 cycles for 16x16 muls, but 4*(980+3) = 3932 cycles for 16x32 muls*/

  /* multiply by rotation factor for odd factor 3 or 5 (not for 4)
     Same code (duplicated) for both ii=2 and ii=3 */
  kk = 1;
  ee = 0;
  ff = 0;

  for (gg=0; gg<19; gg++) {
    kk += 20;
    ff = ff+4;
    for (hh=0; hh<2; hh++) {
      ee = ff + (int16_t)WEBRTC_SPL_MUL_16_16(hh, ff);
      dd = ee + 60;
      ccc2Q14 = kCosTabFfftQ14[ee];
      sss2Q14 = kCosTabFfftQ14[dd];
      if (iSign==1) {
        sss2Q14 = -sss2Q14;
      }
      for (ii=0; ii<4; ii++) {
        akQx = RexQx[kk];
        bkQx = ImxQx[kk];
        RexQx[kk] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akQx, 14) - // Q14*Qx>>14 = Qx
            (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkQx, 14);
        ImxQx[kk] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akQx, 14) + // Q14*Qx>>14 = Qx
            (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkQx, 14);


        kk += 60;
      }
      kk = kk - 220;
    }
    // Complexity: 2*(13+5+4*13+2) = 144 for 16x16 muls, but 2*(13+5+4*33+2) = 304 cycles for 16x32 muls
    kk = kk - 59;
  }
  // Complexity: 19*144 = 2736 for 16x16 muls, but 19*304 = 5776 cycles for 16x32 muls

  // transform for factor of 5
  kk = 0;
  ccc2Q14 = kCosTabFfftQ14[96];
  sss2Q14 = kCosTabFfftQ14[84];
  if (iSign==1) {
    sss2Q14 = -sss2Q14;
  }

  for (hh=0; hh<4; hh++) {
    for (ii=0; ii<12; ii++) {
      k1 = kk + 4;
      k2 = k1 + 4;
      k3 = k2 + 4;
      k4 = k3 + 4;

      akpQx = RexQx[k1] + RexQx[k4];
      akmQx = RexQx[k1] - RexQx[k4];
      bkpQx = ImxQx[k1] + ImxQx[k4];
      bkmQx = ImxQx[k1] - ImxQx[k4];
      ajpQx = RexQx[k2] + RexQx[k3];
      ajmQx = RexQx[k2] - RexQx[k3];
      bjpQx = ImxQx[k2] + ImxQx[k3];
      bjmQx = ImxQx[k2] - ImxQx[k3];
      aaQx = RexQx[kk];
      bbQx = ImxQx[kk];
      RexQx[kk] = aaQx + akpQx + ajpQx;
      ImxQx[kk] = bbQx + bkpQx + bjpQx;

      akQx = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, akpQx, 14) +
          (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, ajpQx, 14)  + aaQx;
      bkQx = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, bkpQx, 14) +
          (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bjpQx, 14)  + bbQx;
      ajQx = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, akmQx, 14) +
          (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, ajmQx, 14);
      bjQx = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, bkmQx, 14) +
          (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bjmQx, 14);
      // 32+4*8=64 or 32+4*20=112

      RexQx[k1] = akQx - bjQx;
      RexQx[k4] = akQx + bjQx;
      ImxQx[k1] = bkQx + ajQx;
      ImxQx[k4] = bkQx - ajQx;

      akQx = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akpQx, 14)  +
          (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, ajpQx, 14) + aaQx;
      bkQx = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkpQx, 14)  +
          (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, bjpQx, 14) + bbQx;
      ajQx = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akmQx, 14) -
          (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, ajmQx, 14);
      bjQx = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkmQx, 14) -
          (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, bjmQx, 14);
      // 8+4*8=40 or 8+4*20=88

      RexQx[k2] = akQx - bjQx;
      RexQx[k3] = akQx + bjQx;
      ImxQx[k2] = bkQx + ajQx;
      ImxQx[k3] = bkQx - ajQx;

      kk = k4 + 4;
    }
    // Complexity: 12*(64+40+10) = 1368 for 16x16 muls, but 12*(112+88+10) = 2520 cycles for 16x32 muls
    kk -= 239;
  }
  // Complexity: 4*1368 = 5472 for 16x16 muls, but 4*2520 = 10080 cycles for 16x32 muls

  /* multiply by rotation factor for odd factor 3 or 5 (not for 4)
     Same code (duplicated) for both ii=2 and ii=3 */
  kk = 1;
  ee=0;

  for (gg=0; gg<3; gg++) {
    kk += 4;
    dd = 12 + (int16_t)WEBRTC_SPL_MUL_16_16(12, gg);
    ff = 0;
    for (hh=0; hh<4; hh++) {
      ff = ff+dd;
      ee = ff+60;
      for (ii=0; ii<12; ii++) {
        akQx = RexQx[kk];
        bkQx = ImxQx[kk];

        ccc2Q14 = kCosTabFfftQ14[ff];
        sss2Q14 = kCosTabFfftQ14[ee];

        if (iSign==1) {
          sss2Q14 = -sss2Q14;
        }

        RexQx[kk] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akQx, 14) -
            (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkQx, 14);
        ImxQx[kk] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akQx, 14) +
            (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkQx, 14);

        kk += 20;
      }
      kk = kk - 236;
      // Complexity: 12*(12+12) = 288 for 16x16 muls, but 12*(12+32) = 528 cycles for 16x32 muls
    }
    kk = kk - 19;
    // Complexity: 4*288+6 for 16x16 muls, but 4*528+6 cycles for 16x32 muls
  }
  // Complexity: 3*4*288+6 = 3462 for 16x16 muls, but 3*4*528+6 = 6342 cycles for 16x32 muls


  // last transform for factor of 4 */
  for (kk=0; kk<240; kk=kk+4) {
    k1 = kk + 1;
    k2 = k1 + 1;
    k3 = k2 + 1;

    akpQx = RexQx[kk] + RexQx[k2];
    akmQx = RexQx[kk] - RexQx[k2];
    ajpQx = RexQx[k1] + RexQx[k3];
    ajmQx = RexQx[k1] - RexQx[k3];
    bkpQx = ImxQx[kk] + ImxQx[k2];
    bkmQx = ImxQx[kk] - ImxQx[k2];
    bjpQx = ImxQx[k1] + ImxQx[k3];
    bjmQx = ImxQx[k1] - ImxQx[k3];
    RexQx[kk] = akpQx + ajpQx;
    ImxQx[kk] = bkpQx + bjpQx;
    ajpQx = akpQx - ajpQx;
    bjpQx = bkpQx - bjpQx;
    if (iSign < 0) {
      akpQx = akmQx + bjmQx;
      bkpQx = bkmQx - ajmQx;
      akmQx -= bjmQx;
      bkmQx += ajmQx;
    } else {
      akpQx = akmQx - bjmQx;
      bkpQx = bkmQx + ajmQx;
      akmQx += bjmQx;
      bkmQx -= ajmQx;
    }
    RexQx[k1] = akpQx;
    RexQx[k2] = ajpQx;
    RexQx[k3] = akmQx;
    ImxQx[k1] = bkpQx;
    ImxQx[k2] = bjpQx;
    ImxQx[k3] = bkmQx;
  }
  // Complexity: 60*45 = 2700 for 16x16 muls, but 60*45 = 2700 cycles for 16x32 muls

  /* permute the results to normal order */
  for (ii=0; ii<240; ii++) {
    ReDATAQx[ii]=RexQx[ii];
    ImDATAQx[ii]=ImxQx[ii];
  }
  // Complexity: 240*2=480 cycles

  for (ii=0; ii<240; ii++) {
    RexQx[ii]=ReDATAQx[kSortTabFft[ii]];
    ImxQx[ii]=ImDATAQx[kSortTabFft[ii]];
  }
  // Complexity: 240*2*2=960 cycles

  // Total complexity:
  //            16x16 16x32
  // Complexity:   10    10
  // Complexity:   99   171
  // Complexity: 2972  3932
  // Complexity: 2736  5776
  // Complexity: 5472 10080
  // Complexity: 3462  6342
  // Complexity: 2700  2700
  // Complexity:  480   480
  // Complexity:  960   960
  // =======================
  //            18891 30451
  //
  // If this FFT is called 2 time each frame, i.e. 67 times per second, it will correspond to
  // a C54 complexity of 67*18891/1000000 = 1.27 MIPS with 16x16-muls, and 67*30451/1000000 =
  // = 2.04 MIPS with 16x32-muls. Note that this routine somtimes is called 6 times during the
  // encoding of a frame, i.e. the max complexity would be 7/2*1.27 = 4.4 MIPS for the 16x16 mul case.


  return 0;
}
예제 #14
0
void WebRtcIlbcfix_Poly2Lsp(
    int16_t *a,  /* (o) A coefficients in Q12 */
    int16_t *lsp, /* (i) LSP coefficients in Q15 */
    int16_t *old_lsp /* (i) old LSP coefficients that are used if the new
                              coefficients turn out to be unstable */
                            ) {
  int16_t f[2][6]; /* f[0][] represents f1 and f[1][] represents f2 */
  int16_t *a_i_ptr, *a_10mi_ptr;
  int16_t *f1ptr, *f2ptr;
  int32_t tmpW32;
  int16_t x, y, xlow, ylow, xmid, ymid, xhigh, yhigh, xint;
  int16_t shifts, sign;
  int i, j;
  int foundFreqs;
  int fi_select;

  /*
     Calculate the two polynomials f1(z) and f2(z)
     (the sum and the diff polynomial)
     f1[0] = f2[0] = 1.0;
     f1[i+1] = a[i+1] + a[10-i] - f1[i];
     f2[i+1] = a[i+1] - a[10-i] - f1[i];
  */

  a_i_ptr = a + 1;
  a_10mi_ptr = a + 10;
  f1ptr = f[0];
  f2ptr = f[1];
  (*f1ptr) = 1024; /* 1.0 in Q10 */
  (*f2ptr) = 1024; /* 1.0 in Q10 */
  for (i = 0; i < 5; i++) {
    (*(f1ptr+1)) = (int16_t)(WEBRTC_SPL_RSHIFT_W32(((int32_t)(*a_i_ptr)+(*a_10mi_ptr)), 2) - (*f1ptr));
    (*(f2ptr+1)) = (int16_t)(WEBRTC_SPL_RSHIFT_W32(((int32_t)(*a_i_ptr)-(*a_10mi_ptr)), 2) + (*f2ptr));
    a_i_ptr++;
    a_10mi_ptr--;
    f1ptr++;
    f2ptr++;
  }

  /*
    find the LSPs using the Chebychev pol. evaluation
  */

  fi_select = 0; /* selector between f1 and f2, start with f1 */

  foundFreqs = 0;

  xlow = WebRtcIlbcfix_kCosGrid[0];
  ylow = WebRtcIlbcfix_Chebyshev(xlow, f[fi_select]);

  /*
     Iterate until all the 10 LSP's have been found or
     all the grid points have been tried. If the 10 LSP's can
     not be found, set the LSP vector to previous LSP
  */

  for (j = 1; j < COS_GRID_POINTS && foundFreqs < 10; j++) {
    xhigh = xlow;
    yhigh = ylow;
    xlow = WebRtcIlbcfix_kCosGrid[j];
    ylow = WebRtcIlbcfix_Chebyshev(xlow, f[fi_select]);

    if (WEBRTC_SPL_MUL_16_16(ylow, yhigh) <= 0) {
      /* Run 4 times to reduce the interval */
      for (i = 0; i < 4; i++) {
        /* xmid =(xlow + xhigh)/2 */
        xmid = WEBRTC_SPL_RSHIFT_W16(xlow, 1) + WEBRTC_SPL_RSHIFT_W16(xhigh, 1);
        ymid = WebRtcIlbcfix_Chebyshev(xmid, f[fi_select]);

        if (WEBRTC_SPL_MUL_16_16(ylow, ymid) <= 0) {
          yhigh = ymid;
          xhigh = xmid;
        } else {
          ylow = ymid;
          xlow = xmid;
        }
      }

      /*
        Calculater xint by linear interpolation:
        xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow);
      */

      x = xhigh - xlow;
      y = yhigh - ylow;

      if (y == 0) {
        xint = xlow;
      } else {
        sign = y;
        y = WEBRTC_SPL_ABS_W16(y);
        shifts = (int16_t)WebRtcSpl_NormW32(y)-16;
        y = WEBRTC_SPL_LSHIFT_W16(y, shifts);
        y = (int16_t)WebRtcSpl_DivW32W16(536838144, y); /* 1/(yhigh-ylow) */

        tmpW32 = WEBRTC_SPL_MUL_16_16_RSFT(x, y, (19-shifts));

        /* y=(xhigh-xlow)/(yhigh-ylow) */
        y = (int16_t)(tmpW32&0xFFFF);

        if (sign < 0) {
          y = -y;
        }
        /* tmpW32 = ylow*(xhigh-xlow)/(yhigh-ylow) */
        tmpW32 = WEBRTC_SPL_MUL_16_16_RSFT(ylow, y, 10);
        xint = xlow-(int16_t)(tmpW32&0xFFFF);
      }

      /* Store the calculated lsp */
      lsp[foundFreqs] = (int16_t)xint;
      foundFreqs++;

      /* if needed, set xlow and ylow for next recursion */
      if (foundFreqs<10) {
        xlow = xint;
        /* Swap between f1 and f2 (f[0][] and f[1][]) */
        fi_select = ((fi_select+1)&0x1);

        ylow = WebRtcIlbcfix_Chebyshev(xlow, f[fi_select]);
      }
    }
  }

  /* Check if M roots found, if not then use the old LSP */
  if (foundFreqs < 10) {
    WEBRTC_SPL_MEMCPY_W16(lsp, old_lsp, 10);
  }
  return;
}
예제 #15
0
void WebRtcIsacfix_GetVars(const WebRtc_Word16 *input, const WebRtc_Word16 *pitchGains_Q12,
                           WebRtc_UWord32 *oldEnergy, WebRtc_Word16 *varscale)
{
  int k;
  WebRtc_UWord32 nrgQ[4];
  WebRtc_Word16 nrgQlog[4];
  WebRtc_Word16 tmp16, chng1, chng2, chng3, chng4, tmp, chngQ, oldNrgQlog, pgQ, pg3;
  WebRtc_Word32 expPg32;
  WebRtc_Word16 expPg, divVal;
  WebRtc_Word16 tmp16_1, tmp16_2;

  /* Calculate energies of first and second frame halfs */
  nrgQ[0]=0;
  for (k = QLOOKAHEAD/2; k < (FRAMESAMPLES/4 + QLOOKAHEAD) / 2; k++) {
    nrgQ[0] +=WEBRTC_SPL_MUL_16_16(input[k],input[k]);
  }
  nrgQ[1]=0;
  for ( ; k < (FRAMESAMPLES/2 + QLOOKAHEAD) / 2; k++) {
    nrgQ[1] +=WEBRTC_SPL_MUL_16_16(input[k],input[k]);
  }
  nrgQ[2]=0;
  for ( ; k < (WEBRTC_SPL_MUL_16_16(FRAMESAMPLES, 3)/4 + QLOOKAHEAD) / 2; k++) {
    nrgQ[2] +=WEBRTC_SPL_MUL_16_16(input[k],input[k]);
  }
  nrgQ[3]=0;
  for ( ; k < (FRAMESAMPLES + QLOOKAHEAD) / 2; k++) {
    nrgQ[3] +=WEBRTC_SPL_MUL_16_16(input[k],input[k]);
  }

  for ( k=0; k<4; k++) {
    nrgQlog[k] = (WebRtc_Word16)log2_Q8_LPC(nrgQ[k]); /* log2(nrgQ) */
  }
  oldNrgQlog = (WebRtc_Word16)log2_Q8_LPC(*oldEnergy);

  /* Calculate average level change */
  chng1 = WEBRTC_SPL_ABS_W16(nrgQlog[3]-nrgQlog[2]);
  chng2 = WEBRTC_SPL_ABS_W16(nrgQlog[2]-nrgQlog[1]);
  chng3 = WEBRTC_SPL_ABS_W16(nrgQlog[1]-nrgQlog[0]);
  chng4 = WEBRTC_SPL_ABS_W16(nrgQlog[0]-oldNrgQlog);
  tmp = chng1+chng2+chng3+chng4;
  chngQ = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp, kChngFactor, 10); /* Q12 */
  chngQ += 2926; /* + 1.0/1.4 in Q12 */

  /* Find average pitch gain */
  pgQ = 0;
  for (k=0; k<4; k++)
  {
    pgQ += pitchGains_Q12[k];
  }

  pg3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(pgQ, pgQ,11); /* pgQ in Q(12+2)=Q14. Q14*Q14>>11 => Q17 */
  pg3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(pgQ, pg3,13); /* Q17*Q14>>13 =>Q18  */
  pg3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(pg3, kMulPitchGain ,5); /* Q10  kMulPitchGain = -25 = -200 in Q-3. */

  tmp16=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(kExp2,pg3,13);/* Q13*Q10>>13 => Q10*/
  if (tmp16<0) {
    tmp16_2 = (0x0400 | (tmp16 & 0x03FF));
    tmp16_1 = (WEBRTC_SPL_RSHIFT_W16((WebRtc_UWord16)(tmp16 ^ 0xFFFF), 10)-3); /* Gives result in Q14 */
    if (tmp16_1<0)
      expPg=(WebRtc_Word16) -WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1);
    else
      expPg=(WebRtc_Word16) -WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1);
  } else
    expPg = (WebRtc_Word16) -16384; /* 1 in Q14, since 2^0=1 */

  expPg32 = (WebRtc_Word32)WEBRTC_SPL_LSHIFT_W16((WebRtc_Word32)expPg, 8); /* Q22 */
  divVal = WebRtcSpl_DivW32W16ResW16(expPg32, chngQ); /* Q22/Q12=Q10 */

  tmp16=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(kExp2,divVal,13);/* Q13*Q10>>13 => Q10*/
  if (tmp16<0) {
    tmp16_2 = (0x0400 | (tmp16 & 0x03FF));
    tmp16_1 = (WEBRTC_SPL_RSHIFT_W16((WebRtc_UWord16)(tmp16 ^ 0xFFFF), 10)-3); /* Gives result in Q14 */
    if (tmp16_1<0)
      expPg=(WebRtc_Word16) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1);
    else
      expPg=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1);
  } else
    expPg = (WebRtc_Word16) 16384; /* 1 in Q14, since 2^0=1 */

  *varscale = expPg-1;
  *oldEnergy = nrgQ[3];
}
예제 #16
0
void WebRtcIlbcfix_Refiner(
    WebRtc_Word16 *updStartPos, /* (o) updated start point (Q-2) */
    WebRtc_Word16 *idata,   /* (i) original data buffer */
    WebRtc_Word16 idatal,   /* (i) dimension of idata */
    WebRtc_Word16 centerStartPos, /* (i) beginning center segment */
    WebRtc_Word16 estSegPos,  /* (i) estimated beginning other segment (Q-2) */
    WebRtc_Word16 *surround,  /* (i/o) The contribution from this sequence
                                           summed with earlier contributions */
    WebRtc_Word16 gain    /* (i) Gain to use for this sequence */
                           ){
  WebRtc_Word16 estSegPosRounded,searchSegStartPos,searchSegEndPos,corrdim;
  WebRtc_Word16 tloc,tloc2,i,st,en,fraction;

  WebRtc_Word32 maxtemp, scalefact;
  WebRtc_Word16 *filtStatePtr, *polyPtr;
  /* Stack based */
  WebRtc_Word16 filt[7];
  WebRtc_Word32 corrVecUps[ENH_CORRDIM*ENH_UPS0];
  WebRtc_Word32 corrVecTemp[ENH_CORRDIM];
  WebRtc_Word16 vect[ENH_VECTL];
  WebRtc_Word16 corrVec[ENH_CORRDIM];

  /* defining array bounds */

  estSegPosRounded=WEBRTC_SPL_RSHIFT_W16((estSegPos - 2),2);

  searchSegStartPos=estSegPosRounded-ENH_SLOP;

  if (searchSegStartPos<0) {
    searchSegStartPos=0;
  }
  searchSegEndPos=estSegPosRounded+ENH_SLOP;

  if(searchSegEndPos+ENH_BLOCKL >= idatal) {
    searchSegEndPos=idatal-ENH_BLOCKL-1;
  }
  corrdim=searchSegEndPos-searchSegStartPos+1;

  /* compute upsampled correlation and find
     location of max */

  WebRtcIlbcfix_MyCorr(corrVecTemp,idata+searchSegStartPos,
                       (WebRtc_Word16)(corrdim+ENH_BLOCKL-1),idata+centerStartPos,ENH_BLOCKL);

  /* Calculate the rescaling factor for the correlation in order to
     put the correlation in a WebRtc_Word16 vector instead */
  maxtemp=WebRtcSpl_MaxAbsValueW32(corrVecTemp, (WebRtc_Word16)corrdim);

  scalefact=WebRtcSpl_GetSizeInBits(maxtemp)-15;

  if (scalefact>0) {
    for (i=0;i<corrdim;i++) {
      corrVec[i]=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(corrVecTemp[i], scalefact);
    }
  } else {
    for (i=0;i<corrdim;i++) {
      corrVec[i]=(WebRtc_Word16)corrVecTemp[i];
    }
  }
  /* In order to guarantee that all values are initialized */
  for (i=corrdim;i<ENH_CORRDIM;i++) {
    corrVec[i]=0;
  }

  /* Upsample the correlation */
  WebRtcIlbcfix_EnhUpsample(corrVecUps,corrVec);

  /* Find maximum */
  tloc=WebRtcSpl_MaxIndexW32(corrVecUps, (WebRtc_Word16) (ENH_UPS0*corrdim));

  /* make vector can be upsampled without ever running outside
     bounds */
  *updStartPos = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(searchSegStartPos,4) + tloc + 4;

  tloc2 = WEBRTC_SPL_RSHIFT_W16((tloc+3), 2);

  st=searchSegStartPos+tloc2-ENH_FL0;

  /* initialize the vector to be filtered, stuff with zeros
     when data is outside idata buffer */
  if(st<0){
    WebRtcSpl_MemSetW16(vect, 0, (WebRtc_Word16)(-st));
    WEBRTC_SPL_MEMCPY_W16(&vect[-st], idata, (ENH_VECTL+st));
  }
  else{
    en=st+ENH_VECTL;

    if(en>idatal){
      WEBRTC_SPL_MEMCPY_W16(vect, &idata[st],
                            (ENH_VECTL-(en-idatal)));
      WebRtcSpl_MemSetW16(&vect[ENH_VECTL-(en-idatal)], 0,
                          (WebRtc_Word16)(en-idatal));
    }
    else {
      WEBRTC_SPL_MEMCPY_W16(vect, &idata[st], ENH_VECTL);
    }
  }
  /* Calculate which of the 4 fractions to use */
  fraction=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16(tloc2,ENH_UPS0)-tloc;

  /* compute the segment (this is actually a convolution) */

  filtStatePtr = filt + 6;
  polyPtr = (WebRtc_Word16*)WebRtcIlbcfix_kEnhPolyPhaser[fraction];
  for (i=0;i<7;i++) {
    *filtStatePtr-- = *polyPtr++;
  }

  WebRtcSpl_FilterMAFastQ12(
      &vect[6], vect, filt,
      ENH_FLO_MULT2_PLUS1, ENH_BLOCKL);

  /* Add the contribution from this vector (scaled with gain) to the total surround vector */
  WebRtcSpl_AddAffineVectorToVector(
      surround, vect, gain,
      (WebRtc_Word32)32768, 16, ENH_BLOCKL);

  return;
}
예제 #17
0
void WebRtcIsacfix_PitchFilterGains(const int16_t* indatQ0,
                                    PitchFiltstr* pfp,
                                    int16_t* lagsQ7,
                                    int16_t* gainsQ12) {
  int  k, n, m, ind, pos, pos3QQ;

  int16_t ubufQQ[PITCH_INTBUFFSIZE];
  int16_t oldLagQ7, lagdeltaQ7, curLagQ7;
  const int16_t* fracoeffQQ = NULL;
  int16_t scale;
  int16_t cnt = 0, frcQQ, indW16 = 0, tmpW16;
  int32_t tmpW32, tmp2W32, csum1QQ, esumxQQ;

  // Set up buffer and states.
  memcpy(ubufQQ, pfp->ubufQQ, sizeof(pfp->ubufQQ));
  oldLagQ7 = pfp->oldlagQ7;

  // No interpolation if pitch lag step is big.
  if ((WEBRTC_SPL_MUL_16_16_RSFT(lagsQ7[0], 3, 1) < oldLagQ7) ||
      (lagsQ7[0] > WEBRTC_SPL_MUL_16_16_RSFT(oldLagQ7, 3, 1))) {
    oldLagQ7 = lagsQ7[0];
  }

  ind = 0;
  pos = ind + PITCH_BUFFSIZE;
  scale = 0;
  for (k = 0; k < PITCH_SUBFRAMES; k++) {

    // Calculate interpolation steps.
    lagdeltaQ7 = lagsQ7[k] - oldLagQ7;
    lagdeltaQ7 = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
                   lagdeltaQ7, kDivFactor, 15);
    curLagQ7 = oldLagQ7;
    oldLagQ7 = lagsQ7[k];

    csum1QQ = 1;
    esumxQQ = 1;

    // Same as function WebRtcIsacfix_PitchFilter(), we break the pitch
    // filtering into two for-loops (5 x 12) below.
    for (cnt = 0; cnt < kSegments; cnt++) {
      // Update parameters for each segment.
      curLagQ7 += lagdeltaQ7;
      indW16 = (int16_t)CalcLrIntQ(curLagQ7, 7);
      tmpW16 = WEBRTC_SPL_LSHIFT_W16(indW16, 7);
      tmpW16 -= curLagQ7;
      frcQQ = WEBRTC_SPL_RSHIFT_W16(tmpW16, 4);
      frcQQ += 4;

      if (frcQQ == PITCH_FRACS) {
        frcQQ = 0;
      }
      fracoeffQQ = kIntrpCoef[frcQQ];

      pos3QQ = pos - (indW16 + 4);

      for (n = 0; n < PITCH_SUBFRAME_LEN / kSegments; n++) {
        // Filter to get fractional pitch.

        tmpW32 = 0;
        for (m = 0; m < PITCH_FRACORDER; m++) {
          tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQ[pos3QQ + m], fracoeffQQ[m]);
        }

        // Subtract from input and update buffer.
        ubufQQ[pos] = indatQ0[ind];

        tmp2W32 = WEBRTC_SPL_MUL_16_32_RSFT14(indatQ0[ind], tmpW32);
        tmpW32 += 8192;
        tmpW16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32, 14);
        tmpW32 = WEBRTC_SPL_MUL_16_16(tmpW16, tmpW16);

        if ((tmp2W32 > 1073700000) || (csum1QQ > 1073700000) ||
            (tmpW32 > 1073700000) || (esumxQQ > 1073700000)) {  // 2^30
          scale++;
          csum1QQ = WEBRTC_SPL_RSHIFT_W32(csum1QQ, 1);
          esumxQQ = WEBRTC_SPL_RSHIFT_W32(esumxQQ, 1);
        }
        tmp2W32 = WEBRTC_SPL_RSHIFT_W32(tmp2W32, scale);
        csum1QQ += tmp2W32;
        tmpW32 = WEBRTC_SPL_RSHIFT_W32(tmpW32, scale);
        esumxQQ += tmpW32;

        ind++;
        pos++;
        pos3QQ++;
      }
    }

    if (csum1QQ < esumxQQ) {
      tmp2W32 = WebRtcSpl_DivResultInQ31(csum1QQ, esumxQQ);

      // Gain should be half the correlation.
      tmpW32 = WEBRTC_SPL_RSHIFT_W32(tmp2W32, 20);
    } else {
      tmpW32 = 4096;
    }
    gainsQ12[k] = (int16_t)WEBRTC_SPL_SAT(PITCH_MAX_GAIN_Q12, tmpW32, 0);
  }

  // Export buffer and states.
  memcpy(pfp->ubufQQ, ubufQQ + PITCH_FRAME_LEN, sizeof(pfp->ubufQQ));
  pfp->oldlagQ7 = lagsQ7[PITCH_SUBFRAMES - 1];
  pfp->oldgainQ12 = gainsQ12[PITCH_SUBFRAMES - 1];

}