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