blob: 3a2e5a23449ce6802d25ac01069731320c4550a9 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
turaj@webrtc.org10d3b522012-05-24 21:20:25 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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"
andrew@webrtc.org621df672013-10-22 10:27:23 +000031#ifndef WEBRTC_ARCH_BIG_ENDIAN
niklase@google.com470e71d2011-07-07 08:21:25 +000032#include "swap_bytes.h"
33#endif
34
35/*----------------------------------------------------------------*
36 * main decoder function
37 *---------------------------------------------------------------*/
38
39void WebRtcIlbcfix_DecodeImpl(
pbos@webrtc.org0946a562013-04-09 00:28:06 +000040 int16_t *decblock, /* (o) decoded signal block */
41 const uint16_t *bytes, /* (i) encoded signal bits */
pbos@webrtc.orgeb544462014-12-17 15:23:29 +000042 IlbcDecoder *iLBCdec_inst, /* (i/o) the decoder state
niklase@google.com470e71d2011-07-07 08:21:25 +000043 structure */
pbos@webrtc.org0946a562013-04-09 00:28:06 +000044 int16_t mode /* (i) 0: bad packet, PLC,
niklase@google.com470e71d2011-07-07 08:21:25 +000045 1: normal */
46 ) {
47 int i;
pbos@webrtc.org0946a562013-04-09 00:28:06 +000048 int16_t order_plus_one;
niklase@google.com470e71d2011-07-07 08:21:25 +000049
pbos@webrtc.org0946a562013-04-09 00:28:06 +000050 int16_t last_bit;
51 int16_t *data;
niklase@google.com470e71d2011-07-07 08:21:25 +000052 /* Stack based */
pbos@webrtc.org0946a562013-04-09 00:28:06 +000053 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];
andrew@webrtc.org621df672013-10-22 10:27:23 +000057#ifndef WEBRTC_ARCH_BIG_ENDIAN
pbos@webrtc.org0946a562013-04-09 00:28:06 +000058 uint16_t swapped[NO_OF_WORDS_30MS];
turaj@webrtc.org837bc7b2012-07-14 00:34:54 +000059#endif
niklase@google.com470e71d2011-07-07 08:21:25 +000060 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
turaj@webrtc.org10d3b522012-05-24 21:20:25 +000065 if (mode) { /* the data are good */
niklase@google.com470e71d2011-07-07 08:21:25 +000066
67 /* decode data */
68
niklase@google.com470e71d2011-07-07 08:21:25 +000069 /* Unpacketize bits into parameters */
70
andrew@webrtc.org621df672013-10-22 10:27:23 +000071#ifndef WEBRTC_ARCH_BIG_ENDIAN
turaj@webrtc.org837bc7b2012-07-14 00:34:54 +000072 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);
niklase@google.com470e71d2011-07-07 08:21:25 +000076#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
turaj@webrtc.org10d3b522012-05-24 21:20:25 +000088 if (mode) { /* No bit errors was detected, continue decoding */
niklase@google.com470e71d2011-07-07 08:21:25 +000089 /* Stack based */
pbos@webrtc.org0946a562013-04-09 00:28:06 +000090 int16_t lsfdeq[LPC_FILTERORDER*LPC_N_MAX];
91 int16_t weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
niklase@google.com470e71d2011-07-07 08:21:25 +000092
93 /* adjust index */
94 WebRtcIlbcfix_IndexConvDec(iLBCbits_inst->cb_index);
95
96 /* decode the lsf */
pbos@webrtc.org0946a562013-04-09 00:28:06 +000097 WebRtcIlbcfix_SimpleLsfDeQ(lsfdeq, (int16_t*)(iLBCbits_inst->lsf), iLBCdec_inst->lpc_n);
niklase@google.com470e71d2011-07-07 08:21:25 +000098 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( PLCresidual, PLClpc, 0,
107 decresidual, syntdenum + (LPC_FILTERORDER + 1)*(iLBCdec_inst->nsub - 1),
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000108 (int16_t)(iLBCdec_inst->last_lag), iLBCdec_inst);
niklase@google.com470e71d2011-07-07 08:21:25 +0000109
110 /* Use the output from doThePLC */
111 WEBRTC_SPL_MEMCPY_W16(decresidual, PLCresidual, iLBCdec_inst->blockl);
112 }
113
114 }
115
116 if (mode == 0) {
117 /* the data is bad (either a PLC call
118 * was made or a bit error was detected)
119 */
120
121 /* packet loss conceal */
122
123 WebRtcIlbcfix_DoThePlc( PLCresidual, PLClpc, 1,
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000124 decresidual, syntdenum, (int16_t)(iLBCdec_inst->last_lag), iLBCdec_inst);
niklase@google.com470e71d2011-07-07 08:21:25 +0000125
126 WEBRTC_SPL_MEMCPY_W16(decresidual, PLCresidual, iLBCdec_inst->blockl);
127
128 order_plus_one = LPC_FILTERORDER + 1;
129
130 for (i = 0; i < iLBCdec_inst->nsub; i++) {
131 WEBRTC_SPL_MEMCPY_W16(syntdenum+(i*order_plus_one),
132 PLClpc, order_plus_one);
133 }
134 }
135
136 if ((*iLBCdec_inst).use_enhancer == 1) { /* Enhancer activated */
137
138 /* Update the filter and filter coefficients if there was a packet loss */
139 if (iLBCdec_inst->prev_enh_pl==2) {
140 for (i=0;i<iLBCdec_inst->nsub;i++) {
141 WEBRTC_SPL_MEMCPY_W16(&(iLBCdec_inst->old_syntdenum[i*(LPC_FILTERORDER+1)]),
142 syntdenum, (LPC_FILTERORDER+1));
143 }
144 }
145
146 /* post filtering */
147 (*iLBCdec_inst).last_lag =
148 WebRtcIlbcfix_EnhancerInterface(data, decresidual, iLBCdec_inst);
149
150 /* synthesis filtering */
151
152 /* Set up the filter state */
153 WEBRTC_SPL_MEMCPY_W16(&data[-LPC_FILTERORDER], iLBCdec_inst->syntMem, LPC_FILTERORDER);
154
155 if (iLBCdec_inst->mode==20) {
156 /* Enhancer has 40 samples delay */
157 i=0;
158 WebRtcSpl_FilterARFastQ12(
159 data, data,
160 iLBCdec_inst->old_syntdenum + (i+iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1),
161 LPC_FILTERORDER+1, SUBL);
162
163 for (i=1; i < iLBCdec_inst->nsub; i++) {
164 WebRtcSpl_FilterARFastQ12(
165 data+i*SUBL, data+i*SUBL,
166 syntdenum+(i-1)*(LPC_FILTERORDER+1),
167 LPC_FILTERORDER+1, SUBL);
168 }
169
170 } else if (iLBCdec_inst->mode==30) {
171 /* Enhancer has 80 samples delay */
172 for (i=0; i < 2; i++) {
173 WebRtcSpl_FilterARFastQ12(
174 data+i*SUBL, data+i*SUBL,
175 iLBCdec_inst->old_syntdenum + (i+4)*(LPC_FILTERORDER+1),
176 LPC_FILTERORDER+1, SUBL);
177 }
178 for (i=2; i < iLBCdec_inst->nsub; i++) {
179 WebRtcSpl_FilterARFastQ12(
180 data+i*SUBL, data+i*SUBL,
181 syntdenum+(i-2)*(LPC_FILTERORDER+1),
182 LPC_FILTERORDER+1, SUBL);
183 }
184 }
185
186 /* Save the filter state */
187 WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &data[iLBCdec_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);
188
189 } else { /* Enhancer not activated */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000190 int16_t lag;
niklase@google.com470e71d2011-07-07 08:21:25 +0000191
192 /* Find last lag (since the enhancer is not called to give this info) */
193 lag = 20;
194 if (iLBCdec_inst->mode==20) {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000195 lag = (int16_t)WebRtcIlbcfix_XcorrCoef(
niklase@google.com470e71d2011-07-07 08:21:25 +0000196 &decresidual[iLBCdec_inst->blockl-60],
197 &decresidual[iLBCdec_inst->blockl-60-lag],
198 60,
199 80, lag, -1);
200 } else {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000201 lag = (int16_t)WebRtcIlbcfix_XcorrCoef(
niklase@google.com470e71d2011-07-07 08:21:25 +0000202 &decresidual[iLBCdec_inst->blockl-ENH_BLOCKL],
203 &decresidual[iLBCdec_inst->blockl-ENH_BLOCKL-lag],
204 ENH_BLOCKL,
205 100, lag, -1);
206 }
207
208 /* Store lag (it is needed if next packet is lost) */
209 (*iLBCdec_inst).last_lag = (int)lag;
210
211 /* copy data and run synthesis filter */
212 WEBRTC_SPL_MEMCPY_W16(data, decresidual, iLBCdec_inst->blockl);
213
214 /* Set up the filter state */
215 WEBRTC_SPL_MEMCPY_W16(&data[-LPC_FILTERORDER], iLBCdec_inst->syntMem, LPC_FILTERORDER);
216
217 for (i=0; i < iLBCdec_inst->nsub; i++) {
218 WebRtcSpl_FilterARFastQ12(
219 data+i*SUBL, data+i*SUBL,
220 syntdenum + i*(LPC_FILTERORDER+1),
221 LPC_FILTERORDER+1, SUBL);
222 }
223
224 /* Save the filter state */
225 WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &data[iLBCdec_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);
226 }
227
228 WEBRTC_SPL_MEMCPY_W16(decblock,data,iLBCdec_inst->blockl);
229
230 /* High pass filter the signal (with upscaling a factor 2 and saturation) */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000231 WebRtcIlbcfix_HpOutput(decblock, (int16_t*)WebRtcIlbcfix_kHpOutCoefs,
niklase@google.com470e71d2011-07-07 08:21:25 +0000232 iLBCdec_inst->hpimemy, iLBCdec_inst->hpimemx,
233 iLBCdec_inst->blockl);
234
235 WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->old_syntdenum,
236 syntdenum, iLBCdec_inst->nsub*(LPC_FILTERORDER+1));
237
238 iLBCdec_inst->prev_enh_pl=0;
239
240 if (mode==0) { /* PLC was used */
241 iLBCdec_inst->prev_enh_pl=1;
242 }
243}