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