• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /*
19 
20  Pathname: ./src/fwd_long_complex_rot.c
21  Funtions: fwd_long_complex_rot
22 
23 ------------------------------------------------------------------------------
24  REVISION HISTORY
25 
26  Date: 10/18/2002
27  Description:
28             (1) Change the input arguments, no shifts information from
29                 long_fft_rx4 is passed, only a single max is passed.
30             (2) Eliminate search for max, a fixed shift has replaced the
31                 search for max with minimal loss of precision.
32             (3) Eliminated unused variables
33 
34  Date: 10/28/2002
35  Description:
36             (1) Added comments per code review
37             (2) Eliminated hardly used condition on if-else (exp==0)
38 
39  Description:
40 
41  ------------------------------------------------------------------------------
42  INPUT AND OUTPUT DEFINITIONS
43 
44  Inputs:
45 
46     Data_in   = Input vector (sized for long windows
47                 TWICE_FWD_LONG_CX_ROT_LENGTH), with time domain samples
48                 type Int32 *
49 
50     Data_out  = Output vector with a post-rotation by exp(-j(2pi/N)(k+1/8)),
51                 (sized for long windows TWICE_FWD_LONG_CX_ROT_LENGTH)
52                 type Int32 *
53 
54     max       = Input, carries the maximum value of the input vector
55                 "Data_in"
56                 type Int32
57 
58 
59  Local Stores/Buffers/Pointers Needed:
60     None
61 
62  Global Stores/Buffers/Pointers Needed:
63     None
64 
65  Outputs:
66     exp = shift factor to reflect signal scaling
67 
68  Pointers and Buffers Modified:
69     Results are return in "Data_out"
70 
71  Local Stores Modified:
72     None
73 
74  Global Stores Modified:
75     None
76 ------------------------------------------------------------------------------
77  FUNCTION DESCRIPTION
78 
79     fwd_long_complex_rot() performs the pre complex rotation for the MDCT
80     for the case of long windows. It also performs digit reverse ordering of
81     the first and second halves of the input vector "Data_in", as well as
82     reordering of the two half vectors (following radix-2 decomposition)
83     Word normalization is also done to ensure 16 by 16 bit multiplications.
84 
85 ------------------------------------------------------------------------------
86  REQUIREMENTS
87 
88     fwd_long_complex_rot() should execute a pre-rotation by
89     exp(-j(2pi/N)(k+1/8)), digit reverse ordering and normalization
90 ------------------------------------------------------------------------------
91  REFERENCES
92 
93 ------------------------------------------------------------------------------
94  RESOURCES USED
95    When the code is written for a specific target processor the
96      the resources used should be documented below.
97 
98  STACK USAGE: [stack count for this module] + [variable to represent
99           stack usage for each subroutine called]
100 
101      where: [stack usage variable] = stack usage for [subroutine
102          name] (see [filename].ext)
103 
104  DATA MEMORY USED: x words
105 
106  PROGRAM MEMORY USED: x words
107 
108  CLOCK CYCLES: [cycle count equation for this module] + [variable
109            used to represent cycle count for each subroutine
110            called]
111 
112      where: [cycle count variable] = cycle count for [subroutine
113         name] (see [filename].ext)
114 
115 ------------------------------------------------------------------------------
116 */
117 
118 
119 /*----------------------------------------------------------------------------
120 ; INCLUDES
121 ----------------------------------------------------------------------------*/
122 
123 #include "fwd_long_complex_rot.h"
124 #include "digit_reversal_tables.h"
125 #include "imdct_fxp.h"
126 #include "pv_normalize.h"
127 
128 #include "fxp_mul32.h"
129 
130 /*----------------------------------------------------------------------------
131 ; MACROS
132 ; Define module specific macros here
133 ----------------------------------------------------------------------------*/
134 
135 /*----------------------------------------------------------------------------
136 ; DEFINES
137 ; Include all pre-processor statements here. Include conditional
138 ; compile variables also.
139 ----------------------------------------------------------------------------*/
140 
141 /*----------------------------------------------------------------------------
142 ; LOCAL FUNCTION DEFINITIONS
143 ; Function Prototype declaration
144 ----------------------------------------------------------------------------*/
145 
146 /*----------------------------------------------------------------------------
147 ; LOCAL VARIABLE DEFINITIONS
148 ; Variable declaration - defined here and used outside this module
149 ----------------------------------------------------------------------------*/
150 
151 /*----------------------------------------------------------------------------
152 ; EXTERNAL FUNCTION REFERENCES
153 ; Declare functions defined elsewhere and referenced in this module
154 ----------------------------------------------------------------------------*/
155 
156 /*----------------------------------------------------------------------------
157 ; EXTERNAL VARIABLES REFERENCES
158 ; Declare variables used in this module but defined elsewhere
159 ----------------------------------------------------------------------------*/
160 
fwd_long_complex_rot(Int32 * Data_in,Int32 * Data_out,Int32 max)161 Int fwd_long_complex_rot(
162     Int32 *Data_in,
163     Int32 *Data_out,
164     Int32  max)
165 {
166     Int     i;
167     const   Int32 *p_rotate;
168     Int32   temp_re;
169     Int32   temp_im;
170     Int32   *pData_in_ref1;
171     Int32   *pData_in_ref2;
172     Int32   exp_jw;
173     Int32   temp_re_32;
174     Int32   temp_im_32;
175 
176     Int32   *pData_out_1;
177     Int32   *pData_out_2;
178     Int32   *pData_out_3;
179     Int32   *pData_out_4;
180 
181     Int32 *pData_in_1;
182     Int32 *pData_in_2;
183 
184     Int     exp;
185 
186     p_rotate       =  exp_rotation_N_2048;
187 
188     pData_in_ref1  =  Data_in;
189     pData_in_ref2  = &Data_in[TWICE_FWD_LONG_CX_ROT_LENGTH];
190 
191     pData_out_1 = Data_out;
192     pData_out_2 = &Data_out[LONG_WINDOW_LENGTH_m_1];
193     pData_out_3 = &Data_out[LONG_WINDOW_LENGTH];
194     pData_out_4 = &Data_out[TWICE_LONG_WINDOW_LENGTH_m_1];
195 
196     /*
197      *  Data_out
198      *                                   >>>>                   <<<<
199      *                                pData_out_3             pData_out_4
200      *      |             |             |             |             |
201      * pData_out_1               pData_out_2
202      *      >>>>                     <<<<
203      */
204 
205 
206     exp = 16 - pv_normalize(max);
207 
208     if (exp < 0)
209     {
210         exp = 0;
211     }
212 
213     /*
214      *  Apply  A/2^(diff) + B
215      */
216 
217 
218     pData_in_1 = pData_in_ref1;
219     pData_in_2 = pData_in_ref2;
220 
221     for (i = FWD_LONG_CX_ROT_LENGTH; i != 0; i--)
222     {
223 
224         /*
225          * cos_n + j*sin_n == exp(j(2pi/N)(k+1/8))
226          */
227 
228         exp_jw = *p_rotate++;
229 
230         /*
231          *  Use auxiliary variables to avoid double accesses to memory.
232          *  Data in is scaled to use only lower 16 bits.
233          */
234 
235         temp_re =  *(pData_in_1++) >> exp;
236         temp_im =  *(pData_in_1++) >> exp;
237 
238         /*
239          *   Pre-rotation
240          */
241 
242         temp_re_32  = (cmplx_mul32_by_16(temp_re,   temp_im,  exp_jw));
243         temp_im_32  = (cmplx_mul32_by_16(temp_im,  -temp_re,  exp_jw));
244 
245         *(pData_out_1++) = - temp_re_32;
246         *(pData_out_2--) =   temp_im_32;
247         *(pData_out_3++) = - temp_im_32;
248         *(pData_out_4--) =   temp_re_32;
249 
250         /*
251          *   Pointer increment to jump over imag (1 & 4) or real parts
252          *   (2 & 3)
253          */
254         pData_out_1++;
255         pData_out_2--;
256         pData_out_3++;
257         pData_out_4--;
258 
259         /*
260          *   Repeat procedure for odd index at the output
261          */
262 
263         exp_jw = *p_rotate++;
264 
265         temp_re =  *(pData_in_2++) >> exp;
266         temp_im =  *(pData_in_2++) >> exp;
267 
268         temp_re_32  = (cmplx_mul32_by_16(temp_re,   temp_im,  exp_jw));
269         temp_im_32  = (cmplx_mul32_by_16(temp_im,  -temp_re,  exp_jw));
270 
271         *(pData_out_1++) = - temp_re_32;
272         *(pData_out_2--) =   temp_im_32;
273         *(pData_out_3++) = - temp_im_32;
274         *(pData_out_4--) =   temp_re_32;
275 
276         pData_out_1++;
277         pData_out_2--;
278         pData_out_3++;
279         pData_out_4--;
280 
281     }
282 
283     return (exp + 1);
284 }
285