Пример #1
0
void WebRtcIlbcfix_CreateAugmentedVec(
    WebRtc_Word16 index,  /* (i) Index for the augmented vector to be created */
    WebRtc_Word16 *buffer,  /* (i) Pointer to the end of the codebook memory that
                                           is used for creation of the augmented codebook */
    WebRtc_Word16 *cbVec  /* (o) The construced codebook vector */
                                      ) {
  WebRtc_Word16 ilow;
  WebRtc_Word16 *ppo, *ppi;
  WebRtc_Word16 cbVecTmp[4];

  ilow = index-4;

  /* copy the first noninterpolated part */
  ppo = buffer-index;
  WEBRTC_SPL_MEMCPY_W16(cbVec, ppo, index);

  /* interpolation */
  ppo = buffer - 4;
  ppi = buffer - index - 4;

  /* perform cbVec[ilow+k] = ((ppi[k]*alphaTbl[k])>>15) + ((ppo[k]*alphaTbl[3-k])>>15);
     for k = 0..3
  */
  WebRtcSpl_ElementwiseVectorMult(&cbVec[ilow], ppi, WebRtcIlbcfix_kAlpha, 4, 15);
  WebRtcSpl_ReverseOrderMultArrayElements(cbVecTmp, ppo, &WebRtcIlbcfix_kAlpha[3], 4, 15);
  WebRtcSpl_AddVectorsAndShift(&cbVec[ilow], &cbVec[ilow], cbVecTmp, 4, 0);

  /* copy the second noninterpolated part */
  ppo = buffer - index;
  WEBRTC_SPL_MEMCPY_W16(cbVec+index,ppo,(SUBL-index));
}
Пример #2
0
void WebRtcG729fix_Init_Decod_ld8a(Decod_ld8a_state *st)
{
  /* Initialize lsp_old[] */

  WEBRTC_SPL_MEMCPY_W16(st->lsp_old, WebRtcG729fix_lsp_old_reset, M);

  /* Initialize static pointer */

  st->exc = st->old_exc + PIT_MAX + L_INTERPOL;

  /* Static vectors to zero */

  WebRtcSpl_ZerosArrayW16(st->old_exc, PIT_MAX+L_INTERPOL);
  WebRtcSpl_ZerosArrayW16(st->mem_syn, M);

  st->sharp  = SHARPMIN;
  st->old_T0 = 60;
  st->gain_code = 0;
  st->gain_pitch = 0;

  WebRtcG729fix_Lsp_decw_reset(st);

  /* for G.729B */
  st->seed_fer = 21845;
  st->past_ftyp = 1;
  st->seed = INIT_SEED;
  st->sid_sav = 0;
  st->sh_sid_sav = 1;
  WebRtcG729fix_Init_lsfq_noise(st->noise_fg);

  /* Initialize Dec_gain */
  WEBRTC_SPL_MEMCPY_W16(st->past_qua_en, WebRtcG729fix_past_qua_en_reset, 4);

  return;
}
void WebRtcIlbcfix_DecoderInterpolateLsp(
    int16_t *syntdenum,  /* (o) synthesis filter coefficients */
    int16_t *weightdenum, /* (o) weighting denumerator
                                   coefficients */
    int16_t *lsfdeq,   /* (i) dequantized lsf coefficients */
    int16_t length,   /* (i) length of lsf coefficient vector */
    IlbcDecoder *iLBCdec_inst
    /* (i) the decoder state structure */
                                          ){
  size_t i;
  int pos, lp_length;
  int16_t  lp[LPC_FILTERORDER + 1], *lsfdeq2;

  lsfdeq2 = lsfdeq + length;
  lp_length = length + 1;

  if (iLBCdec_inst->mode==30) {
    /* subframe 1: Interpolation between old and first LSF */

    WebRtcIlbcfix_LspInterpolate2PolyDec(lp, (*iLBCdec_inst).lsfdeqold, lsfdeq,
                                         WebRtcIlbcfix_kLsfWeight30ms[0], length);
    WEBRTC_SPL_MEMCPY_W16(syntdenum,lp,lp_length);
    WebRtcIlbcfix_BwExpand(weightdenum, lp, (int16_t*)WebRtcIlbcfix_kLpcChirpSyntDenum, (int16_t)lp_length);

    /* subframes 2 to 6: interpolation between first and last LSF */

    pos = lp_length;
    for (i = 1; i < 6; i++) {
      WebRtcIlbcfix_LspInterpolate2PolyDec(lp, lsfdeq, lsfdeq2,
                                           WebRtcIlbcfix_kLsfWeight30ms[i], length);
      WEBRTC_SPL_MEMCPY_W16(syntdenum + pos,lp,lp_length);
      WebRtcIlbcfix_BwExpand(weightdenum + pos, lp,
                             (int16_t*)WebRtcIlbcfix_kLpcChirpSyntDenum, (int16_t)lp_length);
      pos += lp_length;
    }
  } else { /* iLBCdec_inst->mode=20 */
    /* subframes 1 to 4: interpolation between old and new LSF */
    pos = 0;
    for (i = 0; i < iLBCdec_inst->nsub; i++) {
      WebRtcIlbcfix_LspInterpolate2PolyDec(lp, iLBCdec_inst->lsfdeqold, lsfdeq,
                                           WebRtcIlbcfix_kLsfWeight20ms[i], length);
      WEBRTC_SPL_MEMCPY_W16(syntdenum+pos,lp,lp_length);
      WebRtcIlbcfix_BwExpand(weightdenum+pos, lp,
                             (int16_t*)WebRtcIlbcfix_kLpcChirpSyntDenum, (int16_t)lp_length);
      pos += lp_length;
    }
  }

  /* update memory */

  if (iLBCdec_inst->mode==30) {
    WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->lsfdeqold, lsfdeq2, length);
  } else {
    WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->lsfdeqold, lsfdeq, length);
  }
}
void WebRtcIlbcfix_SimpleInterpolateLsf(
    int16_t *syntdenum, /* (o) the synthesis filter denominator
                                   resulting from the quantized
                                   interpolated lsf Q12 */
    int16_t *weightdenum, /* (o) the weighting filter denominator
                                   resulting from the unquantized
                                   interpolated lsf Q12 */
    int16_t *lsf,  /* (i) the unquantized lsf coefficients Q13 */
    int16_t *lsfdeq,  /* (i) the dequantized lsf coefficients Q13 */
    int16_t *lsfold,  /* (i) the unquantized lsf coefficients of
                                           the previous signal frame Q13 */
    int16_t *lsfdeqold, /* (i) the dequantized lsf coefficients of the
                                   previous signal frame Q13 */
    int16_t length  /* (i) should equate FILTERORDER */
                                        ) {
  int i, pos, lp_length;

  int16_t *lsf2, *lsfdeq2;
  /* Stack based */
  int16_t lp[LPC_FILTERORDER + 1];

  lsf2 = lsf + length;
  lsfdeq2 = lsfdeq + length;
  lp_length = length + 1;

    pos = 0;
    for (i = 0; i < 4; i++) {

      /* Calculate Analysis/Syntehsis filter from quantized LSF */
      WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsfdeqold, lsfdeq,
                                           WebRtcIlbcfix_kLsfWeight20ms[i],
                                           length);
      WEBRTC_SPL_MEMCPY_W16(syntdenum + pos, lp, lp_length);

      /* Calculate Weighting filter from quantized LSF */
      WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsfold, lsf,
                                           WebRtcIlbcfix_kLsfWeight20ms[i],
                                           length);
      WebRtcIlbcfix_BwExpand(weightdenum+pos, lp,
                             (int16_t*)WebRtcIlbcfix_kLpcChirpWeightDenum,
                             (int16_t)lp_length);

      pos += lp_length;
    }

    /* update memory */

    WEBRTC_SPL_MEMCPY_W16(lsfold, lsf, length);
    WEBRTC_SPL_MEMCPY_W16(lsfdeqold, lsfdeq, length);

  return;
}
Пример #5
0
void WebRtcIlbcfix_CreateAugmentedVec(
    size_t index,          /* (i) Index for the augmented vector to be
                              created */
    const int16_t* buffer, /* (i) Pointer to the end of the codebook memory
                              that is used for creation of the augmented
                              codebook */
    int16_t* cbVec) {      /* (o) The constructed codebook vector */
  size_t ilow;
  const int16_t *ppo, *ppi;
  int16_t cbVecTmp[4];
  /* Interpolation starts 4 elements before cbVec+index, but must not start
     outside |cbVec|; clamping interp_len to stay within |cbVec|.
   */
  size_t interp_len = WEBRTC_SPL_MIN(index, 4);

  ilow = index - interp_len;

  /* copy the first noninterpolated part */
  ppo = buffer-index;
  WEBRTC_SPL_MEMCPY_W16(cbVec, ppo, index);

  /* interpolation */
  ppo = buffer - interp_len;
  ppi = buffer - index - interp_len;

  /* perform cbVec[ilow+k] = ((ppi[k]*alphaTbl[k])>>15) +
                             ((ppo[k]*alphaTbl[interp_len-1-k])>>15);
     for k = 0..interp_len-1
  */
  WebRtcSpl_ElementwiseVectorMult(&cbVec[ilow], ppi, WebRtcIlbcfix_kAlpha,
                                  interp_len, 15);
  WebRtcSpl_ReverseOrderMultArrayElements(
      cbVecTmp, ppo, &WebRtcIlbcfix_kAlpha[interp_len - 1], interp_len, 15);
  WebRtcSpl_AddVectorsAndShift(&cbVec[ilow], &cbVec[ilow], cbVecTmp, interp_len,
                               0);

  /* copy the second noninterpolated part */
  ppo = buffer - index;
  /* |tempbuff2| is declared in WebRtcIlbcfix_GetCbVec and is SUBL+5 elements
     long. |buffer| points one element past the end of that vector, i.e., at
     tempbuff2+SUBL+5. Since ppo=buffer-index, we cannot read any more than
     |index| elements from |ppo|.

     |cbVec| is declared to be SUBL elements long in WebRtcIlbcfix_CbConstruct.
     Therefore, we can only write SUBL-index elements to cbVec+index.

     These two conditions limit the number of elements to copy.
   */
  WEBRTC_SPL_MEMCPY_W16(cbVec+index, ppo, WEBRTC_SPL_MIN(SUBL-index, index));
}
Пример #6
0
int16_t WebRtcIlbcfix_InitEncode(	/* (o) Number of bytes encoded */
					      iLBC_Enc_Inst_t * iLBCenc_inst,	/* (i/o) Encoder instance */
					      int16_t mode	/* (i) frame size mode */
    )
{
	iLBCenc_inst->mode = mode;

	/* Set all the variables that are dependent on the frame size mode */
	if (mode == 30) {
		iLBCenc_inst->blockl = BLOCKL_30MS;
		iLBCenc_inst->nsub = NSUB_30MS;
		iLBCenc_inst->nasub = NASUB_30MS;
		iLBCenc_inst->lpc_n = LPC_N_30MS;
		iLBCenc_inst->no_of_bytes = NO_OF_BYTES_30MS;
		iLBCenc_inst->no_of_words = NO_OF_WORDS_30MS;
		iLBCenc_inst->state_short_len = STATE_SHORT_LEN_30MS;
	} else if (mode == 20) {
		iLBCenc_inst->blockl = BLOCKL_20MS;
		iLBCenc_inst->nsub = NSUB_20MS;
		iLBCenc_inst->nasub = NASUB_20MS;
		iLBCenc_inst->lpc_n = LPC_N_20MS;
		iLBCenc_inst->no_of_bytes = NO_OF_BYTES_20MS;
		iLBCenc_inst->no_of_words = NO_OF_WORDS_20MS;
		iLBCenc_inst->state_short_len = STATE_SHORT_LEN_20MS;
	} else {
		return (-1);
	}

	/* Clear the buffers and set the previous LSF and LSP to the mean value */
	WebRtcSpl_MemSetW16(iLBCenc_inst->anaMem, 0, LPC_FILTERORDER);
	WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->lsfold, WebRtcIlbcfix_kLsfMean,
			      LPC_FILTERORDER);
	WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->lsfdeqold, WebRtcIlbcfix_kLsfMean,
			      LPC_FILTERORDER);
	WebRtcSpl_MemSetW16(iLBCenc_inst->lpc_buffer, 0,
			    LPC_LOOKBACK + BLOCKL_MAX);

	/* Set the filter state of the HP filter to 0 */
	WebRtcSpl_MemSetW16(iLBCenc_inst->hpimemx, 0, 2);
	WebRtcSpl_MemSetW16(iLBCenc_inst->hpimemy, 0, 4);

#ifdef SPLIT_10MS
	/*Zeroing the past samples for 10msec Split */
	WebRtcSpl_MemSetW16(iLBCenc_inst->past_samples, 0, 160);
	iLBCenc_inst->section = 0;
#endif

	return (iLBCenc_inst->no_of_bytes);
}
Пример #7
0
void WebRtcSpl_CopyFromEndW16(const int16_t *vector_in,
                              size_t length,
                              size_t samples,
                              int16_t *vector_out)
{
    // Copy the last <samples> of the input vector to vector_out
    WEBRTC_SPL_MEMCPY_W16(vector_out, &vector_in[length - samples], samples);
}
Пример #8
0
void WebRtcIlbcfix_DecodeImpl(
    int16_t *decblock,    /* (o) decoded signal block */
    const uint16_t *bytes, /* (i) encoded signal bits */
    iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state
                                           structure */
    int16_t mode      /* (i) 0: bad packet, PLC,
                                                                   1: normal */
                           ) {
  int i;
  int16_t order_plus_one;

  int16_t last_bit;
  int16_t *data;
  /* Stack based */
  int16_t decresidual[BLOCKL_MAX];
  int16_t PLCresidual[BLOCKL_MAX + LPC_FILTERORDER];
  int16_t syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)];
  int16_t PLClpc[LPC_FILTERORDER + 1];
#ifndef WEBRTC_ARCH_BIG_ENDIAN
  uint16_t swapped[NO_OF_WORDS_30MS];
#endif
  iLBC_bits *iLBCbits_inst = (iLBC_bits*)PLCresidual;

  /* Reuse some buffers that are non overlapping in order to save stack memory */
  data = &PLCresidual[LPC_FILTERORDER];

  if (mode) { /* the data are good */

    /* decode data */

    /* Unpacketize bits into parameters */

#ifndef WEBRTC_ARCH_BIG_ENDIAN
    WebRtcIlbcfix_SwapBytes(bytes, iLBCdec_inst->no_of_words, swapped);
    last_bit = WebRtcIlbcfix_UnpackBits(swapped, iLBCbits_inst, iLBCdec_inst->mode);
#else
    last_bit = WebRtcIlbcfix_UnpackBits(bytes, iLBCbits_inst, iLBCdec_inst->mode);
#endif

    /* Check for bit errors */
    if (iLBCbits_inst->startIdx<1)
      mode = 0;
    if ((iLBCdec_inst->mode==20) && (iLBCbits_inst->startIdx>3))
      mode = 0;
    if ((iLBCdec_inst->mode==30) && (iLBCbits_inst->startIdx>5))
      mode = 0;
    if (last_bit==1)
      mode = 0;

    if (mode) { /* No bit errors was detected, continue decoding */
      /* Stack based */
      int16_t lsfdeq[LPC_FILTERORDER*LPC_N_MAX];
      int16_t weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];

      /* adjust index */
      WebRtcIlbcfix_IndexConvDec(iLBCbits_inst->cb_index);

      /* decode the lsf */
      WebRtcIlbcfix_SimpleLsfDeQ(lsfdeq, (int16_t*)(iLBCbits_inst->lsf), iLBCdec_inst->lpc_n);
      WebRtcIlbcfix_LsfCheck(lsfdeq, LPC_FILTERORDER, iLBCdec_inst->lpc_n);
      WebRtcIlbcfix_DecoderInterpolateLsp(syntdenum, weightdenum,
                                          lsfdeq, LPC_FILTERORDER, iLBCdec_inst);

      /* Decode the residual using the cb and gain indexes */
      WebRtcIlbcfix_DecodeResidual(iLBCdec_inst, iLBCbits_inst, decresidual, syntdenum);

      /* preparing the plc for a future loss! */
      WebRtcIlbcfix_DoThePlc( PLCresidual, PLClpc, 0,
                              decresidual, syntdenum + (LPC_FILTERORDER + 1)*(iLBCdec_inst->nsub - 1),
                              (int16_t)(iLBCdec_inst->last_lag), iLBCdec_inst);

      /* Use the output from doThePLC */
      WEBRTC_SPL_MEMCPY_W16(decresidual, PLCresidual, iLBCdec_inst->blockl);
    }

  }

  if (mode == 0) {
    /* the data is bad (either a PLC call
     * was made or a bit error was detected)
     */

    /* packet loss conceal */

    WebRtcIlbcfix_DoThePlc( PLCresidual, PLClpc, 1,
                            decresidual, syntdenum, (int16_t)(iLBCdec_inst->last_lag), iLBCdec_inst);

    WEBRTC_SPL_MEMCPY_W16(decresidual, PLCresidual, iLBCdec_inst->blockl);

    order_plus_one = LPC_FILTERORDER + 1;

    for (i = 0; i < iLBCdec_inst->nsub; i++) {
      WEBRTC_SPL_MEMCPY_W16(syntdenum+(i*order_plus_one),
                            PLClpc, order_plus_one);
    }
  }

  if ((*iLBCdec_inst).use_enhancer == 1) { /* Enhancer activated */

    /* Update the filter and filter coefficients if there was a packet loss */
    if (iLBCdec_inst->prev_enh_pl==2) {
      for (i=0;i<iLBCdec_inst->nsub;i++) {
        WEBRTC_SPL_MEMCPY_W16(&(iLBCdec_inst->old_syntdenum[i*(LPC_FILTERORDER+1)]),
                              syntdenum, (LPC_FILTERORDER+1));
      }
    }

    /* post filtering */
    (*iLBCdec_inst).last_lag =
        WebRtcIlbcfix_EnhancerInterface(data, decresidual, iLBCdec_inst);

    /* synthesis filtering */

    /* Set up the filter state */
    WEBRTC_SPL_MEMCPY_W16(&data[-LPC_FILTERORDER], iLBCdec_inst->syntMem, LPC_FILTERORDER);

    if (iLBCdec_inst->mode==20) {
      /* Enhancer has 40 samples delay */
      i=0;
      WebRtcSpl_FilterARFastQ12(
          data, data,
          iLBCdec_inst->old_syntdenum + (i+iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1),
          LPC_FILTERORDER+1, SUBL);

      for (i=1; i < iLBCdec_inst->nsub; i++) {
        WebRtcSpl_FilterARFastQ12(
            data+i*SUBL, data+i*SUBL,
            syntdenum+(i-1)*(LPC_FILTERORDER+1),
            LPC_FILTERORDER+1, SUBL);
      }

    } else if (iLBCdec_inst->mode==30) {
      /* Enhancer has 80 samples delay */
      for (i=0; i < 2; i++) {
        WebRtcSpl_FilterARFastQ12(
            data+i*SUBL, data+i*SUBL,
            iLBCdec_inst->old_syntdenum + (i+4)*(LPC_FILTERORDER+1),
            LPC_FILTERORDER+1, SUBL);
      }
      for (i=2; i < iLBCdec_inst->nsub; i++) {
        WebRtcSpl_FilterARFastQ12(
            data+i*SUBL, data+i*SUBL,
            syntdenum+(i-2)*(LPC_FILTERORDER+1),
            LPC_FILTERORDER+1, SUBL);
      }
    }

    /* Save the filter state */
    WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &data[iLBCdec_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);

  } else { /* Enhancer not activated */
    int16_t lag;

    /* Find last lag (since the enhancer is not called to give this info) */
    lag = 20;
    if (iLBCdec_inst->mode==20) {
      lag = (int16_t)WebRtcIlbcfix_XcorrCoef(
          &decresidual[iLBCdec_inst->blockl-60],
          &decresidual[iLBCdec_inst->blockl-60-lag],
          60,
          80, lag, -1);
    } else {
      lag = (int16_t)WebRtcIlbcfix_XcorrCoef(
          &decresidual[iLBCdec_inst->blockl-ENH_BLOCKL],
          &decresidual[iLBCdec_inst->blockl-ENH_BLOCKL-lag],
          ENH_BLOCKL,
          100, lag, -1);
    }

    /* Store lag (it is needed if next packet is lost) */
    (*iLBCdec_inst).last_lag = (int)lag;

    /* copy data and run synthesis filter */
    WEBRTC_SPL_MEMCPY_W16(data, decresidual, iLBCdec_inst->blockl);

    /* Set up the filter state */
    WEBRTC_SPL_MEMCPY_W16(&data[-LPC_FILTERORDER], iLBCdec_inst->syntMem, LPC_FILTERORDER);

    for (i=0; i < iLBCdec_inst->nsub; i++) {
      WebRtcSpl_FilterARFastQ12(
          data+i*SUBL, data+i*SUBL,
          syntdenum + i*(LPC_FILTERORDER+1),
          LPC_FILTERORDER+1, SUBL);
    }

    /* Save the filter state */
    WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &data[iLBCdec_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);
  }

  WEBRTC_SPL_MEMCPY_W16(decblock,data,iLBCdec_inst->blockl);

  /* High pass filter the signal (with upscaling a factor 2 and saturation) */
  WebRtcIlbcfix_HpOutput(decblock, (int16_t*)WebRtcIlbcfix_kHpOutCoefs,
                         iLBCdec_inst->hpimemy, iLBCdec_inst->hpimemx,
                         iLBCdec_inst->blockl);

  WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->old_syntdenum,
                        syntdenum, iLBCdec_inst->nsub*(LPC_FILTERORDER+1));

  iLBCdec_inst->prev_enh_pl=0;

  if (mode==0) { /* PLC was used */
    iLBCdec_inst->prev_enh_pl=1;
  }
}
Пример #9
0
void WebRtcIlbcfix_GetCbVec(
    int16_t *cbvec,   /* (o) Constructed codebook vector */
    int16_t *mem,   /* (i) Codebook buffer */
    int16_t index,   /* (i) Codebook index */
    int16_t lMem,   /* (i) Length of codebook buffer */
    int16_t cbveclen   /* (i) Codebook vector length */
                            ){
  int16_t k, base_size;
  int16_t lag;
  /* Stack based */
  int16_t tempbuff2[SUBL+5];

  /* Determine size of codebook sections */

  base_size=lMem-cbveclen+1;

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

  /* No filter -> First codebook section */

  if (index<lMem-cbveclen+1) {

    /* first non-interpolated vectors */

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

  } else if (index < base_size) {

    /* Calculate lag */

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

    lag=WEBRTC_SPL_RSHIFT_W16(k, 1);

    WebRtcIlbcfix_CreateAugmentedVec(lag, mem+lMem, cbvec);

  }

  /* Higher codebbok section based on filtering */

  else {

    int16_t memIndTest;

    /* first non-interpolated vectors */

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

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

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

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

      /* do filtering to get the codebook vector */

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

    /* interpolated vectors */

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

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

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

      WebRtcIlbcfix_CreateAugmentedVec(lag, tempbuff2+SUBL+5, cbvec);
    }
  }
}
Пример #10
0
void WebRtcIlbcfix_DecodeResidual(
    IlbcDecoder *iLBCdec_inst,
    /* (i/o) the decoder state structure */
    iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits, which are used
                                for the decoding  */
    int16_t *decresidual,  /* (o) decoded residual frame */
    int16_t *syntdenum   /* (i) the decoded synthesis filter
                                  coefficients */
                                  ) {
  int16_t meml_gotten, Nfor, Nback, diff, start_pos;
  int16_t subcount, subframe;
  int16_t *reverseDecresidual = iLBCdec_inst->enh_buf; /* Reversed decoded data, used for decoding backwards in time (reuse memory in state) */
  int16_t *memVec = iLBCdec_inst->prevResidual;  /* Memory for codebook and filter state (reuse memory in state) */
  int16_t *mem = &memVec[CB_HALFFILTERLEN];   /* Memory for codebook */

  diff = STATE_LEN - iLBCdec_inst->state_short_len;

  if (iLBC_encbits->state_first == 1) {
    start_pos = (iLBC_encbits->startIdx-1)*SUBL;
  } else {
    start_pos = (iLBC_encbits->startIdx-1)*SUBL + diff;
  }

  /* decode scalar part of start state */

  WebRtcIlbcfix_StateConstruct(iLBC_encbits->idxForMax,
                               iLBC_encbits->idxVec, &syntdenum[(iLBC_encbits->startIdx-1)*(LPC_FILTERORDER+1)],
                               &decresidual[start_pos], iLBCdec_inst->state_short_len
                               );

  if (iLBC_encbits->state_first) { /* put adaptive part in the end */

    /* setup memory */

    WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-iLBCdec_inst->state_short_len));
    WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-iLBCdec_inst->state_short_len, decresidual+start_pos,
                          iLBCdec_inst->state_short_len);

    /* construct decoded vector */

    WebRtcIlbcfix_CbConstruct(
        &decresidual[start_pos+iLBCdec_inst->state_short_len],
        iLBC_encbits->cb_index, iLBC_encbits->gain_index,
        mem+CB_MEML-ST_MEM_L_TBL,
        ST_MEM_L_TBL, (int16_t)diff
                              );

  }
  else {/* put adaptive part in the beginning */

    /* setup memory */

    meml_gotten = iLBCdec_inst->state_short_len;
    WebRtcSpl_MemCpyReversedOrder(mem+CB_MEML-1,
                                  decresidual+start_pos, meml_gotten);
    WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-meml_gotten));

    /* construct decoded vector */

    WebRtcIlbcfix_CbConstruct(
        reverseDecresidual,
        iLBC_encbits->cb_index, iLBC_encbits->gain_index,
        mem+CB_MEML-ST_MEM_L_TBL,
        ST_MEM_L_TBL, diff
                              );

    /* get decoded residual from reversed vector */

    WebRtcSpl_MemCpyReversedOrder(&decresidual[start_pos-1],
                                  reverseDecresidual, diff);
  }

  /* counter for predicted subframes */

  subcount=1;

  /* forward prediction of subframes */

  Nfor = iLBCdec_inst->nsub-iLBC_encbits->startIdx-1;

  if( Nfor > 0 ) {

    /* setup memory */
    WebRtcSpl_MemSetW16(mem, 0, CB_MEML-STATE_LEN);
    WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-STATE_LEN,
                          decresidual+(iLBC_encbits->startIdx-1)*SUBL, STATE_LEN);

    /* loop over subframes to encode */

    for (subframe=0; subframe<Nfor; subframe++) {

      /* construct decoded vector */
      WebRtcIlbcfix_CbConstruct(
          &decresidual[(iLBC_encbits->startIdx+1+subframe)*SUBL],
          iLBC_encbits->cb_index+subcount*CB_NSTAGES,
          iLBC_encbits->gain_index+subcount*CB_NSTAGES,
          mem, MEM_LF_TBL, SUBL
                                );

      /* update memory */
      memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
      WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
                            &decresidual[(iLBC_encbits->startIdx+1+subframe)*SUBL], SUBL);

      subcount++;
    }

  }

  /* backward prediction of subframes */

  Nback = iLBC_encbits->startIdx-1;

  if( Nback > 0 ){

    /* setup memory */

    meml_gotten = SUBL*(iLBCdec_inst->nsub+1-iLBC_encbits->startIdx);
    if( meml_gotten > CB_MEML ) {
      meml_gotten=CB_MEML;
    }

    WebRtcSpl_MemCpyReversedOrder(mem+CB_MEML-1,
                                  decresidual+(iLBC_encbits->startIdx-1)*SUBL, meml_gotten);
    WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-meml_gotten));

    /* loop over subframes to decode */

    for (subframe=0; subframe<Nback; subframe++) {

      /* construct decoded vector */
      WebRtcIlbcfix_CbConstruct(
          &reverseDecresidual[subframe*SUBL],
          iLBC_encbits->cb_index+subcount*CB_NSTAGES,
          iLBC_encbits->gain_index+subcount*CB_NSTAGES,
          mem, MEM_LF_TBL, SUBL
                                );

      /* update memory */
      memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
      WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
                            &reverseDecresidual[subframe*SUBL], SUBL);

      subcount++;
    }

    /* get decoded residual from reversed vector */
    WebRtcSpl_MemCpyReversedOrder(decresidual+SUBL*Nback-1,
                                  reverseDecresidual, SUBL*Nback);
  }
}
Пример #11
0
void WebRtcIlbcfix_Refiner(
    WebRtc_Word16 *updStartPos, /* (o) updated start point (Q-2) */
    WebRtc_Word16 *idata,   /* (i) original data buffer */
    WebRtc_Word16 idatal,   /* (i) dimension of idata */
    WebRtc_Word16 centerStartPos, /* (i) beginning center segment */
    WebRtc_Word16 estSegPos,  /* (i) estimated beginning other segment (Q-2) */
    WebRtc_Word16 *surround,  /* (i/o) The contribution from this sequence
                                           summed with earlier contributions */
    WebRtc_Word16 gain    /* (i) Gain to use for this sequence */
                           ){
  WebRtc_Word16 estSegPosRounded,searchSegStartPos,searchSegEndPos,corrdim;
  WebRtc_Word16 tloc,tloc2,i,st,en,fraction;

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

  /* defining array bounds */

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

  searchSegStartPos=estSegPosRounded-ENH_SLOP;

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

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

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

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

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

  scalefact=WebRtcSpl_GetSizeInBits(maxtemp)-15;

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

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

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

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

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

  st=searchSegStartPos+tloc2-ENH_FL0;

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

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

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

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

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

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

  return;
}
Пример #12
0
void WebRtcIlbcfix_SimpleInterpolateLsf(
    int16_t *syntdenum, /* (o) the synthesis filter denominator
                                   resulting from the quantized
                                   interpolated lsf Q12 */
    int16_t *weightdenum, /* (o) the weighting filter denominator
                                   resulting from the unquantized
                                   interpolated lsf Q12 */
    int16_t *lsf,  /* (i) the unquantized lsf coefficients Q13 */
    int16_t *lsfdeq,  /* (i) the dequantized lsf coefficients Q13 */
    int16_t *lsfold,  /* (i) the unquantized lsf coefficients of
                                           the previous signal frame Q13 */
    int16_t *lsfdeqold, /* (i) the dequantized lsf coefficients of the
                                   previous signal frame Q13 */
    int16_t length,  /* (i) should equate FILTERORDER */
    iLBC_Enc_Inst_t *iLBCenc_inst
    /* (i/o) the encoder state structure */
                                        ) {
  int i, pos, lp_length;

  int16_t *lsf2, *lsfdeq2;
  /* Stack based */
  int16_t lp[LPC_FILTERORDER + 1];

  lsf2 = lsf + length;
  lsfdeq2 = lsfdeq + length;
  lp_length = length + 1;

  if (iLBCenc_inst->mode==30) {
    /* subframe 1: Interpolation between old and first set of
       lsf coefficients */

    /* Calculate Analysis/Syntehsis filter from quantized LSF */
    WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsfdeqold, lsfdeq,
                                         WebRtcIlbcfix_kLsfWeight30ms[0],
                                         length);
    WEBRTC_SPL_MEMCPY_W16(syntdenum, lp, lp_length);

    /* Calculate Weighting filter from quantized LSF */
    WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsfold, lsf,
                                         WebRtcIlbcfix_kLsfWeight30ms[0],
                                         length);
    WebRtcIlbcfix_BwExpand(weightdenum, lp,
                           (int16_t*)WebRtcIlbcfix_kLpcChirpWeightDenum,
                           (int16_t)lp_length);

    /* subframe 2 to 6: Interpolation between first and second
       set of lsf coefficients */

    pos = lp_length;
    for (i = 1; i < iLBCenc_inst->nsub; i++) {

      /* Calculate Analysis/Syntehsis filter from quantized LSF */
      WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsfdeq, lsfdeq2,
                                           WebRtcIlbcfix_kLsfWeight30ms[i],
                                           length);
      WEBRTC_SPL_MEMCPY_W16(syntdenum + pos, lp, lp_length);

      /* Calculate Weighting filter from quantized LSF */
      WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsf, lsf2,
                                           WebRtcIlbcfix_kLsfWeight30ms[i],
                                           length);
      WebRtcIlbcfix_BwExpand(weightdenum + pos, lp,
                             (int16_t*)WebRtcIlbcfix_kLpcChirpWeightDenum,
                             (int16_t)lp_length);

      pos += lp_length;
    }

    /* update memory */

    WEBRTC_SPL_MEMCPY_W16(lsfold, lsf2, length);
    WEBRTC_SPL_MEMCPY_W16(lsfdeqold, lsfdeq2, length);

  } else { /* iLBCenc_inst->mode==20 */
    pos = 0;
    for (i = 0; i < iLBCenc_inst->nsub; i++) {

      /* Calculate Analysis/Syntehsis filter from quantized LSF */
      WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsfdeqold, lsfdeq,
                                           WebRtcIlbcfix_kLsfWeight20ms[i],
                                           length);
      WEBRTC_SPL_MEMCPY_W16(syntdenum + pos, lp, lp_length);

      /* Calculate Weighting filter from quantized LSF */
      WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsfold, lsf,
                                           WebRtcIlbcfix_kLsfWeight20ms[i],
                                           length);
      WebRtcIlbcfix_BwExpand(weightdenum+pos, lp,
                             (int16_t*)WebRtcIlbcfix_kLpcChirpWeightDenum,
                             (int16_t)lp_length);

      pos += lp_length;
    }

    /* update memory */

    WEBRTC_SPL_MEMCPY_W16(lsfold, lsf, length);
    WEBRTC_SPL_MEMCPY_W16(lsfdeqold, lsfdeq, length);

  }

  return;
}
Пример #13
0
void WebRtcIlbcfix_EncodeImpl(
    WebRtc_UWord16 *bytes,     /* (o) encoded data bits iLBC */
    const WebRtc_Word16 *block, /* (i) speech vector to encode */
    iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder
                                     state */
                          ){
  int n, meml_gotten, Nfor, Nback;
  WebRtc_Word16 diff, start_pos;
  int index;
  int subcount, subframe;
  WebRtc_Word16 start_count, end_count;
  WebRtc_Word16 *residual;
  WebRtc_Word32 en1, en2;
  WebRtc_Word16 scale, max;
  WebRtc_Word16 *syntdenum;
  WebRtc_Word16 *decresidual;
  WebRtc_Word16 *reverseResidual;
  WebRtc_Word16 *reverseDecresidual;
  /* Stack based */
  WebRtc_Word16 weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
  WebRtc_Word16 dataVec[BLOCKL_MAX + LPC_FILTERORDER];
  WebRtc_Word16 memVec[CB_MEML+CB_FILTERLEN];
  WebRtc_Word16 bitsMemory[sizeof(iLBC_bits)/sizeof(WebRtc_Word16)];
  iLBC_bits *iLBCbits_inst = (iLBC_bits*)bitsMemory;


#ifdef SPLIT_10MS
  WebRtc_Word16 *weightdenumbuf = iLBCenc_inst->weightdenumbuf;
  WebRtc_Word16 last_bit;
#endif

  WebRtc_Word16 *data = &dataVec[LPC_FILTERORDER];
  WebRtc_Word16 *mem = &memVec[CB_HALFFILTERLEN];

  /* Reuse som buffers to save stack memory */
  residual = &iLBCenc_inst->lpc_buffer[LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl];
  syntdenum = mem;      /* syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX] and mem are used non overlapping in the code */
  decresidual = residual;     /* Already encoded residual is overwritten by the decoded version */
  reverseResidual = data;     /* data and reverseResidual are used non overlapping in the code */
  reverseDecresidual = reverseResidual; /* Already encoded residual is overwritten by the decoded version */

#ifdef SPLIT_10MS

  WebRtcSpl_MemSetW16 (  (WebRtc_Word16 *) iLBCbits_inst, 0,
                         (WebRtc_Word16) (sizeof(iLBC_bits) / sizeof(WebRtc_Word16))  );

  start_pos = iLBCenc_inst->start_pos;
  diff = iLBCenc_inst->diff;

  if (iLBCenc_inst->section != 0){
    WEBRTC_SPL_MEMCPY_W16 (weightdenum, weightdenumbuf,
                           SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
    /* Un-Packetize the frame into parameters */
    last_bit = WebRtcIlbcfix_UnpackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
    if (last_bit)
      return;
    /* adjust index */
    WebRtcIlbcfix_IndexConvDec (iLBCbits_inst->cb_index);

    if (iLBCenc_inst->section == 1){
      /* Save first 80 samples of a 160/240 sample frame for 20/30msec */
      WEBRTC_SPL_MEMCPY_W16 (iLBCenc_inst->past_samples, block, 80);
    }
    else{ // iLBCenc_inst->section == 2 AND mode = 30ms
      /* Save second 80 samples of a 240 sample frame for 30msec */
      WEBRTC_SPL_MEMCPY_W16 (iLBCenc_inst->past_samples + 80, block, 80);
    }
  }
  else{ // iLBCenc_inst->section == 0
    /* form a complete frame of 160/240 for 20msec/30msec mode */
    WEBRTC_SPL_MEMCPY_W16 (data + (iLBCenc_inst->mode * 8) - 80, block, 80);
    WEBRTC_SPL_MEMCPY_W16 (data, iLBCenc_inst->past_samples,
                           (iLBCenc_inst->mode * 8) - 80);
    iLBCenc_inst->Nfor_flag = 0;
    iLBCenc_inst->Nback_flag = 0;
#else
    /* copy input block to data*/
    WEBRTC_SPL_MEMCPY_W16(data,block,iLBCenc_inst->blockl);
#endif

    /* high pass filtering of input signal and scale down the residual (*0.5) */
    WebRtcIlbcfix_HpInput(data, (WebRtc_Word16*)WebRtcIlbcfix_kHpInCoefs,
                          iLBCenc_inst->hpimemy, iLBCenc_inst->hpimemx,
                          iLBCenc_inst->blockl);

    /* LPC of hp filtered input data */
    WebRtcIlbcfix_LpcEncode(syntdenum, weightdenum, iLBCbits_inst->lsf, data,
                            iLBCenc_inst);

    /* Set up state */
    WEBRTC_SPL_MEMCPY_W16(dataVec, iLBCenc_inst->anaMem, LPC_FILTERORDER);

    /* inverse filter to get residual */
    for (n=0; n<iLBCenc_inst->nsub; n++ ) {
      WebRtcSpl_FilterMAFastQ12(
          &data[n*SUBL], &residual[n*SUBL],
          &syntdenum[n*(LPC_FILTERORDER+1)],
          LPC_FILTERORDER+1, SUBL);
    }

    /* Copy the state for next frame */
    WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->anaMem, &data[iLBCenc_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);

    /* find state location */

    iLBCbits_inst->startIdx = WebRtcIlbcfix_FrameClassify(iLBCenc_inst,residual);

    /* check if state should be in first or last part of the
       two subframes */

    index = (iLBCbits_inst->startIdx-1)*SUBL;
    max=WebRtcSpl_MaxAbsValueW16(&residual[index], 2*SUBL);
    scale=WebRtcSpl_GetSizeInBits(WEBRTC_SPL_MUL_16_16(max,max));

    /* Scale to maximum 25 bits so that the MAC won't cause overflow */
    scale = scale - 25;
    if(scale < 0) {
      scale = 0;
    }

    diff = STATE_LEN - iLBCenc_inst->state_short_len;
    en1=WebRtcSpl_DotProductWithScale(&residual[index], &residual[index],
                                      iLBCenc_inst->state_short_len, scale);
    index += diff;
    en2=WebRtcSpl_DotProductWithScale(&residual[index], &residual[index],
                                      iLBCenc_inst->state_short_len, scale);
    if (en1 > en2) {
      iLBCbits_inst->state_first = 1;
      start_pos = (iLBCbits_inst->startIdx-1)*SUBL;
    } else {
      iLBCbits_inst->state_first = 0;
      start_pos = (iLBCbits_inst->startIdx-1)*SUBL + diff;
    }

    /* scalar quantization of state */

    WebRtcIlbcfix_StateSearch(iLBCenc_inst, iLBCbits_inst, &residual[start_pos],
                              &syntdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)],
                              &weightdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)]);

    WebRtcIlbcfix_StateConstruct(iLBCbits_inst->idxForMax, iLBCbits_inst->idxVec,
                                 &syntdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)],
                                 &decresidual[start_pos], iLBCenc_inst->state_short_len
                                 );

    /* predictive quantization in state */

    if (iLBCbits_inst->state_first) { /* put adaptive part in the end */

      /* setup memory */

      WebRtcSpl_MemSetW16(mem, 0, (WebRtc_Word16)(CB_MEML-iLBCenc_inst->state_short_len));
      WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-iLBCenc_inst->state_short_len,
                            decresidual+start_pos, iLBCenc_inst->state_short_len);

      /* encode subframes */

      WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
                             &residual[start_pos+iLBCenc_inst->state_short_len],
                             mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, diff,
                             &weightdenum[iLBCbits_inst->startIdx*(LPC_FILTERORDER+1)], 0);

      /* construct decoded vector */

      WebRtcIlbcfix_CbConstruct(&decresidual[start_pos+iLBCenc_inst->state_short_len],
                                iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
                                mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL,
                                diff
                                );

    }
    else { /* put adaptive part in the beginning */

      /* create reversed vectors for prediction */

      WebRtcSpl_MemCpyReversedOrder(&reverseResidual[diff-1],
                                    &residual[(iLBCbits_inst->startIdx+1)*SUBL-STATE_LEN], diff);

      /* setup memory */

      meml_gotten = iLBCenc_inst->state_short_len;
      WebRtcSpl_MemCpyReversedOrder(&mem[CB_MEML-1], &decresidual[start_pos], meml_gotten);
      WebRtcSpl_MemSetW16(mem, 0, (WebRtc_Word16)(CB_MEML-iLBCenc_inst->state_short_len));

      /* encode subframes */
      WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
                             reverseResidual, mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, diff,
                             &weightdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)],
                             0);

      /* construct decoded vector */

      WebRtcIlbcfix_CbConstruct(reverseDecresidual,
                                iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
                                mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL,
                                diff
                                );

      /* get decoded residual from reversed vector */

      WebRtcSpl_MemCpyReversedOrder(&decresidual[start_pos-1], reverseDecresidual, diff);
    }

#ifdef SPLIT_10MS
    iLBCenc_inst->start_pos = start_pos;
    iLBCenc_inst->diff = diff;
    iLBCenc_inst->section++;
    /* adjust index */
    WebRtcIlbcfix_IndexConvEnc (iLBCbits_inst->cb_index);
    /* Packetize the parameters into the frame */
    WebRtcIlbcfix_PackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
    WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum,
                           SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
    return;
  }
#endif

  /* forward prediction of subframes */

  Nfor = iLBCenc_inst->nsub-iLBCbits_inst->startIdx-1;

  /* counter for predicted subframes */
#ifdef SPLIT_10MS
  if (iLBCenc_inst->mode == 20)
  {
    subcount = 1;
  }
  if (iLBCenc_inst->mode == 30)
  {
    if (iLBCenc_inst->section == 1)
    {
      subcount = 1;
    }
    if (iLBCenc_inst->section == 2)
    {
      subcount = 3;
    }
  }
#else
  subcount=1;
#endif

  if( Nfor > 0 ){

    /* setup memory */

    WebRtcSpl_MemSetW16(mem, 0, CB_MEML-STATE_LEN);
    WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-STATE_LEN,
                          decresidual+(iLBCbits_inst->startIdx-1)*SUBL, STATE_LEN);

#ifdef SPLIT_10MS
    if (iLBCenc_inst->Nfor_flag > 0)
    {
      for (subframe = 0; subframe < WEBRTC_SPL_MIN (Nfor, 2); subframe++)
      {
        /* update memory */
        WEBRTC_SPL_MEMCPY_W16 (mem, mem + SUBL, (CB_MEML - SUBL));
        WEBRTC_SPL_MEMCPY_W16 (mem + CB_MEML - SUBL,
                               &decresidual[(iLBCbits_inst->startIdx + 1 +
                                             subframe) * SUBL], SUBL);
      }
    }

    iLBCenc_inst->Nfor_flag++;

    if (iLBCenc_inst->mode == 20)
    {
      start_count = 0;
      end_count = Nfor;
    }
    if (iLBCenc_inst->mode == 30)
    {
      if (iLBCenc_inst->section == 1)
      {
        start_count = 0;
        end_count = WEBRTC_SPL_MIN (Nfor, 2);
      }
      if (iLBCenc_inst->section == 2)
      {
        start_count = WEBRTC_SPL_MIN (Nfor, 2);
        end_count = Nfor;
      }
    }
#else
    start_count = 0;
    end_count = (WebRtc_Word16)Nfor;
#endif

    /* loop over subframes to encode */

    for (subframe = start_count; subframe < end_count; subframe++){

      /* encode subframe */

      WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
                             iLBCbits_inst->gain_index+subcount*CB_NSTAGES,
                             &residual[(iLBCbits_inst->startIdx+1+subframe)*SUBL],
                             mem, MEM_LF_TBL, SUBL,
                             &weightdenum[(iLBCbits_inst->startIdx+1+subframe)*(LPC_FILTERORDER+1)],
                             (WebRtc_Word16)subcount);

      /* construct decoded vector */

      WebRtcIlbcfix_CbConstruct(&decresidual[(iLBCbits_inst->startIdx+1+subframe)*SUBL],
                                iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
                                iLBCbits_inst->gain_index+subcount*CB_NSTAGES,
                                mem, MEM_LF_TBL,
                                SUBL
                                );

      /* update memory */

      WEBRTC_SPL_MEMMOVE_W16(mem, mem+SUBL, (CB_MEML-SUBL));
      WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
                            &decresidual[(iLBCbits_inst->startIdx+1+subframe)*SUBL], SUBL);

      subcount++;
    }
  }

#ifdef SPLIT_10MS
  if ((iLBCenc_inst->section == 1) &&
      (iLBCenc_inst->mode == 30) && (Nfor > 0) && (end_count == 2))
  {
    iLBCenc_inst->section++;
    /* adjust index */
    WebRtcIlbcfix_IndexConvEnc (iLBCbits_inst->cb_index);
    /* Packetize the parameters into the frame */
    WebRtcIlbcfix_PackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
    WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum,
                           SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
    return;
  }
#endif

  /* backward prediction of subframes */

  Nback = iLBCbits_inst->startIdx-1;

  if( Nback > 0 ){

    /* create reverse order vectors
       (The decresidual does not need to be copied since it is
       contained in the same vector as the residual)
    */

    WebRtcSpl_MemCpyReversedOrder(&reverseResidual[Nback*SUBL-1], residual, Nback*SUBL);

    /* setup memory */

    meml_gotten = SUBL*(iLBCenc_inst->nsub+1-iLBCbits_inst->startIdx);
    if( meml_gotten > CB_MEML ) {
      meml_gotten=CB_MEML;
    }

    WebRtcSpl_MemCpyReversedOrder(&mem[CB_MEML-1], &decresidual[Nback*SUBL], meml_gotten);
    WebRtcSpl_MemSetW16(mem, 0, (WebRtc_Word16)(CB_MEML-meml_gotten));

#ifdef SPLIT_10MS
    if (iLBCenc_inst->Nback_flag > 0)
    {
      for (subframe = 0; subframe < WEBRTC_SPL_MAX (2 - Nfor, 0); subframe++)
      {
        /* update memory */
        WEBRTC_SPL_MEMCPY_W16 (mem, mem + SUBL, (CB_MEML - SUBL));
        WEBRTC_SPL_MEMCPY_W16 (mem + CB_MEML - SUBL,
                               &reverseDecresidual[subframe * SUBL], SUBL);
      }
    }

    iLBCenc_inst->Nback_flag++;


    if (iLBCenc_inst->mode == 20)
    {
      start_count = 0;
      end_count = Nback;
    }
    if (iLBCenc_inst->mode == 30)
    {
      if (iLBCenc_inst->section == 1)
      {
        start_count = 0;
        end_count = WEBRTC_SPL_MAX (2 - Nfor, 0);
      }
      if (iLBCenc_inst->section == 2)
      {
        start_count = WEBRTC_SPL_MAX (2 - Nfor, 0);
        end_count = Nback;
      }
    }
#else
    start_count = 0;
    end_count = (WebRtc_Word16)Nback;
#endif

    /* loop over subframes to encode */

    for (subframe = start_count; subframe < end_count; subframe++){

      /* encode subframe */

      WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
                             iLBCbits_inst->gain_index+subcount*CB_NSTAGES, &reverseResidual[subframe*SUBL],
                             mem, MEM_LF_TBL, SUBL,
                             &weightdenum[(iLBCbits_inst->startIdx-2-subframe)*(LPC_FILTERORDER+1)],
                             (WebRtc_Word16)subcount);

      /* construct decoded vector */

      WebRtcIlbcfix_CbConstruct(&reverseDecresidual[subframe*SUBL],
                                iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
                                iLBCbits_inst->gain_index+subcount*CB_NSTAGES,
                                mem, MEM_LF_TBL, SUBL
                                );

      /* update memory */

      WEBRTC_SPL_MEMMOVE_W16(mem, mem+SUBL, (CB_MEML-SUBL));
      WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
                            &reverseDecresidual[subframe*SUBL], SUBL);

      subcount++;

    }

    /* get decoded residual from reversed vector */

    WebRtcSpl_MemCpyReversedOrder(&decresidual[SUBL*Nback-1], reverseDecresidual, SUBL*Nback);
  }
  /* end encoding part */

  /* adjust index */

  WebRtcIlbcfix_IndexConvEnc(iLBCbits_inst->cb_index);

  /* Packetize the parameters into the frame */

#ifdef SPLIT_10MS
  if( (iLBCenc_inst->mode==30) && (iLBCenc_inst->section==1) ){
    WebRtcIlbcfix_PackBits(iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
  }
  else{
    WebRtcIlbcfix_PackBits(bytes, iLBCbits_inst, iLBCenc_inst->mode);
  }
#else
  WebRtcIlbcfix_PackBits(bytes, iLBCbits_inst, iLBCenc_inst->mode);
#endif

#ifndef WEBRTC_BIG_ENDIAN
  /* Swap bytes for LITTLE ENDIAN since the packbits()
     function assumes BIG_ENDIAN machine */
#ifdef SPLIT_10MS
  if (( (iLBCenc_inst->section == 1) && (iLBCenc_inst->mode == 20) ) ||
      ( (iLBCenc_inst->section == 2) && (iLBCenc_inst->mode == 30) )){
    WebRtcIlbcfix_SwapBytes(bytes, iLBCenc_inst->no_of_words, bytes);
  }
#else
  WebRtcIlbcfix_SwapBytes(bytes, iLBCenc_inst->no_of_words, bytes);
#endif
#endif

#ifdef SPLIT_10MS
  if (subcount == (iLBCenc_inst->nsub - 1))
  {
    iLBCenc_inst->section = 0;
  }
  else
  {
    iLBCenc_inst->section++;
    WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum,
                           SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
  }
#endif

}
Пример #14
0
void WebRtcIlbcfix_SimpleLpcAnalysis(
    WebRtc_Word16 *lsf,   /* (o) lsf coefficients */
    WebRtc_Word16 *data,   /* (i) new block of speech */
    iLBC_Enc_Inst_t *iLBCenc_inst
    /* (i/o) the encoder state structure */
                                     ) {
  int k;
  int scale;
  WebRtc_Word16 is;
  WebRtc_Word16 stability;
  /* Stack based */
  WebRtc_Word16 A[LPC_FILTERORDER + 1];
  WebRtc_Word32 R[LPC_FILTERORDER + 1];
  WebRtc_Word16 windowedData[BLOCKL_MAX];
  WebRtc_Word16 rc[LPC_FILTERORDER];

  is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;
  WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->lpc_buffer+is,data,iLBCenc_inst->blockl);

  /* No lookahead, last window is asymmetric */

  for (k = 0; k < iLBCenc_inst->lpc_n; k++) {

    is = LPC_LOOKBACK;

    if (k < (iLBCenc_inst->lpc_n - 1)) {

      /* Hanning table WebRtcIlbcfix_kLpcWin[] is in Q15-domain so the output is right-shifted 15 */
      WebRtcSpl_ElementwiseVectorMult(windowedData, iLBCenc_inst->lpc_buffer, WebRtcIlbcfix_kLpcWin, BLOCKL_MAX, 15);
    } else {

      /* Hanning table WebRtcIlbcfix_kLpcAsymWin[] is in Q15-domain so the output is right-shifted 15 */
      WebRtcSpl_ElementwiseVectorMult(windowedData, iLBCenc_inst->lpc_buffer+is, WebRtcIlbcfix_kLpcAsymWin, BLOCKL_MAX, 15);
    }

    /* Compute autocorrelation */
    WebRtcSpl_AutoCorrelation(windowedData, BLOCKL_MAX, LPC_FILTERORDER, R, &scale);

    /* Window autocorrelation vector */
    WebRtcIlbcfix_Window32W32(R, R, WebRtcIlbcfix_kLpcLagWin, LPC_FILTERORDER + 1 );

    /* Calculate the A coefficients from the Autocorrelation using Levinson Durbin algorithm */
    stability=WebRtcSpl_LevinsonDurbin(R, A, rc, LPC_FILTERORDER);

    /*
       Set the filter to {1.0, 0.0, 0.0,...} if filter from Levinson Durbin algorithm is unstable
       This should basically never happen...
    */
    if (stability!=1) {
      A[0]=4096;
      WebRtcSpl_MemSetW16(&A[1], 0, LPC_FILTERORDER);
    }

    /* Bandwidth expand the filter coefficients */
    WebRtcIlbcfix_BwExpand(A, A, (WebRtc_Word16*)WebRtcIlbcfix_kLpcChirpSyntDenum, LPC_FILTERORDER+1);

    /* Convert from A to LSF representation */
    WebRtcIlbcfix_Poly2Lsf(lsf + k*LPC_FILTERORDER, A);
  }

  is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;
  WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->lpc_buffer,
                        iLBCenc_inst->lpc_buffer+LPC_LOOKBACK+BLOCKL_MAX-is, is);

  return;
}
Пример #15
0
void WebRtcG729fix_Decod_ld8a(
  Decod_ld8a_state *st,
  int16_t  parm[],      /* (i)   : vector of synthesis parameters
                                  parm[0] = bad frame indicator (bfi)   */
  int16_t  synth[],     /* (o)   : synthesis speech                     */
  int16_t  A_t[],       /* (o)   : decoded LP filter in 2 subframes     */
  int16_t  *T2,         /* (o)   : decoded pitch lag in 2 subframes     */
  int16_t  *Vad,        /* (o)   : frame type                           */
  int16_t  bad_lsf      /* (i)   : bad LSF indicator                    */
)
{
  int16_t  *Az;                  /* Pointer on A_t   */
  int16_t  lsp_new[M];           /* LSPs             */
  int16_t  code[L_SUBFR];        /* ACELP codevector */

  /* Scalars */

  int16_t  i, j, i_subfr;
  int16_t  T0, T0_frac, index;
  int16_t  bfi;
  int32_t  L_temp;

  int16_t bad_pitch;             /* bad pitch indicator */

  /* for G.729B */
  int16_t ftyp;
  int16_t lsfq_mem[MA_NP][M];

  int Overflow;

  /* Test bad frame indicator (bfi) */

  bfi = *parm++;
  /* for G.729B */
  ftyp = *parm;

  if(bfi == 1) {
    if(st->past_ftyp == 1) {
      ftyp = 1;
      parm[4] = 1;    /* G.729 maintenance */
    }
    else ftyp = 0;
    *parm = ftyp;  /* modification introduced in version V1.3 */
  }
  
  *Vad = ftyp;

  /* Processing non active frames (SID & not transmitted) */
  if(ftyp != 1) {
    
    WebRtcG729fix_Get_decfreq_prev(st, lsfq_mem);
    WebRtcG729fix_Dec_cng(st, st->past_ftyp, st->sid_sav, st->sh_sid_sav,
            parm, st->exc, st->lsp_old, A_t, &st->seed, lsfq_mem);
    WebRtcG729fix_Update_decfreq_prev(st, lsfq_mem);

    Az = A_t;
    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) {
      Overflow = WebRtcG729fix_Syn_filt(Az, &st->exc[i_subfr], &synth[i_subfr], L_SUBFR, st->mem_syn, 0);
      if(Overflow != 0) {
        /* In case of overflow in the synthesis          */
        /* -> Scale down vector exc[] and redo synthesis */
        
        for (i = 0; i < PIT_MAX + L_INTERPOL + L_FRAME; i++)
          st->old_exc[i] = shr(st->old_exc[i], 2);
        
        WebRtcG729fix_Syn_filt(Az, &st->exc[i_subfr], &synth[i_subfr], L_SUBFR, st->mem_syn, 1);
      }
      else
        WEBRTC_SPL_MEMCPY_W16(st->mem_syn, &synth[i_subfr+L_SUBFR-M], M);
      
      Az += MP1;

      *T2++ = st->old_T0;
    }
    st->sharp = SHARPMIN;
    
  }
  /* Processing active frame */
  else {
    
    st->seed = INIT_SEED;
    parm++;

    /* Decode the LSPs */
    
    WebRtcG729fix_D_lsp(st, parm, lsp_new, WebRtcSpl_AddSatW16(bfi, bad_lsf));
    parm += 2;
    
    /*
       Note: "bad_lsf" is introduce in case the standard is used with
       channel protection.
       */
    
    /* Interpolation of LPC for the 2 subframes */
    
    WebRtcG729fix_Int_qlpc(st->lsp_old, lsp_new, A_t);
    
    /* update the LSFs for the next frame */
    
    WEBRTC_SPL_MEMCPY_W16(st->lsp_old, lsp_new, M);
    
    /*------------------------------------------------------------------------*
     *          Loop for every subframe in the analysis frame                 *
     *------------------------------------------------------------------------*
     * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR  *
     *  times                                                                 *
     *     - decode the pitch delay                                           *
     *     - decode algebraic code                                            *
     *     - decode pitch and codebook gains                                  *
     *     - find the excitation and compute synthesis speech                 *
     *------------------------------------------------------------------------*/
    
    Az = A_t;            /* pointer to interpolated LPC parameters */
    
    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
      {

        index = *parm++;        /* pitch index */

        if(i_subfr == 0)
          {
            i = *parm++;        /* get parity check result */
            bad_pitch = WebRtcSpl_AddSatW16(bfi, i);
            if( bad_pitch == 0)
              {
                WebRtcG729fix_Dec_lag3(index, PIT_MIN, PIT_MAX, i_subfr, &T0, &T0_frac);
                st->old_T0 = T0;
              }
            else                /* Bad frame, or parity error */
              {
                T0  = st->old_T0;
                T0_frac = 0;
                st->old_T0 = WebRtcSpl_AddSatW16(st->old_T0, 1);
                if(st->old_T0 > PIT_MAX) {
                  st->old_T0 = PIT_MAX;
                }
              }
          }
        else                    /* second subframe */
          {
            if(bfi == 0)
              {
                WebRtcG729fix_Dec_lag3(index, PIT_MIN, PIT_MAX, i_subfr, &T0, &T0_frac);
                st->old_T0 = T0;
              }
            else
              {
                T0 = st->old_T0;
                T0_frac = 0;
                st->old_T0 = WebRtcSpl_AddSatW16(st->old_T0, 1);
                if (st->old_T0 > PIT_MAX) {
                  st->old_T0 = PIT_MAX;
                }
              }
          }
        *T2++ = T0;

        /*-------------------------------------------------*
         * - Find the adaptive codebook vector.            *
         *-------------------------------------------------*/

        WebRtcG729fix_Pred_lt_3(&st->exc[i_subfr], T0, T0_frac, L_SUBFR);

        /*-------------------------------------------------------*
         * - Decode innovative codebook.                         *
         * - Add the fixed-gain pitch contribution to code[].    *
         *-------------------------------------------------------*/

        if(bfi != 0)            /* Bad frame */
          {

            parm[0] = WebRtcG729fix_Random(&st->seed_fer) & (int16_t)0x1fff; /* 13 bits random */
            parm[1] = WebRtcG729fix_Random(&st->seed_fer) & (int16_t)0x000f; /*  4 bits random */
          }

        WebRtcG729fix_Decod_ACELP(parm[1], parm[0], code);
        parm +=2;

        j = shl(st->sharp, 1);      /* From Q14 to Q15 */
        if(T0 < L_SUBFR) {
          for (i = T0; i < L_SUBFR; i++) {
            code[i] = WebRtcSpl_AddSatW16(code[i], mult(code[i-T0], j));
          }
        }

        /*-------------------------------------------------*
         * - Decode pitch and codebook gains.              *
         *-------------------------------------------------*/

        index = *parm++;        /* index of energy VQ */

        WebRtcG729fix_Dec_gain(st, index, code, L_SUBFR, bfi, &st->gain_pitch, &st->gain_code);

        /*-------------------------------------------------------------*
         * - Update pitch sharpening "sharp" with quantized gain_pitch *
         *-------------------------------------------------------------*/

        st->sharp = st->gain_pitch;
        if (st->sharp > SHARPMAX)      { st->sharp = SHARPMAX; }
        else if (st->sharp < SHARPMIN) { st->sharp = SHARPMIN; }

        /*-------------------------------------------------------*
         * - Find the total excitation.                          *
         * - Find synthesis speech corresponding to exc[].       *
         *-------------------------------------------------------*/

        for (i = 0; i < L_SUBFR;  i++)
          {
            /* exc[i] = gain_pitch*exc[i] + gain_code*code[i]; */
            /* exc[i]  in Q0   gain_pitch in Q14               */
            /* code[i] in Q13  gain_codeode in Q1              */
            
            L_temp = L_mult(st->exc[i+i_subfr], st->gain_pitch);
            L_temp = L_mac(L_temp, code[i], st->gain_code);
            L_temp = L_shl(L_temp, 1);
            st->exc[i+i_subfr] = L_round(L_temp);
          }
        
        Overflow = WebRtcG729fix_Syn_filt(Az, &st->exc[i_subfr], &synth[i_subfr], L_SUBFR, st->mem_syn, 0);
        if(Overflow != 0)
          {
            /* In case of overflow in the synthesis          */
            /* -> Scale down vector exc[] and redo synthesis */

            for (i = 0; i < PIT_MAX + L_INTERPOL + L_FRAME; i++)
              st->old_exc[i] = shr(st->old_exc[i], 2);

            WebRtcG729fix_Syn_filt(Az, &st->exc[i_subfr], &synth[i_subfr], L_SUBFR, st->mem_syn, 1);
          }
        else
          WEBRTC_SPL_MEMCPY_W16(st->mem_syn, &synth[i_subfr+L_SUBFR-M], M);

        Az += MP1;              /* interpolated LPC parameters for next subframe */
      }
  }
  
  /*------------*
   *  For G729b
   *-----------*/
  if(bfi == 0) {
    L_temp = 0L;
    for (i = 0; i < L_FRAME; i++) {
      L_temp = L_mac(L_temp, st->exc[i], st->exc[i]);
    } /* may overflow => last level of SID quantizer */
    st->sh_sid_sav = WebRtcSpl_NormW32(L_temp);
    st->sid_sav = L_round(L_shl(L_temp, st->sh_sid_sav));
    st->sh_sid_sav = WebRtcSpl_SubSatW16(16, st->sh_sid_sav);
  }

 /*--------------------------------------------------*
  * Update signal for next frame.                    *
  * -> shift to the left by L_FRAME  exc[]           *
  *--------------------------------------------------*/

  Copy(&st->old_exc[L_FRAME], &st->old_exc[0], PIT_MAX+L_INTERPOL);

  /* for G729b */
  st->past_ftyp = ftyp;

  return;
}
Пример #16
0
/*-----------------------------------------------------------*
 * procedure Calc_exc_rand                                   *
 *           ~~~~~~~~~~~~~                                   *
 *   Computes comfort noise excitation                       *
 *   for SID and not-transmitted frames                      *
 *-----------------------------------------------------------*/
void WebRtcG729fix_Calc_exc_rand(
  int32_t L_exc_err[],
  int16_t cur_gain,      /* (i)   :   target sample gain                 */
  int16_t *exc,          /* (i/o) :   excitation array                   */
  int16_t *seed,         /* (i)   :   current Vad decision               */
  int flag_cod           /* (i)   :   encoder/decoder flag               */
)
{
  int16_t i, j, i_subfr;
  int16_t temp1, temp2;
  int16_t pos[4];
  int16_t sign[4];
  int16_t t0, frac;
  int16_t *cur_exc;
  int16_t g, Gp, Gp2;
  int16_t excg[L_SUBFR], excs[L_SUBFR];
  int32_t L_acc, L_ener, L_k;
  int16_t max, hi, lo, inter_exc;
  int16_t sh;
  int16_t x1, x2;
  
  if (cur_gain == 0) {
    WebRtcSpl_ZerosArrayW16(exc, L_FRAME);
    Gp = 0;
    t0 = WebRtcSpl_AddSatW16(L_SUBFR,1);
    for (i_subfr = 0;  i_subfr < L_FRAME; i_subfr += L_SUBFR) {
      if (flag_cod != FLAG_DEC)
        WebRtcG729fix_update_exc_err(L_exc_err, Gp, t0);
    }
    return;
  }
  
  /* Loop on subframes */
  
  cur_exc = exc;
  
  for (i_subfr = 0;  i_subfr < L_FRAME; i_subfr += L_SUBFR) {

    /* generate random adaptive codebook & fixed codebook parameters */
    /*****************************************************************/
    temp1 = WebRtcG729fix_Random(seed);
    frac = WebRtcSpl_SubSatW16((temp1 & (int16_t)0x0003), 1);
    if(frac == 2) frac = 0;
    temp1 = shr(temp1, 2);
    t0 = WebRtcSpl_AddSatW16((temp1 & (int16_t)0x003F), 40);
    temp1 = shr(temp1, 6);
    temp2 = temp1 & (int16_t)0x0007;
    pos[0] = WebRtcSpl_AddSatW16(shl(temp2, 2), temp2); /* 5 * temp2 */
    temp1 = shr(temp1, 3);
    sign[0] = temp1 & (int16_t)0x0001;
    temp1 = shr(temp1, 1);
    temp2 = temp1 & (int16_t)0x0007;
    temp2 = WebRtcSpl_AddSatW16(shl(temp2, 2), temp2);
    pos[1] = WebRtcSpl_AddSatW16(temp2, 1);     /* 5 * x + 1 */
    temp1 = shr(temp1, 3);
    sign[1] = temp1 & (int16_t)0x0001;
    temp1 = WebRtcG729fix_Random(seed);
    temp2 = temp1 & (int16_t)0x0007;
    temp2 = WebRtcSpl_AddSatW16(shl(temp2, 2), temp2);
    pos[2] = WebRtcSpl_AddSatW16(temp2, 2);     /* 5 * x + 2 */
    temp1 = shr(temp1, 3);
    sign[2] = temp1 & (int16_t)0x0001;
    temp1 = shr(temp1, 1);
    temp2 = temp1 & (int16_t)0x000F;
    pos[3] = WebRtcSpl_AddSatW16((temp2 & (int16_t)1), 3); /* j+3*/
    temp2 = (shr(temp2, 1)) & (int16_t)7;
    temp2 = WebRtcSpl_AddSatW16(shl(temp2, 2), temp2); /* 5i */
    pos[3] = WebRtcSpl_AddSatW16(pos[3], temp2);
    temp1 = shr(temp1, 4);
    sign[3] = temp1 & (int16_t)0x0001;
    Gp = WebRtcG729fix_Random(seed) & (int16_t)0x1FFF; /* < 0.5 Q14 */
    Gp2 = shl(Gp, 1);           /* Q15 */


    /* Generate gaussian excitation */
    /********************************/
    L_acc = 0L;
    for(i=0; i<L_SUBFR; i++) {
      temp1 = Gauss(seed);
      L_acc = L_mac(L_acc, temp1, temp1);
      excg[i] = temp1;
    }

/*
    Compute fact = alpha x cur_gain * sqrt(L_SUBFR / Eg)
    with Eg = SUM(i=0->39) excg[i]^2
    and alpha = 0.5
    alpha x sqrt(L_SUBFR)/2 = 1 + FRAC1
*/
    L_acc = WebRtcG729fix_Inv_sqrt(L_shr(L_acc,1));  /* Q30 */
    WebRtcG729fix_L_Extract(L_acc, &hi, &lo);
    /* cur_gain = cur_gainR << 3 */
    temp1 = mult_r(cur_gain, FRAC1);
    temp1 = WebRtcSpl_AddSatW16(cur_gain, temp1);
    /* <=> alpha x cur_gainR x 2^2 x sqrt(L_SUBFR) */

    L_acc = WebRtcG729fix_Mpy_32_16(hi, lo, temp1);   /* fact << 17 */
    sh = WebRtcSpl_NormW32(L_acc);
    temp1 = extract_h(L_shl(L_acc, sh));  /* fact << (sh+1) */

    sh = WebRtcSpl_SubSatW16(sh, 14);
    for (i = 0; i < L_SUBFR; i++) {
      temp2 = mult_r(excg[i], temp1);
      temp2 = shr_r(temp2, sh);   /* shl if sh < 0 */
      excg[i] = temp2;
    }

    /* generate random  adaptive excitation */
    /****************************************/
    WebRtcG729fix_Pred_lt_3(cur_exc, t0, frac, L_SUBFR);


    /* compute adaptive + gaussian exc -> cur_exc */
    /**********************************************/
    max = 0;
    for(i = 0; i < L_SUBFR; i++) {
      temp1 = mult_r(cur_exc[i], Gp2);
      temp1 = WebRtcSpl_AddSatW16(temp1, excg[i]); /* may overflow */
      cur_exc[i] = temp1;
      temp1 = abs_s(temp1);
      if (temp1 > max)
        max = temp1;
    }

    /* rescale cur_exc -> excs */
    if (max == 0)
      sh = 0;
    else {
      sh = WebRtcSpl_SubSatW16(3, WebRtcSpl_NormW16(max));
      if (sh <= 0)
        sh = 0;
    }
    for (i = 0; i < L_SUBFR; i++) {
      excs[i] = shr(cur_exc[i], sh);
    }

    /* Compute fixed code gain */
    /***************************/

    /**********************************************************/
    /*** Solve EQ(X) = 4 X**2 + 2 b X + c                     */
    /**********************************************************/

    L_ener = 0L;
    for (i = 0; i < L_SUBFR; i++) {
      L_ener = L_mac(L_ener, excs[i], excs[i]);
    } /* ener x 2^(-2sh + 1) */

    /* inter_exc = b >> sh */
    inter_exc = 0;
    for (i = 0; i < 4; i++) {
      j = pos[i];
      if (sign[i] == 0) {
        inter_exc = WebRtcSpl_SubSatW16(inter_exc, excs[j]);
      }
      else {
        inter_exc = WebRtcSpl_AddSatW16(inter_exc, excs[j]);
      }
    }

    /* Compute k = cur_gainR x cur_gainR x L_SUBFR */
    L_acc = L_mult(cur_gain, L_SUBFR);
    L_acc = L_shr(L_acc, 6);
    temp1 = extract_l(L_acc);   /* cur_gainR x L_SUBFR x 2^(-2) */
    L_k   = L_mult(cur_gain, temp1); /* k << 2 */
    temp1 = WebRtcSpl_AddSatW16(1, shl(sh,1));
    L_acc = L_shr(L_k, temp1);  /* k x 2^(-2sh+1) */

    /* Compute delta = b^2 - 4 c */
    L_acc = WebRtcSpl_SubSatW32(L_acc, L_ener); /* - 4 c x 2^(-2sh-1) */
    inter_exc = shr(inter_exc, 1);
    L_acc = L_mac(L_acc, inter_exc, inter_exc); /* 2^(-2sh-1) */
    sh = WebRtcSpl_AddSatW16(sh, 1);
    /* inter_exc = b x 2^(-sh) */
    /* L_acc = delta x 2^(-2sh+1) */

    if (L_acc < 0) {

      /* adaptive excitation = 0 */
      WEBRTC_SPL_MEMCPY_W16(cur_exc, excg, L_SUBFR);
      temp1 = abs_s(excg[(int)pos[0]]) | abs_s(excg[(int)pos[1]]);
      temp2 = abs_s(excg[(int)pos[2]]) | abs_s(excg[(int)pos[3]]);
      temp1 = temp1 | temp2;
      sh = ((temp1 & (int16_t)0x4000) == 0) ? (int16_t)1 : (int16_t)2;
      inter_exc = 0;
      for(i=0; i<4; i++) {
        temp1 = shr(excg[(int)pos[i]], sh);
        if(sign[i] == 0) {
          inter_exc = WebRtcSpl_SubSatW16(inter_exc, temp1);
        }
        else {
          inter_exc = WebRtcSpl_AddSatW16(inter_exc, temp1);
        }
      } /* inter_exc = b >> sh */
      WebRtcG729fix_L_Extract(L_k, &hi, &lo);
      L_acc = WebRtcG729fix_Mpy_32_16(hi, lo, K0); /* k x (1- alpha^2) << 2 */
      temp1 = WebRtcSpl_SubSatW16(shl(sh, 1), 1); /* temp1 > 0 */
      L_acc = L_shr(L_acc, temp1); /* 4k x (1 - alpha^2) << (-2sh+1) */
      L_acc = L_mac(L_acc, inter_exc, inter_exc); /* delta << (-2sh+1) */
      Gp = 0;
    }

    temp2 = Sqrt(L_acc);        /* >> sh */
    x1 = WebRtcSpl_SubSatW16(temp2, inter_exc);
    x2 = negate(WebRtcSpl_AddSatW16(inter_exc, temp2)); /* x 2^(-sh+2) */
    if(abs_s(x2) < abs_s(x1)) x1 = x2;
    temp1 = WebRtcSpl_SubSatW16(2, sh);
    g = shr_r(x1, temp1);       /* shl if temp1 < 0 */
    if (g >= 0) {
      if (g > G_MAX)
        g = G_MAX;
    }
    else {
      if (WebRtcSpl_AddSatW16(g, G_MAX) < 0)
        g = negate(G_MAX);
    }

    /* Update cur_exc with ACELP excitation */
    for (i = 0; i < 4; i++) {
      j = pos[i];
      if (sign[i] != 0) {
        cur_exc[j] = WebRtcSpl_AddSatW16(cur_exc[j], g);
      }
      else {
        cur_exc[j] = WebRtcSpl_SubSatW16(cur_exc[j], g);
      }
    }

    if (flag_cod != FLAG_DEC)
      WebRtcG729fix_update_exc_err(L_exc_err, Gp, t0);

    cur_exc += L_SUBFR;
  } /* end of loop on subframes */
  
  return;
}
Пример #17
0
void WebRtcIlbcfix_CbSearch(
    IlbcEncoder *iLBCenc_inst,
    /* (i) the encoder state structure */
    int16_t *index,  /* (o) Codebook indices */
    int16_t *gain_index, /* (o) Gain quantization indices */
    int16_t *intarget, /* (i) Target vector for encoding */
    int16_t *decResidual,/* (i) Decoded residual for codebook construction */
    int16_t lMem,  /* (i) Length of buffer */
    int16_t lTarget,  /* (i) Length of vector */
    int16_t *weightDenum,/* (i) weighting filter coefficients in Q12 */
    int16_t block  /* (i) the subblock number */
                            ) {
  int16_t i, j, stage, range;
  int16_t *pp, scale, tmp;
  int16_t bits, temp1, temp2;
  int16_t base_size;
  int32_t codedEner, targetEner;
  int16_t gains[CB_NSTAGES+1];
  int16_t *cb_vecPtr;
  int16_t indexOffset, sInd, eInd;
  int32_t CritMax=0;
  int16_t shTotMax=WEBRTC_SPL_WORD16_MIN;
  int16_t bestIndex=0;
  int16_t bestGain=0;
  int16_t indexNew, CritNewSh;
  int32_t CritNew;
  int32_t *cDotPtr;
  int16_t noOfZeros;
  int16_t *gainPtr;
  int32_t t32, tmpW32;
  int16_t *WebRtcIlbcfix_kGainSq5_ptr;
  /* Stack based */
  int16_t CBbuf[CB_MEML+LPC_FILTERORDER+CB_HALFFILTERLEN];
  int32_t cDot[128];
  int32_t Crit[128];
  int16_t targetVec[SUBL+LPC_FILTERORDER];
  int16_t cbvectors[CB_MEML + 1];  /* Adding one extra position for
                                            Coverity warnings. */
  int16_t codedVec[SUBL];
  int16_t interpSamples[20*4];
  int16_t interpSamplesFilt[20*4];
  int16_t energyW16[CB_EXPAND*128];
  int16_t energyShifts[CB_EXPAND*128];
  int16_t *inverseEnergy=energyW16;   /* Reuse memory */
  int16_t *inverseEnergyShifts=energyShifts; /* Reuse memory */
  int16_t *buf = &CBbuf[LPC_FILTERORDER];
  int16_t *target = &targetVec[LPC_FILTERORDER];
  int16_t *aug_vec = (int16_t*)cDot;   /* length [SUBL], reuse memory */

  /* Determine size of codebook sections */

  base_size=lMem-lTarget+1;
  if (lTarget==SUBL) {
    base_size=lMem-19;
  }

  /* weighting of the CB memory */
  noOfZeros=lMem-WebRtcIlbcfix_kFilterRange[block];
  WebRtcSpl_MemSetW16(&buf[-LPC_FILTERORDER], 0, noOfZeros+LPC_FILTERORDER);
  WebRtcSpl_FilterARFastQ12(
      decResidual+noOfZeros, buf+noOfZeros,
      weightDenum, LPC_FILTERORDER+1, WebRtcIlbcfix_kFilterRange[block]);

  /* weighting of the target vector */
  WEBRTC_SPL_MEMCPY_W16(&target[-LPC_FILTERORDER], buf+noOfZeros+WebRtcIlbcfix_kFilterRange[block]-LPC_FILTERORDER, LPC_FILTERORDER);
  WebRtcSpl_FilterARFastQ12(
      intarget, target,
      weightDenum, LPC_FILTERORDER+1, lTarget);

  /* Store target, towards the end codedVec is calculated as
     the initial target minus the remaining target */
  WEBRTC_SPL_MEMCPY_W16(codedVec, target, lTarget);

  /* Find the highest absolute value to calculate proper
     vector scale factor (so that it uses 12 bits) */
  temp1 = WebRtcSpl_MaxAbsValueW16(buf, (int16_t)lMem);
  temp2 = WebRtcSpl_MaxAbsValueW16(target, (int16_t)lTarget);

  if ((temp1>0)&&(temp2>0)) {
    temp1 = WEBRTC_SPL_MAX(temp1, temp2);
    scale = WebRtcSpl_GetSizeInBits(WEBRTC_SPL_MUL_16_16(temp1, temp1));
  } else {
    /* temp1 or temp2 is negative (maximum was -32768) */
    scale = 30;
  }

  /* Scale to so that a mul-add 40 times does not overflow */
  scale = scale - 25;
  scale = WEBRTC_SPL_MAX(0, scale);

  /* Compute energy of the original target */
  targetEner = WebRtcSpl_DotProductWithScale(target, target, lTarget, scale);

  /* Prepare search over one more codebook section. This section
     is created by filtering the original buffer with a filter. */
  WebRtcIlbcfix_FilteredCbVecs(cbvectors, buf, lMem, WebRtcIlbcfix_kFilterRange[block]);

  range = WebRtcIlbcfix_kSearchRange[block][0];

  if(lTarget == SUBL) {
    /* Create the interpolated samples and store them for use in all stages */

    /* First section, non-filtered half of the cb */
    WebRtcIlbcfix_InterpolateSamples(interpSamples, buf, lMem);

    /* Second section, filtered half of the cb */
    WebRtcIlbcfix_InterpolateSamples(interpSamplesFilt, cbvectors, lMem);

    /* Compute the CB vectors' energies for the first cb section (non-filtered) */
    WebRtcIlbcfix_CbMemEnergyAugmentation(interpSamples, buf,
                                          scale, 20, energyW16, energyShifts);

    /* Compute the CB vectors' energies for the second cb section (filtered cb) */
    WebRtcIlbcfix_CbMemEnergyAugmentation(interpSamplesFilt, cbvectors,
                                          scale, (int16_t)(base_size+20), energyW16, energyShifts);

    /* Compute the CB vectors' energies and store them in the vector
     * energyW16. Also the corresponding shift values are stored. The
     * energy values are used in all three stages. */
    WebRtcIlbcfix_CbMemEnergy(range, buf, cbvectors, lMem,
                              lTarget, energyW16+20, energyShifts+20, scale, base_size);

  } else {
    /* Compute the CB vectors' energies and store them in the vector
     * energyW16. Also the corresponding shift values are stored. The
     * energy values are used in all three stages. */
    WebRtcIlbcfix_CbMemEnergy(range, buf, cbvectors, lMem,
                              lTarget, energyW16, energyShifts, scale, base_size);

    /* Set the energy positions 58-63 and 122-127 to zero
       (otherwise they are uninitialized) */
    WebRtcSpl_MemSetW16(energyW16+range, 0, (base_size-range));
    WebRtcSpl_MemSetW16(energyW16+range+base_size, 0, (base_size-range));
  }

  /* Calculate Inverse Energy (energyW16 is already normalized
     and will contain the inverse energy in Q29 after this call */
  WebRtcIlbcfix_EnergyInverse(energyW16, base_size*CB_EXPAND);

  /* The gain value computed in the previous stage is used
   * as an upper limit to what the next stage gain value
   * is allowed to be. In stage 0, 16384 (1.0 in Q14) is used as
   * the upper limit. */
  gains[0] = 16384;

  for (stage=0; stage<CB_NSTAGES; stage++) {

    /* Set up memories */
    range = WebRtcIlbcfix_kSearchRange[block][stage];

    /* initialize search measures */
    CritMax=0;
    shTotMax=-100;
    bestIndex=0;
    bestGain=0;

    /* loop over lags 40+ in the first codebook section, full search */
    cb_vecPtr = buf+lMem-lTarget;

    /* Calculate all the cross correlations (augmented part of CB) */
    if (lTarget==SUBL) {
      WebRtcIlbcfix_AugmentedCbCorr(target, buf+lMem,
                                    interpSamples, cDot,
                                    20, 39, scale);
      cDotPtr=&cDot[20];
    } else {
      cDotPtr=cDot;
    }
    /* Calculate all the cross correlations (main part of CB) */
    WebRtcSpl_CrossCorrelation(cDotPtr, target, cb_vecPtr, lTarget, range, scale, -1);

    /* Adjust the search range for the augmented vectors */
    if (lTarget==SUBL) {
      range=WebRtcIlbcfix_kSearchRange[block][stage]+20;
    } else {
      range=WebRtcIlbcfix_kSearchRange[block][stage];
    }

    indexOffset=0;

    /* Search for best index in this part of the vector */
    WebRtcIlbcfix_CbSearchCore(
        cDot, range, stage, inverseEnergy,
        inverseEnergyShifts, Crit,
        &indexNew, &CritNew, &CritNewSh);

    /* Update the global best index and the corresponding gain */
    WebRtcIlbcfix_CbUpdateBestIndex(
        CritNew, CritNewSh, (int16_t)(indexNew+indexOffset), cDot[indexNew+indexOffset],
        inverseEnergy[indexNew+indexOffset], inverseEnergyShifts[indexNew+indexOffset],
        &CritMax, &shTotMax, &bestIndex, &bestGain);

    sInd=bestIndex-(int16_t)(CB_RESRANGE>>1);
    eInd=sInd+CB_RESRANGE;
    if (sInd<0) {
      eInd-=sInd;
      sInd=0;
    }
    if (eInd>=range) {
      eInd=range-1;
      sInd=eInd-CB_RESRANGE;
    }

    range = WebRtcIlbcfix_kSearchRange[block][stage];

    if (lTarget==SUBL) {
      i=sInd;
      if (sInd<20) {
        WebRtcIlbcfix_AugmentedCbCorr(target, cbvectors+lMem,
                                      interpSamplesFilt, cDot,
                                      (int16_t)(sInd+20), (int16_t)(WEBRTC_SPL_MIN(39, (eInd+20))), scale);
        i=20;
      }

      cDotPtr=&cDot[WEBRTC_SPL_MAX(0,(20-sInd))];
      cb_vecPtr = cbvectors+lMem-20-i;

      /* Calculate the cross correlations (main part of the filtered CB) */
      WebRtcSpl_CrossCorrelation(cDotPtr, target, cb_vecPtr, lTarget, (int16_t)(eInd-i+1), scale, -1);

    } else {
      cDotPtr = cDot;
      cb_vecPtr = cbvectors+lMem-lTarget-sInd;

      /* Calculate the cross correlations (main part of the filtered CB) */
      WebRtcSpl_CrossCorrelation(cDotPtr, target, cb_vecPtr, lTarget, (int16_t)(eInd-sInd+1), scale, -1);

    }

    /* Adjust the search range for the augmented vectors */
    indexOffset=base_size+sInd;

    /* Search for best index in this part of the vector */
    WebRtcIlbcfix_CbSearchCore(
        cDot, (int16_t)(eInd-sInd+1), stage, inverseEnergy+indexOffset,
        inverseEnergyShifts+indexOffset, Crit,
        &indexNew, &CritNew, &CritNewSh);

    /* Update the global best index and the corresponding gain */
    WebRtcIlbcfix_CbUpdateBestIndex(
        CritNew, CritNewSh, (int16_t)(indexNew+indexOffset), cDot[indexNew],
        inverseEnergy[indexNew+indexOffset], inverseEnergyShifts[indexNew+indexOffset],
        &CritMax, &shTotMax, &bestIndex, &bestGain);

    index[stage] = bestIndex;


    bestGain = WebRtcIlbcfix_GainQuant(bestGain,
                                       (int16_t)WEBRTC_SPL_ABS_W16(gains[stage]), stage, &gain_index[stage]);

    /* Extract the best (according to measure) codebook vector
       Also adjust the index, so that the augmented vectors are last.
       Above these vectors were first...
    */

    if(lTarget==(STATE_LEN-iLBCenc_inst->state_short_len)) {

      if(index[stage]<base_size) {
        pp=buf+lMem-lTarget-index[stage];
      } else {
        pp=cbvectors+lMem-lTarget-
            index[stage]+base_size;
      }

    } else {

      if (index[stage]<base_size) {
        if (index[stage]>=20) {
          /* Adjust index and extract vector */
          index[stage]-=20;
          pp=buf+lMem-lTarget-index[stage];
        } else {
          /* Adjust index and extract vector */
          index[stage]+=(base_size-20);

          WebRtcIlbcfix_CreateAugmentedVec((int16_t)(index[stage]-base_size+40),
                                           buf+lMem, aug_vec);
          pp = aug_vec;

        }
      } else {

        if ((index[stage] - base_size) >= 20) {
          /* Adjust index and extract vector */
          index[stage]-=20;
          pp=cbvectors+lMem-lTarget-
              index[stage]+base_size;
        } else {
          /* Adjust index and extract vector */
          index[stage]+=(base_size-20);
          WebRtcIlbcfix_CreateAugmentedVec((int16_t)(index[stage]-2*base_size+40),
                                           cbvectors+lMem, aug_vec);
          pp = aug_vec;
        }
      }
    }

    /* Subtract the best codebook vector, according
       to measure, from the target vector */

    WebRtcSpl_AddAffineVectorToVector(target, pp, (int16_t)(-bestGain), (int32_t)8192, (int16_t)14, (int)lTarget);

    /* record quantized gain */
    gains[stage+1] = bestGain;

  } /* end of Main Loop. for (stage=0;... */

  /* Calculte the coded vector (original target - what's left) */
  for (i=0;i<lTarget;i++) {
    codedVec[i]-=target[i];
  }

  /* Gain adjustment for energy matching */
  codedEner = WebRtcSpl_DotProductWithScale(codedVec, codedVec, lTarget, scale);

  j=gain_index[0];

  temp1 = (int16_t)WebRtcSpl_NormW32(codedEner);
  temp2 = (int16_t)WebRtcSpl_NormW32(targetEner);

  if(temp1 < temp2) {
    bits = 16 - temp1;
  } else {
    bits = 16 - temp2;
  }

  tmp = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(gains[1],gains[1], 14);

  targetEner = WEBRTC_SPL_MUL_16_16(
      WEBRTC_SPL_SHIFT_W32(targetEner, -bits), tmp);

  tmpW32 = ((int32_t)(gains[1]-1))<<1;

  /* Pointer to the table that contains
     gain_sq5TblFIX * gain_sq5TblFIX in Q14 */
  gainPtr=(int16_t*)WebRtcIlbcfix_kGainSq5Sq+gain_index[0];
  temp1 = (int16_t)WEBRTC_SPL_SHIFT_W32(codedEner, -bits);

  WebRtcIlbcfix_kGainSq5_ptr = (int16_t*)&WebRtcIlbcfix_kGainSq5[j];

  /* targetEner and codedEner are in Q(-2*scale) */
  for (i=gain_index[0];i<32;i++) {

    /* Change the index if
       (codedEnergy*gainTbl[i]*gainTbl[i])<(targetEn*gain[0]*gain[0]) AND
       gainTbl[i] < 2*gain[0]
    */

    t32 = WEBRTC_SPL_MUL_16_16(temp1, (*gainPtr));
    t32 = t32 - targetEner;
    if (t32 < 0) {
      if ((*WebRtcIlbcfix_kGainSq5_ptr) < tmpW32) {
        j=i;
        WebRtcIlbcfix_kGainSq5_ptr = (int16_t*)&WebRtcIlbcfix_kGainSq5[i];
      }
    }
    gainPtr++;
  }
  gain_index[0]=j;

  return;
}
Пример #18
0
int16_t WebRtcIsacfix_DecodeImpl(int16_t       *signal_out16,
                                 ISACFIX_DecInst_t *ISACdec_obj,
                                 int16_t       *current_framesamples)
{
  int k;
  int err;
  int16_t BWno;
  int16_t len = 0;

  int16_t model;


  int16_t Vector_Word16_1[FRAMESAMPLES/2];
  int16_t Vector_Word16_2[FRAMESAMPLES/2];

  int32_t Vector_Word32_1[FRAMESAMPLES/2];
  int32_t Vector_Word32_2[FRAMESAMPLES/2];

  int16_t lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs
  int16_t hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs
  int32_t gain_lo_hiQ17[2*SUBFRAMES];

  int16_t PitchLags_Q7[PITCH_SUBFRAMES];
  int16_t PitchGains_Q12[PITCH_SUBFRAMES];
  int16_t AvgPitchGain_Q12;

  int16_t tmp_1, tmp_2;
  int32_t tmp32a, tmp32b;
  int16_t gainQ13;


  int16_t frame_nb; /* counter */
  int16_t frame_mode; /* 0 for 20ms and 30ms, 1 for 60ms */
  int16_t processed_samples;

  /* PLC */
  int16_t overlapWin[ 240 ];

  (ISACdec_obj->bitstr_obj).W_upper = 0xFFFFFFFF;
  (ISACdec_obj->bitstr_obj).streamval = 0;
  (ISACdec_obj->bitstr_obj).stream_index = 0;
  (ISACdec_obj->bitstr_obj).full = 1;


  /* decode framelength and BW estimation - not used, only for stream pointer*/
  err = WebRtcIsacfix_DecodeFrameLen(&ISACdec_obj->bitstr_obj, current_framesamples);
  if (err<0)  // error check
    return err;

  frame_mode = (int16_t)WEBRTC_SPL_DIV(*current_framesamples, MAX_FRAMESAMPLES); /* 0, or 1 */
  processed_samples = (int16_t)WEBRTC_SPL_DIV(*current_framesamples, frame_mode+1); /* either 320 (20ms) or 480 (30, 60 ms) */

  err = WebRtcIsacfix_DecodeSendBandwidth(&ISACdec_obj->bitstr_obj, &BWno);
  if (err<0)  // error check
    return err;

  /* one loop if it's one frame (20 or 30ms), 2 loops if 2 frames bundled together (60ms) */
  for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) {

    /* decode & dequantize pitch parameters */
    err = WebRtcIsacfix_DecodePitchGain(&(ISACdec_obj->bitstr_obj), PitchGains_Q12);
    if (err<0)  // error check
      return err;

    err = WebRtcIsacfix_DecodePitchLag(&ISACdec_obj->bitstr_obj, PitchGains_Q12, PitchLags_Q7);
    if (err<0)  // error check
      return err;

    AvgPitchGain_Q12 = (int16_t)(((int32_t)PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3])>>2);

    /* decode & dequantize FiltCoef */
    err = WebRtcIsacfix_DecodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15,
                                  &ISACdec_obj->bitstr_obj, &model);

    if (err<0)  // error check
      return err;

    /* decode & dequantize spectrum */
    len = WebRtcIsacfix_DecodeSpec(&ISACdec_obj->bitstr_obj, Vector_Word16_1, Vector_Word16_2, AvgPitchGain_Q12);
    if (len < 0)  // error check
      return len;

    // Why does this need Q16 in and out? /JS
    WebRtcIsacfix_Spec2Time(Vector_Word16_1, Vector_Word16_2, Vector_Word32_1, Vector_Word32_2);

    for (k=0; k<FRAMESAMPLES/2; k++) {
      Vector_Word16_1[k] = (int16_t)WEBRTC_SPL_RSHIFT_W32(Vector_Word32_1[k]+64, 7); //Q16 -> Q9
    }

    /* ----  If this is recovery frame ---- */
    if( (ISACdec_obj->plcstr_obj).used == PLC_WAS_USED )
    {
      (ISACdec_obj->plcstr_obj).used = PLC_NOT_USED;
      if( (ISACdec_obj->plcstr_obj).B < 1000 )
      {
        (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 4000;
      }

      ISACdec_obj->plcstr_obj.decayCoeffPriodic = WEBRTC_SPL_WORD16_MAX;    /* DECAY_RATE is in Q15 */
      ISACdec_obj->plcstr_obj.decayCoeffNoise = WEBRTC_SPL_WORD16_MAX;    /* DECAY_RATE is in Q15 */
      ISACdec_obj->plcstr_obj.pitchCycles = 0;

      PitchGains_Q12[0] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(PitchGains_Q12[0], 700, 10 );

      /* ---- Add-overlap ---- */
      WebRtcSpl_GetHanningWindow( overlapWin, RECOVERY_OVERLAP );
      for( k = 0; k < RECOVERY_OVERLAP; k++ )
        Vector_Word16_1[k] = WebRtcSpl_AddSatW16(
            (int16_t)WEBRTC_SPL_MUL_16_16_RSFT( (ISACdec_obj->plcstr_obj).overlapLP[k], overlapWin[RECOVERY_OVERLAP - k - 1], 14),
            (int16_t)WEBRTC_SPL_MUL_16_16_RSFT( Vector_Word16_1[k], overlapWin[k], 14) );



    }

    /* --- Store side info --- */
    if( frame_nb == frame_mode )
    {
      /* --- LPC info */
      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).lofilt_coefQ15, &lofilt_coefQ15[(SUBFRAMES-1)*ORDERLO], ORDERLO );
      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).hifilt_coefQ15, &hifilt_coefQ15[(SUBFRAMES-1)*ORDERHI], ORDERHI );
      (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0] = gain_lo_hiQ17[(SUBFRAMES-1) * 2];
      (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1] = gain_lo_hiQ17[(SUBFRAMES-1) * 2 + 1];

      /* --- LTP info */
      (ISACdec_obj->plcstr_obj).AvgPitchGain_Q12 = PitchGains_Q12[3];
      (ISACdec_obj->plcstr_obj).lastPitchGain_Q12 = PitchGains_Q12[3];
      (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = PitchLags_Q7[3];

      if( PitchLags_Q7[3] < 3000 )
        (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 += PitchLags_Q7[3];

      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvIn, Vector_Word16_1, FRAMESAMPLES/2 );

    }
    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

    /* inverse pitch filter */
    WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2, &ISACdec_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 4);

    if( frame_nb == frame_mode )
    {
      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvOut, &(Vector_Word16_2[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10)]), PITCH_MAX_LAG );
    }


    /* reduce gain to compensate for pitch enhancer */
    /* gain = 1.0f - 0.45f * AvgPitchGain; */
    tmp32a = WEBRTC_SPL_MUL_16_16_RSFT(AvgPitchGain_Q12, 29, 0); // Q18
    tmp32b = 262144 - tmp32a;  // Q18
    gainQ13 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q13

    for (k = 0; k < FRAMESAMPLES/2; k++)
    {
      Vector_Word32_1[k] = (int32_t) WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(Vector_Word16_2[k], gainQ13), 3); // Q25
    }


    /* perceptual post-filtering (using normalized lattice filter) */
    WebRtcIsacfix_NormLatticeFilterAr(ORDERLO, (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0,
                                      Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1);

    /* --- Store Highpass Residual --- */
    for (k = 0; k < FRAMESAMPLES/2; k++)
      Vector_Word32_1[k]    = WEBRTC_SPL_LSHIFT_W32(Vector_Word32_2[k], 9); // Q16 -> Q25

    for( k = 0; k < PITCH_MAX_LAG + 10; k++ )
      (ISACdec_obj->plcstr_obj).prevHP[k] = Vector_Word32_1[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10) + k];


    WebRtcIsacfix_NormLatticeFilterAr(ORDERHI, (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0,
                                      Vector_Word32_1, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2);

    /* recombine the 2 bands */

    /* Form the polyphase signals, and compensate for DC offset */
    for (k=0;k<FRAMESAMPLES/2;k++) {
      tmp_1 = (int16_t)WebRtcSpl_SatW32ToW16(((int32_t)Vector_Word16_1[k]+Vector_Word16_2[k] + 1)); /* Construct a new upper channel signal*/
      tmp_2 = (int16_t)WebRtcSpl_SatW32ToW16(((int32_t)Vector_Word16_1[k]-Vector_Word16_2[k])); /* Construct a new lower channel signal*/
      Vector_Word16_1[k] = tmp_1;
      Vector_Word16_2[k] = tmp_2;
    }

    WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1, Vector_Word16_2, signal_out16 + frame_nb * processed_samples, &ISACdec_obj->postfiltbankstr_obj);

  }
  return len;
}
Пример #19
0
WebRtc_Word16 WebRtcIlbcfix_InitDecode(  /* (o) Number of decoded samples */
    iLBC_Dec_Inst_t *iLBCdec_inst,  /* (i/o) Decoder instance */
    WebRtc_Word16 mode,  /* (i) frame size mode */
    int use_enhancer) {  /* (i) 1: use enhancer, 0: no enhancer */
  int i;

  iLBCdec_inst->mode = mode;

  /* Set all the variables that are dependent on the frame size mode */
  if (mode==30) {
    iLBCdec_inst->blockl = BLOCKL_30MS;
    iLBCdec_inst->nsub = NSUB_30MS;
    iLBCdec_inst->nasub = NASUB_30MS;
    iLBCdec_inst->lpc_n = LPC_N_30MS;
    iLBCdec_inst->no_of_bytes = NO_OF_BYTES_30MS;
    iLBCdec_inst->no_of_words = NO_OF_WORDS_30MS;
    iLBCdec_inst->state_short_len=STATE_SHORT_LEN_30MS;
  }
  else if (mode==20) {
    iLBCdec_inst->blockl = BLOCKL_20MS;
    iLBCdec_inst->nsub = NSUB_20MS;
    iLBCdec_inst->nasub = NASUB_20MS;
    iLBCdec_inst->lpc_n = LPC_N_20MS;
    iLBCdec_inst->no_of_bytes = NO_OF_BYTES_20MS;
    iLBCdec_inst->no_of_words = NO_OF_WORDS_20MS;
    iLBCdec_inst->state_short_len=STATE_SHORT_LEN_20MS;
  }
  else {
    return(-1);
  }

  /* Reset all the previous LSF to mean LSF */
  WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->lsfdeqold, WebRtcIlbcfix_kLsfMean, LPC_FILTERORDER);

  /* Clear the synthesis filter memory */
  WebRtcSpl_MemSetW16(iLBCdec_inst->syntMem, 0, LPC_FILTERORDER);

  /* Set the old synthesis filter to {1.0 0.0 ... 0.0} */
  WebRtcSpl_MemSetW16(iLBCdec_inst->old_syntdenum, 0, ((LPC_FILTERORDER + 1)*NSUB_MAX));
  for (i=0; i<NSUB_MAX; i++) {
    iLBCdec_inst->old_syntdenum[i*(LPC_FILTERORDER+1)] = 4096;
  }

  /* Clear the variables that are used for the PLC */
  iLBCdec_inst->last_lag = 20;
  iLBCdec_inst->consPLICount = 0;
  iLBCdec_inst->prevPLI = 0;
  iLBCdec_inst->perSquare = 0;
  iLBCdec_inst->prevLag = 120;
  iLBCdec_inst->prevLpc[0] = 4096;
  WebRtcSpl_MemSetW16(iLBCdec_inst->prevLpc+1, 0, LPC_FILTERORDER);
  WebRtcSpl_MemSetW16(iLBCdec_inst->prevResidual, 0, BLOCKL_MAX);

  /* Initialize the seed for the random number generator */
  iLBCdec_inst->seed = 777;

  /* Set the filter state of the HP filter to 0 */
  WebRtcSpl_MemSetW16(iLBCdec_inst->hpimemx, 0, 2);
  WebRtcSpl_MemSetW16(iLBCdec_inst->hpimemy, 0, 4);

  /* Set the variables that are used in the ehnahcer */
  iLBCdec_inst->use_enhancer = use_enhancer;
  WebRtcSpl_MemSetW16(iLBCdec_inst->enh_buf, 0, (ENH_BUFL+ENH_BUFL_FILTEROVERHEAD));
  for (i=0;i<ENH_NBLOCKS_TOT;i++) {
    iLBCdec_inst->enh_period[i]=160; /* Q(-4) */
  }

  iLBCdec_inst->prev_enh_pl = 0;

  return (iLBCdec_inst->blockl);
}
Пример #20
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;
}