• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
WebRtcIlbcfix_DecodeImpl(int16_t * decblock,const uint16_t * bytes,iLBC_Dec_Inst_t * iLBCdec_inst,int16_t mode)39 void WebRtcIlbcfix_DecodeImpl(
40     int16_t *decblock,    /* (o) decoded signal block */
41     const uint16_t *bytes, /* (i) encoded signal bits */
42     iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state
43                                            structure */
44     int16_t mode      /* (i) 0: bad packet, PLC,
45                                                                    1: normal */
46                            ) {
47   int 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( PLCresidual, PLClpc, 0,
107                               decresidual, syntdenum + (LPC_FILTERORDER + 1)*(iLBCdec_inst->nsub - 1),
108                               (int16_t)(iLBCdec_inst->last_lag), iLBCdec_inst);
109 
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,
124                             decresidual, syntdenum, (int16_t)(iLBCdec_inst->last_lag), iLBCdec_inst);
125 
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 */
190     int16_t lag;
191 
192     /* Find last lag (since the enhancer is not called to give this info) */
193     lag = 20;
194     if (iLBCdec_inst->mode==20) {
195       lag = (int16_t)WebRtcIlbcfix_XcorrCoef(
196           &decresidual[iLBCdec_inst->blockl-60],
197           &decresidual[iLBCdec_inst->blockl-60-lag],
198           60,
199           80, lag, -1);
200     } else {
201       lag = (int16_t)WebRtcIlbcfix_XcorrCoef(
202           &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) */
231   WebRtcIlbcfix_HpOutput(decblock, (int16_t*)WebRtcIlbcfix_kHpOutCoefs,
232                          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 }
244