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: ./src/fft_rx4_short.c
21dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Funtions: fft_rx4_short
22dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
23dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
24dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber REVISION HISTORY
25dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
26dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:
27dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            (1) Eliminated search for max in the main loop.
28dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            (2) Simplified the function by eliminating different conditions
29dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                for exp.
30dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            (3) Reduced precision on w_64rx4 from Q15 to Q12, so now the
31dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                input can be as high as 1.0 and saturation will not occurre
32dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                because the accumulation times the new Q12 format will never
33dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                exceed 31 bits.
34dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
35dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:
36dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            (1) Added comment to explain max search elimination and
37dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                Q format during multiplications
38dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            (2) Increased down shift from 1 to 2, to ensure that 32-bit
39dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                numbers will not overflow when 2 consecutive adds are done
40dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                This was found during code review.
41dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
42dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Who:                                   Date:
43dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Description:
44dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
45dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
46dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber INPUT AND OUTPUT DEFINITIONS
47dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
48dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Inputs:
49dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Data       =  Input complex vector, arranged in the following order:
50dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                  real, imag, real, imag...
51dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                  This is a complex vector whose elements (real and Imag) are
52dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                  Int32.
53dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                  type Int32 *
54dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
55dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    peak_value =  Input,  peak value of the input vector
56dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                  Output,  peak value of the resulting vector
57dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                  type Int32 *
58dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
59dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Local Stores/Buffers/Pointers Needed:
60dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    None
61dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
62dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Global Stores/Buffers/Pointers Needed:
63dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    None
64dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
65dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Outputs:
66dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    exponent returns a shift to compensate the scaling introduced by
67dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    overflow protection
68dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
69dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Pointers and Buffers Modified:
70dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    calculation are done in-place and returned in Data
71dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
72dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Local Stores Modified:
73dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    None
74dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
75dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber Global Stores Modified:
76dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    None
77dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
78dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
79dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber FUNCTION DESCRIPTION
80dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
81dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Fast Fourier Transform, radix 4 with Decimation in Frequency and block
82dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    floating point arithmetic.
83dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    The radix-4 FFT  simply divides the FFT into four smaller FFTs. Each of
84dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    the smaller FFTs is then further divided into smaller ones and so on.
85dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    It consists of log 4 N stages and each stage consists of N/4 dragonflies.
86dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
87dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    An FFT is nothing but a bundle of multiplications and summations which
88dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    may overflow during calculations.
89dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
90dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
91dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    This routine uses a scheme to test and scale the result output from
92dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    each FFT stage in order to fix the accumulation overflow.
93dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
94dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    The Input Data should be in Q13 format to get the highest precision.
95dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    At the end of each dragonfly calculation, a test for possible bit growth
96dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    is made, if bit growth is possible the Data is scale down back to Q13.
97dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
98dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
99dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
100dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber REQUIREMENTS
101dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
102dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    This function should provide a fixed point FFT for an input array
103dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    of size 64.
104dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
105dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
106dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber REFERENCES
107dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
108dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    [1] Advance Digital Signal Processing, J. Proakis, C. Rader, F. Ling,
109dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        C. Nikias, Macmillan Pub. Co.
110dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
111dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
112dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber PSEUDO-CODE
113dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
114dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
115dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   MODIFY( x[] )
116dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   RETURN( exponent )
117dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
118dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
119dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber RESOURCES USED
120dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber   When the code is written for a specific target processor the
121dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     the resources used should be documented below.
122dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
123dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber STACK USAGE: [stack count for this module] + [variable to represent
124dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber          stack usage for each subroutine called]
125dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
126dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     where: [stack usage variable] = stack usage for [subroutine
127dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber         name] (see [filename].ext)
128dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
129dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber DATA MEMORY USED: x words
130dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
131dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber PROGRAM MEMORY USED: x words
132dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
133dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber CLOCK CYCLES: [cycle count equation for this module] + [variable
134dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber           used to represent cycle count for each subroutine
135dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber           called]
136dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
137dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber     where: [cycle count variable] = cycle count for [subroutine
138dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        name] (see [filename].ext)
139dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
140dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber------------------------------------------------------------------------------
141dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber*/
142dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
143dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; INCLUDES
144dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
145dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
146dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber#include "pv_audio_type_defs.h"
147dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber#include "fft_rx4.h"
148dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber#include "pv_normalize.h"
149dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber#include "fxp_mul32.h"
150dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
151dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
152dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; MACROS
153dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; Define module specific macros here
154dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
155dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
156dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
157dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; DEFINES
158dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; Include all pre-processor statements here. Include conditional
159dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; compile variables also.
160dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
161dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
162dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
163dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; LOCAL FUNCTION DEFINITIONS
164dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; Function Prototype declaration
165dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
166dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
167dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
168dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; LOCAL VARIABLE DEFINITIONS
169dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; Variable declaration - defined here and used outside this module
170dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
171dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
172dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
173dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; EXTERNAL FUNCTION REFERENCES
174dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; Declare functions defined elsewhere and referenced in this module
175dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
176dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
177dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
178dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; EXTERNAL VARIABLES REFERENCES
179dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; Declare variables used in this module but defined elsewhere
180dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
181dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
182dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
183dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
184dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; Declare variables used in this module but defined elsewhere
185dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
186dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
187dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber/*----------------------------------------------------------------------------
188dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber; FUNCTION CODE
189dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber----------------------------------------------------------------------------*/
190dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
191dacaa73ae5010b66f4224d70a520945e5b653544Andreas HuberInt fft_rx4_short(
192dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32      Data[],
193dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32      *peak_value)
194dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
195dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber{
196dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int     n1;
197dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int     n2;
198dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int     n3;
199dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int     j;
200dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int     k;
201dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int     i;
202dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   exp_jw1;
203dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   exp_jw2;
204dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   exp_jw3;
205dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
206dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
207dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   t1;
208dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   t2;
209dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   r1;
210dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   r2;
211dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   r3;
212dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   s1;
213dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   s2;
214dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   s3;
215dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
216dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   *pData1;
217dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   *pData2;
218dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   *pData3;
219dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   *pData4;
220dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    const Int32  *pw;
221dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   temp1;
222dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   temp2;
223dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   temp3;
224dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   temp4;
225dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int32   max;
226dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int     exp;
227dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int     exponent = 0;
228dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    Int     shift;
229dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
230dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
231dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    max = *peak_value;
232dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    exp = 0;
233dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
234dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    if (max > 0x008000)
235dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    {
236dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        exp = 8 - pv_normalize(max);   /* use 24 bits  */
237dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
238dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        exponent = exp;        /* keeps track of # of shifts */
239dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
240dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    }
241dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
242dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    n2 = FFT_RX4_SHORT;
243dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
244dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    pw = W_64rx4;
245dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
246dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
247dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    /* shift down to avoid possible overflow in first pass of the loop */
248dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    shift = 2;
249dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
250dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    for (k = FFT_RX4_SHORT; k > 4; k >>= 2)
251dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    {
252dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
253dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        n1 = n2;
254dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        n2 >>= 2;
255dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        n3 = n1 >> 1;
256dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
257dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        exp -= 2;
258dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
259dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        for (i = 0; i < FFT_RX4_SHORT; i += n1)
260dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        {
261dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            pData1 = &Data[ i<<1];
262dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            pData3 = pData1 + n3;
263dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            pData2 = pData1 + n1;
264dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            pData4 = pData3 + n1;
265dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
266dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp1   = *(pData1);
267dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp2   = *(pData2);
268dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp1   >>= shift;
269dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp2   >>= shift;
270dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
271dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            r1      = temp1 + temp2;
272dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            r2      = temp1 - temp2;
273dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
274dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp3   = *(pData3++);
275dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp4   = *(pData4++);
276dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp3   >>= shift;
277dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp4   >>= shift;
278dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
279dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            t1      = temp3 + temp4;
280dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            t2      = temp3 - temp4;
281dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
282dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            *(pData1++) = (r1 + t1) >> exp;
283dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            *(pData2++) = (r1 - t1) >> exp;
284dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
285dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp1   = *pData1;
286dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp2   = *pData2;
287dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp1   >>= shift;
288dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp2   >>= shift;
289dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
290dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            s1      = temp1 + temp2;
291dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            s2      = temp1 - temp2;
292dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
293dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp3   = *pData3;
294dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp4   = *pData4;
295dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp3   >>= shift;
296dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            temp4   >>= shift;
297dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
298dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            t1      = temp3 + temp4;
299dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            r1      = temp3 - temp4;
300dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
301dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            *pData1   = (s1 + t1) >> exp;
302dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            *pData2   = (s1 - t1) >> exp;
303dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
304dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            *pData4--    = (s2 + t2) >> exp;
305dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            *pData4      = (r2 - r1) >> exp;
306dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
307dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            *pData3--    = (s2 - t2) >> exp;
308dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            *pData3      = (r2 + r1) >> exp;
309dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
310dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
311dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        }  /* i */
312dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
313dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        for (j = 1; j < n2; j++)
314dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        {
315dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            exp_jw1 = *pw++;
316dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            exp_jw2 = *pw++;
317dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            exp_jw3 = *pw++;
318dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
319dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
320dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            for (i = j; i < FFT_RX4_SHORT; i += n1)
321dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            {
322dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                pData1 = &Data[ i<<1];
323dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                pData3 = pData1 + n3;
324dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                pData2 = pData1 + n1;
325dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                pData4 = pData3 + n1;
326dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
327dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp1   = *(pData1);
328dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp2   = *(pData2++);
329dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp1   >>= shift;
330dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp2   >>= shift;
331dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
332dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                r1      = temp1 + temp2;
333dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                r2      = temp1 - temp2;
334dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp3   = *(pData3++);
335dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp4   = *(pData4++);
336dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp3   >>= shift;
337dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp4   >>= shift;
338dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
339dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                t1      = temp3 + temp4;
340dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                t2      = temp3 - temp4;
341dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
342dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                *(pData1++) = (r1 + t1) >> exp;
343dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                r1          = (r1 - t1) >> exp;
344dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
345dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp1   = *pData1;
346dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp2   = *pData2;
347dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp1   >>= shift;
348dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp2   >>= shift;
349dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
350dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                s1      = temp1 + temp2;
351dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                s2      = temp1 - temp2;
352dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
353dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                s3      = (s2 + t2) >> exp;
354dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                s2      = (s2 - t2) >> exp;
355dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
356dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp3   = *pData3;
357dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp4   = *pData4 ;
358dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp3   >>= shift;
359dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                temp4   >>= shift;
360dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
361dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                t1      = temp3 + temp4;
362dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                t2      = temp3 - temp4;
363dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
364dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                *pData1  = (s1 + t1) >> exp;
365dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                s1       = (s1 - t1) >> exp;
366dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
367dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
368dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                *pData2--  = cmplx_mul32_by_16(s1, -r1, exp_jw2) << 1;
369dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                *pData2    = cmplx_mul32_by_16(r1,  s1, exp_jw2) << 1;
370dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
371dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                r3       = ((r2 - t2) >> exp);
372dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                r2       = ((r2 + t2) >> exp);
373dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
374dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                *pData3--  = cmplx_mul32_by_16(s2, -r2, exp_jw1) << 1;
375dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                *pData3    = cmplx_mul32_by_16(r2,  s2, exp_jw1) << 1;
376dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
377dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                *pData4--  = cmplx_mul32_by_16(s3, -r3, exp_jw3) << 1;
378dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber                *pData4    = cmplx_mul32_by_16(r3,  s3, exp_jw3) << 1;
379dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
380dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber            }  /* i */
381dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
382dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        }  /*  j */
383dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
384dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        /*
385dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber         *  this will reset exp and shift to zero for the second pass of the
386dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber         *  loop
387dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber         */
388dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        exp   = 2;
389dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        shift = 0;
390dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
391dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    } /* k */
392dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
393dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
394dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    max = 0;
395dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
396dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    pData1 = Data - 7;
397dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
398dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    for (i = ONE_FOURTH_FFT_RX4_SHORT; i != 0 ; i--)
399dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    {
400dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        pData1 += 7;
401dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
402dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        pData3 = pData1 + 2;
403dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        pData2 = pData1 + 4;
404dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        pData4 = pData1 + 6;
405dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
406dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        temp1   = *pData1;
407dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        temp2   = *pData2++;
408dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
409dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        r1      = temp1 + temp2;
410dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        r2      = temp1 - temp2;
411dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
412dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        temp1   = *pData3++;
413dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        temp2   = *pData4++;
414dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
415dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        t1      = temp1 + temp2;
416dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        t2      = temp1 - temp2;
417dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
418dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        temp1       = (r1 + t1);
419dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        r1          = (r1 - t1);
420dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        *(pData1++) = temp1;
421dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        max        |= (temp1 >> 31) ^ temp1;
422dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
423dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
424dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
425dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        temp1   = *pData1;
426dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        temp2   = *pData2;
427dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
428dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        s1      = temp1 + temp2;
429dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        s2      = temp1 - temp2;
430dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
431dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        s3      = (s2 + t2);
432dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        s2      = (s2 - t2);
433dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
434dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        temp1   = *pData3;
435dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        temp2   = *pData4;
436dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
437dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        t1      = temp1 + temp2;
438dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        t2      = temp1 - temp2;
439dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
440dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        temp1      = (s1 + t1);
441dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        temp2      = (s1 - t1);
442dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        *pData1    = temp1;
443dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        *pData2--  = temp2;
444dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        max       |= (temp1 >> 31) ^ temp1;
445dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        max       |= (temp2 >> 31) ^ temp2;
446dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
447dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        *pData2    = r1;
448dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        *pData3--  = s2;
449dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        *pData4--  = s3;
450dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        max       |= (r1 >> 31) ^ r1;
451dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        max       |= (s2 >> 31) ^ s2;
452dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        max       |= (s3 >> 31) ^ s3;
453dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
454dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        temp1      = (r2 - t2);
455dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        temp2      = (r2 + t2);
456dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        *pData4    = temp1;
457dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        *pData3    = temp2;
458dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        max       |= (temp1 >> 31) ^ temp1;
459dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber        max       |= (temp2 >> 31) ^ temp2;
460dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
461dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    }  /* i */
462dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
463dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    *peak_value = max;
464dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
465dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
466dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber    return (exponent);
467dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber
468dacaa73ae5010b66f4224d70a520945e5b653544Andreas Huber}
469