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