lagconceal.cpp revision 4f1efc098cb5791c3e9f483f2af84aef70d2d0a0
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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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----------------------------------------------------------------------------*/
101void insertion_sort(int16 array[], int16 n);
102void 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
124void 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
138void 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
333void 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
347void 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