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 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 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