Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_wb / dec / src / lagconceal.cpp
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 ------------------------------------------------------------------------------
37  INPUT AND OUTPUT DEFINITIONS
38
39      int16 gain_hist[],                     (i)  : Gain history
40      int16 lag_hist[],                      (i)  : Subframe size
41      int16 * T0,                            (i/o): current lag
42      int16 * old_T0,                        (i/o): previous lag
43      int16 * seed,
44      int16 unusable_frame
45
46 ------------------------------------------------------------------------------
47  FUNCTION DESCRIPTION
48
49     Concealment of LTP lags during bad frames
50
51 ------------------------------------------------------------------------------
52  REQUIREMENTS
53
54
55 ------------------------------------------------------------------------------
56  REFERENCES
57
58 ------------------------------------------------------------------------------
59  PSEUDO-CODE
60
61 ------------------------------------------------------------------------------
62 */
63
64
65 /*----------------------------------------------------------------------------
66 ; INCLUDES
67 ----------------------------------------------------------------------------*/
68
69 #include "pv_amr_wb_type_defs.h"
70 #include "pvamrwbdecoder_basic_op.h"
71 #include "pvamrwbdecoder_cnst.h"
72 #include "pvamrwbdecoder_acelp.h"
73
74 /*----------------------------------------------------------------------------
75 ; MACROS
76 ; Define module specific macros here
77 ----------------------------------------------------------------------------*/
78
79
80 /*----------------------------------------------------------------------------
81 ; DEFINES
82 ; Include all pre-processor statements here. Include conditional
83 ; compile variables also.
84 ----------------------------------------------------------------------------*/
85 #define L_LTPHIST 5
86 #define ONE_PER_3 10923
87 #define ONE_PER_LTPHIST 6554
88
89 /*----------------------------------------------------------------------------
90 ; LOCAL FUNCTION DEFINITIONS
91 ; Function Prototype declaration
92 ----------------------------------------------------------------------------*/
93 void insertion_sort(int16 array[], int16 n);
94 void insert(int16 array[], int16 num, int16 x);
95
96 /*----------------------------------------------------------------------------
97 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
98 ; Variable declaration - defined here and used outside this module
99 ----------------------------------------------------------------------------*/
100
101 /*----------------------------------------------------------------------------
102 ; EXTERNAL FUNCTION REFERENCES
103 ; Declare functions defined elsewhere and referenced in this module
104 ----------------------------------------------------------------------------*/
105
106 /*----------------------------------------------------------------------------
107 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
108 ; Declare variables used in this module but defined elsewhere
109 ----------------------------------------------------------------------------*/
110
111 /*----------------------------------------------------------------------------
112 ; FUNCTION CODE
113 ----------------------------------------------------------------------------*/
114
115
116 void Init_Lagconc(int16 lag_hist[])
117 {
118     int16 i;
119
120     for (i = 0; i < L_LTPHIST; i++)
121     {
122         lag_hist[i] = 64;
123     }
124 }
125
126 /*----------------------------------------------------------------------------
127 ; FUNCTION CODE
128 ----------------------------------------------------------------------------*/
129
130 void lagconceal(
131     int16 gain_hist[],                   /* (i) : Gain history     */
132     int16 lag_hist[],                    /* (i) : Subframe size    */
133     int16 * T0,
134     int16 * old_T0,
135     int16 * seed,
136     int16 unusable_frame
137 )
138 {
139     int16 maxLag, minLag, lastLag, lagDif, meanLag = 0;
140     int16 lag_hist2[L_LTPHIST] = {0};
141     int16 i, tmp, tmp2;
142     int16 minGain, lastGain, secLastGain;
143     int16 D, D2;
144
145     /* Is lag index such that it can be aplied directly or does it has to be subtituted */
146
147     lastGain = gain_hist[4];
148     secLastGain = gain_hist[3];
149
150     lastLag = lag_hist[0];
151
152     /******* SMALLEST history lag *******/
153     minLag = lag_hist[0];
154     /*******  BIGGEST history lag *******/
155     maxLag = lag_hist[0];
156     for (i = 1; i < L_LTPHIST; i++)
157     {
158         if (lag_hist[i] < minLag)
159         {
160             minLag = lag_hist[i];
161         }
162         if (lag_hist[i] > maxLag)
163         {
164             maxLag = lag_hist[i];
165         }
166     }
167     /***********SMALLEST history gain***********/
168     minGain = gain_hist[0];
169     for (i = 1; i < L_LTPHIST; i++)
170     {
171
172         if (gain_hist[i] < minGain)
173         {
174             minGain = gain_hist[i];
175         }
176     }
177     /***Difference between MAX and MIN lag**/
178     lagDif = sub_int16(maxLag, minLag);
179
180
181     if (unusable_frame != 0)
182     {
183         /* LTP-lag for RX_SPEECH_LOST */
184         /**********Recognition of the LTP-history*********/
185
186         if ((minGain > 8192) && (lagDif < 10))
187         {
188             *T0 = *old_T0;
189         }
190         else if (lastGain > 8192 && secLastGain > 8192)
191         {
192             *T0 = lag_hist[0];
193         }
194         else
195         {
196             /********SORT************/
197             /* The sorting of the lag history */
198             for (i = 0; i < L_LTPHIST; i++)
199             {
200                 lag_hist2[i] = lag_hist[i];
201             }
202             insertion_sort(lag_hist2, 5);
203
204             /* Lag is weighted towards bigger lags */
205             /* and random variation is added */
206             lagDif = sub_int16(lag_hist2[4], lag_hist2[2]);
207
208
209             if (lagDif > 40)
210             {
211                 lagDif = 40;
212             }
213
214             D = noise_gen_amrwb(seed);              /* D={-1, ...,1} */
215             /* D2={-lagDif/2..lagDif/2} */
216             tmp = lagDif >> 1;
217             D2 = mult_int16(tmp, D);
218             tmp = add_int16(add_int16(lag_hist2[2], lag_hist2[3]), lag_hist2[4]);
219             *T0 = add_int16(mult_int16(tmp, ONE_PER_3), D2);
220         }
221         /* New lag is not allowed to be bigger or smaller than last lag values */
222
223         if (*T0 > maxLag)
224         {
225             *T0 = maxLag;
226         }
227
228         if (*T0 < minLag)
229         {
230             *T0 = minLag;
231         }
232     }
233     else
234     {
235         /* LTP-lag for RX_BAD_FRAME */
236
237         /***********MEAN lag**************/
238         meanLag = 0;
239         for (i = 0; i < L_LTPHIST; i++)
240         {
241             meanLag = add_int16(meanLag, lag_hist[i]);
242         }
243         meanLag = mult_int16(meanLag, ONE_PER_LTPHIST);
244
245         tmp  = *T0 - maxLag;
246         tmp2 = *T0 - lastLag;
247
248         if ((lagDif < 10) && (*T0 > (minLag - 5)) && (tmp < 5))
249         {
250             *T0 = *T0;
251         }
252         else if ((lastGain > 8192) && (secLastGain > 8192) && ((tmp2 + 10) > 0 && tmp2 < 10))
253         {
254             *T0 = *T0;
255         }
256         else if ((minGain < 6554) && (lastGain == minGain) && (*T0 > minLag && *T0 < maxLag))
257         {
258             *T0 = *T0;
259         }
260         else if ((lagDif < 70) && (*T0 > minLag) && (*T0 < maxLag))
261         {
262             *T0 = *T0;
263         }
264         else if ((*T0 > meanLag) && (*T0 < maxLag))
265         {
266             *T0 = *T0;
267         }
268         else
269         {
270
271
272             if ((minGain > 8192) & (lagDif < 10))
273             {
274                 *T0 = lag_hist[0];
275             }
276             else if ((lastGain > 8192) && (secLastGain > 8192))
277             {
278                 *T0 = lag_hist[0];
279             }
280             else
281             {
282                 /********SORT************/
283                 /* The sorting of the lag history */
284                 for (i = 0; i < L_LTPHIST; i++)
285                 {
286                     lag_hist2[i] = lag_hist[i];
287                 }
288                 insertion_sort(lag_hist2, 5);
289
290                 /* Lag is weighted towards bigger lags */
291                 /* and random variation is added */
292                 lagDif = sub_int16(lag_hist2[4], lag_hist2[2]);
293
294                 if (lagDif > 40)
295                 {
296                     lagDif = 40;
297                 }
298
299                 D = noise_gen_amrwb(seed);          /* D={-1,.., 1} */
300                 /* D2={-lagDif/2..lagDif/2} */
301                 tmp = lagDif >> 1;
302                 D2 = mult_int16(tmp, D);
303                 tmp = add_int16(add_int16(lag_hist2[2], lag_hist2[3]), lag_hist2[4]);
304                 *T0 = add_int16(mult_int16(tmp, ONE_PER_3), D2);
305             }
306             /* New lag is not allowed to be bigger or smaller than last lag values */
307
308             if (*T0 > maxLag)
309             {
310                 *T0 = maxLag;
311             }
312
313             if (*T0 < minLag)
314             {
315                 *T0 = minLag;
316             }
317         }
318     }
319 }
320
321 /*----------------------------------------------------------------------------
322 ; FUNCTION CODE
323 ----------------------------------------------------------------------------*/
324
325 void insertion_sort(int16 array[], int16 n)
326 {
327     int16 i;
328
329     for (i = 0; i < n; i++)
330     {
331         insert(array, i, array[i]);
332     }
333 }
334
335 /*----------------------------------------------------------------------------
336 ; FUNCTION CODE
337 ----------------------------------------------------------------------------*/
338
339 void insert(int16 array[], int16 n, int16 x)
340 {
341     int16 i;
342
343     for (i = (n - 1); i >= 0; i--)
344     {
345
346         if (x < array[i])
347         {
348             array[i + 1] = array[i];
349         }
350         else
351         {
352             break;
353         }
354     }
355     array[i + 1] = x;
356 }