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 20 Pathname: apply_tns.c 21 22------------------------------------------------------------------------------ 23 INPUT AND OUTPUT DEFINITIONS 24 25 Inputs: 26 coef = Array of input coefficients. 27 [Int32 *, length 1024] 28 29 q_format = Array of q-formats, one per scalefactor band, for the 30 entire frame. In the case of tns_inv_filter, only the 31 first element is used, since the input to tns_inv_filter 32 is all of the same q-format. 33 [Int * const, length MAX_SFB] 34 35 pFrameInfo = Pointer to structure that holds information about each group. 36 (long block flag, number of windows, scalefactor bands 37 per group, etc.) 38 [const FrameInfo * const] 39 40 pTNS_frame_info = pointer to structure containing the details on each 41 TNS filter (order, filter coefficients, 42 coefficient res., etc.) 43 [TNS_frame_info * const] 44 45 inverse_flag = TRUE if inverse filter is to be applied. 46 FALSE if forward filter is to be applied. 47 [Bool] 48 49 scratch_Int_buffer = Pointer to scratch memory to store the 50 filter's state memory. Used by both 51 tns_inv_filter. 52 [Int *, length TNS_MAX_ORDER] 53 54 Local Stores/Buffers/Pointers Needed: 55 None 56 57 Global Stores/Buffers/Pointers Needed: 58 None 59 60 Outputs: 61 None 62 63 Pointers and Buffers Modified: 64 coef[] = TNS altered data. 65 q_format = q-formats in TNS scalefactor bands may be modified. 66 67 Local Stores Modified: 68 None 69 70 Global Stores Modified: 71 None 72 73------------------------------------------------------------------------------ 74 FUNCTION DESCRIPTION 75 76 This function applies either the TNS forward or TNS inverse filter, based 77 on inverse_flag being FALSE or TRUE, respectively. 78 79 For the TNS forward filter, the data fed into tns_ar_filter is normalized 80 all to the same q-format. 81 82------------------------------------------------------------------------------ 83 REQUIREMENTS 84 85 The input, coef, should use all 32-bits, else the scaling by tns_ar_filter 86 may eliminate the data. 87 88------------------------------------------------------------------------------ 89 REFERENCES 90 91 (1) ISO/IEC 14496-3:1999(E) 92 Part 3 93 Subpart 4.6.8 (Temporal Noise Shaping) 94 95------------------------------------------------------------------------------ 96 PSEUDO-CODE 97 98 NO PSEUDO-CODE 99 100------------------------------------------------------------------------------ 101 RESOURCES USED 102 When the code is written for a specific target processor 103 the resources used should be documented below. 104 105 STACK USAGE: [stack count for this module] + [variable to represent 106 stack usage for each subroutine called] 107 108 where: [stack usage variable] = stack usage for [subroutine 109 name] (see [filename].ext) 110 111 DATA MEMORY USED: x words 112 113 PROGRAM MEMORY USED: x words 114 115 CLOCK CYCLES: [cycle count equation for this module] + [variable 116 used to represent cycle count for each subroutine 117 called] 118 119 where: [cycle count variable] = cycle count for [subroutine 120 name] (see [filename].ext) 121 122------------------------------------------------------------------------------ 123*/ 124 125/*---------------------------------------------------------------------------- 126; INCLUDES 127----------------------------------------------------------------------------*/ 128#include "pv_audio_type_defs.h" 129#include "s_tns_frame_info.h" 130#include "s_tnsfilt.h" 131#include "s_frameinfo.h" 132#include "tns_inv_filter.h" 133#include "tns_ar_filter.h" 134#include "apply_tns.h" 135 136/*---------------------------------------------------------------------------- 137; MACROS 138; Define module specific macros here 139----------------------------------------------------------------------------*/ 140 141/*---------------------------------------------------------------------------- 142; DEFINES 143; Include all pre-processor statements here. Include conditional 144; compile variables also. 145----------------------------------------------------------------------------*/ 146 147/*---------------------------------------------------------------------------- 148; LOCAL FUNCTION DEFINITIONS 149; Function Prototype declaration 150----------------------------------------------------------------------------*/ 151 152/*---------------------------------------------------------------------------- 153; LOCAL STORE/BUFFER/POINTER DEFINITIONS 154; Variable declaration - defined here and used outside this module 155----------------------------------------------------------------------------*/ 156 157/*---------------------------------------------------------------------------- 158; EXTERNAL FUNCTION REFERENCES 159; Declare functions defined elsewhere and referenced in this module 160----------------------------------------------------------------------------*/ 161 162/*---------------------------------------------------------------------------- 163; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 164; Declare variables used in this module but defined elsewhere 165----------------------------------------------------------------------------*/ 166 167/*---------------------------------------------------------------------------- 168; FUNCTION CODE 169----------------------------------------------------------------------------*/ 170 171void apply_tns( 172 Int32 coef[], 173 Int q_format[], 174 const FrameInfo * const pFrameInfo, 175 TNS_frame_info * const pTNS_frame_info, 176 const Bool inverse_flag, 177 Int32 scratch_Int_buffer[]) 178{ 179 Int num_tns_bands; 180 Int num_TNS_coef; 181 182 Int f; 183 184 Int tempInt; 185 Int tempInt2; 186 187 Int sfb_per_win; 188 Int sfbWidth; 189 190 Int coef_per_win; 191 Int min_q; 192 Int win; 193 194 Int32 *pCoef = coef; 195 Int32 *pTempCoef; 196 197 Int *pStartQformat = q_format; 198 199 Int *pQformat; 200 Int32 *pLpcCoef; 201 202 Int sfb_offset; 203 204 const Int16 *pWinSfbTop; 205 206 TNSfilt *pFilt; 207 208 coef_per_win = pFrameInfo->coef_per_win[0]; 209 sfb_per_win = pFrameInfo->sfb_per_win[0]; 210 211 win = 0; 212 213 pLpcCoef = pTNS_frame_info->lpc_coef; 214 215 pFilt = pTNS_frame_info->filt; 216 217 do 218 { 219 for (f = pTNS_frame_info->n_filt[win]; f > 0; f--) 220 { 221 /* Skip to the next filter if the order is 0 */ 222 tempInt = pFilt->order; 223 224 if (tempInt > 0) 225 { 226 /* 227 * Do not call tns_ar_filter or tns_inv_filter 228 * if the difference 229 * between start_coef and stop_stop is <= 0. 230 * 231 */ 232 num_TNS_coef = (pFilt->stop_coef - pFilt->start_coef); 233 234 if (num_TNS_coef > 0) 235 { 236 if (inverse_flag != FALSE) 237 { 238 tns_inv_filter( 239 &(pCoef[pFilt->start_coef]), 240 num_TNS_coef, 241 pFilt->direction, 242 pLpcCoef, 243 pFilt->q_lpc, 244 pFilt->order, 245 scratch_Int_buffer); 246 } 247 else 248 { 249 num_tns_bands = (pFilt->stop_band - pFilt->start_band); 250 251 /* 252 * pQformat is initialized only once. 253 * 254 * Here is how TNS is applied on scalefactor bands 255 * 256 * [0][1][2][3][4][5][6][7][8] 257 * | \ 258 * start_band stop_band 259 * 260 * In this example, TNS would be applied to 8 261 * scalefactor bands, 0-7. 262 * 263 * pQformat is initially set to &(pStartQformat[8]) 264 * 265 * 1st LOOP 266 * Entry: pQformat = &(pStartQformat[8]) 267 * 268 * pQformat is pre-decremented 8 times in the 269 * search for min_q 270 * 271 * Exit: pQformat = &(pStartQformat[0]) 272 * 273 * 2nd LOOP 274 * Entry: pQformat = &(pStartQformat[0]) 275 * 276 * pQformat is post-incremented 8 times in the 277 * normalization of the data loop. 278 * 279 * Exit: pQformat = &(pStartQformat[8] 280 * 281 * 282 * shift_amt = tns_ar_filter(...) 283 * 284 * 3rd LOOP 285 * Entry: pQformat = &(pStartQformat[8]) 286 * 287 * pQformat is pre-decremented 8 times in the 288 * adjustment of the q-format to min_q - shift_amt 289 * 290 * Exit: pQformat = &(pStartQformat[0]) 291 * 292 */ 293 294 pQformat = 295 &(pStartQformat[pFilt->stop_band]); 296 297 /* 298 * Scan the array of q-formats and find the minimum over 299 * the range where the filter is to be applied. 300 * 301 * At the end of this scan, 302 * pQformat = &(q-format[pFilt->start_band]); 303 * 304 */ 305 306 min_q = INT16_MAX; 307 308 for (tempInt = num_tns_bands; tempInt > 0; tempInt--) 309 { 310 tempInt2 = *(--pQformat); 311 312 if (tempInt2 < min_q) 313 { 314 min_q = tempInt2; 315 } 316 } /* for(tempInt = num_bands; tempInt > 0; tempInt--)*/ 317 318 /* 319 * Set up the pointers so we can index into coef[] 320 * on a scalefactor band basis. 321 */ 322 tempInt = pFilt->start_band; 323 324 tempInt--; 325 326 /* Initialize sfb_offset and pWinSfbTop */ 327 if (tempInt >= 0) 328 { 329 pWinSfbTop = 330 &(pFrameInfo->win_sfb_top[win][tempInt]); 331 332 sfb_offset = *(pWinSfbTop++); 333 } 334 else 335 { 336 pWinSfbTop = pFrameInfo->win_sfb_top[win]; 337 sfb_offset = 0; 338 } 339 340 pTempCoef = pCoef + pFilt->start_coef; 341 342 /* Scale the data in the TNS bands to min_q q-format */ 343 for (tempInt = num_tns_bands; tempInt > 0; tempInt--) 344 { 345 sfbWidth = *(pWinSfbTop++) - sfb_offset; 346 347 sfb_offset += sfbWidth; 348 349 tempInt2 = *(pQformat++) - min_q; 350 351 /* 352 * This should zero out the data in one scalefactor 353 * band if it is so much less than the neighboring 354 * scalefactor bands. 355 * 356 * The only way this "should" happen is if one 357 * scalefactor band contains zero data. 358 * 359 * Zero data can be of any q-format, but we always 360 * set it very high to avoid the zero-data band being 361 * picked as the one to normalize to in the scan for 362 * min_q. 363 * 364 */ 365 if (tempInt2 > 31) 366 { 367 tempInt2 = 31; 368 } 369 370 for (sfbWidth >>= 2; sfbWidth > 0; sfbWidth--) 371 { 372 *(pTempCoef++) >>= tempInt2; 373 *(pTempCoef++) >>= tempInt2; 374 *(pTempCoef++) >>= tempInt2; 375 *(pTempCoef++) >>= tempInt2; 376 } 377 378 } /* for(tempInt = num_bands; tempInt > 0; tempInt--)*/ 379 380 tempInt2 = 381 tns_ar_filter( 382 &(pCoef[pFilt->start_coef]), 383 num_TNS_coef, 384 pFilt->direction, 385 pLpcCoef, 386 pFilt->q_lpc, 387 pFilt->order); 388 389 /* 390 * Update the q-format for all the scalefactor bands 391 * taking into account the adjustment caused by 392 * tns_ar_filter 393 */ 394 395 min_q -= tempInt2; 396 397 for (tempInt = num_tns_bands; tempInt > 0; tempInt--) 398 { 399 *(--pQformat) = min_q; 400 } 401 402 } /* if (inverse_flag != FALSE) */ 403 404 } /* if (num_TNS_coef > 0) */ 405 406 pLpcCoef += pFilt->order; 407 408 } /* if (tempInt > 0) */ 409 410 pFilt++; 411 412 } /* for (f = pTNSinfo->n_filt; f > 0; f--) */ 413 414 pCoef += coef_per_win; 415 pStartQformat += sfb_per_win; 416 417 win++; 418 419 } 420 while (win < pFrameInfo->num_win); 421 422 return; 423 424} /* apply_tns() */ 425