Пример #1
0
/* The conversion is implemented by the step-down algorithm */
void WebRtcSpl_AToK_JSK(
    WebRtc_Word16 *a16, /* Q11 */
    WebRtc_Word16 useOrder,
    WebRtc_Word16 *k16  /* Q15 */
                        )
{
  int m, k;
  WebRtc_Word32 tmp32[MAX_AR_MODEL_ORDER];
  WebRtc_Word32 tmp32b;
  WebRtc_Word32 tmp_inv_denum32;
  WebRtc_Word16 tmp_inv_denum16;

  k16[useOrder-1]= WEBRTC_SPL_LSHIFT_W16(a16[useOrder], 4); //Q11<<4 => Q15

  for (m=useOrder-1; m>0; m--) {
    tmp_inv_denum32 = ((WebRtc_Word32) 1073741823) - WEBRTC_SPL_MUL_16_16(k16[m], k16[m]); // (1 - k^2) in Q30
    tmp_inv_denum16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp_inv_denum32, 15); // (1 - k^2) in Q15

    for (k=1; k<=m; k++) {
      tmp32b = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)a16[k], 16) -
          WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(k16[m], a16[m-k+1]), 1);

      tmp32[k] = WebRtcSpl_DivW32W16(tmp32b, tmp_inv_denum16); //Q27/Q15 = Q12
    }

    for (k=1; k<m; k++) {
      a16[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32[k], 1); //Q12>>1 => Q11
    }

    tmp32[m] = WEBRTC_SPL_SAT(4092, tmp32[m], -4092);
    k16[m-1] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(tmp32[m], 3); //Q12<<3 => Q15
  }

  return;
}
Пример #2
0
int WebRtcNetEQ_RTCPUpdate(WebRtcNetEQ_RTCP_t *RTCP_inst, uint16_t uw16_seqNo,
                           uint32_t uw32_timeStamp, uint32_t uw32_recTime)
{
    int16_t w16_SeqDiff;
    int32_t w32_TimeDiff;
    int32_t w32_JitterDiff;

    /*
     * Update number of received packets, and largest packet number received.
     */
    RTCP_inst->received++;
    w16_SeqDiff = uw16_seqNo - RTCP_inst->max_seq;
    if (w16_SeqDiff >= 0)
    {
        if (uw16_seqNo < RTCP_inst->max_seq)
        {
            /* Wrap around detected */
            RTCP_inst->cycles++;
        }
        RTCP_inst->max_seq = uw16_seqNo;
    }

    /* Calculate Jitter, and update previous timestamps */
    /* Note that the value in RTCP_inst->jitter is in Q4. */
    if (RTCP_inst->received > 1)
    {
        w32_TimeDiff = (uw32_recTime - (uw32_timeStamp - RTCP_inst->transit));
        w32_TimeDiff = WEBRTC_SPL_ABS_W32(w32_TimeDiff);
        w32_JitterDiff = WEBRTC_SPL_LSHIFT_W16(w32_TimeDiff, 4) - RTCP_inst->jitter;
        RTCP_inst->jitter = RTCP_inst->jitter + WEBRTC_SPL_RSHIFT_W32((w32_JitterDiff + 8), 4);
    }
    RTCP_inst->transit = (uw32_timeStamp - uw32_recTime);
    return 0;
}
Пример #3
0
void WebRtcIlbcfix_Lsp2Lsf(
    WebRtc_Word16 *lsp, /* (i) lsp vector -1...+1 in Q15 */
    WebRtc_Word16 *lsf, /* (o) Lsf vector 0...Pi in Q13
                           (ordered, so that lsf[i]<lsf[i+1]) */
    WebRtc_Word16 m  /* (i) Number of coefficients */
                           )
{
  WebRtc_Word16 i, k;
  WebRtc_Word16 diff; /* diff between table value and desired value (Q15) */
  WebRtc_Word16 freq; /* lsf/(2*pi) (Q16) */
  WebRtc_Word16 *lspPtr, *lsfPtr, *cosTblPtr;
  WebRtc_Word16 tmp;

  /* set the index to maximum index value in WebRtcIlbcfix_kCos */
  k = 63;

  /*
     Start with the highest LSP and then work the way down
     For each LSP the lsf is calculated by first order approximation
     of the acos(x) function
  */
  lspPtr = &lsp[9];
  lsfPtr = &lsf[9];
  cosTblPtr=(WebRtc_Word16*)&WebRtcIlbcfix_kCos[k];
  for(i=m-1; i>=0; i--)
  {
    /*
       locate value in the table, which is just above lsp[i],
       basically an approximation to acos(x)
    */
    while( (((WebRtc_Word32)(*cosTblPtr)-(*lspPtr)) < 0)&&(k>0) )
    {
      k-=1;
      cosTblPtr--;
    }

    /* Calculate diff, which is used in the linear approximation of acos(x) */
    diff = (*lspPtr)-(*cosTblPtr);

    /*
       The linear approximation of acos(lsp[i]) :
       acos(lsp[i])= k*512 + (WebRtcIlbcfix_kAcosDerivative[ind]*offset >> 11)
    */

    /* tmp (linear offset) in Q16 */
    tmp = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIlbcfix_kAcosDerivative[k],diff, 11);

    /* freq in Q16 */
    freq = (WebRtc_Word16)WEBRTC_SPL_LSHIFT_W16(k,9)+tmp;

    /* lsf = freq*2*pi */
    (*lsfPtr) = (WebRtc_Word16)(((WebRtc_Word32)freq*25736)>>15);

    lsfPtr--;
    lspPtr--;
  }

  return;
}
Пример #4
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);

}
Пример #5
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);

}
Пример #6
0
static __inline WebRtc_Word32 log2_Q8_LPC( WebRtc_UWord32 x ) {

  WebRtc_Word32 zeros, lg2;
  WebRtc_Word16 frac;

  zeros=WebRtcSpl_NormU32(x);
  frac=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(((WebRtc_UWord32)WEBRTC_SPL_LSHIFT_W32(x, zeros)&0x7FFFFFFF), 23);

  /* log2(x) */

  lg2= (WEBRTC_SPL_LSHIFT_W16((31-zeros), 8)+frac);
  return lg2;

}
Пример #7
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
}
Пример #8
0
static __inline int32_t log2_Q8_LPC( uint32_t x ) {

  int32_t zeros, lg2;
  int16_t frac;

  zeros=WebRtcSpl_NormU32(x);
  frac=(int16_t)WEBRTC_SPL_RSHIFT_W32(((uint32_t)WEBRTC_SPL_LSHIFT_W32(x, zeros)&0x7FFFFFFF), 23);

  /* log2(x) */

  lg2= (WEBRTC_SPL_LSHIFT_W16((31-zeros), 8)+frac);
  return lg2;

}
Пример #9
0
void WebRtcSpl_LpcToReflCoef(int16_t* a16, int use_order, int16_t* k16)
{
    int m, k;
    int32_t tmp32[SPL_LPC_TO_REFL_COEF_MAX_AR_MODEL_ORDER];
    int32_t tmp_inv_denom32;
    int16_t tmp_inv_denom16;

    k16[use_order - 1] = WEBRTC_SPL_LSHIFT_W16(a16[use_order], 3); //Q12<<3 => Q15
    for (m = use_order - 1; m > 0; m--)
    {
        // (1 - k^2) in Q30
        tmp_inv_denom32 = ((int32_t)1073741823) - WEBRTC_SPL_MUL_16_16(k16[m], k16[m]);
        // (1 - k^2) in Q15
        tmp_inv_denom16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp_inv_denom32, 15);

        for (k = 1; k <= m; k++)
        {
            // tmp[k] = (a[k] - RC[m] * a[m-k+1]) / (1.0 - RC[m]*RC[m]);

            // [Q12<<16 - (Q15*Q12)<<1] = [Q28 - Q28] = Q28
            tmp32[k] = WEBRTC_SPL_LSHIFT_W32((int32_t)a16[k], 16)
                    - WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(k16[m], a16[m-k+1]), 1);

            tmp32[k] = WebRtcSpl_DivW32W16(tmp32[k], tmp_inv_denom16); //Q28/Q15 = Q13
        }

        for (k = 1; k < m; k++)
        {
            a16[k] = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp32[k], 1); //Q13>>1 => Q12
        }

        tmp32[m] = WEBRTC_SPL_SAT(8191, tmp32[m], -8191);
        k16[m - 1] = (int16_t)WEBRTC_SPL_LSHIFT_W32(tmp32[m], 2); //Q13<<2 => Q15
    }
    return;
}
Пример #10
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];
}
Пример #11
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];

}
Пример #12
0
WebRtc_Word16 WebRtcVad_FindMinimum(VadInstT* inst,
                                    WebRtc_Word16 x,
                                    int n)
{
    int i, j, k, II = -1, offset;
    WebRtc_Word16 meanV, alpha;
    WebRtc_Word32 tmp32, tmp32_1;
    WebRtc_Word16 *valptr, *idxptr, *p1, *p2, *p3;

    // Offset to beginning of the 16 minimum values in memory
    offset = WEBRTC_SPL_LSHIFT_W16(n, 4);

    // Pointer to memory for the 16 minimum values and the age of each value
    idxptr = &inst->index_vector[offset];
    valptr = &inst->low_value_vector[offset];

    // Each value in low_value_vector is getting 1 loop older.
    // Update age of each value in indexVal, and remove old values.
    for (i = 0; i < 16; i++)
    {
        p3 = idxptr + i;
        if (*p3 != 100)
        {
            *p3 += 1;
        } else
        {
            p1 = valptr + i + 1;
            p2 = p3 + 1;
            for (j = i; j < 16; j++)
            {
                *(valptr + j) = *p1++;
                *(idxptr + j) = *p2++;
            }
            *(idxptr + 15) = 101;
            *(valptr + 15) = 10000;
        }
    }

    // Check if x smaller than any of the values in low_value_vector.
    // If so, find position.
    if (x < *(valptr + 7))
    {
        if (x < *(valptr + 3))
        {
            if (x < *(valptr + 1))
            {
                if (x < *valptr)
                {
                    II = 0;
                } else
                {
                    II = 1;
                }
            } else if (x < *(valptr + 2))
            {
                II = 2;
            } else
            {
                II = 3;
            }
        } else if (x < *(valptr + 5))
        {
            if (x < *(valptr + 4))
            {
                II = 4;
            } else
            {
                II = 5;
            }
        } else if (x < *(valptr + 6))
        {
            II = 6;
        } else
        {
            II = 7;
        }
    } else if (x < *(valptr + 15))
    {
        if (x < *(valptr + 11))
        {
            if (x < *(valptr + 9))
            {
                if (x < *(valptr + 8))
                {
                    II = 8;
                } else
                {
                    II = 9;
                }
            } else if (x < *(valptr + 10))
            {
                II = 10;
            } else
            {
                II = 11;
            }
        } else if (x < *(valptr + 13))
        {
            if (x < *(valptr + 12))
            {
                II = 12;
            } else
            {
                II = 13;
            }
        } else if (x < *(valptr + 14))
        {
            II = 14;
        } else
        {
            II = 15;
        }
    }

    // Put new min value on right position and shift bigger values up
    if (II > -1)
    {
        for (i = 15; i > II; i--)
        {
            k = i - 1;
            *(valptr + i) = *(valptr + k);
            *(idxptr + i) = *(idxptr + k);
        }
        *(valptr + II) = x;
        *(idxptr + II) = 1;
    }

    meanV = 0;
    if ((inst->frame_counter) > 4)
    {
        j = 5;
    } else
    {
        j = inst->frame_counter;
    }

    if (j > 2)
    {
        meanV = *(valptr + 2);
    } else if (j > 0)
    {
        meanV = *valptr;
    } else
    {
        meanV = 1600;
    }

    if (inst->frame_counter > 0)
    {
        if (meanV < inst->mean_value[n])
        {
            alpha = (WebRtc_Word16)ALPHA1; // 0.2 in Q15
        } else
        {
            alpha = (WebRtc_Word16)ALPHA2; // 0.99 in Q15
        }
    } else
    {
        alpha = 0;
    }

    tmp32 = WEBRTC_SPL_MUL_16_16((alpha+1), inst->mean_value[n]);
    tmp32_1 = WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_WORD16_MAX - alpha, meanV);
    tmp32 += tmp32_1;
    tmp32 += 16384;
    inst->mean_value[n] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 15);

    return inst->mean_value[n];
}
Пример #13
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;
}