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