OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / media / libstagefright / codecs / aacdec / tns_inv_filter.cpp
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: tns_inv_filter.c
21
22 ------------------------------------------------------------------------------
23  REVISION HISTORY
24
25  Description: Changes made per review comments.
26
27  Description: As requested by JT, the q-format for the LPC coefficients is
28  now passed via the parameter lpc_qformat.
29
30  Description: For speed, the calculation of the shift amount was pulled
31  outside of the loop.
32
33  Description:
34     Modified casting to ensure proper operations for different platforms
35
36  Description:
37     Simplified MAC operations for filter by eliminating extra variables
38
39  Who:                       Date:
40  Description:
41
42 ------------------------------------------------------------------------------
43  INPUT AND OUTPUT DEFINITIONS
44
45  Inputs:
46
47     coef           = spectral input to be shaped by the filter.
48                      Fixed point format
49                      [Int32[], length = num_coef]
50
51     num_coef       = length of spec array.
52                      [const Int]
53
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])
59                      [const Int]
60
61     lpc            = array of lpc coefficients.
62                      Fixed point format Q-11
63                      [const Int[], length = TNS_MAX_ORDER]
64
65     lpc_qformat    = The q-format of the lpc coefficients.
66                      [const Int]
67
68     order          = order of the TNS filter (Range of 1 : TNS_MAX_ORDER)
69                      [const Int]
70
71     scratch_memory = scratch_memory needed for filter operation
72                      [Int[], length = TNS_MAX_ORDER]
73
74  Local Stores/Buffers/Pointers Needed:
75     None
76
77  Global Stores/Buffers/Pointers Needed:
78     None
79
80  Outputs:
81     None
82
83  Pointers and Buffers Modified:
84     coef = contains spectral data after application of TNS filter
85            q-format is not modified.
86            Int32 array
87            length = num_coef
88
89  Local Stores Modified:
90     None
91
92  Global Stores Modified:
93     None
94
95 ------------------------------------------------------------------------------
96  FUNCTION DESCRIPTION
97
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[])
101
102     TNS filter equation
103         y(n) =  x(n) + lpc(2)*x(n-1) + ... + lpc(order+1)*x(n-order)
104
105     The filter calculation is performed in place, i.e. the output is passed
106     back to the calling function via (Int32 coef[])
107
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.
110
111     The filter's order is defined by the variable (const Int order)
112
113     The direction of the filter's application is defined by
114     (const Int direction)
115
116 ------------------------------------------------------------------------------
117  REQUIREMENTS
118
119     [Int32 coef] must store no more than 16 bits of data.
120
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.
124
125     This function should not be called for order <= 0.
126
127     This function must not be called with lpc_qformat < 5
128 ------------------------------------------------------------------------------
129  REFERENCES
130
131  (1) ISO/IEC 14496-3:1999(E)
132      Part 3
133         Subpart 4.6.6.4.1 (LTP with TNS)
134         Subpart 4.6.8 (Temporal Noise Shaping)
135
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
156    works."
157    Copyright(c)1996.
158
159 ------------------------------------------------------------------------------
160  PSEUDO-CODE
161
162     IF (direction == -1)
163     THEN
164         pCoef = pCoef + (num_coef - 1);
165     END IF
166
167     FOR (i = order; i > 0; i--)
168
169         *(pFilterInput) = 0;
170         pFilterInput = pFilterInput + 1;
171
172     END FOR
173
174     wrap_point = 0;
175
176     shift_amt  = (lpc_qformat - 5);
177
178     FOR (i = num_coef; i > 0; i--)
179
180         pLPC = lpc;
181
182         mult = 0;
183
184         FOR (j = wrap_point; j>0; j--)
185
186            tempInt32 = (Int32)(*(pLPC) * *(pFilterInput));
187            tempInt32 = tempInt32 >> 5;
188
189            mult = mult + tempInt32;
190
191            pFilterInput = pFilterInput + 1;
192            pLPC = pLPC + 1;
193
194         ENDFOR
195
196         pFilterInput = scratch_memory;
197
198         FOR (j = (order - wrap_point); j>0; j--)
199
200            tempInt32 = (Int32)(*(pLPC) * *(pFilterInput));
201            tempInt32 = tempInt32 >> 5;
202
203            mult = mult + tempInt32;
204
205            pFilterInput = pFilterInput + 1;
206            pLPC = pLPC + 1;
207
208         ENDFOR
209
210         pFilterInput = pFilterInput - 1;
211         *(pFilterInput) = (Int)(*pCoef);
212
213         mult = mult >> shift_amt;
214
215         *(pCoef) = *(pCoef) + mult;
216
217         pCoef = pCoef + direction;
218
219         wrap_point = wrap_point + 1;
220
221         IF (wrap_point == order)
222         THEN
223             wrap_point = 0;
224         END IF
225
226     END FOR
227
228 ------------------------------------------------------------------------------
229  RESOURCES USED
230
231    When the code is written for a specific target processor
232      the resources used should be documented below.
233
234  STACK USAGE: [stack count for this module] + [variable to represent
235           stack usage for each subroutine called]
236
237      where: [stack usage variable] = stack usage for [subroutine
238          name] (see [filename].ext)
239
240  DATA MEMORY USED: x words
241
242  PROGRAM MEMORY USED: x words
243
244  CLOCK CYCLES: [cycle count equation for this module] + [variable
245            used to represent cycle count for each subroutine
246            called]
247
248      where: [cycle count variable] = cycle count for [subroutine
249         name] (see [filename].ext)
250
251 ------------------------------------------------------------------------------
252 */
253
254 /*----------------------------------------------------------------------------
255 ; INCLUDES
256 ----------------------------------------------------------------------------*/
257 #include "pv_audio_type_defs.h"
258 #include "tns_inv_filter.h"
259 #include "fxp_mul32.h"
260
261 /*----------------------------------------------------------------------------
262 ; MACROS
263 ; Define module specific macros here
264 ----------------------------------------------------------------------------*/
265
266 /*----------------------------------------------------------------------------
267 ; DEFINES
268 ; Include all pre-processor statements here. Include conditional
269 ; compile variables also.
270 ----------------------------------------------------------------------------*/
271
272 /*----------------------------------------------------------------------------
273 ; LOCAL FUNCTION DEFINITIONS
274 ; Function Prototype declaration
275 ----------------------------------------------------------------------------*/
276
277 /*----------------------------------------------------------------------------
278 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
279 ; Variable declaration - defined here and used outside this module
280 ----------------------------------------------------------------------------*/
281
282 /*----------------------------------------------------------------------------
283 ; EXTERNAL FUNCTION REFERENCES
284 ; Declare functions defined elsewhere and referenced in this module
285 ----------------------------------------------------------------------------*/
286
287 /*----------------------------------------------------------------------------
288 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
289 ; Declare variables used in this module but defined elsewhere
290 ----------------------------------------------------------------------------*/
291
292 /*----------------------------------------------------------------------------
293 ; FUNCTION CODE
294 ----------------------------------------------------------------------------*/
295
296 void tns_inv_filter(
297     Int32 coef[],
298     const Int num_coef,
299     const Int direction,
300     const Int32 lpc[],
301     const Int lpc_qformat,
302     const Int order,
303     Int32 scratch_memory[])
304 {
305
306     Int i;
307     Int j;
308     Int shift_amt;
309     Int wrap_point;
310
311     Int32 mult;
312
313     /*
314      * Circular buffer to hold the filter's input
315      *
316      * (x[n-1],x[n-2],x[n-3],etc.)
317      *
318      * This scratch space is necessary, because
319      * the filter's output is returned in-place.
320      *
321      * pFilterInput and pLPC should take advantage
322      * of any special circular buffer instructions
323      * if this code is hand-optimized in assembly.
324      *
325      */
326     Int32 *pFilterInput = scratch_memory;
327
328     const Int32 *pLPC;
329
330     /*
331      * Pointer to the I/O memory space
332      */
333     Int32 *pCoef = coef;
334
335     if (direction == -1)
336     {
337         pCoef += (num_coef - 1);
338     }
339
340     /* Make sure the scratch memory is "clean" */
341     for (i = order; i != 0; i--)
342     {
343         *(pFilterInput++) = 0;
344     }
345
346     wrap_point = 0;
347
348     shift_amt  = (lpc_qformat - 5);
349
350     for (i = num_coef; i > 0; i--)
351     {
352         /*
353          * Copy spectral input into special
354          * filter input buffer.
355          */
356         pLPC = lpc;
357
358         mult = 0;
359
360         /*
361          * wrap_point = 0 when this code is
362          * entered for the first iteration of
363          * for(i=num_coef; i>0; i--)
364          *
365          * So, this first for-loop will be
366          * skipped when i == num_coef.
367          */
368
369         for (j = wrap_point; j > 0; j--)
370         {
371             mult += fxp_mul32_Q31(*(pLPC++), *(pFilterInput++)) >> 5;
372
373         } /* for (j = wrap_point; j>0; j--) */
374
375         /*
376          * pFilterInput has reached &scratch_memory[order-1]
377          * Reset pointer to beginning of filter's state memory
378          */
379         pFilterInput = scratch_memory;
380
381         for (j = (order - wrap_point); j > 0; j--)
382         {
383             mult += fxp_mul32_Q31(*(pLPC++), *(pFilterInput++)) >> 5;
384
385         } /* for (j = wrap_point; j>0; j--) */
386
387
388         /*
389          * Fill the filter's state buffer
390          * avoid obvious casting
391          */
392         *(--pFilterInput) = (*pCoef);
393
394
395         /* Scale the data down so the output q-format is not adjusted.
396          *
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.
400          *
401          * Q-(coef) * Q-(lpc_qformat) >> 5 = Q-(coef + lpc_q_format - 5)
402          *
403          * Q-(coef + lpc_q_format - 5) >> (lpc_qformat - 5) = Q-(coef)
404          */
405
406         /* Store output in place */
407         *(pCoef) += (mult >> shift_amt);
408
409         /* Adjust pointers and placeholders */
410         pCoef += direction;
411
412         wrap_point++;
413
414         if (wrap_point == order)
415         {
416             wrap_point = 0;
417         }
418
419     } /* for (i = num_coef; i > 0; i--) */
420
421 } /* tns_inv_filter */