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.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)
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 Pathname: ./audio/gsm-amr/c/src/lsp_lsf.c
31 Functions: Lsp_lsf
32            Lsf_lsp
33
34------------------------------------------------------------------------------
35 REVISION HISTORY
36
37 Description: Updated template used to PV coding template.
38
39 Description: Deleted variables listed in the Local Stores Needed/Modified
40              section.
41
42 Description: Synchronized file with UMTS version 3.2.0. Updated coding
43              template and removed unnecessary include files.
44
45 Description: Replaced basic_op.h with the header file of the math functions
46              used in the file.
47
48 Description: Changed to accept the pOverflow flag for EPOC compatibility.
49
50 Description: Placed table declarations in a .c file, rather than an included
51 .tab.  The tables are now referenced via an extern in this file.
52
53 Description:  For Lsp_lsf()
54              1. Eliminated unused include file typedef.h.
55              2. Replaced array addressing by pointers
56
57 Description:  Replaced "int" and/or "char" with defined types.
58               Added proper casting (Word32) to some left shifting operations
59
60 Description: Changed round function name to pv_round to avoid conflict with
61              round function in C standard library.
62
63 Description: Added #ifdef __cplusplus around extern'ed table.
64
65 Who:                           Date:
66 Description:
67
68------------------------------------------------------------------------------
69 MODULE DESCRIPTION
70
71 This file contains the functions that convert line spectral pairs (LSP) to
72 line spectral frequencies (LSF) and vice-versa.
73
74------------------------------------------------------------------------------
75*/
76
77/*----------------------------------------------------------------------------
78; INCLUDES
79----------------------------------------------------------------------------*/
80#include "lsp_lsf.h"
81#include "basicop_malloc.h"
82#include "basic_op.h"
83
84/*--------------------------------------------------------------------------*/
85#ifdef __cplusplus
86extern "C"
87{
88#endif
89
90    /*----------------------------------------------------------------------------
91    ; MACROS
92    ; Define module specific macros here
93    ----------------------------------------------------------------------------*/
94
95    /*----------------------------------------------------------------------------
96    ; DEFINES
97    ; Include all pre-processor statements here. Include conditional
98    ; compile variables also.
99    ----------------------------------------------------------------------------*/
100
101    /*----------------------------------------------------------------------------
102    ; LOCAL FUNCTION DEFINITIONS
103    ; Function Prototype declaration
104    ----------------------------------------------------------------------------*/
105
106    /*----------------------------------------------------------------------------
107    ; LOCAL VARIABLE DEFINITIONS
108    ; Variable declaration - defined here and used outside this module
109    ----------------------------------------------------------------------------*/
110
111    extern const Word16 table[];
112    extern const Word16 slope[];
113
114
115    /*--------------------------------------------------------------------------*/
116#ifdef __cplusplus
117}
118#endif
119
120/*
121------------------------------------------------------------------------------
122 FUNCTION NAME: Lsf_lsp
123------------------------------------------------------------------------------
124 INPUT AND OUTPUT DEFINITIONS
125
126 Inputs:
127    lsf = buffer containing normalized line spectral frequencies; valid
128          range is between 0 and 0.5 (Word16)
129    lsp = buffer containing line spectral pairs; valid range is between
130          -1 and 1 (Word16)
131    m = LPC order (Word16)
132
133 Outputs:
134    lsp contains the newly calculated line spectral pairs
135
136 Returns:
137    None
138
139 Global Variables Used:
140    table = cosine table
141
142 Local Variables Needed:
143    None
144
145------------------------------------------------------------------------------
146 FUNCTION DESCRIPTION
147
148 This function performs the LSF to LSP transformation using the equation:
149
150    lsf[i] = arccos(lsp[i])/(2*pi)
151
152 The transformation from lsp[i] to lsf[i] is approximated by a look-up table
153 and interpolation.
154
155------------------------------------------------------------------------------
156 REQUIREMENTS
157
158 None
159
160------------------------------------------------------------------------------
161 REFERENCES
162
163 lsp_lsf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
164
165------------------------------------------------------------------------------
166 PSEUDO-CODE
167
168void Lsf_lsp (
169    Word16 lsf[],       // (i) : lsf[m] normalized (range: 0.0<=val<=0.5)
170    Word16 lsp[],       // (o) : lsp[m] (range: -1<=val<1)
171    Word16 m            // (i) : LPC order
172)
173{
174    Word16 i, ind, offset;
175    Word32 L_tmp;
176
177    for (i = 0; i < m; i++)
178    {
179        ind = shr (lsf[i], 8);      // ind    = b8-b15 of lsf[i]
180        offset = lsf[i] & 0x00ff;    // offset = b0-b7  of lsf[i]
181
182        // lsp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 256
183
184        L_tmp = L_mult (sub (table[ind + 1], table[ind]), offset);
185        lsp[i] = add (table[ind], extract_l (L_shr (L_tmp, 9)));
186
187    }
188    return;
189}
190
191------------------------------------------------------------------------------
192 RESOURCES USED [optional]
193
194 When the code is written for a specific target processor the
195 the resources used should be documented below.
196
197 HEAP MEMORY USED: x bytes
198
199 STACK MEMORY USED: x bytes
200
201 CLOCK CYCLES: (cycle count equation for this function) + (variable
202                used to represent cycle count for each subroutine
203                called)
204     where: (cycle count variable) = cycle count for [subroutine
205                                     name]
206
207------------------------------------------------------------------------------
208 CAUTION [optional]
209 [State any special notes, constraints or cautions for users of this function]
210
211------------------------------------------------------------------------------
212*/
213
214void Lsf_lsp(
215    Word16 lsf[],       /* (i) : lsf[m] normalized (range: 0.0<=val<=0.5) */
216    Word16 lsp[],       /* (o) : lsp[m] (range: -1<=val<1)                */
217    Word16 m,           /* (i) : LPC order                                */
218    Flag   *pOverflow   /* (o) : Flag set when overflow occurs            */
219)
220{
221    Word16 i, ind, offset;
222    Word32 L_tmp;
223
224    for (i = 0; i < m; i++)
225    {
226        ind = lsf[i] >> 8;           /* ind    = b8-b15 of lsf[i] */
227        offset = lsf[i] & 0x00ff;    /* offset = b0-b7  of lsf[i] */
228
229        /* lsp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 256 */
230
231        L_tmp = ((Word32)(table[ind + 1] - table[ind]) * offset) >> 8;
232        lsp[i] = add(table[ind], (Word16) L_tmp, pOverflow);
233
234    }
235
236    return;
237}
238
239/****************************************************************************/
240
241
242/*
243------------------------------------------------------------------------------
244 FUNCTION NAME: Lsp_lsf
245------------------------------------------------------------------------------
246 INPUT AND OUTPUT DEFINITIONS
247
248 Inputs:
249    lsp = buffer containing line spectral pairs; valid range is between
250          -1 and 1 (Word16)
251    lsf = buffer containing normalized line spectral frequencies; valid
252          range is between 0 and 0.5 (Word16)
253    m = LPC order (Word16)
254
255 Outputs:
256    lsf contains the newly calculated normalized line spectral frequencies
257
258 Returns:
259    None
260
261 Global Variables Used:
262    table = cosine table
263    slope = table to used to calculate inverse cosine
264
265 Local Variables Needed:
266    None
267
268------------------------------------------------------------------------------
269 FUNCTION DESCRIPTION
270
271 This function performs the LSP to LSF transformation using the equation:
272
273    lsp[i] = cos(2*pi*lsf[i])
274
275 The transformation from lsf[i] to lsp[i] is approximated by a look-up table
276 and interpolation.
277
278------------------------------------------------------------------------------
279 REQUIREMENTS
280
281 None
282
283------------------------------------------------------------------------------
284 REFERENCES
285
286 lsp_lsf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
287
288------------------------------------------------------------------------------
289 PSEUDO-CODE
290
291void Lsp_lsf (
292    Word16 lsp[],       // (i)  : lsp[m] (range: -1<=val<1)
293    Word16 lsf[],       // (o)  : lsf[m] normalized (range: 0.0<=val<=0.5)
294    Word16 m            // (i)  : LPC order
295)
296{
297    Word16 i, ind;
298    Word32 L_tmp;
299
300    ind = 63;                        // begin at end of table -1
301
302    for (i = m - 1; i >= 0; i--)
303    {
304        // find value in table that is just greater than lsp[i]
305
306        while (sub (table[ind], lsp[i]) < 0)
307        {
308            ind--;
309
310        }
311
312        // acos(lsp[i])= ind*256 + ( ( lsp[i]-table[ind] ) *
313           slope[ind] )/4096
314
315        L_tmp = L_mult (sub (lsp[i], table[ind]), slope[ind]);
316        //(lsp[i]-table[ind])*slope[ind])>>12
317        lsf[i] = pv_round (L_shl (L_tmp, 3));
318        lsf[i] = add (lsf[i], shl (ind, 8));
319    }
320    return;
321}
322
323------------------------------------------------------------------------------
324 RESOURCES USED [optional]
325
326 When the code is written for a specific target processor the
327 the resources used should be documented below.
328
329 HEAP MEMORY USED: x bytes
330
331 STACK MEMORY USED: x bytes
332
333 CLOCK CYCLES: (cycle count equation for this function) + (variable
334                used to represent cycle count for each subroutine
335                called)
336     where: (cycle count variable) = cycle count for [subroutine
337                                     name]
338
339------------------------------------------------------------------------------
340 CAUTION [optional]
341 [State any special notes, constraints or cautions for users of this function]
342
343------------------------------------------------------------------------------
344*/
345
346void Lsp_lsf(
347    Word16 lsp[],       /* (i)  : lsp[m] (range: -1<=val<1)                */
348    Word16 lsf[],       /* (o)  : lsf[m] normalized (range: 0.0<=val<=0.5) */
349    Word16 m,           /* (i)  : LPC order                                */
350    Flag  *pOverflow    /* (o)  : Flag set when overflow occurs            */
351)
352{
353    Word16 i;
354    Word16 ind;
355    Word16 temp;
356    Word32 L_tmp;
357    Word16 *p_lsp = &lsp[m-1];
358    Word16 *p_lsf = &lsf[m-1];
359    OSCL_UNUSED_ARG(pOverflow);
360
361    ind = 63;                        /* begin at end of table -1 */
362
363    for (i = m - 1; i >= 0; i--)
364    {
365        /* find value in table that is just greater than lsp[i] */
366        temp = *(p_lsp--);
367        while (table[ind] < temp)
368        {
369            ind--;
370        }
371
372        /* acos(lsp[i])= ind*256 + ( ( lsp[i]-table[ind] ) *
373           slope[ind] )/4096 */
374
375        L_tmp = (Word32)(temp - table[ind]) * slope[ind];
376
377        /*(lsp[i]-table[ind])*slope[ind])>>12*/
378        L_tmp  = (L_tmp + 0x00000800) >> 12;
379
380        *(p_lsf--) = (Word16)(L_tmp) + (ind << 8);
381    }
382
383    return;
384}
385