Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / common / src / lsp_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.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24
25 (C) 2004, 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  Filename: lsp_az.cpp
32  Functions: Get_lsp_pol
33            Lsp_Az
34
35 ------------------------------------------------------------------------------
36  MODULE DESCRIPTION
37
38  This file contains functions that convert line spectral pairs (LSP) to
39  linear predictive (LP) coefficients (filter order = 10). The functions
40  included in this file include Get_lsp_pol, which finds the coefficients of
41  F1(z) and F2(z), and Lsp_Az, which converts LSP to LPC by multiplying
42  F1(z) by 1+z^(-1) and F2(z) by 1-z^(-1), then calculating A(z) = (F1(z) +
43  F2(z))/2.
44
45 ------------------------------------------------------------------------------
46 */
47
48 /*----------------------------------------------------------------------------
49 ; INCLUDES
50 ----------------------------------------------------------------------------*/
51 #include "lsp_az.h"
52
53 /*----------------------------------------------------------------------------
54 ; MACROS
55 ; Define module specific macros here
56 ----------------------------------------------------------------------------*/
57
58 /*----------------------------------------------------------------------------
59 ; DEFINES
60 ; Include all pre-processor statements here. Include conditional
61 ; compile variables also.
62 ----------------------------------------------------------------------------*/
63
64 /*----------------------------------------------------------------------------
65 ; LOCAL FUNCTION DEFINITIONS
66 ; Function Prototype declaration
67 ----------------------------------------------------------------------------*/
68
69 /*----------------------------------------------------------------------------
70 ; LOCAL VARIABLE DEFINITIONS
71 ; Variable declaration - defined here and used outside this module
72 ----------------------------------------------------------------------------*/
73
74
75 /*
76 ------------------------------------------------------------------------------
77  FUNCTION NAME: Get_lsp_pol
78 ------------------------------------------------------------------------------
79  INPUT AND OUTPUT DEFINITIONS
80
81  Inputs:
82     lsp = pointer to the buffer containing the line spectral pairs (LSP)
83           of type Word16
84     f = pointer to the polynomial of type Word32 to be generated
85
86     pOverflow  = pointer set in case where one of the operations overflows.
87                  [data type Pointer to Flag]
88
89  Outputs:
90     buffer pointed to by f contains the polynomial generated
91
92     pOverflow  = pointer set in case where one of the operations overflows.
93                  [data type Pointer to Flag]
94
95  Returns:
96     None
97
98  Global Variables Used:
99     None
100
101  Local Variables Needed:
102     None
103
104 ------------------------------------------------------------------------------
105  FUNCTION DESCRIPTION
106
107  This function finds the polynomial F1(z) or F2(z) from the LSPs. If the LSP
108  vector is passed at address 0, F1(z) is computed and if it is passed at
109  address 1, F2(z) is computed.
110
111  This is performed by expanding the product polynomials:
112
113     F1(z) =   product   ( 1 - 2 lsp[i] z^-1 + z^-2 )
114         i=0,2,4,6,8
115     F2(z) =   product   ( 1 - 2 lsp[i] z^-1 + z^-2 )
116         i=1,3,5,7,9
117
118  where lsp[] is the LSP vector in the cosine domain.
119
120  The expansion is performed using the following recursion:
121
122     f[0] = 1
123     b = -2.0 * lsp[0]
124     f[1] = b
125     for i=2 to 5 do
126         b = -2.0 * lsp[2*i-2];
127         for j=i-1 down to 2 do
128             f[j] = f[j] + b*f[j-1] + f[j-2];
129         f[1] = f[1] + b;
130
131 ------------------------------------------------------------------------------
132  REQUIREMENTS
133
134  None
135
136 ------------------------------------------------------------------------------
137  REFERENCES
138
139  lsp_az.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
140
141 ------------------------------------------------------------------------------
142  PSEUDO-CODE
143
144 static void Get_lsp_pol (Word16 *lsp, Word32 *f)
145 {
146     Word16 i, j, hi, lo;
147     Word32 t0;
148
149     // f[0] = 1.0;
150     *f = L_mult (4096, 2048);
151     f++;
152     *f = L_msu ((Word32) 0, *lsp, 512);    // f[1] =  -2.0 * lsp[0];
153     f++;
154     lsp += 2;                              // Advance lsp pointer
155
156     for (i = 2; i <= 5; i++)
157     {
158         *f = f[-2];
159
160         for (j = 1; j < i; j++, f--)
161         {
162             L_Extract (f[-1], &hi, &lo);
163             t0 = Mpy_32_16 (hi, lo, *lsp); // t0 = f[-1] * lsp
164             t0 = L_shl (t0, 1);
165             *f = L_add (*f, f[-2]); // *f += f[-2]
166             *f = L_sub (*f, t0); // *f -= t0
167         }
168         *f = L_msu (*f, *lsp, 512); // *f -= lsp<<9
169         f += i;                            // Advance f pointer
170         lsp += 2;                          // Advance lsp pointer
171     }
172
173     return;
174 }
175
176 ------------------------------------------------------------------------------
177  CAUTION [optional]
178  [State any special notes, constraints or cautions for users of this function]
179
180 ------------------------------------------------------------------------------
181 */
182
183 static void Get_lsp_pol(
184     Word16 *lsp,
185     Word32 *f,
186     Flag   *pOverflow)
187 {
188     register Word16 i;
189     register Word16 j;
190
191     Word16 hi;
192     Word16 lo;
193     Word32 t0;
194     OSCL_UNUSED_ARG(pOverflow);
195
196     /* f[0] = 1.0;             */
197     *f++ = (Word32) 0x01000000;
198     *f++ = (Word32) - *(lsp++) << 10;       /* f[1] =  -2.0 * lsp[0];  */
199     lsp++;                                  /* Advance lsp pointer     */
200
201     for (i = 2; i <= 5; i++)
202     {
203         *f = *(f - 2);
204
205         for (j = 1; j < i; j++)
206         {
207             hi = (Word16)(*(f - 1) >> 16);
208
209             lo = (Word16)((*(f - 1) >> 1) - ((Word32) hi << 15));
210
211             t0  = ((Word32)hi * *lsp);
212             t0 += ((Word32)lo * *lsp) >> 15;
213
214             *(f) +=  *(f - 2);          /*      *f += f[-2]      */
215             *(f--) -=  t0 << 2;         /*      *f -= t0         */
216
217         }
218
219         *f -= (Word32)(*lsp++) << 10;
220
221         f  += i;
222         lsp++;
223     }
224
225     return;
226 }
227
228 /****************************************************************************/
229
230
231
232
233 /*
234 ------------------------------------------------------------------------------
235  FUNCTION NAME: Lsp_Az
236 ------------------------------------------------------------------------------
237  INPUT AND OUTPUT DEFINITIONS
238
239  Inputs:
240     lsp = pointer to the buffer containing the line spectral pairs (LSP)
241           of type Word16
242
243       a = pointer to the buffer containing Linear Predictive (LP)
244           coefficients of type Word16 to be generated
245
246     pOverflow  = pointer set in case where one of the operations overflows.
247                  [data type Pointer to Flag]
248
249  Local Stores/Buffers/Pointers Needed:
250     None
251
252  Global Stores/Buffers/Pointers Needed:
253     None
254
255  Outputs:
256     pOverflow  = pointer set in case where one of the operations overflows.
257                  [data type Pointer to Flag]
258
259  Pointers and Buffers Modified:
260     a buffer contains the generated Linear Predictive (LP) coefficients
261
262  Local Stores Modified:
263     None
264
265  Global Stores Modified:
266         None
267
268 ------------------------------------------------------------------------------
269  FUNCTION DESCRIPTION
270
271  This function converts from the line spectral pairs (LSP) to LP coefficients
272  for a 10th order filter.
273
274  This is done by:
275     (1) Find the coefficients of F1(z) and F2(z) (see Get_lsp_pol)
276     (2) Multiply F1(z) by 1+z^{-1} and F2(z) by 1-z^{-1}
277     (3) A(z) = ( F1(z) + F2(z) ) / 2
278
279 ------------------------------------------------------------------------------
280  REQUIREMENTS
281
282  None
283
284 ------------------------------------------------------------------------------
285  REFERENCES
286
287  lsp_az.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
288
289 ------------------------------------------------------------------------------
290  PSEUDO-CODE
291
292 void Lsp_Az (
293     Word16 lsp[],        // (i)  : line spectral frequencies
294     Word16 a[]           // (o)  : predictor coefficients (order = 10)
295 )
296 {
297     Word16 i, j;
298     Word32 f1[6], f2[6];
299     Word32 t0;
300
301     Get_lsp_pol (&lsp[0], f1);
302     Get_lsp_pol (&lsp[1], f2);
303
304     for (i = 5; i > 0; i--)
305     {
306         f1[i] = L_add (f1[i], f1[i - 1]); // f1[i] += f1[i-1];
307         f2[i] = L_sub (f2[i], f2[i - 1]); // f2[i] -= f2[i-1];
308     }
309
310     a[0] = 4096;
311     for (i = 1, j = 10; i <= 5; i++, j--)
312     {
313         t0 = L_add (f1[i], f2[i]);           // f1[i] + f2[i]
314         a[i] = extract_l (L_shr_r (t0, 13));
315         t0 = L_sub (f1[i], f2[i]);           // f1[i] - f2[i]
316         a[j] = extract_l (L_shr_r (t0, 13));
317     }
318
319     return;
320 }
321
322 ------------------------------------------------------------------------------
323  CAUTION [optional]
324  [State any special notes, constraints or cautions for users of this function]
325
326 ------------------------------------------------------------------------------
327 */
328
329 OSCL_EXPORT_REF void Lsp_Az(
330     Word16 lsp[],        /* (i)  : line spectral frequencies            */
331     Word16 a[],          /* (o)  : predictor coefficients (order = 10)  */
332     Flag  *pOverflow     /* (o)  : overflow flag                        */
333 )
334 {
335     register Word16 i;
336     register Word16 j;
337
338     Word32 f1[6];
339     Word32 f2[6];
340     Word32 t0;
341     Word32 t1;
342     Word16 *p_a = &a[0];
343     Word32 *p_f1;
344     Word32 *p_f2;
345
346     Get_lsp_pol(&lsp[0], f1, pOverflow);
347
348     Get_lsp_pol(&lsp[1], f2, pOverflow);
349
350     p_f1 = &f1[5];
351     p_f2 = &f2[5];
352
353     for (i = 5; i > 0; i--)
354     {
355         *(p_f1--) += f1[i-1];
356         *(p_f2--) -= f2[i-1];
357     }
358
359     *(p_a++) = 4096;
360     p_f1 = &f1[1];
361     p_f2 = &f2[1];
362
363     for (i = 1, j = 10; i <= 5; i++, j--)
364     {
365         t0 = *(p_f1) + *(p_f2);               /* f1[i] + f2[i] */
366         t1 = *(p_f1++) - *(p_f2++);           /* f1[i] - f2[i] */
367
368         t0 = t0 + ((Word32) 1 << 12);
369         t1 = t1 + ((Word32) 1 << 12);
370
371         *(p_a++) = (Word16)(t0 >> 13);
372         a[j]     = (Word16)(t1 >> 13);
373     }
374
375     return;
376 }