blob: 3848bc7d7b24d867ce1b979c177e722da34685b5 [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
Niels Möllera12c42a2018-07-25 16:05:48 +020019// Defines WEBRTC_ARCH_BIG_ENDIAN, used below.
20#include "rtc_base/system/arch.h"
21
Mirko Bonadei06c2aa92018-02-01 15:11:41 +010022#include "modules/audio_coding/codecs/ilbc/defines.h"
23#include "modules/audio_coding/codecs/ilbc/simple_lsf_dequant.h"
24#include "modules/audio_coding/codecs/ilbc/decoder_interpolate_lsf.h"
25#include "modules/audio_coding/codecs/ilbc/index_conv_dec.h"
26#include "modules/audio_coding/codecs/ilbc/do_plc.h"
27#include "modules/audio_coding/codecs/ilbc/constants.h"
28#include "modules/audio_coding/codecs/ilbc/enhancer_interface.h"
29#include "modules/audio_coding/codecs/ilbc/xcorr_coef.h"
30#include "modules/audio_coding/codecs/ilbc/lsf_check.h"
31#include "modules/audio_coding/codecs/ilbc/decode_residual.h"
32#include "modules/audio_coding/codecs/ilbc/unpack_bits.h"
33#include "modules/audio_coding/codecs/ilbc/hp_output.h"
34#include "modules/audio_coding/codecs/ilbc/init_decode.h"
andrew@webrtc.org621df672013-10-22 10:27:23 +000035#ifndef WEBRTC_ARCH_BIG_ENDIAN
Mirko Bonadei06c2aa92018-02-01 15:11:41 +010036#include "modules/audio_coding/codecs/ilbc/swap_bytes.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000037#endif
38
39/*----------------------------------------------------------------*
40 * main decoder function
41 *---------------------------------------------------------------*/
42
kwiberg619a2112016-08-24 02:46:44 -070043int WebRtcIlbcfix_DecodeImpl(
pbos@webrtc.org0946a562013-04-09 00:28:06 +000044 int16_t *decblock, /* (o) decoded signal block */
45 const uint16_t *bytes, /* (i) encoded signal bits */
pbos@webrtc.orgeb544462014-12-17 15:23:29 +000046 IlbcDecoder *iLBCdec_inst, /* (i/o) the decoder state
niklase@google.com470e71d2011-07-07 08:21:25 +000047 structure */
pbos@webrtc.org0946a562013-04-09 00:28:06 +000048 int16_t mode /* (i) 0: bad packet, PLC,
niklase@google.com470e71d2011-07-07 08:21:25 +000049 1: normal */
50 ) {
kwiberg619a2112016-08-24 02:46:44 -070051 const int old_mode = iLBCdec_inst->mode;
52 const int old_use_enhancer = iLBCdec_inst->use_enhancer;
53
Peter Kastingdce40cf2015-08-24 14:52:23 -070054 size_t i;
pbos@webrtc.org0946a562013-04-09 00:28:06 +000055 int16_t order_plus_one;
niklase@google.com470e71d2011-07-07 08:21:25 +000056
pbos@webrtc.org0946a562013-04-09 00:28:06 +000057 int16_t last_bit;
58 int16_t *data;
niklase@google.com470e71d2011-07-07 08:21:25 +000059 /* Stack based */
pbos@webrtc.org0946a562013-04-09 00:28:06 +000060 int16_t decresidual[BLOCKL_MAX];
61 int16_t PLCresidual[BLOCKL_MAX + LPC_FILTERORDER];
62 int16_t syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)];
63 int16_t PLClpc[LPC_FILTERORDER + 1];
andrew@webrtc.org621df672013-10-22 10:27:23 +000064#ifndef WEBRTC_ARCH_BIG_ENDIAN
pbos@webrtc.org0946a562013-04-09 00:28:06 +000065 uint16_t swapped[NO_OF_WORDS_30MS];
turaj@webrtc.org837bc7b2012-07-14 00:34:54 +000066#endif
niklase@google.com470e71d2011-07-07 08:21:25 +000067 iLBC_bits *iLBCbits_inst = (iLBC_bits*)PLCresidual;
68
69 /* Reuse some buffers that are non overlapping in order to save stack memory */
70 data = &PLCresidual[LPC_FILTERORDER];
71
turaj@webrtc.org10d3b522012-05-24 21:20:25 +000072 if (mode) { /* the data are good */
niklase@google.com470e71d2011-07-07 08:21:25 +000073
74 /* decode data */
75
niklase@google.com470e71d2011-07-07 08:21:25 +000076 /* Unpacketize bits into parameters */
77
andrew@webrtc.org621df672013-10-22 10:27:23 +000078#ifndef WEBRTC_ARCH_BIG_ENDIAN
turaj@webrtc.org837bc7b2012-07-14 00:34:54 +000079 WebRtcIlbcfix_SwapBytes(bytes, iLBCdec_inst->no_of_words, swapped);
80 last_bit = WebRtcIlbcfix_UnpackBits(swapped, iLBCbits_inst, iLBCdec_inst->mode);
81#else
82 last_bit = WebRtcIlbcfix_UnpackBits(bytes, iLBCbits_inst, iLBCdec_inst->mode);
niklase@google.com470e71d2011-07-07 08:21:25 +000083#endif
84
85 /* Check for bit errors */
86 if (iLBCbits_inst->startIdx<1)
87 mode = 0;
88 if ((iLBCdec_inst->mode==20) && (iLBCbits_inst->startIdx>3))
89 mode = 0;
90 if ((iLBCdec_inst->mode==30) && (iLBCbits_inst->startIdx>5))
91 mode = 0;
92 if (last_bit==1)
93 mode = 0;
94
turaj@webrtc.org10d3b522012-05-24 21:20:25 +000095 if (mode) { /* No bit errors was detected, continue decoding */
niklase@google.com470e71d2011-07-07 08:21:25 +000096 /* Stack based */
pbos@webrtc.org0946a562013-04-09 00:28:06 +000097 int16_t lsfdeq[LPC_FILTERORDER*LPC_N_MAX];
98 int16_t weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
niklase@google.com470e71d2011-07-07 08:21:25 +000099
100 /* adjust index */
101 WebRtcIlbcfix_IndexConvDec(iLBCbits_inst->cb_index);
102
103 /* decode the lsf */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000104 WebRtcIlbcfix_SimpleLsfDeQ(lsfdeq, (int16_t*)(iLBCbits_inst->lsf), iLBCdec_inst->lpc_n);
niklase@google.com470e71d2011-07-07 08:21:25 +0000105 WebRtcIlbcfix_LsfCheck(lsfdeq, LPC_FILTERORDER, iLBCdec_inst->lpc_n);
106 WebRtcIlbcfix_DecoderInterpolateLsp(syntdenum, weightdenum,
107 lsfdeq, LPC_FILTERORDER, iLBCdec_inst);
108
109 /* Decode the residual using the cb and gain indexes */
kwiberg619a2112016-08-24 02:46:44 -0700110 if (!WebRtcIlbcfix_DecodeResidual(iLBCdec_inst, iLBCbits_inst,
111 decresidual, syntdenum))
112 goto error;
niklase@google.com470e71d2011-07-07 08:21:25 +0000113
114 /* preparing the plc for a future loss! */
Peter Kasting728d9032015-06-11 14:31:38 -0700115 WebRtcIlbcfix_DoThePlc(
116 PLCresidual, PLClpc, 0, decresidual,
117 syntdenum + (LPC_FILTERORDER + 1) * (iLBCdec_inst->nsub - 1),
Peter Kastingdce40cf2015-08-24 14:52:23 -0700118 iLBCdec_inst->last_lag, iLBCdec_inst);
niklase@google.com470e71d2011-07-07 08:21:25 +0000119
120 /* Use the output from doThePLC */
121 WEBRTC_SPL_MEMCPY_W16(decresidual, PLCresidual, iLBCdec_inst->blockl);
122 }
123
124 }
125
126 if (mode == 0) {
127 /* the data is bad (either a PLC call
128 * was made or a bit error was detected)
129 */
130
131 /* packet loss conceal */
132
Peter Kasting728d9032015-06-11 14:31:38 -0700133 WebRtcIlbcfix_DoThePlc(PLCresidual, PLClpc, 1, decresidual, syntdenum,
Peter Kastingdce40cf2015-08-24 14:52:23 -0700134 iLBCdec_inst->last_lag, iLBCdec_inst);
niklase@google.com470e71d2011-07-07 08:21:25 +0000135
136 WEBRTC_SPL_MEMCPY_W16(decresidual, PLCresidual, iLBCdec_inst->blockl);
137
138 order_plus_one = LPC_FILTERORDER + 1;
139
140 for (i = 0; i < iLBCdec_inst->nsub; i++) {
141 WEBRTC_SPL_MEMCPY_W16(syntdenum+(i*order_plus_one),
142 PLClpc, order_plus_one);
143 }
144 }
145
146 if ((*iLBCdec_inst).use_enhancer == 1) { /* Enhancer activated */
147
148 /* Update the filter and filter coefficients if there was a packet loss */
149 if (iLBCdec_inst->prev_enh_pl==2) {
150 for (i=0;i<iLBCdec_inst->nsub;i++) {
151 WEBRTC_SPL_MEMCPY_W16(&(iLBCdec_inst->old_syntdenum[i*(LPC_FILTERORDER+1)]),
152 syntdenum, (LPC_FILTERORDER+1));
153 }
154 }
155
156 /* post filtering */
157 (*iLBCdec_inst).last_lag =
158 WebRtcIlbcfix_EnhancerInterface(data, decresidual, iLBCdec_inst);
159
160 /* synthesis filtering */
161
162 /* Set up the filter state */
163 WEBRTC_SPL_MEMCPY_W16(&data[-LPC_FILTERORDER], iLBCdec_inst->syntMem, LPC_FILTERORDER);
164
165 if (iLBCdec_inst->mode==20) {
166 /* Enhancer has 40 samples delay */
167 i=0;
168 WebRtcSpl_FilterARFastQ12(
169 data, data,
170 iLBCdec_inst->old_syntdenum + (i+iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1),
171 LPC_FILTERORDER+1, SUBL);
172
173 for (i=1; i < iLBCdec_inst->nsub; i++) {
174 WebRtcSpl_FilterARFastQ12(
175 data+i*SUBL, data+i*SUBL,
176 syntdenum+(i-1)*(LPC_FILTERORDER+1),
177 LPC_FILTERORDER+1, SUBL);
178 }
179
180 } else if (iLBCdec_inst->mode==30) {
181 /* Enhancer has 80 samples delay */
182 for (i=0; i < 2; i++) {
183 WebRtcSpl_FilterARFastQ12(
184 data+i*SUBL, data+i*SUBL,
185 iLBCdec_inst->old_syntdenum + (i+4)*(LPC_FILTERORDER+1),
186 LPC_FILTERORDER+1, SUBL);
187 }
188 for (i=2; i < iLBCdec_inst->nsub; i++) {
189 WebRtcSpl_FilterARFastQ12(
190 data+i*SUBL, data+i*SUBL,
191 syntdenum+(i-2)*(LPC_FILTERORDER+1),
192 LPC_FILTERORDER+1, SUBL);
193 }
194 }
195
196 /* Save the filter state */
197 WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &data[iLBCdec_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);
198
199 } else { /* Enhancer not activated */
Peter Kastingdce40cf2015-08-24 14:52:23 -0700200 size_t lag;
niklase@google.com470e71d2011-07-07 08:21:25 +0000201
202 /* Find last lag (since the enhancer is not called to give this info) */
203 lag = 20;
204 if (iLBCdec_inst->mode==20) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700205 lag = WebRtcIlbcfix_XcorrCoef(
niklase@google.com470e71d2011-07-07 08:21:25 +0000206 &decresidual[iLBCdec_inst->blockl-60],
207 &decresidual[iLBCdec_inst->blockl-60-lag],
208 60,
209 80, lag, -1);
210 } else {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700211 lag = WebRtcIlbcfix_XcorrCoef(
niklase@google.com470e71d2011-07-07 08:21:25 +0000212 &decresidual[iLBCdec_inst->blockl-ENH_BLOCKL],
213 &decresidual[iLBCdec_inst->blockl-ENH_BLOCKL-lag],
214 ENH_BLOCKL,
215 100, lag, -1);
216 }
217
218 /* Store lag (it is needed if next packet is lost) */
Peter Kastingb7e50542015-06-11 12:55:50 -0700219 (*iLBCdec_inst).last_lag = lag;
niklase@google.com470e71d2011-07-07 08:21:25 +0000220
221 /* copy data and run synthesis filter */
222 WEBRTC_SPL_MEMCPY_W16(data, decresidual, iLBCdec_inst->blockl);
223
224 /* Set up the filter state */
225 WEBRTC_SPL_MEMCPY_W16(&data[-LPC_FILTERORDER], iLBCdec_inst->syntMem, LPC_FILTERORDER);
226
227 for (i=0; i < iLBCdec_inst->nsub; i++) {
228 WebRtcSpl_FilterARFastQ12(
229 data+i*SUBL, data+i*SUBL,
230 syntdenum + i*(LPC_FILTERORDER+1),
231 LPC_FILTERORDER+1, SUBL);
232 }
233
234 /* Save the filter state */
235 WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &data[iLBCdec_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);
236 }
237
238 WEBRTC_SPL_MEMCPY_W16(decblock,data,iLBCdec_inst->blockl);
239
240 /* High pass filter the signal (with upscaling a factor 2 and saturation) */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000241 WebRtcIlbcfix_HpOutput(decblock, (int16_t*)WebRtcIlbcfix_kHpOutCoefs,
niklase@google.com470e71d2011-07-07 08:21:25 +0000242 iLBCdec_inst->hpimemy, iLBCdec_inst->hpimemx,
243 iLBCdec_inst->blockl);
244
245 WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->old_syntdenum,
246 syntdenum, iLBCdec_inst->nsub*(LPC_FILTERORDER+1));
247
248 iLBCdec_inst->prev_enh_pl=0;
249
250 if (mode==0) { /* PLC was used */
251 iLBCdec_inst->prev_enh_pl=1;
252 }
kwiberg619a2112016-08-24 02:46:44 -0700253
254 return 0; // Success.
255
256error:
257 // The decoder got sick from eating that data. Reset it and return.
258 WebRtcIlbcfix_InitDecode(iLBCdec_inst, old_mode, old_use_enhancer);
259 return -1; // Error
niklase@google.com470e71d2011-07-07 08:21:25 +0000260}