1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 2470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Use of this source code is governed by a BSD-style license 5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * that can be found in the LICENSE file in the root of the source 6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * tree. An additional intellectual property rights grant can be found 7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * in the file PATENTS. All contributing project authors may 8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * be found in the AUTHORS file in the root of the source tree. 9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************** 12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com iLBC Speech Coder ANSI-C Source Code 14470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIlbcfix_StateSearch.c 16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 17470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com******************************************************************/ 18470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 19470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "defines.h" 20470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "constants.h" 21470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "abs_quant.h" 22470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 23470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*----------------------------------------------------------------* 24470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * encoding of start state 25470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *---------------------------------------------------------------*/ 26470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 27470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid WebRtcIlbcfix_StateSearch( 28eb544460e47140d494dddf1217a698a1dcf4dee0pbos@webrtc.org IlbcEncoder *iLBCenc_inst, 29470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* (i) Encoder instance */ 30470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com iLBC_bits *iLBC_encbits,/* (i/o) Encoded bits (output idxForMax 31470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com and idxVec, input state_first) */ 320946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *residual, /* (i) target residual vector */ 330946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *syntDenum, /* (i) lpc synthesis filter */ 340946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *weightDenum /* (i) weighting filter denuminator */ 35470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ) { 36dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t k, index; 370946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t maxVal; 380946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t scale, shift; 390946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int32_t maxValsq; 400946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t scaleRes; 410946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t max; 42470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int i; 43470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Stack based */ 440946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t numerator[1+LPC_FILTERORDER]; 450946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t residualLongVec[2*STATE_SHORT_LEN_30MS+LPC_FILTERORDER]; 460946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t sampleMa[2*STATE_SHORT_LEN_30MS]; 470946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *residualLong = &residualLongVec[LPC_FILTERORDER]; 480946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org int16_t *sampleAr = residualLong; 49470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 50470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Scale to maximum 12 bits to avoid saturation in circular convolution filter */ 51470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com max = WebRtcSpl_MaxAbsValueW16(residual, iLBCenc_inst->state_short_len); 52470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com scaleRes = WebRtcSpl_GetSizeInBits(max)-12; 53470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com scaleRes = WEBRTC_SPL_MAX(0, scaleRes); 54470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Set up the filter coefficients for the circular convolution */ 55470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (i=0; i<LPC_FILTERORDER+1; i++) { 56470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com numerator[i] = (syntDenum[LPC_FILTERORDER-i]>>scaleRes); 57470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 58470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 59470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Copy the residual to a temporary buffer that we can filter 60470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * and set the remaining samples to zero. 61470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 62470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_SPL_MEMCPY_W16(residualLong, residual, iLBCenc_inst->state_short_len); 63470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_MemSetW16(residualLong + iLBCenc_inst->state_short_len, 0, iLBCenc_inst->state_short_len); 64470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 65470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Run the Zero-Pole filter (Ciurcular convolution) */ 66470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_MemSetW16(residualLongVec, 0, LPC_FILTERORDER); 67dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting WebRtcSpl_FilterMAFastQ12(residualLong, sampleMa, numerator, 68dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting LPC_FILTERORDER + 1, 69dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting iLBCenc_inst->state_short_len + LPC_FILTERORDER); 70470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_MemSetW16(&sampleMa[iLBCenc_inst->state_short_len + LPC_FILTERORDER], 0, iLBCenc_inst->state_short_len - LPC_FILTERORDER); 71470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 72470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_FilterARFastQ12( 73470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sampleMa, sampleAr, 74b7e5054414ff524f9db81dab7917729b8c4c8bcbPeter Kasting syntDenum, LPC_FILTERORDER+1, 2 * iLBCenc_inst->state_short_len); 75470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 76470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for(k=0;k<iLBCenc_inst->state_short_len;k++){ 77470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sampleAr[k] += sampleAr[k+iLBCenc_inst->state_short_len]; 78470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 79470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 80470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Find maximum absolute value in the vector */ 81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com maxVal=WebRtcSpl_MaxAbsValueW16(sampleAr, iLBCenc_inst->state_short_len); 82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 83470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Find the best index */ 84470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 850946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org if ((((int32_t)maxVal)<<scaleRes)<23170) { 860946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org maxValsq=((int32_t)maxVal*maxVal)<<(2+2*scaleRes); 87470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 880946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org maxValsq=(int32_t)WEBRTC_SPL_WORD32_MAX; 89470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 90470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 91470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index=0; 92470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (i=0;i<63;i++) { 93470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 94470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (maxValsq>=WebRtcIlbcfix_kChooseFrgQuant[i]) { 95470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com index=i+1; 96470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 97470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com i=63; 98470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com iLBC_encbits->idxForMax=index; 101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Rescale the vector before quantization */ 103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com scale=WebRtcIlbcfix_kScale[index]; 104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (index<27) { /* scale table is in Q16, fout[] is in Q(-1) and we want the result to be in Q11 */ 106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shift=4; 107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { /* scale table is in Q21, fout[] is in Q(-1) and we want the result to be in Q11 */ 108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com shift=9; 109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Set up vectors for AbsQuant and rescale it with the scale factor */ 112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcSpl_ScaleVectorWithSat(sampleAr, sampleAr, scale, 1130946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org iLBCenc_inst->state_short_len, (int16_t)(shift-scaleRes)); 114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* Quantize the values in fout[] */ 116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtcIlbcfix_AbsQuant(iLBCenc_inst, iLBC_encbits, sampleAr, weightDenum); 117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return; 119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 120