1dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/* ------------------------------------------------------------------
2dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber * Copyright (C) 1998-2009 PacketVideo
3dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber *
4dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber * you may not use this file except in compliance with the License.
6dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber * You may obtain a copy of the License at
7dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber *
8dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber *
10dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber * Unless required by applicable law or agreed to in writing, software
11dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber * express or implied.
14dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber * See the License for the specific language governing permissions
15dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber * and limitations under the License.
16dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber * -------------------------------------------------------------------
17dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber */
18dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*
19dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
20dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Pathname: tns_ar_filter.c
21dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
22dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
23dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber REVISION HISTORY
24dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
25dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:  Modified from original shareware code
26dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
27dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:  Implemented 24-bit fixed point version
28dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber               Optimized C code
29dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
30dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:
31dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            - Added OVERFLOW_SHIFT_DOWN to avoid overflow.
32dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            - Increased precision by using the Q format of the LPC coefficient.
33dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            - Modified interface to add LPC Q format and scratch memory
34dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber              for the state variables.
35dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            - Added pv_memset to clear state filter
36dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            - Updated format for comments (to PV standard)
37dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            - Updated copyright notice
38dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
39dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:
40dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            - Changed multiplication scheme to increase precision. This
41dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber              works better than older version.
42dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
43dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:
44dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            - Include log2(order) as a scaling down parameter.
45dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
46dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:
47dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            Modified to reflect code review comments
48dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                - misspelled words, extra comments and explicit requirements
49dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
50dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:
51dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            deleted comment about fix Q format (L 107)
52dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
53dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:  Implemented a more efficient version, which eliminated the use
54dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber of "scratch memory" via introducing a pointer that references the actual
55dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber output.
56dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
57dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description: Removed the parameter "scratch_Int32_buffer" as this space
58dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber in memory is no longer needed by this function.
59dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
60dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description: Removed references to "scratch_Int32_buffer" in the Inputs
61dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber section.
62dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
63dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:
64dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Modified casting to ensure proper operations for different platforms
65dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
66dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:
67dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Per code review comment:
68dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Eliminated casting to UInt and Int in b_low and b_high, they are
69dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    redundant and may add unncessary extra cycles in some platforms
70dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
71dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description: Updated the SW template to include the full pathname to the
72dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber source file and a slightly modified copyright header.
73dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
74dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description: Changed the order of the unsigned * signed multiply so the
75dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber casting to Int32 is performed on the unsigned operand.
76dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
77dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:
78dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Modified 32 by 16 bit multiplications to avoid unnecessary moves to
79dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    registers. Also split the code (based on flag direction) to simplify
80dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    pointer's updates
81dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
82dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:
83dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
84dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
85dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber INPUT AND OUTPUT DEFINITIONS
86dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
87dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Inputs:
88dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    spec  = spectral input to be shaped by the filter.
89dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            Fixed point format
90dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            Int32[]
91dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            length = spec_length
92dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
93dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    spec_length  = length of spec array.
94dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            const Int
95dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
96dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    direction = direction for application of tns filter.
97dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                +1  filters spectrum from low to high frequencies
98dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                    (first input to filter is spec[0])
99dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                -1  filters spectrum from high to low frequencies
100dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                    (first input to filter is spec[spec_length-1])
101dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                const Int
102dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
103dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    lpc   = array of lpc coefficients, minus lpc[0] which is assumed to be "1"
104dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            Fixed point format
105dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            const Int[]
106dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            length = TNS_MAX_ORDER
107dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
108dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Q_lpc = Q format for the lpc coeffcients (for max. precision, it assumes
109dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            that all 16 bits are used)
110dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            const Int
111dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
112dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    order = order of the TNS filter (Range of 1 - TNS_MAX_ORDER)
113dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            Int
114dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
115dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Local Stores/Buffers/Pointers Needed:
116dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    None
117dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
118dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Global Stores/Buffers/Pointers Needed:
119dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    None
120dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
121dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Outputs:
122dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    None
123dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
124dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Pointers and Buffers Modified:
125dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    spec = contains spectral data after application of TNS filter
126dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber           Int32 array
127dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber           length = spec_length
128dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
129dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
130dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Local Stores Modified:
131dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
132dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Global Stores Modified:
133dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
134dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
135dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
136dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber FUNCTION DESCRIPTION
137dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
138dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    A block of spectral data (Int32 spec[]) of length (const Int spec_length)
139dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    is processed by a simple all-pole filter defined by
140dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    LPC coefficients passed via (const Int lpc[])
141dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
142dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    TNS filter equation
143dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        y(n) =  x(n) - lpc(2)*y(n-1) - ... - lpc(order+1)*y(n-order)
144dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
145dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    The filter calculation is performed in place, i.e. the output is passed
146dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    back to the calling function via (Int32 spec[])
147dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
148dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    The filter's order is defined by the variable (const Int order)
149dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    The direction of the filter's application is defined by (const Int inc)
150dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
151dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
152dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber REQUIREMENTS
153dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
154dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    This function should match the functionality of the ISO code.
155dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    The implementation does support filter orders bigger or equal to 1.
156dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    The size of the spectral coeffcients has to be bigger or equal than 1.
157dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
158dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
159dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber REFERENCES
160dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
161dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber (1) ISO/IEC 14496-3:1999(E)
162dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     Part 3
163dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        Subpart 4.6.8 (Temporal Noise Shaping)
164dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
165dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber (2) MPEG-2 NBC Audio Decoder
166dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   "This software module was originally developed by AT&T, Dolby
167dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   Laboratories, Fraunhofer Gesellschaft IIS in the course of development
168dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and
169dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   3. This software module is an implementation of a part of one or more
170dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
171dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   Audio standard. ISO/IEC  gives users of the MPEG-2 NBC/MPEG-4 Audio
172dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   standards free license to this software module or modifications thereof
173dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   for use in hardware or software products claiming conformance to the
174dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   MPEG-2 NBC/MPEG-4 Audio  standards. Those intending to use this software
175dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   module in hardware or software products are advised that this use may
176dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   infringe existing patents. The original developer of this software
177dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   module and his/her company, the subsequent editors and their companies,
178dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   and ISO/IEC have no liability for use of this software module or
179dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   modifications thereof in an implementation. Copyright is not released
180dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original
181dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   developer retains full right to use the code for his/her  own purpose,
182dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   assign or donate the code to a third party and to inhibit third party
183dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products.
184dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   This copyright notice must be included in all copies or derivative
185dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   works."
186dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   Copyright(c)1996.
187dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
188dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
189dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber PSEUDO-CODE
190dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
191dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
192dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    FOR (i=0; i<order; i++)
193dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        state[i] = 0;
194dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    ENDFOR
195dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
196dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    IF (inc == -1)
197dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    THEN
198dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        spec = spec + spec_length - 1;
199dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    ENDIF
200dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
201dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    FOR (i=0; i<spec_length; i++)
202dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
203dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        y = *spec;
204dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
205dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        FOR (j=0; j<order; j++)
206dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
207dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            y -= lpc[j] * state[j];
208dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
209dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        ENDFOR
210dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
211dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        FOR (j=order-1; j>0; j--)
212dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
213dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            state[j] = state[j-1];
214dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
215dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        ENDFOR
216dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
217dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        state[0] = y;
218dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
219dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        *spec = y;
220dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
221dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        spec = spec + inc;
222dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
223dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    ENDFOR
224dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
225dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
226dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
227dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber RESOURCES USED
228dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
229dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   When the code is written for a specific target processor
230dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     the resources used should be documented below.
231dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
232dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber STACK USAGE: [stack count for this module] + [variable to represent
233dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber          stack usage for each subroutine called]
234dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
235dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     where: [stack usage variable] = stack usage for [subroutine
236dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber         name] (see [filename].ext)
237dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
238dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber DATA MEMORY USED: x words
239dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
240dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber PROGRAM MEMORY USED: x words
241dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
242dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber CLOCK CYCLES: [cycle count equation for this module] + [variable
243dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber           used to represent cycle count for each subroutine
244dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber           called]
245dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
246dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     where: [cycle count variable] = cycle count for [subroutine
247dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        name] (see [filename].ext)
248dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
249dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
250dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber*/
251dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
252dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
253dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; INCLUDES
254dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
255dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber#include "pv_audio_type_defs.h"
256dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber#include "e_tns_const.h"
257dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber#include "tns_ar_filter.h"
258dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber#include "fxp_mul32.h"
259dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
260dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
261dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; MACROS
262dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; Define module specific macros here
263dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
264dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
265dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
266dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; DEFINES
267dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; Include all pre-processor statements here. Include conditional
268dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; compile variables also.
269dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
270dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber#define MASK_LOW16               0xFFFF
271dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber#define UPPER16                      16
272dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
273dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
274dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; LOCAL FUNCTION DEFINITIONS
275dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; Function Prototype declaration
276dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
277dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
278dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
279dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; LOCAL STORE/BUFFER/POINTER DEFINITIONS
280dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; Variable declaration - defined here and used outside this module
281dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
282dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
283dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
284dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; EXTERNAL FUNCTION REFERENCES
285dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; Declare functions defined elsewhere and referenced in this module
286dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
287dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
288dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
289dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
290dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; Declare variables used in this module but defined elsewhere
291dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
292dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
293dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
294dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; FUNCTION CODE
295dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
296dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
297dacaa73ae5010b66f4224d70a520945e5b653544Andreas HuberInt tns_ar_filter(
298dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32 spec[],
299dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    const Int spec_length,
300dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    const Int direction,
301dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    const Int32 lpc[],
302dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    const Int Q_lpc,
303dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    const Int order)
304dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber{
305dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
306dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int i;
307dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int j;
308dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
309dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    /*
310dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     * Multiplication related variables
311dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     */
312dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
313dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32 temp;
314dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
315dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    /*
316dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *  Filter related variables
317dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     */
318dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32 y0;
319dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
320dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    /*
321dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *  Circular buffer to hold the filter's state
322dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *  (y[n-1],y[n-2],y[n-3],etc.)
323dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *
324dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *  p_state and p_lpc should take advantage
325dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *  of any special circular buffer instructions
326dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *  if this code is hand-optimized in assembly.
327dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     */
328dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
329dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32 *p_state = NULL;
330dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
331dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    const Int32 *p_lpc;
332dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
333dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
334dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int shift_up;
335dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int shift_down_amount;
336dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
337dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    /*
338dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *  Pointer to the I/O memory space
339dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     */
340dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32 *p_spec = spec;
341dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
342dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
343dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    i = 0;
344dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    j = order;
345dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
346dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    /*
347dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *  get the power of 2 that is bigger than the order
348dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *  i is the bit counter and j is modified until exceed
349dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *  the power of 2 corresponding to TNS_MAX_ORDER
350dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     */
351dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
352dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    while (j < 0x010)
353dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    {
354dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        j <<= 1;
355dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        i++;
356dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    }
357dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
358dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    /*
359dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *  5 is the number of bits needed to represent 0x010
360dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *  TNS_MAX_ORDER = 20, power of 2 that include 20 is 5
361dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     */
362dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    shift_down_amount = 4 - i;
363dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
364dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    shift_up = UPPER16 - Q_lpc;
365dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
366dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    /*
367dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     *  shift_down_amount == power of 2 that is bigger than the order - 1
368dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     */
369dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
370dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    shift_down_amount += shift_up;
371dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
372dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    if (direction == -1)
373dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    {
374dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        p_spec += spec_length - 1;
375dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
376dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        for (i = order; i != 0; i--)
377dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        {
378dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
379dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            y0 = *p_spec >> shift_down_amount;
380dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
381dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            p_lpc = lpc;
382dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
383dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            /* 32 by 32 bit multiplication */
384dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            for (j = order; j > i; j--)
385dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            {
386dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp = *p_state++;
387dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                y0 -= fxp_mul32_Q31(temp, *(p_lpc++)) << shift_up;
388dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            }
389dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
390dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            /*
391dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            * Record the output in-place
392dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            */
393dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            p_state     = p_spec;
394dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            *(p_spec--) = y0;
395dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
396dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        }
397dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
398dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        if (spec_length > order)
399dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        {
400dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            for (i = (spec_length - order); i != 0; i--)
401dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            {
402dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                y0 = *p_spec >> shift_down_amount;
403dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
404dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                p_lpc = &(lpc[0]);
405dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
406dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                /* 32 by 32 bit multiplication */
407dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                for (j = order; j != 0; j--)
408dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                {
409dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                    temp = *p_state++;
410dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                    y0 -= fxp_mul32_Q31(temp, *(p_lpc++)) << shift_up;
411dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                }
412dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
413dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                /*
414dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                 * Record the output in-place
415dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                 */
416dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                p_state     = p_spec;
417dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                *(p_spec--) = y0;
418dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
419dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            } /* END for (i = (spec_length - order); i>0; i--) */
420dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        }
421dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
422dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    }
423dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    else
424dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    {
425dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        for (i = order; i != 0; i--)
426dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        {
427dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
428dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            p_lpc =  lpc;
429dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
430dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            y0 = 0;
431dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
432dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            /* 32 by 32 bit multiplication */
433dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            for (j = order; j > i; j--)
434dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            {
435dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                y0 -= fxp_mul32_Q31(*p_state--, *(p_lpc++));
436dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            }
437dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
438dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            p_state     = p_spec;
439dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            /*
440dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            * Record the output in-place
441dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            */
442dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            *(p_spec) = (*p_spec >> shift_down_amount) + (y0 << shift_up);
443dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            p_spec++;
444dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        }
445dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
446dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        if (spec_length > order)
447dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        {
448dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            for (i = (spec_length - order); i != 0; i--)
449dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            {
450dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                p_lpc =  lpc;
451dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
452dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                y0 = 0;
453dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
454dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                /* 32 by 32 bit multiplication */
455dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                for (j = order; j != 0; j--)
456dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                {
457dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                    y0 -= fxp_mul32_Q31(*p_state--, *(p_lpc++));
458dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                }
459dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
460dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                p_state     = p_spec;
461dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                /*
462dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                 * Record the output in-place
463dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                 */
464dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                *(p_spec) = (*p_spec >> shift_down_amount) + (y0 << shift_up);
465dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                p_spec++;
466dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
467dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            } /* END for (i = (spec_length - order); i>0; i--) */
468dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        }
469dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    }
470dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
471dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    return(shift_down_amount);
472dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
473dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
474dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber} /* tns_ar_filter */
475