1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
22 ------------------------------------------------------------------------------
23 INPUT AND OUTPUT DEFINITIONS
26 coef = Array of input coefficients.
27 [Int32 *, length 1024]
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]
35 pFrameInfo = Pointer to structure that holds information about each group.
36 (long block flag, number of windows, scalefactor bands
38 [const FrameInfo * const]
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]
45 inverse_flag = TRUE if inverse filter is to be applied.
46 FALSE if forward filter is to be applied.
49 scratch_Int_buffer = Pointer to scratch memory to store the
50 filter's state memory. Used by both
52 [Int *, length TNS_MAX_ORDER]
54 Local Stores/Buffers/Pointers Needed:
57 Global Stores/Buffers/Pointers Needed:
63 Pointers and Buffers Modified:
64 coef[] = TNS altered data.
65 q_format = q-formats in TNS scalefactor bands may be modified.
67 Local Stores Modified:
70 Global Stores Modified:
73 ------------------------------------------------------------------------------
76 This function applies either the TNS forward or TNS inverse filter, based
77 on inverse_flag being FALSE or TRUE, respectively.
79 For the TNS forward filter, the data fed into tns_ar_filter is normalized
80 all to the same q-format.
82 ------------------------------------------------------------------------------
85 The input, coef, should use all 32-bits, else the scaling by tns_ar_filter
86 may eliminate the data.
88 ------------------------------------------------------------------------------
91 (1) ISO/IEC 14496-3:1999(E)
93 Subpart 4.6.8 (Temporal Noise Shaping)
95 ------------------------------------------------------------------------------
100 ------------------------------------------------------------------------------
102 When the code is written for a specific target processor
103 the resources used should be documented below.
105 STACK USAGE: [stack count for this module] + [variable to represent
106 stack usage for each subroutine called]
108 where: [stack usage variable] = stack usage for [subroutine
109 name] (see [filename].ext)
111 DATA MEMORY USED: x words
113 PROGRAM MEMORY USED: x words
115 CLOCK CYCLES: [cycle count equation for this module] + [variable
116 used to represent cycle count for each subroutine
119 where: [cycle count variable] = cycle count for [subroutine
120 name] (see [filename].ext)
122 ------------------------------------------------------------------------------
125 /*----------------------------------------------------------------------------
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"
136 /*----------------------------------------------------------------------------
138 ; Define module specific macros here
139 ----------------------------------------------------------------------------*/
141 /*----------------------------------------------------------------------------
143 ; Include all pre-processor statements here. Include conditional
144 ; compile variables also.
145 ----------------------------------------------------------------------------*/
147 /*----------------------------------------------------------------------------
148 ; LOCAL FUNCTION DEFINITIONS
149 ; Function Prototype declaration
150 ----------------------------------------------------------------------------*/
152 /*----------------------------------------------------------------------------
153 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
154 ; Variable declaration - defined here and used outside this module
155 ----------------------------------------------------------------------------*/
157 /*----------------------------------------------------------------------------
158 ; EXTERNAL FUNCTION REFERENCES
159 ; Declare functions defined elsewhere and referenced in this module
160 ----------------------------------------------------------------------------*/
162 /*----------------------------------------------------------------------------
163 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
164 ; Declare variables used in this module but defined elsewhere
165 ----------------------------------------------------------------------------*/
167 /*----------------------------------------------------------------------------
169 ----------------------------------------------------------------------------*/
174 const FrameInfo * const pFrameInfo,
175 TNS_frame_info * const pTNS_frame_info,
176 const Bool inverse_flag,
177 Int32 scratch_Int_buffer[])
197 Int *pStartQformat = q_format;
204 const Int16 *pWinSfbTop;
208 coef_per_win = pFrameInfo->coef_per_win[0];
209 sfb_per_win = pFrameInfo->sfb_per_win[0];
213 pLpcCoef = pTNS_frame_info->lpc_coef;
215 pFilt = pTNS_frame_info->filt;
219 for (f = pTNS_frame_info->n_filt[win]; f > 0; f--)
221 /* Skip to the next filter if the order is 0 */
222 tempInt = pFilt->order;
227 * Do not call tns_ar_filter or tns_inv_filter
229 * between start_coef and stop_stop is <= 0.
232 num_TNS_coef = (pFilt->stop_coef - pFilt->start_coef);
234 if (num_TNS_coef > 0)
236 if (inverse_flag != FALSE)
239 &(pCoef[pFilt->start_coef]),
249 num_tns_bands = (pFilt->stop_band - pFilt->start_band);
252 * pQformat is initialized only once.
254 * Here is how TNS is applied on scalefactor bands
256 * [0][1][2][3][4][5][6][7][8]
258 * start_band stop_band
260 * In this example, TNS would be applied to 8
261 * scalefactor bands, 0-7.
263 * pQformat is initially set to &(pStartQformat[8])
266 * Entry: pQformat = &(pStartQformat[8])
268 * pQformat is pre-decremented 8 times in the
271 * Exit: pQformat = &(pStartQformat[0])
274 * Entry: pQformat = &(pStartQformat[0])
276 * pQformat is post-incremented 8 times in the
277 * normalization of the data loop.
279 * Exit: pQformat = &(pStartQformat[8]
282 * shift_amt = tns_ar_filter(...)
285 * Entry: pQformat = &(pStartQformat[8])
287 * pQformat is pre-decremented 8 times in the
288 * adjustment of the q-format to min_q - shift_amt
290 * Exit: pQformat = &(pStartQformat[0])
295 &(pStartQformat[pFilt->stop_band]);
298 * Scan the array of q-formats and find the minimum over
299 * the range where the filter is to be applied.
301 * At the end of this scan,
302 * pQformat = &(q-format[pFilt->start_band]);
308 for (tempInt = num_tns_bands; tempInt > 0; tempInt--)
310 tempInt2 = *(--pQformat);
312 if (tempInt2 < min_q)
316 } /* for(tempInt = num_bands; tempInt > 0; tempInt--)*/
319 * Set up the pointers so we can index into coef[]
320 * on a scalefactor band basis.
322 tempInt = pFilt->start_band;
326 /* Initialize sfb_offset and pWinSfbTop */
330 &(pFrameInfo->win_sfb_top[win][tempInt]);
332 sfb_offset = *(pWinSfbTop++);
336 pWinSfbTop = pFrameInfo->win_sfb_top[win];
340 pTempCoef = pCoef + pFilt->start_coef;
342 /* Scale the data in the TNS bands to min_q q-format */
343 for (tempInt = num_tns_bands; tempInt > 0; tempInt--)
345 sfbWidth = *(pWinSfbTop++) - sfb_offset;
347 sfb_offset += sfbWidth;
349 tempInt2 = *(pQformat++) - min_q;
352 * This should zero out the data in one scalefactor
353 * band if it is so much less than the neighboring
356 * The only way this "should" happen is if one
357 * scalefactor band contains zero data.
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
370 for (sfbWidth >>= 2; sfbWidth > 0; sfbWidth--)
372 *(pTempCoef++) >>= tempInt2;
373 *(pTempCoef++) >>= tempInt2;
374 *(pTempCoef++) >>= tempInt2;
375 *(pTempCoef++) >>= tempInt2;
378 } /* for(tempInt = num_bands; tempInt > 0; tempInt--)*/
382 &(pCoef[pFilt->start_coef]),
390 * Update the q-format for all the scalefactor bands
391 * taking into account the adjustment caused by
397 for (tempInt = num_tns_bands; tempInt > 0; tempInt--)
399 *(--pQformat) = min_q;
402 } /* if (inverse_flag != FALSE) */
404 } /* if (num_TNS_coef > 0) */
406 pLpcCoef += pFilt->order;
408 } /* if (tempInt > 0) */
412 } /* for (f = pTNSinfo->n_filt; f > 0; f--) */
414 pCoef += coef_per_win;
415 pStartQformat += sfb_per_win;
420 while (win < pFrameInfo->num_win);