diff options
Diffstat (limited to 'codecs/ilbc/iLBC_decode.c')
-rwxr-xr-x | codecs/ilbc/iLBC_decode.c | 1130 |
1 files changed, 614 insertions, 516 deletions
diff --git a/codecs/ilbc/iLBC_decode.c b/codecs/ilbc/iLBC_decode.c index 06602ff0a..ace6fd90f 100755 --- a/codecs/ilbc/iLBC_decode.c +++ b/codecs/ilbc/iLBC_decode.c @@ -1,520 +1,618 @@ - -/****************************************************************** - - iLBC Speech Coder ANSI-C Source Code - - iLBC_decode.c - - Copyright (c) 2001, - Global IP Sound AB. - All rights reserved. - -******************************************************************/ - -#include <math.h> -#include <stdlib.h> - -#include "iLBC_define.h" -#include "StateConstructW.h" -#include "LPCdecode.h" -#include "iCBConstruct.h" -#include "doCPLC.h" -#include "helpfun.h" -#include "constants.h" -#include "packing.h" -#include "iLBC_decode.h" -#include "string.h" -#include "enhancer.h" -#include "hpOutput.h" -#include "syntFilter.h" - -/*----------------------------------------------------------------* - * Initiation of decoder instance. - *---------------------------------------------------------------*/ - -short initDecode( /* (o) Number of decoded - samples */ - iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ - int use_enhancer /* (i) 1 to use enhancer - 0 to run without - enhancer */ -){ - int i; - - memset((*iLBCdec_inst).syntMem, 0, - LPC_FILTERORDER*sizeof(float)); - memcpy((*iLBCdec_inst).lsfdeqold, lsfmeanTbl, - LPC_FILTERORDER*sizeof(float)); - - memset((*iLBCdec_inst).old_syntdenum, 0, - ((LPC_FILTERORDER + 1)*NSUB)*sizeof(float)); - for (i=0; i<NSUB; i++) - (*iLBCdec_inst).old_syntdenum[i*(LPC_FILTERORDER+1)]=1.0; - - (*iLBCdec_inst).last_lag = 20; - - (*iLBCdec_inst).prevLag = 120; - (*iLBCdec_inst).prevGain = 0.0; - (*iLBCdec_inst).consPLICount = 0; - (*iLBCdec_inst).prevPLI = 0; - (*iLBCdec_inst).prevLpc[0] = 1.0; - memset((*iLBCdec_inst).prevLpc+1,0, - LPC_FILTERORDER*sizeof(float)); - memset((*iLBCdec_inst).prevResidual, 0, BLOCKL*sizeof(float)); - (*iLBCdec_inst).seed=777; - - memset((*iLBCdec_inst).hpomem, 0, 4*sizeof(float)); - - (*iLBCdec_inst).use_enhancer = use_enhancer; - memset((*iLBCdec_inst).enh_buf, 0, ENH_BUFL*sizeof(float)); - for (i=0;i<ENH_NBLOCKS_TOT;i++) - (*iLBCdec_inst).enh_period[i]=(float)40.0; - + +/****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + iLBC_decode.c + + Copyright (C) The Internet Society (2004). + All Rights Reserved. + +******************************************************************/ + +#include <math.h> +#include <stdlib.h> + +#include "iLBC_define.h" +#include "StateConstructW.h" +#include "LPCdecode.h" +#include "iCBConstruct.h" +#include "doCPLC.h" +#include "helpfun.h" +#include "constants.h" +#include "packing.h" +#include "string.h" +#include "enhancer.h" +#include "hpOutput.h" +#include "syntFilter.h" + +/*----------------------------------------------------------------* + * Initiation of decoder instance. + *---------------------------------------------------------------*/ + +short initDecode( /* (o) Number of decoded + samples */ + iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ + int mode, /* (i) frame size mode */ + int use_enhancer /* (i) 1 to use enhancer + 0 to run without + enhancer */ +){ + int i; + + iLBCdec_inst->mode = mode; + + if (mode==30) { + iLBCdec_inst->blockl = BLOCKL_30MS; + iLBCdec_inst->nsub = NSUB_30MS; + iLBCdec_inst->nasub = NASUB_30MS; + iLBCdec_inst->lpc_n = LPC_N_30MS; + + + iLBCdec_inst->no_of_bytes = NO_OF_BYTES_30MS; + iLBCdec_inst->no_of_words = NO_OF_WORDS_30MS; + iLBCdec_inst->state_short_len=STATE_SHORT_LEN_30MS; + /* ULP init */ + iLBCdec_inst->ULP_inst=&ULP_30msTbl; + } + else if (mode==20) { + iLBCdec_inst->blockl = BLOCKL_20MS; + iLBCdec_inst->nsub = NSUB_20MS; + iLBCdec_inst->nasub = NASUB_20MS; + iLBCdec_inst->lpc_n = LPC_N_20MS; + iLBCdec_inst->no_of_bytes = NO_OF_BYTES_20MS; + iLBCdec_inst->no_of_words = NO_OF_WORDS_20MS; + iLBCdec_inst->state_short_len=STATE_SHORT_LEN_20MS; + /* ULP init */ + iLBCdec_inst->ULP_inst=&ULP_20msTbl; + } + else { + exit(2); + } + + memset(iLBCdec_inst->syntMem, 0, + LPC_FILTERORDER*sizeof(float)); + memcpy((*iLBCdec_inst).lsfdeqold, lsfmeanTbl, + LPC_FILTERORDER*sizeof(float)); + + memset(iLBCdec_inst->old_syntdenum, 0, + ((LPC_FILTERORDER + 1)*NSUB_MAX)*sizeof(float)); + for (i=0; i<NSUB_MAX; i++) + iLBCdec_inst->old_syntdenum[i*(LPC_FILTERORDER+1)]=1.0; + + iLBCdec_inst->last_lag = 20; + + iLBCdec_inst->prevLag = 120; + iLBCdec_inst->per = 0.0; + iLBCdec_inst->consPLICount = 0; + iLBCdec_inst->prevPLI = 0; + iLBCdec_inst->prevLpc[0] = 1.0; + memset(iLBCdec_inst->prevLpc+1,0, + LPC_FILTERORDER*sizeof(float)); + memset(iLBCdec_inst->prevResidual, 0, BLOCKL_MAX*sizeof(float)); + iLBCdec_inst->seed=777; + + memset(iLBCdec_inst->hpomem, 0, 4*sizeof(float)); + + iLBCdec_inst->use_enhancer = use_enhancer; + memset(iLBCdec_inst->enh_buf, 0, ENH_BUFL*sizeof(float)); + for (i=0;i<ENH_NBLOCKS_TOT;i++) + iLBCdec_inst->enh_period[i]=(float)40.0; + iLBCdec_inst->prev_enh_pl = 0; - return (BLOCKL); -} - -/*----------------------------------------------------------------* - * frame residual decoder function (subrutine to iLBC_decode) - *---------------------------------------------------------------*/ - -static void Decode( - float *decresidual, /* (o) decoded residual frame */ - int start, /* (i) location of start state */ - int idxForMax, /* (i) codebook index for the maximum - value */ - int *idxVec, /* (i) codebook indexes for the samples - in the start state */ - float *syntdenum, /* (i) the decoded synthesis filter - coefficients */ - int *cb_index, /* (i) the indexes for the adaptive - codebook */ - int *gain_index, /* (i) the indexes for the corresponding - gains */ - int *extra_cb_index,/* (i) the indexes for the adaptive - codebook part of start state */ - int *extra_gain_index, /* (i) the indexes for the corresponding - gains */ - int state_first /* (i) 1 if non adaptive part of start - state comes first 0 if that part - comes last */ -){ - float reverseDecresidual[BLOCKL], mem[CB_MEML]; - int k, meml_gotten, Nfor, Nback, i; - int diff, start_pos; - int subcount, subframe; - - diff = STATE_LEN - STATE_SHORT_LEN; - - if (state_first == 1) { - start_pos = (start-1)*SUBL; - } else { - start_pos = (start-1)*SUBL + diff; - } - - /* decode scalar part of start state */ - - StateConstructW(idxForMax, idxVec, - &syntdenum[(start-1)*(LPC_FILTERORDER+1)], - &decresidual[start_pos], STATE_SHORT_LEN); - - - if (state_first) { /* put adaptive part in the end */ - - /* setup memory */ - - memset(mem, 0, (CB_MEML-STATE_SHORT_LEN)*sizeof(float)); - memcpy(mem+CB_MEML-STATE_SHORT_LEN, decresidual+start_pos, - STATE_SHORT_LEN*sizeof(float)); - - /* construct decoded vector */ - - iCBConstruct(&decresidual[start_pos+STATE_SHORT_LEN], - extra_cb_index, extra_gain_index, mem+CB_MEML-stMemLTbl, - stMemLTbl, diff, CB_NSTAGES); - - } - else {/* put adaptive part in the beginning */ - - /* create reversed vectors for prediction */ - - for(k=0; k<diff; k++ ){ - reverseDecresidual[k] = - decresidual[(start+1)*SUBL -1-(k+STATE_SHORT_LEN)]; - } - - /* setup memory */ - - meml_gotten = STATE_SHORT_LEN; - for( k=0; k<meml_gotten; k++){ - mem[CB_MEML-1-k] = decresidual[start_pos + k]; - } - memset(mem, 0, (CB_MEML-k)*sizeof(float)); - - /* construct decoded vector */ - - iCBConstruct(reverseDecresidual, extra_cb_index, - extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl, - diff, CB_NSTAGES); - - /* get decoded residual from reversed vector */ - - for( k=0; k<diff; k++ ){ - decresidual[start_pos-1-k] = reverseDecresidual[k]; - } - } - - /* counter for predicted subframes */ - - subcount=0; - - /* forward prediction of subframes */ - - Nfor = NSUB-start-1; - - if( Nfor > 0 ){ - - /* setup memory */ - - memset(mem, 0, (CB_MEML-STATE_LEN)*sizeof(float)); - memcpy(mem+CB_MEML-STATE_LEN, decresidual+(start-1)*SUBL, - STATE_LEN*sizeof(float)); - - /* loop over subframes to encode */ - - for (subframe=0; subframe<Nfor; subframe++) { - - /* construct decoded vector */ - - iCBConstruct(&decresidual[(start+1+subframe)*SUBL], - cb_index+subcount*CB_NSTAGES, - gain_index+subcount*CB_NSTAGES, - mem+CB_MEML-memLfTbl[subcount], - memLfTbl[subcount], SUBL, CB_NSTAGES); - - /* update memory */ - - memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float)); - memcpy(mem+CB_MEML-SUBL, - &decresidual[(start+1+subframe)*SUBL], - SUBL*sizeof(float)); - - subcount++; - - } - - } - - /* backward prediction of subframes */ - - Nback = start-1; - - if( Nback > 0 ){ - - /* setup memory */ - - meml_gotten = SUBL*(NSUB+1-start); - - - if( meml_gotten > CB_MEML ) { - meml_gotten=CB_MEML; - } - for( k=0; k<meml_gotten; k++) { - mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k]; - } - memset(mem, 0, (CB_MEML-k)*sizeof(float)); - - /* loop over subframes to decode */ - - for (subframe=0; subframe<Nback; subframe++) { - - /* construct decoded vector */ - - iCBConstruct(&reverseDecresidual[subframe*SUBL], - cb_index+subcount*CB_NSTAGES, - gain_index+subcount*CB_NSTAGES, - mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], - SUBL, CB_NSTAGES); - - /* update memory */ - - memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float)); - memcpy(mem+CB_MEML-SUBL, - &reverseDecresidual[subframe*SUBL], - SUBL*sizeof(float)); - - subcount++; - } - - /* get decoded residual from reversed vector */ - - for (i = 0; i < SUBL*Nback; i++) - decresidual[SUBL*Nback - i - 1] = - reverseDecresidual[i]; - } -} - -/*----------------------------------------------------------------* - * main decoder function - *---------------------------------------------------------------*/ - -void iLBC_decode( - float *decblock, /* (o) decoded signal block */ - unsigned char *bytes, /* (i) encoded signal bits */ - iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state - structure */ - int mode /* (i) 0: bad packet, PLC, - 1: normal */ -){ - float data[BLOCKL]; - float lsfdeq[LPC_FILTERORDER*LPC_N]; - float PLCresidual[BLOCKL], PLClpc[LPC_FILTERORDER + 1]; - float zeros[BLOCKL], one[LPC_FILTERORDER + 1]; - int k, i, start, idxForMax, pos, lastpart, ulp; - int lag, ilag; - float cc, maxcc; - int idxVec[STATE_LEN]; - int check; - int gain_index[NASUB*CB_NSTAGES], extra_gain_index[CB_NSTAGES]; - int cb_index[CB_NSTAGES*NASUB], extra_cb_index[CB_NSTAGES]; - int lsf_i[LSF_NSPLIT*LPC_N]; - int state_first; - unsigned char *pbytes; - float weightdenum[(LPC_FILTERORDER + 1)*NSUB]; - int order_plus_one; - float syntdenum[NSUB*(LPC_FILTERORDER+1)]; - float decresidual[BLOCKL]; - - if (mode>0) { /* the data are good */ - - /* decode data */ - - pbytes=bytes; - pos=0; - - /* Set everything to zero before decoding */ - - for (k=0;k<6;k++) { - lsf_i[k]=0; - } - start=0; - state_first=0; - idxForMax=0; - for (k=0; k<STATE_SHORT_LEN; k++) { - idxVec[k]=0; - } - for (k=0;k<CB_NSTAGES;k++) { - extra_cb_index[k]=0; - } - for (k=0;k<CB_NSTAGES;k++) { - extra_gain_index[k]=0; - } - for (i=0; i<NASUB; i++) { - for (k=0; k<CB_NSTAGES; k++) { - cb_index[i*CB_NSTAGES+k]=0; - } - } - for (i=0; i<NASUB; i++) { - for (k=0; k<CB_NSTAGES; k++) { - gain_index[i*CB_NSTAGES+k]=0; - } - } - - /* loop over ULP classes */ - - for (ulp=0; ulp<3; ulp++) { - - /* LSF */ - for (k=0;k<6;k++) { - unpack( &pbytes, &lastpart, - ulp_lsf_bitsTbl[k][ulp], &pos); - packcombine(&lsf_i[k], lastpart, - ulp_lsf_bitsTbl[k][ulp]); - } - - /* Start block info */ - - unpack( &pbytes, &lastpart, - ulp_start_bitsTbl[ulp], &pos); - packcombine(&start, lastpart, - ulp_start_bitsTbl[ulp]); - - unpack( &pbytes, &lastpart, - ulp_startfirst_bitsTbl[ulp], &pos); - packcombine(&state_first, lastpart, - ulp_startfirst_bitsTbl[ulp]); - - unpack( &pbytes, &lastpart, - ulp_scale_bitsTbl[ulp], &pos); - packcombine(&idxForMax, lastpart, - ulp_scale_bitsTbl[ulp]); - - for (k=0; k<STATE_SHORT_LEN; k++) { - unpack( &pbytes, &lastpart, - ulp_state_bitsTbl[ulp], &pos); - packcombine(idxVec+k, lastpart, - ulp_state_bitsTbl[ulp]); - } - - /* 22 sample block */ - - for (k=0;k<CB_NSTAGES;k++) { - unpack( &pbytes, &lastpart, - ulp_extra_cb_indexTbl[k][ulp], &pos); - packcombine(extra_cb_index+k, lastpart, - ulp_extra_cb_indexTbl[k][ulp]); - } - for (k=0;k<CB_NSTAGES;k++) { - unpack( &pbytes, &lastpart, - ulp_extra_cb_gainTbl[k][ulp], &pos); - packcombine(extra_gain_index+k, lastpart, - ulp_extra_cb_gainTbl[k][ulp]); - } - - /* The four 40 sample sub blocks */ - - for (i=0; i<NASUB; i++) { - for (k=0; k<CB_NSTAGES; k++) { - unpack( &pbytes, &lastpart, - ulp_cb_indexTbl[i][k][ulp], &pos); - packcombine(cb_index+i*CB_NSTAGES+k, lastpart, - ulp_cb_indexTbl[i][k][ulp]); - } - } - - for (i=0; i<NASUB; i++) { - for (k=0; k<CB_NSTAGES; k++) { - unpack( &pbytes, &lastpart, - ulp_cb_gainTbl[i][k][ulp], &pos); - packcombine(gain_index+i*CB_NSTAGES+k, lastpart, - ulp_cb_gainTbl[i][k][ulp]); - } - } - } - - /* Check for bit errors */ - if( (start<1) || (start>5) ) - mode = 0; - - if (mode==1) { /* No bit errors was detected, - continue decoding */ - - /* adjust index */ - index_conv_dec(cb_index); - - /* decode the lsf */ - - SimplelsfDEQ(lsfdeq, lsf_i); - check=LSF_check(lsfdeq, LPC_FILTERORDER, LPC_N); - DecoderInterpolateLSF(syntdenum, weightdenum, - lsfdeq, LPC_FILTERORDER, iLBCdec_inst); - - Decode(decresidual, start, idxForMax, idxVec, - syntdenum, cb_index, gain_index, - extra_cb_index, extra_gain_index, - state_first); - - /* preparing the plc for a future loss! */ - - doThePLC(PLCresidual, PLClpc, 0, decresidual, - syntdenum + (LPC_FILTERORDER + 1)*(NSUB - 1), - (*iLBCdec_inst).last_lag, iLBCdec_inst); - - - memcpy(decresidual, PLCresidual, BLOCKL*sizeof(float)); - } - - } - - if (mode == 0) { - /* the data is bad (either a PLC call - * was made or a bit error was detected) - */ - - /* packet loss conceal */ - - memset(zeros, 0, BLOCKL*sizeof(float)); - - one[0] = 1; - memset(one+1, 0, LPC_FILTERORDER*sizeof(float)); - - start=0; - - doThePLC(PLCresidual, PLClpc, 1, zeros, one, - (*iLBCdec_inst).last_lag, iLBCdec_inst); - memcpy(decresidual, PLCresidual, BLOCKL*sizeof(float)); - - order_plus_one = LPC_FILTERORDER + 1; - for (i = 0; i < NSUB; i++) { - memcpy(syntdenum+(i*order_plus_one), PLClpc, - order_plus_one*sizeof(float)); - } + return (iLBCdec_inst->blockl); +} + + + +/*----------------------------------------------------------------* + * frame residual decoder function (subrutine to iLBC_decode) + *---------------------------------------------------------------*/ + +void Decode( + iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state + structure */ + float *decresidual, /* (o) decoded residual frame */ + int start, /* (i) location of start + state */ + int idxForMax, /* (i) codebook index for the + maximum value */ + int *idxVec, /* (i) codebook indexes for the + samples in the start + state */ + float *syntdenum, /* (i) the decoded synthesis + filter coefficients */ + int *cb_index, /* (i) the indexes for the + adaptive codebook */ + int *gain_index, /* (i) the indexes for the + corresponding gains */ + int *extra_cb_index, /* (i) the indexes for the + adaptive codebook part + of start state */ + int *extra_gain_index, /* (i) the indexes for the + corresponding gains */ + int state_first /* (i) 1 if non adaptive part + of start state comes + first 0 if that part + comes last */ +){ + float reverseDecresidual[BLOCKL_MAX], mem[CB_MEML]; + int k, meml_gotten, Nfor, Nback, i; + int diff, start_pos; + int subcount, subframe; + + diff = STATE_LEN - iLBCdec_inst->state_short_len; + + if (state_first == 1) { + start_pos = (start-1)*SUBL; + } else { + start_pos = (start-1)*SUBL + diff; + } + + /* decode scalar part of start state */ + + StateConstructW(idxForMax, idxVec, + &syntdenum[(start-1)*(LPC_FILTERORDER+1)], + &decresidual[start_pos], iLBCdec_inst->state_short_len); + + + if (state_first) { /* put adaptive part in the end */ + + + + /* setup memory */ + + memset(mem, 0, + (CB_MEML-iLBCdec_inst->state_short_len)*sizeof(float)); + memcpy(mem+CB_MEML-iLBCdec_inst->state_short_len, + decresidual+start_pos, + iLBCdec_inst->state_short_len*sizeof(float)); + + /* construct decoded vector */ + + iCBConstruct( + &decresidual[start_pos+iLBCdec_inst->state_short_len], + extra_cb_index, extra_gain_index, mem+CB_MEML-stMemLTbl, + stMemLTbl, diff, CB_NSTAGES); + } - - if ((*iLBCdec_inst).use_enhancer == 1) { - - /* post filtering */ - - (*iLBCdec_inst).last_lag = - enhancerInterface(data, decresidual, iLBCdec_inst); - - /* synthesis filtering */ - - for (i=0; i < 2; i++) { - syntFilter(data + i*SUBL, - (*iLBCdec_inst).old_syntdenum + - (i+4)*(LPC_FILTERORDER+1), SUBL, - (*iLBCdec_inst).syntMem); - } - for (i=2; i < NSUB; i++) { - syntFilter(data + i*SUBL, - syntdenum + (i-2)*(LPC_FILTERORDER+1), SUBL, - (*iLBCdec_inst).syntMem); - } - - } else { - - /* Find last lag */ - lag = 20; - maxcc = xCorrCoef(&decresidual[BLOCKL-ENH_BLOCKL], - &decresidual[BLOCKL-ENH_BLOCKL-lag], ENH_BLOCKL); - - for (ilag=21; ilag<120; ilag++) { - cc = xCorrCoef(&decresidual[BLOCKL-ENH_BLOCKL], - &decresidual[BLOCKL-ENH_BLOCKL-ilag], ENH_BLOCKL); - - if (cc > maxcc) { - maxcc = cc; - lag = ilag; - } - } - (*iLBCdec_inst).last_lag = lag; - - /* copy data and run synthesis filter */ - - memcpy(data, decresidual, BLOCKL*sizeof(float)); - for (i=0; i < NSUB; i++) { - syntFilter(data + i*SUBL, - syntdenum + i*(LPC_FILTERORDER+1), SUBL, - (*iLBCdec_inst).syntMem); + else {/* put adaptive part in the beginning */ + + /* create reversed vectors for prediction */ + + for (k=0; k<diff; k++) { + reverseDecresidual[k] = + decresidual[(start+1)*SUBL-1- + (k+iLBCdec_inst->state_short_len)]; + } + + /* setup memory */ + + meml_gotten = iLBCdec_inst->state_short_len; + for (k=0; k<meml_gotten; k++){ + mem[CB_MEML-1-k] = decresidual[start_pos + k]; } - } - - /* high pass filtering on output if desired, otherwise - copy to out */ - - /*hpOutput(data, BLOCKL, decblock, (*iLBCdec_inst).hpomem);*/ - memcpy(decblock,data,BLOCKL*sizeof(float)); - - memcpy((*iLBCdec_inst).old_syntdenum, syntdenum, - NSUB*(LPC_FILTERORDER+1)*sizeof(float)); - - iLBCdec_inst->prev_enh_pl=0; - - if (mode==0) { /* PLC was used */ - iLBCdec_inst->prev_enh_pl=1; - } -} - - + memset(mem, 0, (CB_MEML-k)*sizeof(float)); + + /* construct decoded vector */ + + iCBConstruct(reverseDecresidual, extra_cb_index, + extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl, + diff, CB_NSTAGES); + + /* get decoded residual from reversed vector */ + + for (k=0; k<diff; k++) { + decresidual[start_pos-1-k] = reverseDecresidual[k]; + } + } + + /* counter for predicted sub-frames */ + + subcount=0; + + /* forward prediction of sub-frames */ + + Nfor = iLBCdec_inst->nsub-start-1; + + + + if ( Nfor > 0 ){ + + /* setup memory */ + + memset(mem, 0, (CB_MEML-STATE_LEN)*sizeof(float)); + memcpy(mem+CB_MEML-STATE_LEN, decresidual+(start-1)*SUBL, + STATE_LEN*sizeof(float)); + + /* loop over sub-frames to encode */ + + for (subframe=0; subframe<Nfor; subframe++) { + + /* construct decoded vector */ + + iCBConstruct(&decresidual[(start+1+subframe)*SUBL], + cb_index+subcount*CB_NSTAGES, + gain_index+subcount*CB_NSTAGES, + mem+CB_MEML-memLfTbl[subcount], + memLfTbl[subcount], SUBL, CB_NSTAGES); + + /* update memory */ + + memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float)); + memcpy(mem+CB_MEML-SUBL, + &decresidual[(start+1+subframe)*SUBL], + SUBL*sizeof(float)); + + subcount++; + + } + + } + + /* backward prediction of sub-frames */ + + Nback = start-1; + + if ( Nback > 0 ) { + + /* setup memory */ + + meml_gotten = SUBL*(iLBCdec_inst->nsub+1-start); + + if ( meml_gotten > CB_MEML ) { + meml_gotten=CB_MEML; + } + for (k=0; k<meml_gotten; k++) { + mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k]; + } + memset(mem, 0, (CB_MEML-k)*sizeof(float)); + + /* loop over subframes to decode */ + + + + for (subframe=0; subframe<Nback; subframe++) { + + /* construct decoded vector */ + + iCBConstruct(&reverseDecresidual[subframe*SUBL], + cb_index+subcount*CB_NSTAGES, + gain_index+subcount*CB_NSTAGES, + mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], + SUBL, CB_NSTAGES); + + /* update memory */ + + memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float)); + memcpy(mem+CB_MEML-SUBL, + &reverseDecresidual[subframe*SUBL], + SUBL*sizeof(float)); + + subcount++; + } + + /* get decoded residual from reversed vector */ + + for (i=0; i<SUBL*Nback; i++) + decresidual[SUBL*Nback - i - 1] = + reverseDecresidual[i]; + } +} + +/*----------------------------------------------------------------* + * main decoder function + *---------------------------------------------------------------*/ + +void iLBC_decode( + float *decblock, /* (o) decoded signal block */ + unsigned char *bytes, /* (i) encoded signal bits */ + iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state + structure */ + int mode /* (i) 0: bad packet, PLC, + 1: normal */ +){ + float data[BLOCKL_MAX]; + float lsfdeq[LPC_FILTERORDER*LPC_N_MAX]; + float PLCresidual[BLOCKL_MAX], PLClpc[LPC_FILTERORDER + 1]; + float zeros[BLOCKL_MAX], one[LPC_FILTERORDER + 1]; + int k, i, start, idxForMax, pos, lastpart, ulp; + int lag, ilag; + float cc, maxcc; + int idxVec[STATE_LEN]; + int check; + int gain_index[NASUB_MAX*CB_NSTAGES], + extra_gain_index[CB_NSTAGES]; + int cb_index[CB_NSTAGES*NASUB_MAX], extra_cb_index[CB_NSTAGES]; + int lsf_i[LSF_NSPLIT*LPC_N_MAX]; + int state_first; + + + int last_bit; + unsigned char *pbytes; + float weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX]; + int order_plus_one; + float syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)]; + float decresidual[BLOCKL_MAX]; + + if (mode>0) { /* the data are good */ + + /* decode data */ + + pbytes=bytes; + pos=0; + + /* Set everything to zero before decoding */ + + for (k=0; k<LSF_NSPLIT*LPC_N_MAX; k++) { + lsf_i[k]=0; + } + start=0; + state_first=0; + idxForMax=0; + for (k=0; k<iLBCdec_inst->state_short_len; k++) { + idxVec[k]=0; + } + for (k=0; k<CB_NSTAGES; k++) { + extra_cb_index[k]=0; + } + for (k=0; k<CB_NSTAGES; k++) { + extra_gain_index[k]=0; + } + for (i=0; i<iLBCdec_inst->nasub; i++) { + for (k=0; k<CB_NSTAGES; k++) { + cb_index[i*CB_NSTAGES+k]=0; + } + } + for (i=0; i<iLBCdec_inst->nasub; i++) { + for (k=0; k<CB_NSTAGES; k++) { + gain_index[i*CB_NSTAGES+k]=0; + } + } + + /* loop over ULP classes */ + + for (ulp=0; ulp<3; ulp++) { + + /* LSF */ + for (k=0; k<LSF_NSPLIT*iLBCdec_inst->lpc_n; k++){ + unpack( &pbytes, &lastpart, + iLBCdec_inst->ULP_inst->lsf_bits[k][ulp], &pos); + packcombine(&lsf_i[k], lastpart, + iLBCdec_inst->ULP_inst->lsf_bits[k][ulp]); + } + + + + /* Start block info */ + + unpack( &pbytes, &lastpart, + iLBCdec_inst->ULP_inst->start_bits[ulp], &pos); + packcombine(&start, lastpart, + iLBCdec_inst->ULP_inst->start_bits[ulp]); + + unpack( &pbytes, &lastpart, + iLBCdec_inst->ULP_inst->startfirst_bits[ulp], &pos); + packcombine(&state_first, lastpart, + iLBCdec_inst->ULP_inst->startfirst_bits[ulp]); + + unpack( &pbytes, &lastpart, + iLBCdec_inst->ULP_inst->scale_bits[ulp], &pos); + packcombine(&idxForMax, lastpart, + iLBCdec_inst->ULP_inst->scale_bits[ulp]); + + for (k=0; k<iLBCdec_inst->state_short_len; k++) { + unpack( &pbytes, &lastpart, + iLBCdec_inst->ULP_inst->state_bits[ulp], &pos); + packcombine(idxVec+k, lastpart, + iLBCdec_inst->ULP_inst->state_bits[ulp]); + } + + /* 23/22 (20ms/30ms) sample block */ + + for (k=0; k<CB_NSTAGES; k++) { + unpack( &pbytes, &lastpart, + iLBCdec_inst->ULP_inst->extra_cb_index[k][ulp], + &pos); + packcombine(extra_cb_index+k, lastpart, + iLBCdec_inst->ULP_inst->extra_cb_index[k][ulp]); + } + for (k=0; k<CB_NSTAGES; k++) { + unpack( &pbytes, &lastpart, + iLBCdec_inst->ULP_inst->extra_cb_gain[k][ulp], + &pos); + packcombine(extra_gain_index+k, lastpart, + iLBCdec_inst->ULP_inst->extra_cb_gain[k][ulp]); + } + + /* The two/four (20ms/30ms) 40 sample sub-blocks */ + + for (i=0; i<iLBCdec_inst->nasub; i++) { + for (k=0; k<CB_NSTAGES; k++) { + unpack( &pbytes, &lastpart, + iLBCdec_inst->ULP_inst->cb_index[i][k][ulp], + &pos); + packcombine(cb_index+i*CB_NSTAGES+k, lastpart, + iLBCdec_inst->ULP_inst->cb_index[i][k][ulp]); + } + } + + for (i=0; i<iLBCdec_inst->nasub; i++) { + + + for (k=0; k<CB_NSTAGES; k++) { + unpack( &pbytes, &lastpart, + + iLBCdec_inst->ULP_inst->cb_gain[i][k][ulp], + &pos); + packcombine(gain_index+i*CB_NSTAGES+k, lastpart, + iLBCdec_inst->ULP_inst->cb_gain[i][k][ulp]); + } + } + } + /* Extract last bit. If it is 1 this indicates an + empty/lost frame */ + unpack( &pbytes, &last_bit, 1, &pos); + + /* Check for bit errors or empty/lost frames */ + if (start<1) + mode = 0; + if (iLBCdec_inst->mode==20 && start>3) + mode = 0; + if (iLBCdec_inst->mode==30 && start>5) + mode = 0; + if (last_bit==1) + mode = 0; + + if (mode==1) { /* No bit errors was detected, + continue decoding */ + + /* adjust index */ + index_conv_dec(cb_index); + + /* decode the lsf */ + + SimplelsfDEQ(lsfdeq, lsf_i, iLBCdec_inst->lpc_n); + check=LSF_check(lsfdeq, LPC_FILTERORDER, + iLBCdec_inst->lpc_n); + DecoderInterpolateLSF(syntdenum, weightdenum, + lsfdeq, LPC_FILTERORDER, iLBCdec_inst); + + Decode(iLBCdec_inst, decresidual, start, idxForMax, + idxVec, syntdenum, cb_index, gain_index, + extra_cb_index, extra_gain_index, + state_first); + + /* preparing the plc for a future loss! */ + + doThePLC(PLCresidual, PLClpc, 0, decresidual, + syntdenum + + (LPC_FILTERORDER + 1)*(iLBCdec_inst->nsub - 1), + (*iLBCdec_inst).last_lag, iLBCdec_inst); + + + memcpy(decresidual, PLCresidual, + iLBCdec_inst->blockl*sizeof(float)); + } + + + + } + + if (mode == 0) { + /* the data is bad (either a PLC call + * was made or a severe bit error was detected) + */ + + /* packet loss conceal */ + + memset(zeros, 0, BLOCKL_MAX*sizeof(float)); + + one[0] = 1; + memset(one+1, 0, LPC_FILTERORDER*sizeof(float)); + + start=0; + + doThePLC(PLCresidual, PLClpc, 1, zeros, one, + (*iLBCdec_inst).last_lag, iLBCdec_inst); + memcpy(decresidual, PLCresidual, + iLBCdec_inst->blockl*sizeof(float)); + + order_plus_one = LPC_FILTERORDER + 1; + for (i = 0; i < iLBCdec_inst->nsub; i++) { + memcpy(syntdenum+(i*order_plus_one), PLClpc, + order_plus_one*sizeof(float)); + } + } + + if (iLBCdec_inst->use_enhancer == 1) { + + /* post filtering */ + + iLBCdec_inst->last_lag = + enhancerInterface(data, decresidual, iLBCdec_inst); + + /* synthesis filtering */ + + if (iLBCdec_inst->mode==20) { + /* Enhancer has 40 samples delay */ + i=0; + syntFilter(data + i*SUBL, + iLBCdec_inst->old_syntdenum + + (i+iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1), + SUBL, iLBCdec_inst->syntMem); + for (i=1; i < iLBCdec_inst->nsub; i++) { + syntFilter(data + i*SUBL, + syntdenum + (i-1)*(LPC_FILTERORDER+1), + SUBL, iLBCdec_inst->syntMem); + } + } else if (iLBCdec_inst->mode==30) { + /* Enhancer has 80 samples delay */ + for (i=0; i < 2; i++) { + syntFilter(data + i*SUBL, + + + iLBCdec_inst->old_syntdenum + + (i+iLBCdec_inst->nsub-2)*(LPC_FILTERORDER+1), + SUBL, iLBCdec_inst->syntMem); + } + for (i=2; i < iLBCdec_inst->nsub; i++) { + syntFilter(data + i*SUBL, + syntdenum + (i-2)*(LPC_FILTERORDER+1), SUBL, + iLBCdec_inst->syntMem); + } + } + + } else { + + /* Find last lag */ + lag = 20; + maxcc = xCorrCoef(&decresidual[BLOCKL_MAX-ENH_BLOCKL], + &decresidual[BLOCKL_MAX-ENH_BLOCKL-lag], ENH_BLOCKL); + + for (ilag=21; ilag<120; ilag++) { + cc = xCorrCoef(&decresidual[BLOCKL_MAX-ENH_BLOCKL], + &decresidual[BLOCKL_MAX-ENH_BLOCKL-ilag], + ENH_BLOCKL); + + if (cc > maxcc) { + maxcc = cc; + lag = ilag; + } + } + iLBCdec_inst->last_lag = lag; + + /* copy data and run synthesis filter */ + + memcpy(data, decresidual, + iLBCdec_inst->blockl*sizeof(float)); + for (i=0; i < iLBCdec_inst->nsub; i++) { + syntFilter(data + i*SUBL, + syntdenum + i*(LPC_FILTERORDER+1), SUBL, + iLBCdec_inst->syntMem); + } + } + + /* high pass filtering on output if desired, otherwise + copy to out */ + + hpOutput(data, iLBCdec_inst->blockl, + decblock,iLBCdec_inst->hpomem); + + /* memcpy(decblock,data,iLBCdec_inst->blockl*sizeof(float));*/ + + memcpy(iLBCdec_inst->old_syntdenum, syntdenum, + + iLBCdec_inst->nsub*(LPC_FILTERORDER+1)*sizeof(float)); + + iLBCdec_inst->prev_enh_pl=0; + + + + if (mode==0) { /* PLC was used */ + iLBCdec_inst->prev_enh_pl=1; + } +} + + |