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