Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_wb / dec / src / isp_az.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: isp_az.cpp
35
36 ------------------------------------------------------------------------------
37  INPUT AND OUTPUT DEFINITIONS
38
39      int16 isp[],              (i) Q15 : Immittance spectral pairs
40      int16 a[],                (o) Q12 : predictor coefficients (order=M)
41      int16 m,                  (i)     : order
42      int16 adaptive_scaling    (i) 0   : adaptive scaling disabled
43                                    1   : adaptive scaling enabled
44
45
46 ------------------------------------------------------------------------------
47  FUNCTION DESCRIPTION
48
49     Compute the LPC coefficients from isp (order=M)
50 ------------------------------------------------------------------------------
51  REQUIREMENTS
52
53
54 ------------------------------------------------------------------------------
55  REFERENCES
56
57 ------------------------------------------------------------------------------
58  PSEUDO-CODE
59
60 ------------------------------------------------------------------------------
61 */
62
63
64 /*----------------------------------------------------------------------------
65 ; INCLUDES
66 ----------------------------------------------------------------------------*/
67
68 #include "pv_amr_wb_type_defs.h"
69 #include "pvamrwbdecoder_basic_op.h"
70 #include "pvamrwbdecoder_cnst.h"
71 #include "pvamrwbdecoder_acelp.h"
72 #include "pvamrwb_math_op.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 NC (M/2)
86 #define NC16k (M16k/2)
87
88 /*----------------------------------------------------------------------------
89 ; LOCAL FUNCTION DEFINITIONS
90 ; Function Prototype declaration
91 ----------------------------------------------------------------------------*/
92
93
94 #ifdef __cplusplus
95 extern "C"
96 {
97 #endif
98
99     void Get_isp_pol(int16 * isp, int32 * f, int16 n);
100     void Get_isp_pol_16kHz(int16 * isp, int32 * f, int16 n);
101
102 #ifdef __cplusplus
103 }
104 #endif
105
106 /*----------------------------------------------------------------------------
107 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
108 ; Variable declaration - defined here and used outside this module
109 ----------------------------------------------------------------------------*/
110
111 /*----------------------------------------------------------------------------
112 ; EXTERNAL FUNCTION REFERENCES
113 ; Declare functions defined elsewhere and referenced in this module
114 ----------------------------------------------------------------------------*/
115
116 /*----------------------------------------------------------------------------
117 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
118 ; Declare variables used in this module but defined elsewhere
119 ----------------------------------------------------------------------------*/
120
121 /*----------------------------------------------------------------------------
122 ; FUNCTION CODE
123 ----------------------------------------------------------------------------*/
124
125 void Isp_Az(
126     int16 isp[],            /* (i) Q15 : Immittance spectral pairs         */
127     int16 a[],              /* (o) Q12 : predictor coefficients (order=M)  */
128     int16 m,                /* (i)     : order                     */
129     int16 adaptive_scaling  /* (i) 0   : adaptive scaling disabled */
130     /*     1   : adaptive scaling enabled  */
131 )
132 {
133     int16 i, j;
134     int32 f1[NC16k + 1], f2[NC16k];
135     int16 nc;
136     int32 t0;
137     int32 t1;
138     int16 q, q_sug;
139     int32 tmax;
140
141     nc = m >> 1;
142
143
144     if (nc > 8)
145     {
146         Get_isp_pol_16kHz(&isp[0], f1, nc);
147         for (i = 0; i <= nc; i++)
148         {
149             f1[i] = shl_int32(f1[i], 2);
150         }
151         Get_isp_pol_16kHz(&isp[1], f2, nc - 1);
152         for (i = 0; i <= nc - 1; i++)
153         {
154             f2[i] = shl_int32(f2[i], 2);
155         }
156     }
157     else
158     {
159         Get_isp_pol(&isp[0], f1, nc);
160         Get_isp_pol(&isp[1], f2, nc - 1);
161     }
162
163     /*
164      *  Multiply F2(z) by (1 - z^-2)
165      */
166
167     for (i = nc - 1; i > 1; i--)
168     {
169         f2[i] -= f2[i - 2];      /* f2[i] -= f2[i-2]; */
170     }
171
172     /*
173      *  Scale F1(z) by (1+isp[m-1])  and  F2(z) by (1-isp[m-1])
174      */
175
176     for (i = 0; i < nc; i++)
177     {
178         /* f1[i] *= (1.0 + isp[M-1]); */
179
180         /* f2[i] *= (1.0 - isp[M-1]); */
181         t0 = f1[i];
182         t1 = f2[i];
183         t0 = fxp_mul32_by_16b(t0, isp[m - 1]) << 1;
184         t1 = fxp_mul32_by_16b(t1, isp[m - 1]) << 1;
185         f1[i] += t0;
186         f2[i] -= t1;
187
188     }
189
190     /*
191      *  A(z) = (F1(z)+F2(z))/2
192      *  F1(z) is symmetric and F2(z) is antisymmetric
193      */
194
195     /* a[0] = 1.0; */
196     a[0] = 4096;
197     tmax = 1;
198     j = m - 1;
199     for (i = 1;  i < nc; i++)
200     {
201         /* a[i] = 0.5*(f1[i] + f2[i]); */
202
203         t0 = add_int32(f1[i], f2[i]);          /* f1[i] + f2[i]             */
204         /* compute t1 = abs(t0) */
205         t1 = t0 - (t0 < 0);
206         t1 = t1 ^(t1 >> 31);  /* t1 = t1 ^sign(t1) */
207
208         tmax |= t1;
209         /* from Q23 to Q12 and * 0.5 */
210         a[i] = (int16)((t0 >> 12) + ((t0 >> 11) & 1));
211
212
213         /* a[j] = 0.5*(f1[i] - f2[i]); */
214
215         t0 = sub_int32(f1[i], f2[i]);          /* f1[i] - f2[i]             */
216         /* compute t1 = abs(t0) */
217         t1 = t0 - (t0 < 0);
218         t1 = t1 ^(t1 >> 31);  /* t1 = t1 ^sign(t1) */
219
220         tmax |= t1;
221
222         /* from Q23 to Q12 and * 0.5 */
223         a[j--] = (int16)((t0 >> 12) + ((t0 >> 11) & 1));
224
225     }
226
227     /* rescale data if overflow has occured and reprocess the loop */
228
229
230     if (adaptive_scaling == 1)
231     {
232         q = 4 - normalize_amr_wb(tmax);        /* adaptive scaling enabled */
233     }
234     else
235     {
236         q = 0;                   /* adaptive scaling disabled */
237     }
238
239
240     if (q > 0)
241     {
242         q_sug = 12 + q;
243         for (i = 1, j = m - 1; i < nc; i++, j--)
244         {
245             /* a[i] = 0.5*(f1[i] + f2[i]); */
246
247             t0 = add_int32(f1[i], f2[i]);          /* f1[i] + f2[i]             */
248             /* from Q23 to Q12 and * 0.5 */
249             a[i] = (int16)((t0 >> q_sug) + ((t0 >> (q_sug - 1)) & 1));
250
251
252             /* a[j] = 0.5*(f1[i] - f2[i]); */
253
254             t0 = sub_int32(f1[i], f2[i]);          /* f1[i] - f2[i]             */
255             /* from Q23 to Q12 and * 0.5 */
256             a[j] = (int16)((t0 >> q_sug) + ((t0 >> (q_sug - 1)) & 1));
257
258         }
259         a[0] >>=  q;
260     }
261     else
262     {
263         q_sug = 12;
264         q     = 0;
265     }
266
267     /* a[NC] = 0.5*f1[NC]*(1.0 + isp[M-1]); */
268
269
270     t0 = (int32)(((int64)f1[nc] * isp[m - 1]) >> 16) << 1;
271
272
273     t0 = add_int32(f1[nc], t0);
274
275     /* from Q23 to Q12 and * 0.5 */
276     a[nc] = (int16)((t0 >> q_sug) + ((t0 >> (q_sug - 1)) & 1));
277     a[m] = shr_rnd(isp[m - 1], (3 + q));           /* from Q15 to Q12          */
278
279     /* a[m] = isp[m-1]; */
280
281
282     return;
283 }
284
285
286
287 /*
288 Get_isp_pol
289 ------------------------------------------------------------------------------
290  INPUT AND OUTPUT DEFINITIONS
291
292    isp[]   : isp vector (cosine domaine)         in Q15
293    f[]     : the coefficients of F1 or F2        in Q23
294    n       : == NC for F1(z); == NC-1 for F2(z)
295
296
297 ------------------------------------------------------------------------------
298  FUNCTION DESCRIPTION
299
300     Find the polynomial F1(z) or F2(z) from the ISPs.
301   This is performed by expanding the product polynomials:
302
303   F1(z) =   product   ( 1 - 2 isp_i z^-1 + z^-2 )
304           i=0,2,4,6,8
305   F2(z) =   product   ( 1 - 2 isp_i z^-1 + z^-2 )
306           i=1,3,5,7
307
308   where isp_i are the ISPs in the cosine domain.
309 ------------------------------------------------------------------------------
310  REQUIREMENTS
311
312
313 ------------------------------------------------------------------------------
314  REFERENCES
315
316 ------------------------------------------------------------------------------
317  PSEUDO-CODE
318
319 ----------------------------------------------------------------------------*/
320
321 /*----------------------------------------------------------------------------
322 ; FUNCTION CODE
323 ----------------------------------------------------------------------------*/
324
325
326 void Get_isp_pol(int16 * isp, int32 * f, int16 n)
327 {
328     int16 i, j;
329     int32 t0;
330
331
332     /* All computation in Q23 */
333
334     f[0] = 0x00800000;                        /* f[0] = 1.0;        in Q23  */
335     f[1] = -isp[0] << 9;                      /* f[1] = -2.0*isp[0] in Q23  */
336
337     f += 2;                                   /* Advance f pointer          */
338     isp += 2;                                 /* Advance isp pointer        */
339
340     for (i = 2; i <= n; i++)
341     {
342         *f = f[-2];
343
344         for (j = 1; j < i; j++)
345         {
346
347             t0 = fxp_mul32_by_16b(f[-1], *isp);
348             t0 = shl_int32(t0, 2);
349
350             *f -= t0;                      /* *f -= t0            */
351             *(f) += f[-2];                 /* *f += f[-2]         */
352             f--;
353
354
355         }
356         *f -= *isp << 9;
357
358         f += i;                            /* Advance f pointer   */
359         isp += 2;                          /* Advance isp pointer */
360     }
361 }
362
363 void Get_isp_pol_16kHz(int16 * isp, int32 * f, int16 n)
364 {
365     int16 i, j;
366     int32 t0;
367
368     /* All computation in Q23 */
369
370     f[0] = 0x00200000;                        /* f[0] = 0.25;        in Q23  */
371
372     f[1] = -isp[0] << 7;                      /* f[1] = -0.5*isp[0] in Q23  */
373
374     f += 2;                                   /* Advance f pointer          */
375     isp += 2;                                 /* Advance isp pointer        */
376
377     for (i = 2; i <= n; i++)
378     {
379         *f = f[-2];
380
381         for (j = 1; j < i; j++, f--)
382         {
383             t0 = fxp_mul32_by_16b(f[-1], *isp);
384             t0 = shl_int32(t0, 2);
385
386             *f -= t0;                      /* *f -= t0            */
387             *f += f[-2];                   /* *f += f[-2]         */
388         }
389         *f -= *isp << 7;
390         f += i;                            /* Advance f pointer   */
391         isp += 2;                          /* Advance isp pointer */
392     }
393     return;
394 }
395