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_DecodeResidual.c 16 17******************************************************************/ 18 19#include <string.h> 20 21#include "defines.h" 22#include "state_construct.h" 23#include "cb_construct.h" 24#include "index_conv_dec.h" 25#include "do_plc.h" 26#include "constants.h" 27#include "enhancer_interface.h" 28#include "xcorr_coef.h" 29#include "lsf_check.h" 30 31/*----------------------------------------------------------------* 32 * frame residual decoder function (subrutine to iLBC_decode) 33 *---------------------------------------------------------------*/ 34 35void WebRtcIlbcfix_DecodeResidual( 36 iLBC_Dec_Inst_t *iLBCdec_inst, 37 /* (i/o) the decoder state structure */ 38 iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits, which are used 39 for the decoding */ 40 int16_t *decresidual, /* (o) decoded residual frame */ 41 int16_t *syntdenum /* (i) the decoded synthesis filter 42 coefficients */ 43 ) { 44 int16_t meml_gotten, Nfor, Nback, diff, start_pos; 45 int16_t subcount, subframe; 46 int16_t *reverseDecresidual = iLBCdec_inst->enh_buf; /* Reversed decoded data, used for decoding backwards in time (reuse memory in state) */ 47 int16_t *memVec = iLBCdec_inst->prevResidual; /* Memory for codebook and filter state (reuse memory in state) */ 48 int16_t *mem = &memVec[CB_HALFFILTERLEN]; /* Memory for codebook */ 49 50 diff = STATE_LEN - iLBCdec_inst->state_short_len; 51 52 if (iLBC_encbits->state_first == 1) { 53 start_pos = (iLBC_encbits->startIdx-1)*SUBL; 54 } else { 55 start_pos = (iLBC_encbits->startIdx-1)*SUBL + diff; 56 } 57 58 /* decode scalar part of start state */ 59 60 WebRtcIlbcfix_StateConstruct(iLBC_encbits->idxForMax, 61 iLBC_encbits->idxVec, &syntdenum[(iLBC_encbits->startIdx-1)*(LPC_FILTERORDER+1)], 62 &decresidual[start_pos], iLBCdec_inst->state_short_len 63 ); 64 65 if (iLBC_encbits->state_first) { /* put adaptive part in the end */ 66 67 /* setup memory */ 68 69 WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-iLBCdec_inst->state_short_len)); 70 WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-iLBCdec_inst->state_short_len, decresidual+start_pos, 71 iLBCdec_inst->state_short_len); 72 73 /* construct decoded vector */ 74 75 WebRtcIlbcfix_CbConstruct( 76 &decresidual[start_pos+iLBCdec_inst->state_short_len], 77 iLBC_encbits->cb_index, iLBC_encbits->gain_index, 78 mem+CB_MEML-ST_MEM_L_TBL, 79 ST_MEM_L_TBL, (int16_t)diff 80 ); 81 82 } 83 else {/* put adaptive part in the beginning */ 84 85 /* setup memory */ 86 87 meml_gotten = iLBCdec_inst->state_short_len; 88 WebRtcSpl_MemCpyReversedOrder(mem+CB_MEML-1, 89 decresidual+start_pos, meml_gotten); 90 WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-meml_gotten)); 91 92 /* construct decoded vector */ 93 94 WebRtcIlbcfix_CbConstruct( 95 reverseDecresidual, 96 iLBC_encbits->cb_index, iLBC_encbits->gain_index, 97 mem+CB_MEML-ST_MEM_L_TBL, 98 ST_MEM_L_TBL, diff 99 ); 100 101 /* get decoded residual from reversed vector */ 102 103 WebRtcSpl_MemCpyReversedOrder(&decresidual[start_pos-1], 104 reverseDecresidual, diff); 105 } 106 107 /* counter for predicted subframes */ 108 109 subcount=1; 110 111 /* forward prediction of subframes */ 112 113 Nfor = iLBCdec_inst->nsub-iLBC_encbits->startIdx-1; 114 115 if( Nfor > 0 ) { 116 117 /* setup memory */ 118 WebRtcSpl_MemSetW16(mem, 0, CB_MEML-STATE_LEN); 119 WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-STATE_LEN, 120 decresidual+(iLBC_encbits->startIdx-1)*SUBL, STATE_LEN); 121 122 /* loop over subframes to encode */ 123 124 for (subframe=0; subframe<Nfor; subframe++) { 125 126 /* construct decoded vector */ 127 WebRtcIlbcfix_CbConstruct( 128 &decresidual[(iLBC_encbits->startIdx+1+subframe)*SUBL], 129 iLBC_encbits->cb_index+subcount*CB_NSTAGES, 130 iLBC_encbits->gain_index+subcount*CB_NSTAGES, 131 mem, MEM_LF_TBL, SUBL 132 ); 133 134 /* update memory */ 135 memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem)); 136 WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL, 137 &decresidual[(iLBC_encbits->startIdx+1+subframe)*SUBL], SUBL); 138 139 subcount++; 140 } 141 142 } 143 144 /* backward prediction of subframes */ 145 146 Nback = iLBC_encbits->startIdx-1; 147 148 if( Nback > 0 ){ 149 150 /* setup memory */ 151 152 meml_gotten = SUBL*(iLBCdec_inst->nsub+1-iLBC_encbits->startIdx); 153 if( meml_gotten > CB_MEML ) { 154 meml_gotten=CB_MEML; 155 } 156 157 WebRtcSpl_MemCpyReversedOrder(mem+CB_MEML-1, 158 decresidual+(iLBC_encbits->startIdx-1)*SUBL, meml_gotten); 159 WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-meml_gotten)); 160 161 /* loop over subframes to decode */ 162 163 for (subframe=0; subframe<Nback; subframe++) { 164 165 /* construct decoded vector */ 166 WebRtcIlbcfix_CbConstruct( 167 &reverseDecresidual[subframe*SUBL], 168 iLBC_encbits->cb_index+subcount*CB_NSTAGES, 169 iLBC_encbits->gain_index+subcount*CB_NSTAGES, 170 mem, MEM_LF_TBL, SUBL 171 ); 172 173 /* update memory */ 174 memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem)); 175 WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL, 176 &reverseDecresidual[subframe*SUBL], SUBL); 177 178 subcount++; 179 } 180 181 /* get decoded residual from reversed vector */ 182 WebRtcSpl_MemCpyReversedOrder(decresidual+SUBL*Nback-1, 183 reverseDecresidual, SUBL*Nback); 184 } 185} 186