1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/****************************************************************** 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org iLBC Speech Coder ANSI-C Source Code 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIlbcfix_StateSearch.c 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org******************************************************************/ 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "defines.h" 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "constants.h" 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "abs_quant.h" 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*----------------------------------------------------------------* 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * encoding of start state 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *---------------------------------------------------------------*/ 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIlbcfix_StateSearch( 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org iLBC_Enc_Inst_t *iLBCenc_inst, 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* (i) Encoder instance */ 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org iLBC_bits *iLBC_encbits,/* (i/o) Encoded bits (output idxForMax 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org and idxVec, input state_first) */ 32fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *residual, /* (i) target residual vector */ 33fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *syntDenum, /* (i) lpc synthesis filter */ 34fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *weightDenum /* (i) weighting filter denuminator */ 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ) { 36fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t k, index; 37fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t maxVal; 38fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t scale, shift; 39fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t maxValsq; 40fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t scaleRes; 41fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t max; 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int i; 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Stack based */ 44fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t numerator[1+LPC_FILTERORDER]; 45fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t residualLongVec[2*STATE_SHORT_LEN_30MS+LPC_FILTERORDER]; 46fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t sampleMa[2*STATE_SHORT_LEN_30MS]; 47fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *residualLong = &residualLongVec[LPC_FILTERORDER]; 48fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t *sampleAr = residualLong; 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scale to maximum 12 bits to avoid saturation in circular convolution filter */ 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org max = WebRtcSpl_MaxAbsValueW16(residual, iLBCenc_inst->state_short_len); 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org scaleRes = WebRtcSpl_GetSizeInBits(max)-12; 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org scaleRes = WEBRTC_SPL_MAX(0, scaleRes); 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Set up the filter coefficients for the circular convolution */ 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (i=0; i<LPC_FILTERORDER+1; i++) { 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numerator[i] = (syntDenum[LPC_FILTERORDER-i]>>scaleRes); 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Copy the residual to a temporary buffer that we can filter 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * and set the remaining samples to zero. 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_SPL_MEMCPY_W16(residualLong, residual, iLBCenc_inst->state_short_len); 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_MemSetW16(residualLong + iLBCenc_inst->state_short_len, 0, iLBCenc_inst->state_short_len); 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Run the Zero-Pole filter (Ciurcular convolution) */ 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_MemSetW16(residualLongVec, 0, LPC_FILTERORDER); 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_FilterMAFastQ12( 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org residualLong, sampleMa, 69fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org numerator, LPC_FILTERORDER+1, (int16_t)(iLBCenc_inst->state_short_len + LPC_FILTERORDER)); 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_MemSetW16(&sampleMa[iLBCenc_inst->state_short_len + LPC_FILTERORDER], 0, iLBCenc_inst->state_short_len - LPC_FILTERORDER); 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_FilterARFastQ12( 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sampleMa, sampleAr, 74fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org syntDenum, LPC_FILTERORDER+1, (int16_t)(2*iLBCenc_inst->state_short_len)); 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for(k=0;k<iLBCenc_inst->state_short_len;k++){ 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sampleAr[k] += sampleAr[k+iLBCenc_inst->state_short_len]; 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Find maximum absolute value in the vector */ 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org maxVal=WebRtcSpl_MaxAbsValueW16(sampleAr, iLBCenc_inst->state_short_len); 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Find the best index */ 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 85fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org if ((((int32_t)maxVal)<<scaleRes)<23170) { 86fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org maxValsq=((int32_t)maxVal*maxVal)<<(2+2*scaleRes); 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 88fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org maxValsq=(int32_t)WEBRTC_SPL_WORD32_MAX; 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index=0; 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (i=0;i<63;i++) { 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (maxValsq>=WebRtcIlbcfix_kChooseFrgQuant[i]) { 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org index=i+1; 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org i=63; 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org iLBC_encbits->idxForMax=index; 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Rescale the vector before quantization */ 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org scale=WebRtcIlbcfix_kScale[index]; 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (index<27) { /* scale table is in Q16, fout[] is in Q(-1) and we want the result to be in Q11 */ 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shift=4; 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { /* scale table is in Q21, fout[] is in Q(-1) and we want the result to be in Q11 */ 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org shift=9; 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Set up vectors for AbsQuant and rescale it with the scale factor */ 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_ScaleVectorWithSat(sampleAr, sampleAr, scale, 113fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org iLBCenc_inst->state_short_len, (int16_t)(shift-scaleRes)); 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Quantize the values in fout[] */ 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIlbcfix_AbsQuant(iLBCenc_inst, iLBC_encbits, sampleAr, weightDenum); 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 120