1/*
2 *  Copyright (c) 2012 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_Decode.c
16
17******************************************************************/
18
19#include "defines.h"
20#include "simple_lsf_dequant.h"
21#include "decoder_interpolate_lsf.h"
22#include "index_conv_dec.h"
23#include "do_plc.h"
24#include "constants.h"
25#include "enhancer_interface.h"
26#include "xcorr_coef.h"
27#include "lsf_check.h"
28#include "decode_residual.h"
29#include "unpack_bits.h"
30#include "hp_output.h"
31#ifndef WEBRTC_ARCH_BIG_ENDIAN
32#include "swap_bytes.h"
33#endif
34
35/*----------------------------------------------------------------*
36 *  main decoder function
37 *---------------------------------------------------------------*/
38
39void WebRtcIlbcfix_DecodeImpl(
40    int16_t *decblock,    /* (o) decoded signal block */
41    const uint16_t *bytes, /* (i) encoded signal bits */
42    IlbcDecoder *iLBCdec_inst, /* (i/o) the decoder state
43                                           structure */
44    int16_t mode      /* (i) 0: bad packet, PLC,
45                                                                   1: normal */
46                           ) {
47  size_t i;
48  int16_t order_plus_one;
49
50  int16_t last_bit;
51  int16_t *data;
52  /* Stack based */
53  int16_t decresidual[BLOCKL_MAX];
54  int16_t PLCresidual[BLOCKL_MAX + LPC_FILTERORDER];
55  int16_t syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)];
56  int16_t PLClpc[LPC_FILTERORDER + 1];
57#ifndef WEBRTC_ARCH_BIG_ENDIAN
58  uint16_t swapped[NO_OF_WORDS_30MS];
59#endif
60  iLBC_bits *iLBCbits_inst = (iLBC_bits*)PLCresidual;
61
62  /* Reuse some buffers that are non overlapping in order to save stack memory */
63  data = &PLCresidual[LPC_FILTERORDER];
64
65  if (mode) { /* the data are good */
66
67    /* decode data */
68
69    /* Unpacketize bits into parameters */
70
71#ifndef WEBRTC_ARCH_BIG_ENDIAN
72    WebRtcIlbcfix_SwapBytes(bytes, iLBCdec_inst->no_of_words, swapped);
73    last_bit = WebRtcIlbcfix_UnpackBits(swapped, iLBCbits_inst, iLBCdec_inst->mode);
74#else
75    last_bit = WebRtcIlbcfix_UnpackBits(bytes, iLBCbits_inst, iLBCdec_inst->mode);
76#endif
77
78    /* Check for bit errors */
79    if (iLBCbits_inst->startIdx<1)
80      mode = 0;
81    if ((iLBCdec_inst->mode==20) && (iLBCbits_inst->startIdx>3))
82      mode = 0;
83    if ((iLBCdec_inst->mode==30) && (iLBCbits_inst->startIdx>5))
84      mode = 0;
85    if (last_bit==1)
86      mode = 0;
87
88    if (mode) { /* No bit errors was detected, continue decoding */
89      /* Stack based */
90      int16_t lsfdeq[LPC_FILTERORDER*LPC_N_MAX];
91      int16_t weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
92
93      /* adjust index */
94      WebRtcIlbcfix_IndexConvDec(iLBCbits_inst->cb_index);
95
96      /* decode the lsf */
97      WebRtcIlbcfix_SimpleLsfDeQ(lsfdeq, (int16_t*)(iLBCbits_inst->lsf), iLBCdec_inst->lpc_n);
98      WebRtcIlbcfix_LsfCheck(lsfdeq, LPC_FILTERORDER, iLBCdec_inst->lpc_n);
99      WebRtcIlbcfix_DecoderInterpolateLsp(syntdenum, weightdenum,
100                                          lsfdeq, LPC_FILTERORDER, iLBCdec_inst);
101
102      /* Decode the residual using the cb and gain indexes */
103      WebRtcIlbcfix_DecodeResidual(iLBCdec_inst, iLBCbits_inst, decresidual, syntdenum);
104
105      /* preparing the plc for a future loss! */
106      WebRtcIlbcfix_DoThePlc(
107          PLCresidual, PLClpc, 0, decresidual,
108          syntdenum + (LPC_FILTERORDER + 1) * (iLBCdec_inst->nsub - 1),
109          iLBCdec_inst->last_lag, iLBCdec_inst);
110
111      /* Use the output from doThePLC */
112      WEBRTC_SPL_MEMCPY_W16(decresidual, PLCresidual, iLBCdec_inst->blockl);
113    }
114
115  }
116
117  if (mode == 0) {
118    /* the data is bad (either a PLC call
119     * was made or a bit error was detected)
120     */
121
122    /* packet loss conceal */
123
124    WebRtcIlbcfix_DoThePlc(PLCresidual, PLClpc, 1, decresidual, syntdenum,
125                           iLBCdec_inst->last_lag, iLBCdec_inst);
126
127    WEBRTC_SPL_MEMCPY_W16(decresidual, PLCresidual, iLBCdec_inst->blockl);
128
129    order_plus_one = LPC_FILTERORDER + 1;
130
131    for (i = 0; i < iLBCdec_inst->nsub; i++) {
132      WEBRTC_SPL_MEMCPY_W16(syntdenum+(i*order_plus_one),
133                            PLClpc, order_plus_one);
134    }
135  }
136
137  if ((*iLBCdec_inst).use_enhancer == 1) { /* Enhancer activated */
138
139    /* Update the filter and filter coefficients if there was a packet loss */
140    if (iLBCdec_inst->prev_enh_pl==2) {
141      for (i=0;i<iLBCdec_inst->nsub;i++) {
142        WEBRTC_SPL_MEMCPY_W16(&(iLBCdec_inst->old_syntdenum[i*(LPC_FILTERORDER+1)]),
143                              syntdenum, (LPC_FILTERORDER+1));
144      }
145    }
146
147    /* post filtering */
148    (*iLBCdec_inst).last_lag =
149        WebRtcIlbcfix_EnhancerInterface(data, decresidual, iLBCdec_inst);
150
151    /* synthesis filtering */
152
153    /* Set up the filter state */
154    WEBRTC_SPL_MEMCPY_W16(&data[-LPC_FILTERORDER], iLBCdec_inst->syntMem, LPC_FILTERORDER);
155
156    if (iLBCdec_inst->mode==20) {
157      /* Enhancer has 40 samples delay */
158      i=0;
159      WebRtcSpl_FilterARFastQ12(
160          data, data,
161          iLBCdec_inst->old_syntdenum + (i+iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1),
162          LPC_FILTERORDER+1, SUBL);
163
164      for (i=1; i < iLBCdec_inst->nsub; i++) {
165        WebRtcSpl_FilterARFastQ12(
166            data+i*SUBL, data+i*SUBL,
167            syntdenum+(i-1)*(LPC_FILTERORDER+1),
168            LPC_FILTERORDER+1, SUBL);
169      }
170
171    } else if (iLBCdec_inst->mode==30) {
172      /* Enhancer has 80 samples delay */
173      for (i=0; i < 2; i++) {
174        WebRtcSpl_FilterARFastQ12(
175            data+i*SUBL, data+i*SUBL,
176            iLBCdec_inst->old_syntdenum + (i+4)*(LPC_FILTERORDER+1),
177            LPC_FILTERORDER+1, SUBL);
178      }
179      for (i=2; i < iLBCdec_inst->nsub; i++) {
180        WebRtcSpl_FilterARFastQ12(
181            data+i*SUBL, data+i*SUBL,
182            syntdenum+(i-2)*(LPC_FILTERORDER+1),
183            LPC_FILTERORDER+1, SUBL);
184      }
185    }
186
187    /* Save the filter state */
188    WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &data[iLBCdec_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);
189
190  } else { /* Enhancer not activated */
191    size_t lag;
192
193    /* Find last lag (since the enhancer is not called to give this info) */
194    lag = 20;
195    if (iLBCdec_inst->mode==20) {
196      lag = WebRtcIlbcfix_XcorrCoef(
197          &decresidual[iLBCdec_inst->blockl-60],
198          &decresidual[iLBCdec_inst->blockl-60-lag],
199          60,
200          80, lag, -1);
201    } else {
202      lag = WebRtcIlbcfix_XcorrCoef(
203          &decresidual[iLBCdec_inst->blockl-ENH_BLOCKL],
204          &decresidual[iLBCdec_inst->blockl-ENH_BLOCKL-lag],
205          ENH_BLOCKL,
206          100, lag, -1);
207    }
208
209    /* Store lag (it is needed if next packet is lost) */
210    (*iLBCdec_inst).last_lag = lag;
211
212    /* copy data and run synthesis filter */
213    WEBRTC_SPL_MEMCPY_W16(data, decresidual, iLBCdec_inst->blockl);
214
215    /* Set up the filter state */
216    WEBRTC_SPL_MEMCPY_W16(&data[-LPC_FILTERORDER], iLBCdec_inst->syntMem, LPC_FILTERORDER);
217
218    for (i=0; i < iLBCdec_inst->nsub; i++) {
219      WebRtcSpl_FilterARFastQ12(
220          data+i*SUBL, data+i*SUBL,
221          syntdenum + i*(LPC_FILTERORDER+1),
222          LPC_FILTERORDER+1, SUBL);
223    }
224
225    /* Save the filter state */
226    WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &data[iLBCdec_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);
227  }
228
229  WEBRTC_SPL_MEMCPY_W16(decblock,data,iLBCdec_inst->blockl);
230
231  /* High pass filter the signal (with upscaling a factor 2 and saturation) */
232  WebRtcIlbcfix_HpOutput(decblock, (int16_t*)WebRtcIlbcfix_kHpOutCoefs,
233                         iLBCdec_inst->hpimemy, iLBCdec_inst->hpimemx,
234                         iLBCdec_inst->blockl);
235
236  WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->old_syntdenum,
237                        syntdenum, iLBCdec_inst->nsub*(LPC_FILTERORDER+1));
238
239  iLBCdec_inst->prev_enh_pl=0;
240
241  if (mode==0) { /* PLC was used */
242    iLBCdec_inst->prev_enh_pl=1;
243  }
244}
245