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: isf_extrapolation.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 HfIsf[]    (i/o)  isf vector
48
49------------------------------------------------------------------------------
50 FUNCTION DESCRIPTION
51
52    Conversion of 16th-order 12.8kHz ISF vector
53    into 20th-order 16kHz ISF vector
54
55------------------------------------------------------------------------------
56 REQUIREMENTS
57
58
59------------------------------------------------------------------------------
60 REFERENCES
61
62------------------------------------------------------------------------------
63 PSEUDO-CODE
64
65------------------------------------------------------------------------------
66*/
67
68
69/*----------------------------------------------------------------------------
70; INCLUDES
71----------------------------------------------------------------------------*/
72
73#include "pv_amr_wb_type_defs.h"
74#include "pvamrwbdecoder_basic_op.h"
75#include "pvamrwbdecoder_cnst.h"
76#include "pvamrwbdecoder_acelp.h"
77#include "pvamrwb_math_op.h"
78
79/*----------------------------------------------------------------------------
80; MACROS
81; Define module specific macros here
82----------------------------------------------------------------------------*/
83
84
85/*----------------------------------------------------------------------------
86; DEFINES
87; Include all pre-processor statements here. Include conditional
88; compile variables also.
89----------------------------------------------------------------------------*/
90#define INV_LENGTH 2731                    /* 1/12 */
91
92/*----------------------------------------------------------------------------
93; LOCAL FUNCTION DEFINITIONS
94; Function Prototype declaration
95----------------------------------------------------------------------------*/
96
97/*----------------------------------------------------------------------------
98; LOCAL STORE/BUFFER/POINTER DEFINITIONS
99; Variable declaration - defined here and used outside this module
100----------------------------------------------------------------------------*/
101
102/*----------------------------------------------------------------------------
103; EXTERNAL FUNCTION REFERENCES
104; Declare functions defined elsewhere and referenced in this module
105----------------------------------------------------------------------------*/
106
107/*----------------------------------------------------------------------------
108; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
109; Declare variables used in this module but defined elsewhere
110----------------------------------------------------------------------------*/
111
112/*----------------------------------------------------------------------------
113; FUNCTION CODE
114----------------------------------------------------------------------------*/
115
116
117void isf_extrapolation(int16 HfIsf[])
118{
119    int16 IsfDiff[M - 2];
120    int32 IsfCorr[3];
121    int32 L_tmp;
122    int16 coeff, mean, tmp, tmp2, tmp3;
123    int16 exp, exp2, hi, lo;
124    int16 i, MaxCorr;
125
126    HfIsf[M16k - 1] = HfIsf[M - 1];
127
128    /* Difference vector */
129    for (i = 1; i < (M - 1); i++)
130    {
131        IsfDiff[i - 1] = sub_int16(HfIsf[i], HfIsf[i - 1]);
132    }
133    L_tmp = 0;
134
135    /* Mean of difference vector */
136    for (i = 3; i < (M - 1); i++)
137    {
138        L_tmp = mac_16by16_to_int32(L_tmp, IsfDiff[i - 1], INV_LENGTH);
139
140    }
141    mean = amr_wb_round(L_tmp);
142
143    IsfCorr[0] = 0;
144
145    tmp = 0;
146    for (i = 0; i < (M - 2); i++)
147    {
148        if (IsfDiff[i] > tmp)
149        {
150            tmp = IsfDiff[i];
151        }
152    }
153    exp = norm_s(tmp);
154    for (i = 0; i < (M - 2); i++)
155    {
156        IsfDiff[i] = shl_int16(IsfDiff[i], exp);
157    }
158    mean = shl_int16(mean, exp);
159    for (i = 7; i < (M - 2); i++)
160    {
161        tmp2 = sub_int16(IsfDiff[i], mean);
162        tmp3 = sub_int16(IsfDiff[i - 2], mean);
163        L_tmp = mul_16by16_to_int32(tmp2, tmp3);
164        int32_to_dpf(L_tmp, &hi, &lo);
165        L_tmp = mpy_dpf_32(hi, lo, hi, lo);
166        IsfCorr[0] = add_int32(IsfCorr[0], L_tmp);
167    }
168    IsfCorr[1] = 0;
169    for (i = 7; i < (M - 2); i++)
170    {
171        tmp2 = sub_int16(IsfDiff[i], mean);
172        tmp3 = sub_int16(IsfDiff[i - 3], mean);
173        L_tmp = mul_16by16_to_int32(tmp2, tmp3);
174        int32_to_dpf(L_tmp, &hi, &lo);
175        L_tmp = mpy_dpf_32(hi, lo, hi, lo);
176        IsfCorr[1] = add_int32(IsfCorr[1], L_tmp);
177    }
178    IsfCorr[2] = 0;
179    for (i = 7; i < (M - 2); i++)
180    {
181        tmp2 = sub_int16(IsfDiff[i], mean);
182        tmp3 = sub_int16(IsfDiff[i - 4], mean);
183        L_tmp = mul_16by16_to_int32(tmp2, tmp3);
184        int32_to_dpf(L_tmp, &hi, &lo);
185        L_tmp = mpy_dpf_32(hi, lo, hi, lo);
186        IsfCorr[2] = add_int32(IsfCorr[2], L_tmp);
187    }
188
189    if (IsfCorr[0] > IsfCorr[1])
190    {
191        MaxCorr = 0;
192    }
193    else
194    {
195        MaxCorr = 1;
196    }
197
198
199    if (IsfCorr[2] > IsfCorr[MaxCorr])
200    {
201        MaxCorr = 2;
202    }
203
204    MaxCorr++;             /* Maximum correlation of difference vector */
205
206    for (i = M - 1; i < (M16k - 1); i++)
207    {
208        tmp = sub_int16(HfIsf[i - 1 - MaxCorr], HfIsf[i - 2 - MaxCorr]);
209        HfIsf[i] = add_int16(HfIsf[i - 1], tmp);
210    }
211
212    /* tmp=7965+(HfIsf[2]-HfIsf[3]-HfIsf[4])/6; */
213    tmp = add_int16(HfIsf[4], HfIsf[3]);
214    tmp = sub_int16(HfIsf[2], tmp);
215    tmp = mult_int16(tmp, 5461);
216    tmp += 20390;
217
218
219    if (tmp > 19456)
220    {                                      /* Maximum value of ISF should be at most 7600 Hz */
221        tmp = 19456;
222    }
223    tmp = sub_int16(tmp, HfIsf[M - 2]);
224    tmp2 = sub_int16(HfIsf[M16k - 2], HfIsf[M - 2]);
225
226    exp2 = norm_s(tmp2);
227    exp = norm_s(tmp);
228    exp--;
229    tmp <<= exp;
230    tmp2 <<= exp2;
231    coeff = div_16by16(tmp, tmp2);              /* Coefficient for stretching the ISF vector */
232    exp = exp2 - exp;
233
234    for (i = M - 1; i < (M16k - 1); i++)
235    {
236        tmp = mult_int16(sub_int16(HfIsf[i], HfIsf[i - 1]), coeff);
237        IsfDiff[i - (M - 1)] = shl_int16(tmp, exp);
238    }
239
240    for (i = M; i < (M16k - 1); i++)
241    {
242        /* The difference between ISF(n) and ISF(n-2) should be at least 500 Hz */
243        tmp = IsfDiff[i - (M - 1)] + IsfDiff[i - M] - 1280;
244
245        if (tmp < 0)
246        {
247
248            if (IsfDiff[i - (M - 1)] > IsfDiff[i - M])
249            {
250                IsfDiff[i - M] = 1280 - IsfDiff[i - (M - 1)];
251            }
252            else
253            {
254                IsfDiff[i - (M - 1)] = 1280 - IsfDiff[i - M];
255            }
256        }
257    }
258
259    for (i = M - 1; i < (M16k - 1); i++)
260    {
261        HfIsf[i] = add_int16(HfIsf[i - 1], IsfDiff[i - (M - 1)]);
262    }
263
264    for (i = 0; i < (M16k - 1); i++)
265    {
266        HfIsf[i] = mult_int16(HfIsf[i], 26214);  /* Scale the ISF vector correctly for 16000 kHz */
267    }
268
269    Isf_isp(HfIsf, HfIsf, M16k);
270
271    return;
272}
273
274
275