Esempio n. 1
0
void WebRtcIlbcfix_AbsQuant(
    iLBC_Enc_Inst_t *iLBCenc_inst,
    /* (i) Encoder instance */
    iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits (outputs idxForMax
                                   and idxVec, uses state_first as
                                   input) */
    int16_t *in,     /* (i) vector to encode */
    int16_t *weightDenum   /* (i) denominator of synthesis filter */
                            ) {
  int16_t *syntOut;
  int16_t quantLen[2];

  /* Stack based */
  int16_t syntOutBuf[LPC_FILTERORDER+STATE_SHORT_LEN_30MS];
  int16_t in_weightedVec[STATE_SHORT_LEN_30MS+LPC_FILTERORDER];
  int16_t *in_weighted = &in_weightedVec[LPC_FILTERORDER];

  /* Initialize the buffers */
  WebRtcSpl_MemSetW16(syntOutBuf, 0, LPC_FILTERORDER+STATE_SHORT_LEN_30MS);
  syntOut = &syntOutBuf[LPC_FILTERORDER];
  /* Start with zero state */
  WebRtcSpl_MemSetW16(in_weightedVec, 0, LPC_FILTERORDER);

  /* Perform the quantization loop in two sections of length quantLen[i],
     where the perceptual weighting filter is updated at the subframe
     border */

  if (iLBC_encbits->state_first) {
    quantLen[0]=SUBL;
    quantLen[1]=iLBCenc_inst->state_short_len-SUBL;
  } else {
    quantLen[0]=iLBCenc_inst->state_short_len-SUBL;
    quantLen[1]=SUBL;
  }

  /* Calculate the weighted residual, switch perceptual weighting
     filter at the subframe border */
  WebRtcSpl_FilterARFastQ12(
      in, in_weighted,
      weightDenum, LPC_FILTERORDER+1, quantLen[0]);
  WebRtcSpl_FilterARFastQ12(
      &in[quantLen[0]], &in_weighted[quantLen[0]],
      &weightDenum[LPC_FILTERORDER+1], LPC_FILTERORDER+1, quantLen[1]);

  WebRtcIlbcfix_AbsQuantLoop(
      syntOut,
      in_weighted,
      weightDenum,
      quantLen,
      iLBC_encbits->idxVec);

}
Esempio n. 2
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);
}
Esempio n. 3
0
int WebRtcNetEQ_DbGetPtrs(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec,
                          CodecFuncInst_t *ptr_inst)
{

    int pos = inst->position[codec];
    if ((codec <= kDecoderReservedStart) || (codec >= kDecoderReservedEnd) || (codec
        > NUM_TOTAL_CODECS))
    {
        /* ERROR */
        pos = -1;
    }
    if (pos >= 0)
    {
        ptr_inst->codec_state = inst->codec_state[pos];
        ptr_inst->funcAddLatePkt = inst->funcAddLatePkt[pos];
        ptr_inst->funcDecode = inst->funcDecode[pos];
        ptr_inst->funcDecodeRCU = inst->funcDecodeRCU[pos];
        ptr_inst->funcDecodeInit = inst->funcDecodeInit[pos];
        ptr_inst->funcDecodePLC = inst->funcDecodePLC[pos];
        ptr_inst->funcGetMDinfo = inst->funcGetMDinfo[pos];
        ptr_inst->funcUpdBWEst = inst->funcUpdBWEst[pos];
        ptr_inst->funcGetErrorCode = inst->funcGetErrorCode[pos];
        ptr_inst->codec_fs = inst->codec_fs[pos];
        return 0;
    }
    else
    {
        WebRtcSpl_MemSetW16((WebRtc_Word16*) ptr_inst, 0,
            sizeof(CodecFuncInst_t) / sizeof(WebRtc_Word16));
        return CODEC_DB_NOT_EXIST1;
    }
}
Esempio n. 4
0
int WebRtcNetEQ_RTCPInit(WebRtcNetEQ_RTCP_t *RTCP_inst, uint16_t uw16_seqNo)
{
    /*
     * Initialize everything to zero and then set the start values for the RTP packet stream.
     */
    WebRtcSpl_MemSetW16((int16_t*) RTCP_inst, 0,
        sizeof(WebRtcNetEQ_RTCP_t) / sizeof(int16_t));
    RTCP_inst->base_seq = uw16_seqNo;
    RTCP_inst->max_seq = uw16_seqNo;
    return 0;
}
Esempio n. 5
0
WebRtc_Word16 WebRtcIlbcfix_NetEqPlc(iLBC_decinst_t *iLBCdec_inst, WebRtc_Word16 *decoded, WebRtc_Word16 noOfLostFrames) {

  /* Two input parameters not used, but needed for function pointers in NetEQ */
  (void)(decoded = NULL);
  (void)(noOfLostFrames = 0);

  WebRtcSpl_MemSetW16(((iLBC_Dec_Inst_t*)iLBCdec_inst)->enh_buf, 0, ENH_BUFL);
  ((iLBC_Dec_Inst_t*)iLBCdec_inst)->prev_enh_pl = 2;

  return (0);
}
Esempio n. 6
0
int16_t WebRtcIlbcfix_NetEqPlc(IlbcDecoderInstance* iLBCdec_inst,
                               int16_t* decoded,
                               int16_t noOfLostFrames) {
  /* Two input parameters not used, but needed for function pointers in NetEQ */
  (void)(decoded = NULL);
  (void)(noOfLostFrames = 0);

  WebRtcSpl_MemSetW16(((IlbcDecoder*)iLBCdec_inst)->enh_buf, 0, ENH_BUFL);
  ((IlbcDecoder*)iLBCdec_inst)->prev_enh_pl = 2;

  return (0);
}
Esempio n. 7
0
void WebRtcIlbcfix_Enhancer(int16_t * odata,	/* (o) smoothed block, dimension blockl */
			    int16_t * idata,	/* (i) data buffer used for enhancing */
			    int16_t idatal,	/* (i) dimension idata */
			    int16_t centerStartPos,	/* (i) first sample current block within idata */
			    int16_t * period,	/* (i) pitch period array (pitch bward-in time) */
			    int16_t * plocs,	/* (i) locations where period array values valid */
			    int16_t periodl	/* (i) dimension of period and plocs */
    )
{
	/* Stack based */
	int16_t surround[ENH_BLOCKL];

	WebRtcSpl_MemSetW16(surround, 0, ENH_BLOCKL);

	/* get said second sequence of segments */

	WebRtcIlbcfix_GetSyncSeq(idata, idatal, centerStartPos, period, plocs,
				 periodl, ENH_HL, surround);

	/* compute the smoothed output from said second sequence */

	WebRtcIlbcfix_Smooth(odata, idata + centerStartPos, surround);
}
Esempio n. 8
0
int WebRtcNetEQ_DbReset(CodecDbInst_t *inst)
{
    int i;

    WebRtcSpl_MemSetW16((WebRtc_Word16*) inst, 0,
        sizeof(CodecDbInst_t) / sizeof(WebRtc_Word16));

    for (i = 0; i < NUM_TOTAL_CODECS; i++)
    {
        inst->position[i] = -1;
    }

    for (i = 0; i < NUM_CODECS; i++)
    {
        inst->payloadType[i] = -1;
    }

    for (i = 0; i < NUM_CNG_CODECS; i++)
    {
        inst->CNGpayloadType[i] = -1;
    }

    return 0;
}
Esempio n. 9
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);
}
Esempio n. 10
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

}
Esempio n. 11
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;
}
Esempio n. 12
0
void WebRtcSpl_ZerosArrayW16(int16_t *vector, size_t length)
{
    WebRtcSpl_MemSetW16(vector, 0, length);
}
Esempio n. 13
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);
    }
  }
}
Esempio n. 14
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);
  }
}
Esempio n. 15
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;
}
Esempio n. 16
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;
}