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 * -------------------------------------------------------------------
20 Pathname: tns_inv_filter.c
22 ------------------------------------------------------------------------------
25 Description: Changes made per review comments.
27 Description: As requested by JT, the q-format for the LPC coefficients is
28 now passed via the parameter lpc_qformat.
30 Description: For speed, the calculation of the shift amount was pulled
34 Modified casting to ensure proper operations for different platforms
37 Simplified MAC operations for filter by eliminating extra variables
42 ------------------------------------------------------------------------------
43 INPUT AND OUTPUT DEFINITIONS
47 coef = spectral input to be shaped by the filter.
49 [Int32[], length = num_coef]
51 num_coef = length of spec array.
54 direction = direction for application of tns filter.
55 +1 applies forward filter
56 (first input to filter is coef[0])
57 -1 applies reversed filter
58 (first input to filter is coef[num_coef-1])
61 lpc = array of lpc coefficients.
62 Fixed point format Q-11
63 [const Int[], length = TNS_MAX_ORDER]
65 lpc_qformat = The q-format of the lpc coefficients.
68 order = order of the TNS filter (Range of 1 : TNS_MAX_ORDER)
71 scratch_memory = scratch_memory needed for filter operation
72 [Int[], length = TNS_MAX_ORDER]
74 Local Stores/Buffers/Pointers Needed:
77 Global Stores/Buffers/Pointers Needed:
83 Pointers and Buffers Modified:
84 coef = contains spectral data after application of TNS filter
85 q-format is not modified.
89 Local Stores Modified:
92 Global Stores Modified:
95 ------------------------------------------------------------------------------
98 A block of spectral data (Int32 coef[]) of length (const Int num_coef)
99 is processed by a simple all-zero filter defined by
100 LPC coefficients passed via (const Int lpc[])
103 y(n) = x(n) + lpc(2)*x(n-1) + ... + lpc(order+1)*x(n-order)
105 The filter calculation is performed in place, i.e. the output is passed
106 back to the calling function via (Int32 coef[])
108 In order to avoid overflow, the filter input (Int32 coef[]) must utilize
109 only the lower 16-bits. The upper 16-bits must be available.
111 The filter's order is defined by the variable (const Int order)
113 The direction of the filter's application is defined by
114 (const Int direction)
116 ------------------------------------------------------------------------------
119 [Int32 coef] must store no more than 16 bits of data.
121 This is required to utilize methods that do not change the q-format of
122 the input data [Int32 coef], and to make use of a fast
123 16 x 16 bit multiply.
125 This function should not be called for order <= 0.
127 This function must not be called with lpc_qformat < 5
128 ------------------------------------------------------------------------------
131 (1) ISO/IEC 14496-3:1999(E)
133 Subpart 4.6.6.4.1 (LTP with TNS)
134 Subpart 4.6.8 (Temporal Noise Shaping)
136 (2) MPEG-2 NBC Audio Decoder
137 "This software module was originally developed by AT&T, Dolby
138 Laboratories, Fraunhofer Gesellschaft IIS in the course of development
139 of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and
140 3. This software module is an implementation of a part of one or more
141 MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
142 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio
143 standards free license to this software module or modifications thereof
144 for use in hardware or software products claiming conformance to the
145 MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software
146 module in hardware or software products are advised that this use may
147 infringe existing patents. The original developer of this software
148 module and his/her company, the subsequent editors and their companies,
149 and ISO/IEC have no liability for use of this software module or
150 modifications thereof in an implementation. Copyright is not released
151 for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original
152 developer retains full right to use the code for his/her own purpose,
153 assign or donate the code to a third party and to inhibit third party
154 from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products.
155 This copyright notice must be included in all copies or derivative
159 ------------------------------------------------------------------------------
164 pCoef = pCoef + (num_coef - 1);
167 FOR (i = order; i > 0; i--)
170 pFilterInput = pFilterInput + 1;
176 shift_amt = (lpc_qformat - 5);
178 FOR (i = num_coef; i > 0; i--)
184 FOR (j = wrap_point; j>0; j--)
186 tempInt32 = (Int32)(*(pLPC) * *(pFilterInput));
187 tempInt32 = tempInt32 >> 5;
189 mult = mult + tempInt32;
191 pFilterInput = pFilterInput + 1;
196 pFilterInput = scratch_memory;
198 FOR (j = (order - wrap_point); j>0; j--)
200 tempInt32 = (Int32)(*(pLPC) * *(pFilterInput));
201 tempInt32 = tempInt32 >> 5;
203 mult = mult + tempInt32;
205 pFilterInput = pFilterInput + 1;
210 pFilterInput = pFilterInput - 1;
211 *(pFilterInput) = (Int)(*pCoef);
213 mult = mult >> shift_amt;
215 *(pCoef) = *(pCoef) + mult;
217 pCoef = pCoef + direction;
219 wrap_point = wrap_point + 1;
221 IF (wrap_point == order)
228 ------------------------------------------------------------------------------
231 When the code is written for a specific target processor
232 the resources used should be documented below.
234 STACK USAGE: [stack count for this module] + [variable to represent
235 stack usage for each subroutine called]
237 where: [stack usage variable] = stack usage for [subroutine
238 name] (see [filename].ext)
240 DATA MEMORY USED: x words
242 PROGRAM MEMORY USED: x words
244 CLOCK CYCLES: [cycle count equation for this module] + [variable
245 used to represent cycle count for each subroutine
248 where: [cycle count variable] = cycle count for [subroutine
249 name] (see [filename].ext)
251 ------------------------------------------------------------------------------
254 /*----------------------------------------------------------------------------
256 ----------------------------------------------------------------------------*/
257 #include "pv_audio_type_defs.h"
258 #include "tns_inv_filter.h"
259 #include "fxp_mul32.h"
261 /*----------------------------------------------------------------------------
263 ; Define module specific macros here
264 ----------------------------------------------------------------------------*/
266 /*----------------------------------------------------------------------------
268 ; Include all pre-processor statements here. Include conditional
269 ; compile variables also.
270 ----------------------------------------------------------------------------*/
272 /*----------------------------------------------------------------------------
273 ; LOCAL FUNCTION DEFINITIONS
274 ; Function Prototype declaration
275 ----------------------------------------------------------------------------*/
277 /*----------------------------------------------------------------------------
278 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
279 ; Variable declaration - defined here and used outside this module
280 ----------------------------------------------------------------------------*/
282 /*----------------------------------------------------------------------------
283 ; EXTERNAL FUNCTION REFERENCES
284 ; Declare functions defined elsewhere and referenced in this module
285 ----------------------------------------------------------------------------*/
287 /*----------------------------------------------------------------------------
288 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
289 ; Declare variables used in this module but defined elsewhere
290 ----------------------------------------------------------------------------*/
292 /*----------------------------------------------------------------------------
294 ----------------------------------------------------------------------------*/
301 const Int lpc_qformat,
303 Int32 scratch_memory[])
314 * Circular buffer to hold the filter's input
316 * (x[n-1],x[n-2],x[n-3],etc.)
318 * This scratch space is necessary, because
319 * the filter's output is returned in-place.
321 * pFilterInput and pLPC should take advantage
322 * of any special circular buffer instructions
323 * if this code is hand-optimized in assembly.
326 Int32 *pFilterInput = scratch_memory;
331 * Pointer to the I/O memory space
337 pCoef += (num_coef - 1);
340 /* Make sure the scratch memory is "clean" */
341 for (i = order; i != 0; i--)
343 *(pFilterInput++) = 0;
348 shift_amt = (lpc_qformat - 5);
350 for (i = num_coef; i > 0; i--)
353 * Copy spectral input into special
354 * filter input buffer.
361 * wrap_point = 0 when this code is
362 * entered for the first iteration of
363 * for(i=num_coef; i>0; i--)
365 * So, this first for-loop will be
366 * skipped when i == num_coef.
369 for (j = wrap_point; j > 0; j--)
371 mult += fxp_mul32_Q31(*(pLPC++), *(pFilterInput++)) >> 5;
373 } /* for (j = wrap_point; j>0; j--) */
376 * pFilterInput has reached &scratch_memory[order-1]
377 * Reset pointer to beginning of filter's state memory
379 pFilterInput = scratch_memory;
381 for (j = (order - wrap_point); j > 0; j--)
383 mult += fxp_mul32_Q31(*(pLPC++), *(pFilterInput++)) >> 5;
385 } /* for (j = wrap_point; j>0; j--) */
389 * Fill the filter's state buffer
390 * avoid obvious casting
392 *(--pFilterInput) = (*pCoef);
395 /* Scale the data down so the output q-format is not adjusted.
397 * Here is an equation, which shows how the spectral coefficients
398 * and lpc coefficients are multiplied and the spectral
399 * coefficient's q-format does not change.
401 * Q-(coef) * Q-(lpc_qformat) >> 5 = Q-(coef + lpc_q_format - 5)
403 * Q-(coef + lpc_q_format - 5) >> (lpc_qformat - 5) = Q-(coef)
406 /* Store output in place */
407 *(pCoef) += (mult >> shift_amt);
409 /* Adjust pointers and placeholders */
414 if (wrap_point == order)
419 } /* for (i = num_coef; i > 0; i--) */
421 } /* tns_inv_filter */