示例#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
void WebRtcVad_Allpass(WebRtc_Word16 *in_vector,
                       WebRtc_Word16 *out_vector,
                       WebRtc_Word16 filter_coefficients,
                       int vector_length,
                       WebRtc_Word16 *filter_state)
{
    // The filter can only cause overflow (in the w16 output variable)
    // if more than 4 consecutive input numbers are of maximum value and
    // has the the same sign as the impulse responses first taps.
    // First 6 taps of the impulse response: 0.6399 0.5905 -0.3779
    // 0.2418 -0.1547 0.0990

    int n;
    WebRtc_Word16 tmp16;
    WebRtc_Word32 tmp32, in32, state32;

    state32 = WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)(*filter_state)), 16); // Q31

    for (n = 0; n < vector_length; n++)
    {

        tmp32 = state32 + WEBRTC_SPL_MUL_16_16(filter_coefficients, (*in_vector));
        tmp16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp32, 16);
        *out_vector++ = tmp16;
        in32 = WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)(*in_vector)), 14);
        state32 = in32 - WEBRTC_SPL_MUL_16_16(filter_coefficients, tmp16);
        state32 = WEBRTC_SPL_LSHIFT_W32(state32, 1);
        in_vector += 2;
    }

    *filter_state = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(state32, 16);
}
示例#3
0
/* Filter ar_g_Q0[] and ar_f_Q0[] through an AR filter with coefficients
 * cth_Q15[] and sth_Q15[].
 */
void WebRtcIsacfix_FilterArLoop(int16_t* ar_g_Q0,     // Input samples
                                int16_t* ar_f_Q0,     // Input samples
                                int16_t* cth_Q15,     // Filter coefficients
                                int16_t* sth_Q15,     // Filter coefficients
                                int16_t order_coef) { // order of the filter
  int n = 0;

  for (n = 0; n < HALF_SUBFRAMELEN - 1; n++) {
    int k = 0;
    int16_t tmpAR = 0;
    int32_t tmp32 = 0;
    int32_t tmp32_2 = 0;

    tmpAR = ar_f_Q0[n + 1];
    for (k = order_coef - 1; k >= 0; k--) {
      tmp32 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(cth_Q15[k], tmpAR))
              - (WEBRTC_SPL_MUL_16_16(sth_Q15[k], ar_g_Q0[k])) + 16384), 15);
      tmp32_2 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(sth_Q15[k], tmpAR))
                + (WEBRTC_SPL_MUL_16_16(cth_Q15[k], ar_g_Q0[k])) + 16384), 15);
      tmpAR   = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp32);
      ar_g_Q0[k + 1] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp32_2);
    }
    ar_f_Q0[n + 1] = tmpAR;
    ar_g_Q0[0] = tmpAR;
  }
}
示例#4
0
void WebRtcIsacfix_PitchFilterCore(int loopNumber,
                                   int16_t gain,
                                   int index,
                                   int16_t sign,
                                   int16_t* inputState,
                                   int16_t* outputBuf2,
                                   const int16_t* coefficient,
                                   int16_t* inputBuf,
                                   int16_t* outputBuf,
                                   int* index2) {
  int i = 0, j = 0;  /* Loop counters. */
  int16_t* ubufQQpos2 = &outputBuf2[PITCH_BUFFSIZE - (index + 2)];
  int16_t tmpW16 = 0;

  for (i = 0; i < loopNumber; i++) {
    int32_t tmpW32 = 0;

    /* Filter to get fractional pitch. */
    for (j = 0; j < PITCH_FRACORDER; j++) {
      tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQpos2[*index2 + j], coefficient[j]);
    }

    /* Saturate to avoid overflow in tmpW16. */
    tmpW32 = WEBRTC_SPL_SAT(536862719, tmpW32, -536879104);
    tmpW32 += 8192;
    tmpW16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32, 14);

    /* Shift low pass filter state. */
    memmove(&inputState[1], &inputState[0],
            (PITCH_DAMPORDER - 1) * sizeof(int16_t));
    inputState[0] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
                      gain, tmpW16, 12);

    /* Low pass filter. */
    tmpW32 = 0;
    /* TODO(kma): Define a static inline function WebRtcSpl_DotProduct()
       in spl_inl.h to replace this and other similar loops. */
    for (j = 0; j < PITCH_DAMPORDER; j++) {
      tmpW32 += WEBRTC_SPL_MUL_16_16(inputState[j], kDampFilter[j]);
    }

    /* Saturate to avoid overflow in tmpW16. */
    tmpW32 = WEBRTC_SPL_SAT(1073725439, tmpW32, -1073758208);
    tmpW32 += 16384;
    tmpW16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32, 15);

    /* Subtract from input and update buffer. */
    tmpW32 = inputBuf[*index2] - WEBRTC_SPL_MUL_16_16(sign, tmpW16);
    outputBuf[*index2] = WebRtcSpl_SatW32ToW16(tmpW32);
    tmpW32 = inputBuf[*index2] + outputBuf[*index2];
    outputBuf2[*index2 + PITCH_BUFFSIZE] = WebRtcSpl_SatW32ToW16(tmpW32);

    (*index2)++;
  }
}
示例#5
0
void WebRtcIlbcfix_CbMemEnergy(int16_t range, int16_t * CB,	/* (i) The CB memory (1:st section) */
			       int16_t * filteredCB,	/* (i) The filtered CB memory (2:nd section) */
			       int16_t lMem,	/* (i) Length of the CB memory */
			       int16_t lTarget,	/* (i) Length of the target vector */
			       int16_t * energyW16,	/* (o) Energy in the CB vectors */
			       int16_t * energyShifts,	/* (o) Shift value of the energy */
			       int16_t scale,	/* (i) The scaling of all energy values */
			       int16_t base_size	/* (i) Index to where the energy values should be stored */
    )
{
	int16_t *ppi, *ppo, *pp;
	int32_t energy, tmp32;

	/* Compute the energy and store it in a vector. Also the
	 * corresponding shift values are stored. The energy values
	 * are reused in all three stages. */

	/* Calculate the energy in the first block of 'lTarget' sampels. */
	ppi = CB + lMem - lTarget - 1;
	ppo = CB + lMem - 1;

	pp = CB + lMem - lTarget;
	energy = WebRtcSpl_DotProductWithScale(pp, pp, lTarget, scale);

	/* Normalize the energy and store the number of shifts */
	energyShifts[0] = (int16_t) WebRtcSpl_NormW32(energy);
	tmp32 = WEBRTC_SPL_LSHIFT_W32(energy, energyShifts[0]);
	energyW16[0] = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32, 16);

	/* Compute the energy of the rest of the cb memory
	 * by step wise adding and subtracting the next
	 * sample and the last sample respectively. */
	WebRtcIlbcfix_CbMemEnergyCalc(energy, range, ppi, ppo, energyW16,
				      energyShifts, scale, 0);

	/* Next, precompute the energy values for the filtered cb section */
	pp = filteredCB + lMem - lTarget;

	energy = WebRtcSpl_DotProductWithScale(pp, pp, lTarget, scale);

	/* Normalize the energy and store the number of shifts */
	energyShifts[base_size] = (int16_t) WebRtcSpl_NormW32(energy);
	tmp32 = WEBRTC_SPL_LSHIFT_W32(energy, energyShifts[base_size]);
	energyW16[base_size] = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32, 16);

	ppi = filteredCB + lMem - 1 - lTarget;
	ppo = filteredCB + lMem - 1;

	WebRtcIlbcfix_CbMemEnergyCalc(energy, range, ppi, ppo, energyW16,
				      energyShifts, scale, base_size);
}
示例#6
0
/* Autocorrelation function in fixed point. NOTE! Different from SPLIB-version in how it scales the signal. */
int WebRtcIsacfix_AutocorrFix(
    WebRtc_Word32          *r,
    const WebRtc_Word16 *x,
    WebRtc_Word16          N,
    WebRtc_Word16          order,
    WebRtc_Word16          *scale)
{
  int  j, i;
  WebRtc_Word16  scaling;
  WebRtc_Word32 sum, prod, newsum;
  G_CONST WebRtc_Word16    *xptr1;
  G_CONST WebRtc_Word16    *xptr2;

  sum=0;
  scaling=0;
  /* Calculate r[0] and how much scaling is needed */
  for (i=0; i < N; i++) {
    prod = WEBRTC_SPL_MUL_16_16_RSFT(x[i],x[i],scaling);
    newsum = sum+prod;
    /* If sum gets less than 0 we have overflow and need to scale the signal */
    if(newsum<0) {
      scaling++;
      sum=WEBRTC_SPL_RSHIFT_W32(sum, 1);
      prod=WEBRTC_SPL_RSHIFT_W32(prod, 1);
    }
    sum += prod;
  }
  r[0]=sum;

  /* Perform the actual correlation calculation */
  for (i = 1; i < order + 1; i++)
  {
    int loops=(N-i);
    sum = 0;
    xptr1=(G_CONST WebRtc_Word16 *)x;
    xptr2=(G_CONST WebRtc_Word16 *)&x[i];

    for (j = loops;j > 0; j--)
    {
      sum += WEBRTC_SPL_MUL_16_16_RSFT(*xptr1++,*xptr2++,scaling);
    }

    r[i] = sum;
  }

  *scale = scaling;

  return(order + 1);
}
示例#7
0
文件: sort_sq.c 项目: 0x7678/evilbts
void WebRtcIlbcfix_SortSq(
    WebRtc_Word16 *xq,   /* (o) the quantized value */
    WebRtc_Word16 *index,  /* (o) the quantization index */
    WebRtc_Word16 x,   /* (i) the value to quantize */
    const WebRtc_Word16 *cb, /* (i) the quantization codebook */
    WebRtc_Word16 cb_size  /* (i) the size of the quantization codebook */
                          ){
  int i;

  if (x <= cb[0]) {
    *index = 0;
    *xq = cb[0];
  } else {
    i = 0;
    while ((x > cb[i]) && (i < (cb_size-1))) {
      i++;
    }

    if (x > WEBRTC_SPL_RSHIFT_W32(( (WebRtc_Word32)cb[i] + cb[i - 1] + 1),1)) {
      *index = i;
      *xq = cb[i];
    } else {
      *index = i - 1;
      *xq = cb[i - 1];
    }
  }
}
示例#8
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;
}
示例#9
0
static __inline int32_t CalcLrIntQ(int32_t fixVal,
                                   int16_t qDomain) {
  int32_t intgr;
  int32_t roundVal;

  roundVal = WEBRTC_SPL_LSHIFT_W32((int32_t)1,  qDomain - 1);
  intgr = WEBRTC_SPL_RSHIFT_W32(fixVal + roundVal, qDomain);

  return intgr;
}
示例#10
0
文件: recin.c 项目: CryptoCall/webrtc
WebRtc_UWord32 WebRtcNetEQ_ScaleTimestampInternalToExternal(const MCUInst_t *MCU_inst,
                                                            WebRtc_UWord32 internalTS)
{
    WebRtc_Word32 timestampDiff;
    WebRtc_UWord32 externalTS;

    /* difference between this and last incoming timestamp */
    timestampDiff = (WebRtc_Word32) internalTS - MCU_inst->internalTS;

    switch (MCU_inst->scalingFactor)
    {
        case kTSscalingTwo:
        {
            /* divide by 2 */
            timestampDiff = WEBRTC_SPL_RSHIFT_W32(timestampDiff, 1);
            break;
        }
        case kTSscalingTwoThirds:
        {
            /* multiply with 3/2 */
            timestampDiff = WEBRTC_SPL_MUL_32_16(timestampDiff, 3);
            timestampDiff = WEBRTC_SPL_RSHIFT_W32(timestampDiff, 1);
            break;
        }
        case kTSscalingFourThirds:
        {
            /* multiply with 3/4 */
            timestampDiff = WEBRTC_SPL_MUL_32_16(timestampDiff, 3);
            timestampDiff = WEBRTC_SPL_RSHIFT_W32(timestampDiff, 2);
            break;
        }
        default:
        {
            /* no scaling */
        }
    }

    /* add the scaled difference to last scaled timestamp and save ... */
    externalTS = MCU_inst->externalTS + timestampDiff;

    return externalTS;
}
示例#11
0
/* Compute the energy of the rest of the cb memory
 * by step wise adding and subtracting the next
 * sample and the last sample respectively */
void WebRtcIlbcfix_CbMemEnergyCalc(
    WebRtc_Word32 energy,   /* (i) input start energy */
    WebRtc_Word16 range,   /* (i) number of iterations */
    WebRtc_Word16 *ppi,   /* (i) input pointer 1 */
    WebRtc_Word16 *ppo,   /* (i) input pointer 2 */
    WebRtc_Word16 *energyW16,  /* (o) Energy in the CB vectors */
    WebRtc_Word16 *energyShifts, /* (o) Shift value of the energy */
    WebRtc_Word16 scale,   /* (i) The scaling of all energy values */
    WebRtc_Word16 base_size  /* (i) Index to where the energy values should be stored */
                                   )
{
  WebRtc_Word16 j,shft;
  WebRtc_Word32 tmp;
  WebRtc_Word16 *eSh_ptr;
  WebRtc_Word16 *eW16_ptr;


  eSh_ptr  = &energyShifts[1+base_size];
  eW16_ptr = &energyW16[1+base_size];

  for(j=0;j<range-1;j++) {

    /* Calculate next energy by a +/-
       operation on the edge samples */
    tmp  = WEBRTC_SPL_MUL_16_16(*ppi, *ppi);
    tmp -= WEBRTC_SPL_MUL_16_16(*ppo, *ppo);
    energy += WEBRTC_SPL_RSHIFT_W32(tmp, scale);
    energy = WEBRTC_SPL_MAX(energy, 0);

    ppi--;
    ppo--;

    /* Normalize the energy into a WebRtc_Word16 and store
       the number of shifts */

    shft = (WebRtc_Word16)WebRtcSpl_NormW32(energy);
    *eSh_ptr++ = shft;

    tmp = WEBRTC_SPL_LSHIFT_W32(energy, shft);
    *eW16_ptr++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmp, 16);
  }
}
示例#12
0
static __inline int32_t Log2Q8( 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(magn(i)) */

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

}
示例#13
0
static void AllpassFilterForDec32(WebRtc_Word16         *InOut16, //Q0
                                  const WebRtc_Word32   *APSectionFactors, //Q15
                                  WebRtc_Word16         lengthInOut,
                                  WebRtc_Word32          *FilterState) //Q16
{
  int n, j;
  WebRtc_Word32 a, b;

  for (j=0; j<ALLPASSSECTIONS; j++) {
    for (n=0;n<lengthInOut;n+=2){
      a = WEBRTC_SPL_MUL_16_32_RSFT16(InOut16[n], APSectionFactors[j]); //Q0*Q31=Q31 shifted 16 gives Q15
      a = WEBRTC_SPL_LSHIFT_W32(a, 1); // Q15 -> Q16
      b = WEBRTC_SPL_ADD_SAT_W32(a, FilterState[j]); //Q16+Q16=Q16
      a = WEBRTC_SPL_MUL_16_32_RSFT16(
          (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16),
          -APSectionFactors[j]); //Q0*Q31=Q31 shifted 16 gives Q15
      FilterState[j] = WEBRTC_SPL_ADD_SAT_W32(
          WEBRTC_SPL_LSHIFT_W32(a,1),
          WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)InOut16[n], 16)); // Q15<<1 + Q0<<16 = Q16 + Q16 = Q16
      InOut16[n] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16); //Save as Q0
    }
  }
}
示例#14
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
}
示例#15
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;

}
示例#16
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;
}
示例#17
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;
}
示例#18
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];
  }
}
void WebRtcIlbcfix_CbMemEnergyAugmentation(
    int16_t *interpSamples, /* (i) The interpolated samples */
    int16_t *CBmem,   /* (i) The CB memory */
    int16_t scale,   /* (i) The scaling of all energy values */
    int16_t base_size,  /* (i) Index to where the energy values should be stored */
    int16_t *energyW16,  /* (o) Energy in the CB vectors */
    int16_t *energyShifts /* (o) Shift value of the energy */
                                           ){
  int32_t energy, tmp32;
  int16_t *ppe, *pp, *interpSamplesPtr;
  int16_t *CBmemPtr, lagcount;
  int16_t *enPtr=&energyW16[base_size-20];
  int16_t *enShPtr=&energyShifts[base_size-20];
  int32_t nrjRecursive;

  CBmemPtr = CBmem+147;
  interpSamplesPtr = interpSamples;

  /* Compute the energy for the first (low-5) noninterpolated samples */
  nrjRecursive = WebRtcSpl_DotProductWithScale( CBmemPtr-19, CBmemPtr-19, 15, scale);
  ppe = CBmemPtr - 20;

  for (lagcount=20; lagcount<=39; lagcount++) {

    /* Update the energy recursively to save complexity */
    nrjRecursive = nrjRecursive +
        WEBRTC_SPL_MUL_16_16_RSFT(*ppe, *ppe, scale);
    ppe--;
    energy = nrjRecursive;

    /* interpolation */
    energy += WebRtcSpl_DotProductWithScale(interpSamplesPtr, interpSamplesPtr, 4, scale);
    interpSamplesPtr += 4;

    /* Compute energy for the remaining samples */
    pp = CBmemPtr - lagcount;
    energy += WebRtcSpl_DotProductWithScale(pp, pp, SUBL-lagcount, scale);

    /* Normalize the energy and store the number of shifts */
    (*enShPtr) = (int16_t)WebRtcSpl_NormW32(energy);
    tmp32 = WEBRTC_SPL_LSHIFT_W32(energy, (*enShPtr));
    (*enPtr) = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp32, 16);
    enShPtr++;
    enPtr++;
  }
}
示例#20
0
void WebRtcIlbcfix_CbConstruct(
    WebRtc_Word16 *decvector,  /* (o) Decoded vector */
    WebRtc_Word16 *index,   /* (i) Codebook indices */
    WebRtc_Word16 *gain_index,  /* (i) Gain quantization indices */
    WebRtc_Word16 *mem,   /* (i) Buffer for codevector construction */
    WebRtc_Word16 lMem,   /* (i) Length of buffer */
    WebRtc_Word16 veclen   /* (i) Length of vector */
                               ){
  int j;
  WebRtc_Word16 gain[CB_NSTAGES];
  /* Stack based */
  WebRtc_Word16 cbvec0[SUBL];
  WebRtc_Word16 cbvec1[SUBL];
  WebRtc_Word16 cbvec2[SUBL];
  WebRtc_Word32 a32;
  WebRtc_Word16 *gainPtr;

  /* gain de-quantization */

  gain[0] = WebRtcIlbcfix_GainDequant(gain_index[0], 16384, 0);
  gain[1] = WebRtcIlbcfix_GainDequant(gain_index[1], gain[0], 1);
  gain[2] = WebRtcIlbcfix_GainDequant(gain_index[2], gain[1], 2);

  /* codebook vector construction and construction of total vector */

  /* Stack based */
  WebRtcIlbcfix_GetCbVec(cbvec0, mem, index[0], lMem, veclen);
  WebRtcIlbcfix_GetCbVec(cbvec1, mem, index[1], lMem, veclen);
  WebRtcIlbcfix_GetCbVec(cbvec2, mem, index[2], lMem, veclen);

  gainPtr = &gain[0];
  for (j=0;j<veclen;j++) {
    a32  = WEBRTC_SPL_MUL_16_16(*gainPtr++, cbvec0[j]);
    a32 += WEBRTC_SPL_MUL_16_16(*gainPtr++, cbvec1[j]);
    a32 += WEBRTC_SPL_MUL_16_16(*gainPtr, cbvec2[j]);
    gainPtr -= 2;
    decvector[j] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(a32 + 8192, 14);
  }

  return;
}
示例#21
0
void WebRtcNetEQ_MixVoiceUnvoice(WebRtc_Word16 *pw16_outData, WebRtc_Word16 *pw16_voicedVec,
                                 WebRtc_Word16 *pw16_unvoicedVec,
                                 WebRtc_Word16 *w16_current_vfraction,
                                 WebRtc_Word16 w16_vfraction_change, WebRtc_Word16 N)
{
    int i;
    WebRtc_Word16 w16_tmp2;
    WebRtc_Word16 vfraction = *w16_current_vfraction;

    w16_tmp2 = 16384 - vfraction;
    for (i = 0; i < N; i++)
    {
        pw16_outData[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(
            WEBRTC_SPL_MUL_16_16(vfraction, pw16_voicedVec[i]) +
            WEBRTC_SPL_MUL_16_16(w16_tmp2, pw16_unvoicedVec[i]) + 8192,
            14);
        vfraction -= w16_vfraction_change;
        w16_tmp2 += w16_vfraction_change;
    }
    *w16_current_vfraction = vfraction;
}
int WebRtcSpl_DownsampleFast(WebRtc_Word16 *in_ptr, WebRtc_Word16 in_length,
                             WebRtc_Word16 *out_ptr, WebRtc_Word16 out_length,
                             WebRtc_Word16 *B, WebRtc_Word16 B_length, WebRtc_Word16 factor,
                             WebRtc_Word16 delay)
{
    WebRtc_Word32 o;
    int i, j;

    WebRtc_Word16 *downsampled_ptr = out_ptr;
    WebRtc_Word16 *b_ptr;
    WebRtc_Word16 *x_ptr;
    WebRtc_Word16 endpos = delay
            + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(factor, (out_length - 1)) + 1;

    if (in_length < endpos)
    {
        return -1;
    }

    for (i = delay; i < endpos; i += factor)
    {
        b_ptr = &B[0];
        x_ptr = &in_ptr[i];

        o = (WebRtc_Word32)2048; // Round val

        for (j = 0; j < B_length; j++)
        {
            o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
        }

        o = WEBRTC_SPL_RSHIFT_W32(o, 12);

        // If output is higher than 32768, saturate it. Same with negative side

        *downsampled_ptr++ = WebRtcSpl_SatW32ToW16(o);
    }

    return 0;
}
示例#23
0
void WebRtcIlbcfix_Interpolate(
    WebRtc_Word16 *out, /* (o) output vector */
    WebRtc_Word16 *in1, /* (i) first input vector */
    WebRtc_Word16 *in2, /* (i) second input vector */
    WebRtc_Word16 coef, /* (i) weight coefficient in Q14 */
    WebRtc_Word16 length)  /* (i) number of sample is vectors */
{
  int i;
  WebRtc_Word16 invcoef;

  /*
    Performs the operation out[i] = in[i]*coef + (1-coef)*in2[i] (with rounding)
  */

  invcoef = 16384 - coef; /* 16384 = 1.0 (Q14)*/
  for (i = 0; i < length; i++) {
    out[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(
        (WEBRTC_SPL_MUL_16_16(coef, in1[i]) + WEBRTC_SPL_MUL_16_16(invcoef, in2[i]))+8192,
        14);
  }

  return;
}
示例#24
0
void WebRtcVad_HpOutput(WebRtc_Word16 *in_vector,
                        WebRtc_Word16 in_vector_length,
                        WebRtc_Word16 *out_vector,
                        WebRtc_Word16 *filter_state)
{
    WebRtc_Word16 i, *pi, *outPtr;
    WebRtc_Word32 tmpW32;

    pi = &in_vector[0];
    outPtr = &out_vector[0];

    // The sum of the absolute values of the impulse response:
    // The zero/pole-filter has a max amplification of a single sample of: 1.4546
    // Impulse response: 0.4047 -0.6179 -0.0266  0.1993  0.1035  -0.0194
    // The all-zero section has a max amplification of a single sample of: 1.6189
    // Impulse response: 0.4047 -0.8094  0.4047  0       0        0
    // The all-pole section has a max amplification of a single sample of: 1.9931
    // Impulse response: 1.0000  0.4734 -0.1189 -0.2187 -0.0627   0.04532

    for (i = 0; i < in_vector_length; i++)
    {
        // all-zero section (filter coefficients in Q14)
        tmpW32 = (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpZeroCoefs[0], (*pi));
        tmpW32 += (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpZeroCoefs[1], filter_state[0]);
        tmpW32 += (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpZeroCoefs[2], filter_state[1]); // Q14
        filter_state[1] = filter_state[0];
        filter_state[0] = *pi++;

        // all-pole section
        tmpW32 -= (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpPoleCoefs[1], filter_state[2]); // Q14
        tmpW32 -= (WebRtc_Word32)WEBRTC_SPL_MUL_16_16(kHpPoleCoefs[2], filter_state[3]);
        filter_state[3] = filter_state[2];
        filter_state[2] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32 (tmpW32, 14);
        *outPtr++ = filter_state[2];
    }
}
示例#25
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;
}
示例#26
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;
}
示例#27
0
void WebRtcIsacfix_DecimateAllpass32(const WebRtc_Word16 *in,
                                     WebRtc_Word32 *state_in,        /* array of size: 2*ALLPASSSECTIONS+1 */
                                     WebRtc_Word16 N,                /* number of input samples */
                                     WebRtc_Word16 *out)             /* array of size N/2 */
{
  int n;
  WebRtc_Word16 data_vec[PITCH_FRAME_LEN];

  /* copy input */
  memcpy(data_vec+1, in, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), (N-1)));


  data_vec[0] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(state_in[WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)],16);   //the z^(-1) state
  state_in[WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)] = WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)in[N-1],16);



  AllpassFilterForDec32(data_vec+1, kApUpperQ15, N, state_in);
  AllpassFilterForDec32(data_vec, kApLowerQ15, N, state_in+ALLPASSSECTIONS);

  for (n=0;n<N/2;n++) {
    out[n]=WEBRTC_SPL_ADD_SAT_W16(data_vec[WEBRTC_SPL_MUL_16_16(2, n)], data_vec[WEBRTC_SPL_MUL_16_16(2, n)+1]);
  }
}
示例#28
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;
}
示例#29
0
void WebRtcIsacfix_Spec2TimeC(int16_t *inreQ7, int16_t *inimQ7, int32_t *outre1Q16, int32_t *outre2Q16)
{

  int k;
  int16_t tmp1rQ14, tmp1iQ14;
  int32_t xrQ16, xiQ16, yrQ16, yiQ16;
  int32_t tmpInRe, tmpInIm, tmpInRe2, tmpInIm2;
  int16_t factQ11;
  int16_t sh;

  for (k = 0; k < FRAMESAMPLES/4; k++) {
    /* Move zero in time to beginning of frames */
    tmp1rQ14 = -WebRtcIsacfix_kSinTab2[FRAMESAMPLES/4 - 1 - k];
    tmp1iQ14 = WebRtcIsacfix_kSinTab2[k];

    tmpInRe = WEBRTC_SPL_LSHIFT_W32((int32_t) inreQ7[k], 9);  // Q7 -> Q16
    tmpInIm = WEBRTC_SPL_LSHIFT_W32((int32_t) inimQ7[k], 9);  // Q7 -> Q16
    tmpInRe2 = WEBRTC_SPL_LSHIFT_W32((int32_t) inreQ7[FRAMESAMPLES/2 - 1 - k], 9);  // Q7 -> Q16
    tmpInIm2 = WEBRTC_SPL_LSHIFT_W32((int32_t) inimQ7[FRAMESAMPLES/2 - 1 - k], 9);  // Q7 -> Q16

    xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInRe) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInIm);
    xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInIm) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInRe);
    yrQ16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInIm2) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInRe2);
    yiQ16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInRe2) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInIm2);

    /* Combine into one vector,  z = x + j * y */
    outre1Q16[k] = xrQ16 - yiQ16;
    outre1Q16[FRAMESAMPLES/2 - 1 - k] = xrQ16 + yiQ16;
    outre2Q16[k] = xiQ16 + yrQ16;
    outre2Q16[FRAMESAMPLES/2 - 1 - k] = -xiQ16 + yrQ16;
  }

  /* Get IDFT */
  tmpInRe  = WebRtcSpl_MaxAbsValueW32(outre1Q16, 240);
  tmpInIm = WebRtcSpl_MaxAbsValueW32(outre2Q16, 240);
  if (tmpInIm>tmpInRe) {
    tmpInRe = tmpInIm;
  }

  sh = WebRtcSpl_NormW32(tmpInRe);
  sh = sh-24; //if sh becomes >=0, then we should shift sh steps to the left, and the domain will become Q(16+sh)
  //if sh becomes <0, then we should shift -sh steps to the right, and the domain will become Q(16+sh)

  //"Fastest" vectors
  if (sh>=0) {
    for (k=0; k<240; k++) {
      inreQ7[k] = (int16_t) WEBRTC_SPL_LSHIFT_W32(outre1Q16[k], sh); //Q(16+sh)
      inimQ7[k] = (int16_t) WEBRTC_SPL_LSHIFT_W32(outre2Q16[k], sh); //Q(16+sh)
    }
  } else {
    int32_t round = WEBRTC_SPL_LSHIFT_W32((int32_t)1, -sh-1);
    for (k=0; k<240; k++) {
      inreQ7[k] = (int16_t) WEBRTC_SPL_RSHIFT_W32(outre1Q16[k]+round, -sh); //Q(16+sh)
      inimQ7[k] = (int16_t) WEBRTC_SPL_RSHIFT_W32(outre2Q16[k]+round, -sh); //Q(16+sh)
    }
  }

  WebRtcIsacfix_FftRadix16Fastest(inreQ7, inimQ7, 1); // real call

  //"Fastest" vectors
  if (sh>=0) {
    for (k=0; k<240; k++) {
      outre1Q16[k] = WEBRTC_SPL_RSHIFT_W32((int32_t)inreQ7[k], sh); //Q(16+sh) -> Q16
      outre2Q16[k] = WEBRTC_SPL_RSHIFT_W32((int32_t)inimQ7[k], sh); //Q(16+sh) -> Q16
    }
  } else {
    for (k=0; k<240; k++) {
      outre1Q16[k] = WEBRTC_SPL_LSHIFT_W32((int32_t)inreQ7[k], -sh); //Q(16+sh) -> Q16
      outre2Q16[k] = WEBRTC_SPL_LSHIFT_W32((int32_t)inimQ7[k], -sh); //Q(16+sh) -> Q16
    }
  }

  /* Divide through by the normalizing constant: */
  /* scale all values with 1/240, i.e. with 273 in Q16 */
  /* 273/65536 ~= 0.0041656                            */
  /*     1/240 ~= 0.0041666                            */
  for (k=0; k<240; k++) {
    outre1Q16[k] = WEBRTC_SPL_MUL_16_32_RSFT16(273, outre1Q16[k]);
    outre2Q16[k] = WEBRTC_SPL_MUL_16_32_RSFT16(273, outre2Q16[k]);
  }

  /* Demodulate and separate */
  factQ11 = 31727; // sqrt(240) in Q11 is round(15.49193338482967*2048) = 31727
  for (k = 0; k < FRAMESAMPLES/2; k++) {
    tmp1rQ14 = WebRtcIsacfix_kCosTab1[k];
    tmp1iQ14 = WebRtcIsacfix_kSinTab1[k];
    xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, outre1Q16[k]) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, outre2Q16[k]);
    xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, outre2Q16[k]) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, outre1Q16[k]);
    xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xrQ16);
    xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xiQ16);
    outre2Q16[k] = xiQ16;
    outre1Q16[k] = xrQ16;
  }
}
示例#30
0
void WebRtcIsacfix_Time2SpecC(int16_t *inre1Q9,
                              int16_t *inre2Q9,
                              int16_t *outreQ7,
                              int16_t *outimQ7)
{

  int k;
  int32_t tmpreQ16[FRAMESAMPLES/2], tmpimQ16[FRAMESAMPLES/2];
  int16_t tmp1rQ14, tmp1iQ14;
  int32_t xrQ16, xiQ16, yrQ16, yiQ16;
  int32_t v1Q16, v2Q16;
  int16_t factQ19, sh;

  /* Multiply with complex exponentials and combine into one complex vector */
  factQ19 = 16921; // 0.5/sqrt(240) in Q19 is round(.5/sqrt(240)*(2^19)) = 16921
  for (k = 0; k < FRAMESAMPLES/2; k++) {
    tmp1rQ14 = WebRtcIsacfix_kCosTab1[k];
    tmp1iQ14 = WebRtcIsacfix_kSinTab1[k];
    xrQ16 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(tmp1rQ14, inre1Q9[k]) + WEBRTC_SPL_MUL_16_16(tmp1iQ14, inre2Q9[k]), 7);
    xiQ16 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(tmp1rQ14, inre2Q9[k]) - WEBRTC_SPL_MUL_16_16(tmp1iQ14, inre1Q9[k]), 7);
    tmpreQ16[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xrQ16)+4, 3); // (Q16*Q19>>16)>>3 = Q16
    tmpimQ16[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xiQ16)+4, 3); // (Q16*Q19>>16)>>3 = Q16
  }


  xrQ16  = WebRtcSpl_MaxAbsValueW32(tmpreQ16, FRAMESAMPLES/2);
  yrQ16 = WebRtcSpl_MaxAbsValueW32(tmpimQ16, FRAMESAMPLES/2);
  if (yrQ16>xrQ16) {
    xrQ16 = yrQ16;
  }

  sh = WebRtcSpl_NormW32(xrQ16);
  sh = sh-24; //if sh becomes >=0, then we should shift sh steps to the left, and the domain will become Q(16+sh)
  //if sh becomes <0, then we should shift -sh steps to the right, and the domain will become Q(16+sh)

  //"Fastest" vectors
  if (sh>=0) {
    for (k=0; k<FRAMESAMPLES/2; k++) {
      inre1Q9[k] = (int16_t) WEBRTC_SPL_LSHIFT_W32(tmpreQ16[k], sh); //Q(16+sh)
      inre2Q9[k] = (int16_t) WEBRTC_SPL_LSHIFT_W32(tmpimQ16[k], sh); //Q(16+sh)
    }
  } else {
    int32_t round = WEBRTC_SPL_LSHIFT_W32((int32_t)1, -sh-1);
    for (k=0; k<FRAMESAMPLES/2; k++) {
      inre1Q9[k] = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmpreQ16[k]+round, -sh); //Q(16+sh)
      inre2Q9[k] = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmpimQ16[k]+round, -sh); //Q(16+sh)
    }
  }

  /* Get DFT */
  WebRtcIsacfix_FftRadix16Fastest(inre1Q9, inre2Q9, -1); // real call

  //"Fastest" vectors
  if (sh>=0) {
    for (k=0; k<FRAMESAMPLES/2; k++) {
      tmpreQ16[k] = WEBRTC_SPL_RSHIFT_W32((int32_t)inre1Q9[k], sh); //Q(16+sh) -> Q16
      tmpimQ16[k] = WEBRTC_SPL_RSHIFT_W32((int32_t)inre2Q9[k], sh); //Q(16+sh) -> Q16
    }
  } else {
    for (k=0; k<FRAMESAMPLES/2; k++) {
      tmpreQ16[k] = WEBRTC_SPL_LSHIFT_W32((int32_t)inre1Q9[k], -sh); //Q(16+sh) -> Q16
      tmpimQ16[k] = WEBRTC_SPL_LSHIFT_W32((int32_t)inre2Q9[k], -sh); //Q(16+sh) -> Q16
    }
  }


  /* Use symmetry to separate into two complex vectors and center frames in time around zero */
  for (k = 0; k < FRAMESAMPLES/4; k++) {
    xrQ16 = tmpreQ16[k] + tmpreQ16[FRAMESAMPLES/2 - 1 - k];
    yiQ16 = -tmpreQ16[k] + tmpreQ16[FRAMESAMPLES/2 - 1 - k];
    xiQ16 = tmpimQ16[k] - tmpimQ16[FRAMESAMPLES/2 - 1 - k];
    yrQ16 = tmpimQ16[k] + tmpimQ16[FRAMESAMPLES/2 - 1 - k];
    tmp1rQ14 = -WebRtcIsacfix_kSinTab2[FRAMESAMPLES/4 - 1 - k];
    tmp1iQ14 = WebRtcIsacfix_kSinTab2[k];
    v1Q16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, xrQ16) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, xiQ16);
    v2Q16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, xrQ16) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, xiQ16);
    outreQ7[k] = (int16_t) WEBRTC_SPL_RSHIFT_W32(v1Q16, 9);
    outimQ7[k] = (int16_t) WEBRTC_SPL_RSHIFT_W32(v2Q16, 9);
    v1Q16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, yrQ16) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, yiQ16);
    v2Q16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, yrQ16) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, yiQ16);
    outreQ7[FRAMESAMPLES/2 - 1 - k] = (int16_t)WEBRTC_SPL_RSHIFT_W32(v1Q16, 9); //CalcLrIntQ(v1Q16, 9);
    outimQ7[FRAMESAMPLES/2 - 1 - k] = (int16_t)WEBRTC_SPL_RSHIFT_W32(v2Q16, 9); //CalcLrIntQ(v2Q16, 9);

  }
}