Mercurial > hg > audiostuff
view intercom/ilbc/iLBC_decode.c @ 4:26cd8f1ef0b1
import spandsp-0.0.6pre17
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 15:50:58 +0200 |
parents | 13be24d74cd2 |
children |
line wrap: on
line source
/****************************************************************** 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 (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); } 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]; } 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; } }