• 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: .inv_long_complex_rot.c
21  Funtions:  inv_long_complex_rot
22 
23 ------------------------------------------------------------------------------
24  REVISION HISTORY
25 
26  Description:  Change the input argument, no shifts information from long fft_rx4
27                , do not have to check for shifts.
28 
29  Date: 10/18/2002
30  Description:
31             (1) Change the input argument, only a single max is passed.
32             (2) Eliminate search for max, a fixed shift has replaced the
33                 search for max with minimal loss of precision.
34             (3) Eliminated unused variables
35 
36  Date: 10/28/2002
37  Description:
38             (1) Added comments per code review
39 
40  Description:
41 
42  ------------------------------------------------------------------------------
43  INPUT AND OUTPUT DEFINITIONS
44 
45  Inputs:
46 
47     Data_in   = Input vector (sized for long windows
48                 TWICE_INV_LONG_CX_ROT_LENGTH), with time domain samples
49                 type Int32 *
50 
51     Data_out  = Output vector with a post-rotation by exp(j(2pi/N)(k+1/8)),
52                 (sized for long windows TWICE_INV_LONG_CX_ROT_LENGTH)
53                 type Int32 *
54 
55     max       = Input, carries the maximum value of the input vector
56                 "Data_in"
57                 type Int32
58 
59 
60  Local Stores/Buffers/Pointers Needed:
61     None
62 
63  Global Stores/Buffers/Pointers Needed:
64     None
65 
66  Outputs:
67     exp = shift factor to reflect signal scaling
68 
69  Pointers and Buffers Modified:
70     Results are return in "Data_out"
71 
72  Local Stores Modified:
73     None
74 
75  Global Stores Modified:
76     None
77 ------------------------------------------------------------------------------
78  FUNCTION DESCRIPTION
79 
80     inv_long_complex_rot() performs the complex rotation for the inverse MDCT
81     for the case of long windows. It also performs digit reverse ordering of
82     the first and second halves of the input vector "Data_in", as well as
83     reordering of the two half vectors (following radix-2 decomposition)
84     Word normalization is also done to ensure 16 by 16 bit multiplications.
85 
86 ------------------------------------------------------------------------------
87  REQUIREMENTS
88 
89     inv_long_complex_rot() should execute a post-rotation by
90     exp(-j(2pi/N)(k+1/8)), digit reverse ordering and word normalization
91 
92 ------------------------------------------------------------------------------
93  REFERENCES
94 
95 ------------------------------------------------------------------------------
96  RESOURCES USED
97    When the code is written for a specific target processor the
98      the resources used should be documented below.
99 
100  STACK USAGE: [stack count for this module] + [variable to represent
101           stack usage for each subroutine called]
102 
103      where: [stack usage variable] = stack usage for [subroutine
104          name] (see [filename].ext)
105 
106  DATA MEMORY USED: x words
107 
108  PROGRAM MEMORY USED: x words
109 
110  CLOCK CYCLES: [cycle count equation for this module] + [variable
111            used to represent cycle count for each subroutine
112            called]
113 
114      where: [cycle count variable] = cycle count for [subroutine
115         name] (see [filename].ext)
116 
117 ------------------------------------------------------------------------------
118 */
119 /*----------------------------------------------------------------------------
120 ; INCLUDES
121 ----------------------------------------------------------------------------*/
122 
123 #include "digit_reversal_tables.h"
124 #include "inv_long_complex_rot.h"
125 #include "imdct_fxp.h"
126 #include "inv_long_complex_rot.h"
127 #include "pv_normalize.h"
128 
129 #include "fxp_mul32.h"
130 #include "aac_mem_funcs.h"
131 
132 /*----------------------------------------------------------------------------
133 ; MACROS
134 ; Define module specific macros here
135 ----------------------------------------------------------------------------*/
136 
137 /*----------------------------------------------------------------------------
138 ; DEFINES
139 ; Include all pre-processor statements here. Include conditional
140 ; compile variables also.
141 ----------------------------------------------------------------------------*/
142 
143 /*----------------------------------------------------------------------------
144 ; LOCAL FUNCTION DEFINITIONS
145 ; Function Prototype declaration
146 ----------------------------------------------------------------------------*/
147 
148 /*----------------------------------------------------------------------------
149 ; LOCAL VARIABLE DEFINITIONS
150 ; Variable declaration - defined here and used outside this module
151 ----------------------------------------------------------------------------*/
152 
153 /*----------------------------------------------------------------------------
154 ; EXTERNAL FUNCTION REFERENCES
155 ; Declare functions defined elsewhere and referenced in this module
156 ----------------------------------------------------------------------------*/
157 
158 /*----------------------------------------------------------------------------
159 ; EXTERNAL VARIABLES REFERENCES
160 ; Declare variables used in this module but defined elsewhere
161 ----------------------------------------------------------------------------*/
162 
163 
164 
inv_long_complex_rot(Int32 * Data,Int32 max)165 Int inv_long_complex_rot(
166     Int32 *Data,
167     Int32  max)
168 {
169     Int     i;
170     Int16     I;
171     const   Int32 *p_rotate;
172     Int32   temp_re;
173     Int32   temp_im;
174 
175     Int32    exp_jw;
176     Int32   *pData_in_1;
177     Int32   *pData_in_2;
178     Int     exp;
179     Int32   *pData_in_ref1;
180     Int32   *pData_in_ref2;
181 
182 
183     Int16   temp_re_0;
184     Int16   temp_im_0;
185     Int16   temp_re_1;
186     Int16   temp_im_1;
187     Int16   *p_Data_Int_precision;
188     Int     n     = 2048;
189     Int     n_2   = n >> 1;
190     Int     n_4   = n >> 2;
191     Int     n_3_4 = n_2 + n_4;
192 
193     Int16   *px_1;
194     Int16   *px_2;
195     Int16   *px_3;
196     Int16   *px_4;
197 
198     Int16     J;
199     const   Int32 *p_rotate2;
200 
201 
202 
203 
204     p_rotate    =  &exp_rotation_N_2048[255];
205     p_rotate2   =  &exp_rotation_N_2048[256];
206 
207     pData_in_ref1  =  Data;
208     pData_in_ref2  = &Data[TWICE_INV_LONG_CX_ROT_LENGTH];
209 
210 
211     /*
212      *  Apply  A/2^(diff) + B
213      */
214 
215     p_Data_Int_precision = (Int16 *)Data;
216 
217     exp = 16 - pv_normalize(max);
218 
219 
220     /*
221      *        px2-->               <--px1 px4-->               <--px3
222      *
223      *                     |                           |             |
224      *       |+++++++++++++|+++++++++++++|+++++++++++++|+++++++++++++|
225      *                     |             |             |             |
226      *                    n/4           n/2          3n/4
227      */
228 
229     I = 255;
230     J = 256;
231 
232     pData_in_1 = pData_in_ref2 + I;
233 
234     px_1 = (Int16 *)pData_in_1;
235     px_1++;
236 
237     pData_in_2 = pData_in_ref2 + J;
238 
239     px_4 = (Int16 *)pData_in_2;
240 
241 
242 
243     exp -= 1;
244 
245 
246     for (i = INV_LONG_CX_ROT_LENGTH >> 1; i != 0; i--)
247     {
248 
249         pData_in_2 = pData_in_ref1 + J;
250 
251         temp_im =  *(pData_in_2++);
252         temp_re =  *(pData_in_2);
253 
254 
255         /*
256          * cos_n + j*sin_n == exp(j(2pi/N)(k+1/8))
257          */
258         exp_jw = *p_rotate2++;
259 
260         /*
261          *   Post-rotation
262          */
263 
264 
265 
266         temp_re_0  = (Int16)(cmplx_mul32_by_16(temp_re,  -temp_im,  exp_jw) >> exp);
267         temp_im_0  = (Int16)(cmplx_mul32_by_16(temp_im,   temp_re,  exp_jw) >> exp);
268 
269 
270         pData_in_1 = pData_in_ref2 + I;
271 
272         /*
273          *  Use auxiliary variables to avoid double accesses to memory.
274          *  Data in is scaled to use only lower 16 bits.
275          */
276 
277         temp_re =  *(pData_in_1--);
278         temp_im =  *(pData_in_1);
279 
280         /*
281          * cos_n + j*sin_n == exp(j(2pi/N)(k+1/8))
282          */
283         exp_jw = *p_rotate--;
284 
285 
286         /*
287          *   Post-rotation
288          */
289 
290         temp_re_1  = (Int16)(cmplx_mul32_by_16(temp_re,  -temp_im,  exp_jw) >> exp);
291         temp_im_1  = (Int16)(cmplx_mul32_by_16(temp_im,   temp_re,  exp_jw) >> exp);
292 
293 
294         /*
295          *   Repeat procedure for odd index at the output
296          */
297 
298         pData_in_2 = pData_in_ref2 + J;
299         J += 2;
300 
301         temp_im =  *(pData_in_2++);
302         temp_re =  *(pData_in_2);
303 
304 
305         *(px_1--) =  temp_re_0;
306         *(px_1--) =  temp_im_1;
307         *(px_4++) =  temp_im_0;
308         *(px_4++) =  temp_re_1;
309 
310 
311         exp_jw = *p_rotate2++;
312 
313 
314         *(px_1--)  = (Int16)(cmplx_mul32_by_16(temp_re,  -temp_im,  exp_jw) >> exp);
315         *(px_4++)  = (Int16)(cmplx_mul32_by_16(temp_im,   temp_re,  exp_jw) >> exp);
316 
317 
318 
319         /*
320          *   Repeat procedure for odd index at the output
321          */
322 
323         pData_in_1 = pData_in_ref1 + I;
324         I -= 2;
325 
326         temp_re =  *(pData_in_1--);
327         temp_im =  *(pData_in_1);
328 
329 
330         exp_jw = *p_rotate--;
331 
332 
333         *(px_4++)  = (Int16)(cmplx_mul32_by_16(temp_re,  -temp_im,  exp_jw) >> exp);
334         *(px_1--)  = (Int16)(cmplx_mul32_by_16(temp_im,   temp_re,  exp_jw) >> exp);
335 
336     }
337 
338     /*
339      *                                           <--px1 px4-->
340      *
341      *                     |                           |             |
342      *       |-------------|-------------|/////////////|\\\\\\\\\\\\\|
343      *                     |             |             |             |
344      *                    n/4           n/2          3n/4
345      */
346 
347 
348     px_1 = p_Data_Int_precision + n_2 - 1;
349     px_2 = p_Data_Int_precision;
350 
351     px_4 = p_Data_Int_precision + n_3_4 - 1;
352 
353     for (i = 0; i<INV_LONG_CX_ROT_LENGTH >> 1; i++)
354     {
355 
356         Int16 temp_re_0 = *(px_4--);
357         Int16 temp_im_1 = *(px_4--);
358         Int16 temp_re_2 = *(px_4--);
359         Int16 temp_im_3 = *(px_4--);
360         *(px_1--) = temp_re_0;
361         *(px_1--) = temp_im_1;
362         *(px_1--) = temp_re_2;
363         *(px_1--) = temp_im_3;
364 
365         *(px_2++) = (-temp_re_0);
366         *(px_2++) = (-temp_im_1);
367         *(px_2++) = (-temp_re_2);
368         *(px_2++) = (-temp_im_3);
369 
370     }
371 
372 
373     px_4 = p_Data_Int_precision + n_2;
374 
375 
376     pv_memcpy(px_4, pData_in_ref2 + 256, TWICE_INV_LONG_CX_ROT_LENGTH*sizeof(*px_4));
377 
378 
379 
380     /*
381      *        px2-->               <--px1 px4-->               <--px3
382      *
383      *                     |                           |             |
384      *       |+++++++++++++|+++++++++++++|+++++++++++++|+++++++++++++|
385      *                     |             |             |             |
386      *                    n/4           n/2          3n/4
387      */
388     px_3 = p_Data_Int_precision + n - 1;
389 
390 
391     for (i = 0; i<INV_LONG_CX_ROT_LENGTH >> 1; i++)
392     {
393 
394         Int16 temp_im_0 = *(px_4++);
395         Int16 temp_re_1 = *(px_4++);
396         Int16 temp_im_2 = *(px_4++);
397         Int16 temp_re_3 = *(px_4++);
398         *(px_3--) =  temp_im_0;
399         *(px_3--) =  temp_re_1;
400         *(px_3--) =  temp_im_2;
401         *(px_3--) =  temp_re_3;
402 
403     }
404 
405 
406     return (exp + 1);
407 }
408 
409