示例#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
文件: vq4.c 项目: CEPBEP/onion-phone
void WebRtcIlbcfix_Vq4(int16_t * Xq,	/* quantized vector (Q13) */
		       int16_t * index, int16_t * CB,	/* codebook in Q13 */
		       int16_t * X,	/* vector to quantize (Q13) */
		       int16_t n_cb)
{
	int16_t i, j;
	int16_t pos, minindex = 0;
	int16_t tmp;
	int32_t dist, mindist;

	pos = 0;
	mindist = WEBRTC_SPL_WORD32_MAX;	/* start value */

	/* Find the codebook with the lowest square distance */
	for (j = 0; j < n_cb; j++) {
		tmp = X[0] - CB[pos];
		dist = WEBRTC_SPL_MUL_16_16(tmp, tmp);
		for (i = 1; i < 4; i++) {
			tmp = X[i] - CB[pos + i];
			dist += WEBRTC_SPL_MUL_16_16(tmp, tmp);
		}

		if (dist < mindist) {
			mindist = dist;
			minindex = j;
		}
		pos += 4;
	}

	/* Store the quantized codebook and the index */
	for (i = 0; i < 4; i++) {
		Xq[i] = CB[minindex * 4 + i];
	}
	*index = minindex;
}
示例#4
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;
  }
}
示例#5
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)++;
  }
}
示例#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
void WebRtcIlbcfix_MyCorr(
    int32_t *corr,  /* (o) correlation of seq1 and seq2 */
    int16_t *seq1,  /* (i) first sequence */
    int16_t dim1,  /* (i) dimension first seq1 */
    const int16_t *seq2, /* (i) second sequence */
    int16_t dim2   /* (i) dimension seq2 */
                          ){
  int16_t max, scale, loops;

  /* Calculate correlation between the two sequences. Scale the
     result of the multiplcication to maximum 26 bits in order
     to avoid overflow */
  max=WebRtcSpl_MaxAbsValueW16(seq1, dim1);
  scale=WebRtcSpl_GetSizeInBits(max);

  scale = (int16_t)(WEBRTC_SPL_MUL_16_16(2,scale)-26);
  if (scale<0) {
    scale=0;
  }

  loops=dim1-dim2+1;

  /* Calculate the cross correlations */
  WebRtcSpl_CrossCorrelation(corr, (int16_t*)seq2, seq1, dim2, loops, scale, 1);

  return;
}
示例#8
0
void WebRtcIlbcfix_SimpleLsfDeQ(int16_t * lsfdeq,	/* (o) dequantized lsf coefficients */
				int16_t * index,	/* (i) quantization index */
				int16_t lpc_n	/* (i) number of LPCs */
    )
{
	int i, j, pos, cb_pos;

	/* decode first LSF */

	pos = 0;
	cb_pos = 0;
	for (i = 0; i < LSF_NSPLIT; i++) {
		for (j = 0; j < WebRtcIlbcfix_kLsfDimCb[i]; j++) {
			lsfdeq[pos + j] = WebRtcIlbcfix_kLsfCb[cb_pos +
							       WEBRTC_SPL_MUL_16_16
							       (index[i],
								WebRtcIlbcfix_kLsfDimCb
								[i]) + j];
		}
		pos += WebRtcIlbcfix_kLsfDimCb[i];
		cb_pos +=
		    WEBRTC_SPL_MUL_16_16(WebRtcIlbcfix_kLsfSizeCb[i],
					 WebRtcIlbcfix_kLsfDimCb[i]);
	}

	if (lpc_n > 1) {
		/* decode last LSF */
		pos = 0;
		cb_pos = 0;
		for (i = 0; i < LSF_NSPLIT; i++) {
			for (j = 0; j < WebRtcIlbcfix_kLsfDimCb[i]; j++) {
				lsfdeq[LPC_FILTERORDER + pos + j] =
				    WebRtcIlbcfix_kLsfCb[cb_pos +
							 WEBRTC_SPL_MUL_16_16
							 (index[LSF_NSPLIT + i],
							  WebRtcIlbcfix_kLsfDimCb
							  [i]) + j];
			}
			pos += WebRtcIlbcfix_kLsfDimCb[i];
			cb_pos +=
			    WEBRTC_SPL_MUL_16_16(WebRtcIlbcfix_kLsfSizeCb[i],
						 WebRtcIlbcfix_kLsfDimCb[i]);
		}
	}
	return;
}
示例#9
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);
  }
}
示例#10
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;
}
示例#11
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;
}
static inline void DotProductWithScaleNeon(int32_t* cross_correlation,
                                           const int16_t* vector1,
                                           const int16_t* vector2,
                                           size_t length,
                                           int scaling) {
  size_t i = 0;
  size_t len1 = length >> 3;
  size_t len2 = length & 7;
  int64x2_t sum0 = vdupq_n_s64(0);
  int64x2_t sum1 = vdupq_n_s64(0);

  for (i = len1; i > 0; i -= 1) {
    int16x8_t seq1_16x8 = vld1q_s16(vector1);
    int16x8_t seq2_16x8 = vld1q_s16(vector2);
#if defined(WEBRTC_ARCH_ARM64)
    int32x4_t tmp0 = vmull_s16(vget_low_s16(seq1_16x8),
                               vget_low_s16(seq2_16x8));
    int32x4_t tmp1 = vmull_high_s16(seq1_16x8, seq2_16x8);
#else
    int32x4_t tmp0 = vmull_s16(vget_low_s16(seq1_16x8),
                               vget_low_s16(seq2_16x8));
    int32x4_t tmp1 = vmull_s16(vget_high_s16(seq1_16x8),
                               vget_high_s16(seq2_16x8));
#endif
    sum0 = vpadalq_s32(sum0, tmp0);
    sum1 = vpadalq_s32(sum1, tmp1);
    vector1 += 8;
    vector2 += 8;
  }

  // Calculate the rest of the samples.
  int64_t sum_res = 0;
  for (i = len2; i > 0; i -= 1) {
    sum_res += WEBRTC_SPL_MUL_16_16(*vector1, *vector2);
    vector1++;
    vector2++;
  }

  sum0 = vaddq_s64(sum0, sum1);
#if defined(WEBRTC_ARCH_ARM64)
  int64_t sum2 = vaddvq_s64(sum0);
  *cross_correlation = (int32_t)((sum2 + sum_res) >> scaling);
#else
  int64x1_t shift = vdup_n_s64(-scaling);
  int64x1_t sum2 = vadd_s64(vget_low_s64(sum0), vget_high_s64(sum0));
  sum2 = vadd_s64(sum2, vdup_n_s64(sum_res));
  sum2 = vshl_s64(sum2, shift);
  vst1_lane_s32(cross_correlation, vreinterpret_s32_s64(sum2), 0);
#endif
}
示例#14
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;
}
示例#15
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
}
示例#16
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;
}
示例#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] = 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)(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)(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
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;
}
示例#19
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];
    }
}
示例#20
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]);
  }
}
void WebRtcSpl_AffineTransformVector(WebRtc_Word16 *out, WebRtc_Word16 *in,
                                     WebRtc_Word16 gain, WebRtc_Word32 add_constant,
                                     WebRtc_Word16 right_shifts, int vector_length)
{
    WebRtc_Word16 *inPtr;
    WebRtc_Word16 *outPtr;
    int i;

    inPtr = in;
    outPtr = out;
    for (i = 0; i < vector_length; i++)
    {
        (*outPtr++) = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain)
                + (WebRtc_Word32)add_constant) >> right_shifts);
    }
}
void WebRtcSpl_AffineTransformVector(int16_t *out, int16_t *in,
                                     int16_t gain, int32_t add_constant,
                                     int16_t right_shifts, int vector_length)
{
    int16_t *inPtr;
    int16_t *outPtr;
    int i;

    inPtr = in;
    outPtr = out;
    for (i = 0; i < vector_length; i++)
    {
        (*outPtr++) = (int16_t)((WEBRTC_SPL_MUL_16_16((*inPtr++), gain)
                + (int32_t)add_constant) >> right_shifts);
    }
}
示例#23
0
/* The output is in the same domain as the input */
void WebRtcIlbcfix_BwExpand(
    WebRtc_Word16 *out, /* (o) the bandwidth expanded lpc coefficients */
    WebRtc_Word16 *in,  /* (i) the lpc coefficients before bandwidth
                                   expansion */
    WebRtc_Word16 *coef, /* (i) the bandwidth expansion factor Q15 */
    WebRtc_Word16 length /* (i) the length of lpc coefficient vectors */
) {
    int i;

    out[0] = in[0];
    for (i = 1; i < length; i++) {
        /* out[i] = coef[i] * in[i] with rounding.
           in[] and out[] are in Q12 and coef[] is in Q15
        */
        out[i] = (WebRtc_Word16)((WEBRTC_SPL_MUL_16_16(coef[i], in[i])+16384)>>15);
    }
}
示例#24
0
void WebRtcIsacfix_InitPitchAnalysis(PitchAnalysisStruct *State)
{
  int k;

  for (k = 0; k < PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2; k++) {
    State->dec_buffer16[k] = 0;
  }
  for (k = 0; k < WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)+1; k++) {
    State->decimator_state32[k] = 0;
  }

  for (k = 0; k < QLOOKAHEAD; k++)
    State->inbuf[k] = 0;

  WebRtcIsacfix_InitPitchFilter(&(State->PFstr_wght));

  WebRtcIsacfix_InitPitchFilter(&(State->PFstr));
}
示例#25
0
int16_t WebRtcIlbcfix_GainDequant(
    /* (o) quantized gain value (Q14) */
    int16_t index, /* (i) quantization index */
    int16_t maxIn, /* (i) maximum of unquantized gain (Q14) */
    int16_t stage /* (i) The stage of the search */
                                                ){
  int16_t scale;
  const int16_t *gain;

  /* obtain correct scale factor */

  scale=WEBRTC_SPL_ABS_W16(maxIn);
  scale = WEBRTC_SPL_MAX(1638, scale);  /* if lower than 0.1, set it to 0.1 */

  /* select the quantization table and return the decoded value */
  gain = WebRtcIlbcfix_kGain[stage];

  return((int16_t)((WEBRTC_SPL_MUL_16_16(scale, gain[index])+8192)>>14));
}
示例#26
0
void WebRtcIsacfix_InitPostFilterbank(PostFiltBankstr *postfiltdata)
{
  int k;

  for (k = 0; k < WEBRTC_SPL_MUL_16_16(2, POSTQORDER); k++) {

    postfiltdata->STATE_0_LOWER_fix[k] = 0;
    postfiltdata->STATE_0_UPPER_fix[k] = 0;
  }

  /* High pass filter states */

  postfiltdata->HPstates1_fix[0] = 0;
  postfiltdata->HPstates1_fix[1] = 0;

  postfiltdata->HPstates2_fix[0] = 0;
  postfiltdata->HPstates2_fix[1] = 0;

  return;
}
示例#27
0
void WebRtcIsacfix_InitPreFilterbank(PreFiltBankstr *prefiltdata)
{
  int k;

  for (k = 0; k < QLOOKAHEAD; k++) {
    prefiltdata->INLABUF1_fix[k] = 0;
    prefiltdata->INLABUF2_fix[k] = 0;
  }
  for (k = 0; k < WEBRTC_SPL_MUL_16_16(2,(QORDER-1)); k++) {

    prefiltdata->INSTAT1_fix[k] = 0;
    prefiltdata->INSTAT2_fix[k] = 0;
  }

  /* High pass filter states */
  prefiltdata->HPstates_fix[0] = 0;
  prefiltdata->HPstates_fix[1] = 0;

  return;
}
示例#28
0
void WebRtcIlbcfix_NearestNeighbor(
    int16_t *index, /* (o) index of array element closest to value */
    int16_t *array, /* (i) data array (Q2) */
    int16_t value, /* (i) value (Q2) */
    int16_t arlength /* (i) dimension of data array (==8) */
                                   ){
  int i;
  int16_t diff;
  /* Stack based */
  int32_t crit[8];

  /* Calculate square distance */
  for(i=0;i<arlength;i++){
    diff=array[i]-value;
    crit[i]=WEBRTC_SPL_MUL_16_16(diff, diff);
  }

  /* Find the minimum square distance */
  *index=WebRtcSpl_MinIndexW32(crit, (int16_t)arlength);
}
示例#29
0
/* This routine calculates the residual energy for LPC.
 * Formula as shown in comments inside.
 */
int32_t WebRtcIsacfix_CalculateResidualEnergyC(int lpc_order,
                                               int32_t q_val_corr,
                                               int q_val_polynomial,
                                               int16_t* a_polynomial,
                                               int32_t* corr_coeffs,
                                               int* q_val_residual_energy) {
  int i = 0, j = 0;
  int shift_internal = 0, shift_norm = 0;
  int32_t tmp32 = 0, word32_high = 0, word32_low = 0, residual_energy = 0;
  int64_t sum64 = 0, sum64_tmp = 0;

  for (i = 0; i <= lpc_order; i++) {
    for (j = i; j <= lpc_order; j++) {
      /* For the case of i == 0: residual_energy +=
       *    a_polynomial[j] * corr_coeffs[i] * a_polynomial[j - i];
       * For the case of i != 0: residual_energy +=
       *    a_polynomial[j] * corr_coeffs[i] * a_polynomial[j - i] * 2;
       */

      tmp32 = WEBRTC_SPL_MUL_16_16(a_polynomial[j], a_polynomial[j - i]);
                                   /* tmp32 in Q(q_val_polynomial * 2). */
      if (i != 0) {
        tmp32 <<= 1;
      }
      sum64_tmp = (int64_t)tmp32 * (int64_t)corr_coeffs[i];
      sum64_tmp >>= shift_internal;

      /* Test overflow and sum the result. */
      if(((sum64_tmp > 0 && sum64 > 0) && (LLONG_MAX - sum64 < sum64_tmp)) ||
         ((sum64_tmp < 0 && sum64 < 0) && (LLONG_MIN - sum64 > sum64_tmp))) {
        /* Shift right for overflow. */
        shift_internal += 1;
        sum64 >>= 1;
        sum64 += sum64_tmp >> 1;
      } else {
        sum64 += sum64_tmp;
      }
    }
示例#30
0
void WebRtcIlbcfix_NearestNeighbor(
    iLBC_Dec_Inst_t *iLBCdec_inst,
    /* (i) Decoder state */
    WebRtc_Word16 *index, /* (o) index of array element closest to value */
    WebRtc_Word16 *array, /* (i) data array (Q2) */
    WebRtc_Word16 value, /* (i) value (Q2) */
    WebRtc_Word16 arlength /* (i) dimension of data array (==8) */
                                   ){
  int i;
  WebRtc_Word16 diff;
  /* Stack based */
  WebRtc_Word32 crit[8];
  /* The input variable iLBCdec_inst is unused if not using scratch memory */
  iLBCdec_inst = iLBCdec_inst;

  /* Calculate square distance */
  for(i=0;i<arlength;i++){
    diff=array[i]-value;
    crit[i]=WEBRTC_SPL_MUL_16_16(diff, diff);
  }

  /* Find the minimum square distance */
  *index=WebRtcSpl_MinIndexW32(crit, (WebRtc_Word16)arlength);
}