1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21 3GPP TS 26.173
22 ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec
23 Available from http://www.3gpp.org
24
25 (C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34 Filename: lagconceal.cpp
35
36 Date: 05/08/2007
37
38 ------------------------------------------------------------------------------
39 REVISION HISTORY
40
41
42 Description:
43
44 ------------------------------------------------------------------------------
45 INPUT AND OUTPUT DEFINITIONS
46
47 int16 gain_hist[], (i) : Gain history
48 int16 lag_hist[], (i) : Subframe size
49 int16 * T0, (i/o): current lag
50 int16 * old_T0, (i/o): previous lag
51 int16 * seed,
52 int16 unusable_frame
53
54 ------------------------------------------------------------------------------
55 FUNCTION DESCRIPTION
56
57 Concealment of LTP lags during bad frames
58
59 ------------------------------------------------------------------------------
60 REQUIREMENTS
61
62
63 ------------------------------------------------------------------------------
64 REFERENCES
65
66 ------------------------------------------------------------------------------
67 PSEUDO-CODE
68
69 ------------------------------------------------------------------------------
70 */
71
72
73 /*----------------------------------------------------------------------------
74 ; INCLUDES
75 ----------------------------------------------------------------------------*/
76
77 #include "pv_amr_wb_type_defs.h"
78 #include "pvamrwbdecoder_basic_op.h"
79 #include "pvamrwbdecoder_cnst.h"
80 #include "pvamrwbdecoder_acelp.h"
81
82 /*----------------------------------------------------------------------------
83 ; MACROS
84 ; Define module specific macros here
85 ----------------------------------------------------------------------------*/
86
87
88 /*----------------------------------------------------------------------------
89 ; DEFINES
90 ; Include all pre-processor statements here. Include conditional
91 ; compile variables also.
92 ----------------------------------------------------------------------------*/
93 #define L_LTPHIST 5
94 #define ONE_PER_3 10923
95 #define ONE_PER_LTPHIST 6554
96
97 /*----------------------------------------------------------------------------
98 ; LOCAL FUNCTION DEFINITIONS
99 ; Function Prototype declaration
100 ----------------------------------------------------------------------------*/
101 void insertion_sort(int16 array[], int16 n);
102 void insert(int16 array[], int16 num, int16 x);
103
104 /*----------------------------------------------------------------------------
105 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
106 ; Variable declaration - defined here and used outside this module
107 ----------------------------------------------------------------------------*/
108
109 /*----------------------------------------------------------------------------
110 ; EXTERNAL FUNCTION REFERENCES
111 ; Declare functions defined elsewhere and referenced in this module
112 ----------------------------------------------------------------------------*/
113
114 /*----------------------------------------------------------------------------
115 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
116 ; Declare variables used in this module but defined elsewhere
117 ----------------------------------------------------------------------------*/
118
119 /*----------------------------------------------------------------------------
120 ; FUNCTION CODE
121 ----------------------------------------------------------------------------*/
122
123
Init_Lagconc(int16 lag_hist[])124 void Init_Lagconc(int16 lag_hist[])
125 {
126 int16 i;
127
128 for (i = 0; i < L_LTPHIST; i++)
129 {
130 lag_hist[i] = 64;
131 }
132 }
133
134 /*----------------------------------------------------------------------------
135 ; FUNCTION CODE
136 ----------------------------------------------------------------------------*/
137
lagconceal(int16 gain_hist[],int16 lag_hist[],int16 * T0,int16 * old_T0,int16 * seed,int16 unusable_frame)138 void lagconceal(
139 int16 gain_hist[], /* (i) : Gain history */
140 int16 lag_hist[], /* (i) : Subframe size */
141 int16 * T0,
142 int16 * old_T0,
143 int16 * seed,
144 int16 unusable_frame
145 )
146 {
147 int16 maxLag, minLag, lastLag, lagDif, meanLag = 0;
148 int16 lag_hist2[L_LTPHIST] = {0};
149 int16 i, tmp, tmp2;
150 int16 minGain, lastGain, secLastGain;
151 int16 D, D2;
152
153 /* Is lag index such that it can be aplied directly or does it has to be subtituted */
154
155 lastGain = gain_hist[4];
156 secLastGain = gain_hist[3];
157
158 lastLag = lag_hist[0];
159
160 /******* SMALLEST history lag *******/
161 minLag = lag_hist[0];
162 /******* BIGGEST history lag *******/
163 maxLag = lag_hist[0];
164 for (i = 1; i < L_LTPHIST; i++)
165 {
166 if (lag_hist[i] < minLag)
167 {
168 minLag = lag_hist[i];
169 }
170 if (lag_hist[i] > maxLag)
171 {
172 maxLag = lag_hist[i];
173 }
174 }
175 /***********SMALLEST history gain***********/
176 minGain = gain_hist[0];
177 for (i = 1; i < L_LTPHIST; i++)
178 {
179
180 if (gain_hist[i] < minGain)
181 {
182 minGain = gain_hist[i];
183 }
184 }
185 /***Difference between MAX and MIN lag**/
186 lagDif = sub_int16(maxLag, minLag);
187
188
189 if (unusable_frame != 0)
190 {
191 /* LTP-lag for RX_SPEECH_LOST */
192 /**********Recognition of the LTP-history*********/
193
194 if ((minGain > 8192) && (lagDif < 10))
195 {
196 *T0 = *old_T0;
197 }
198 else if (lastGain > 8192 && secLastGain > 8192)
199 {
200 *T0 = lag_hist[0];
201 }
202 else
203 {
204 /********SORT************/
205 /* The sorting of the lag history */
206 for (i = 0; i < L_LTPHIST; i++)
207 {
208 lag_hist2[i] = lag_hist[i];
209 }
210 insertion_sort(lag_hist2, 5);
211
212 /* Lag is weighted towards bigger lags */
213 /* and random variation is added */
214 lagDif = sub_int16(lag_hist2[4], lag_hist2[2]);
215
216
217 if (lagDif > 40)
218 {
219 lagDif = 40;
220 }
221
222 D = noise_gen_amrwb(seed); /* D={-1, ...,1} */
223 /* D2={-lagDif/2..lagDif/2} */
224 tmp = lagDif >> 1;
225 D2 = mult_int16(tmp, D);
226 tmp = add_int16(add_int16(lag_hist2[2], lag_hist2[3]), lag_hist2[4]);
227 *T0 = add_int16(mult_int16(tmp, ONE_PER_3), D2);
228 }
229 /* New lag is not allowed to be bigger or smaller than last lag values */
230
231 if (*T0 > maxLag)
232 {
233 *T0 = maxLag;
234 }
235
236 if (*T0 < minLag)
237 {
238 *T0 = minLag;
239 }
240 }
241 else
242 {
243 /* LTP-lag for RX_BAD_FRAME */
244
245 /***********MEAN lag**************/
246 meanLag = 0;
247 for (i = 0; i < L_LTPHIST; i++)
248 {
249 meanLag = add_int16(meanLag, lag_hist[i]);
250 }
251 meanLag = mult_int16(meanLag, ONE_PER_LTPHIST);
252
253 tmp = *T0 - maxLag;
254 tmp2 = *T0 - lastLag;
255
256 if ((lagDif < 10) && (*T0 > (minLag - 5)) && (tmp < 5))
257 {
258 *T0 = *T0;
259 }
260 else if ((lastGain > 8192) && (secLastGain > 8192) && ((tmp2 + 10) > 0 && tmp2 < 10))
261 {
262 *T0 = *T0;
263 }
264 else if ((minGain < 6554) && (lastGain == minGain) && (*T0 > minLag && *T0 < maxLag))
265 {
266 *T0 = *T0;
267 }
268 else if ((lagDif < 70) && (*T0 > minLag) && (*T0 < maxLag))
269 {
270 *T0 = *T0;
271 }
272 else if ((*T0 > meanLag) && (*T0 < maxLag))
273 {
274 *T0 = *T0;
275 }
276 else
277 {
278
279
280 if ((minGain > 8192) & (lagDif < 10))
281 {
282 *T0 = lag_hist[0];
283 }
284 else if ((lastGain > 8192) && (secLastGain > 8192))
285 {
286 *T0 = lag_hist[0];
287 }
288 else
289 {
290 /********SORT************/
291 /* The sorting of the lag history */
292 for (i = 0; i < L_LTPHIST; i++)
293 {
294 lag_hist2[i] = lag_hist[i];
295 }
296 insertion_sort(lag_hist2, 5);
297
298 /* Lag is weighted towards bigger lags */
299 /* and random variation is added */
300 lagDif = sub_int16(lag_hist2[4], lag_hist2[2]);
301
302 if (lagDif > 40)
303 {
304 lagDif = 40;
305 }
306
307 D = noise_gen_amrwb(seed); /* D={-1,.., 1} */
308 /* D2={-lagDif/2..lagDif/2} */
309 tmp = lagDif >> 1;
310 D2 = mult_int16(tmp, D);
311 tmp = add_int16(add_int16(lag_hist2[2], lag_hist2[3]), lag_hist2[4]);
312 *T0 = add_int16(mult_int16(tmp, ONE_PER_3), D2);
313 }
314 /* New lag is not allowed to be bigger or smaller than last lag values */
315
316 if (*T0 > maxLag)
317 {
318 *T0 = maxLag;
319 }
320
321 if (*T0 < minLag)
322 {
323 *T0 = minLag;
324 }
325 }
326 }
327 }
328
329 /*----------------------------------------------------------------------------
330 ; FUNCTION CODE
331 ----------------------------------------------------------------------------*/
332
insertion_sort(int16 array[],int16 n)333 void insertion_sort(int16 array[], int16 n)
334 {
335 int16 i;
336
337 for (i = 0; i < n; i++)
338 {
339 insert(array, i, array[i]);
340 }
341 }
342
343 /*----------------------------------------------------------------------------
344 ; FUNCTION CODE
345 ----------------------------------------------------------------------------*/
346
insert(int16 array[],int16 n,int16 x)347 void insert(int16 array[], int16 n, int16 x)
348 {
349 int16 i;
350
351 for (i = (n - 1); i >= 0; i--)
352 {
353
354 if (x < array[i])
355 {
356 array[i + 1] = array[i];
357 }
358 else
359 {
360 break;
361 }
362 }
363 array[i + 1] = x;
364 }
365