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 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
86 extern "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
168 void 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
Lsf_lsp(Word16 lsf[],Word16 lsp[],Word16 m,Flag * pOverflow)214 void 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
291 void 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
Lsp_lsf(Word16 lsp[],Word16 lsf[],Word16 m,Flag * pOverflow)346 void 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