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