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