• 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  Pathname: ./src/fwd_short_complex_rot.c
20  Funtions:  fwd_short_complex_rot
21 
22 ------------------------------------------------------------------------------
23  REVISION HISTORY
24 
25  Date: 10/18/2002
26  Description:
27             (1) Change the input argument, only a single max is passed.
28             (2) Eliminate search for max, a fixed shift has replaced the
29                 search for max with minimal loss of precision.
30             (3) Eliminated unused variables
31 
32  Date: 10/28/2002
33  Description:
34             (1) Added comments per code review
35             (2) Eliminated hardly used condition on if-else (exp==0)
36 
37  Description:
38 
39  ------------------------------------------------------------------------------
40  INPUT AND OUTPUT DEFINITIONS
41 
42  Inputs:
43 
44     Data_in   = Input vector (sized for short windows
45                 2*FWD_SHORT_CX_ROT_LENGTH elements), with freq. domain samples
46                 type Int32 *
47 
48     Data_out  = Output vector with a post-rotation by exp(-j(2pi/N)(k+1/8)),
49                 (sized for short windows 2*FWD_SHORT_CX_ROT_LENGTH)
50                 type Int32 *
51 
52     max       = Input, carries the maximum value of the input vector
53                 "Data_in"
54                 type Int32
55 
56 
57  Local Stores/Buffers/Pointers Needed:
58     None
59 
60  Global Stores/Buffers/Pointers Needed:
61     None
62 
63  Outputs:
64     exp = shift factor to reflect signal scaling
65 
66  Pointers and Buffers Modified:
67     Results are return in "Data_out"
68 
69  Local Stores Modified:
70     None
71 
72  Global Stores Modified:
73     None
74 ------------------------------------------------------------------------------
75  FUNCTION DESCRIPTION
76 
77     fwd_short_complex_rot() performs the complex rotation for the MDCT
78     for the case of short windows. It performs digit reverse ordering as well
79     word normalization to ensure 16 by 16 bit multiplications.
80 
81 ------------------------------------------------------------------------------
82  REQUIREMENTS
83 
84     fwd_short_complex_rot() should execute a pre-rotation by
85     exp(-j(2pi/N)(k+1/8)), digit reverse ordering and word normalization
86 ------------------------------------------------------------------------------
87  REFERENCES
88 
89 ------------------------------------------------------------------------------
90  RESOURCES USED
91    When the code is written for a specific target processor the
92      the resources used should be documented below.
93 
94  STACK USAGE: [stack count for this module] + [variable to represent
95           stack usage for each subroutine called]
96 
97      where: [stack usage variable] = stack usage for [subroutine
98          name] (see [filename].ext)
99 
100  DATA MEMORY USED: x words
101 
102  PROGRAM MEMORY USED: x words
103 
104  CLOCK CYCLES: [cycle count equation for this module] + [variable
105            used to represent cycle count for each subroutine
106            called]
107 
108      where: [cycle count variable] = cycle count for [subroutine
109         name] (see [filename].ext)
110 
111 ------------------------------------------------------------------------------
112 */
113 
114 
115 /*----------------------------------------------------------------------------
116 ; INCLUDES
117 ----------------------------------------------------------------------------*/
118 
119 #include "fwd_short_complex_rot.h"
120 #include "digit_reversal_tables.h"
121 #include "imdct_fxp.h"
122 #include "pv_normalize.h"
123 
124 
125 /*----------------------------------------------------------------------------
126 ; MACROS
127 ; Define module specific macros here
128 ----------------------------------------------------------------------------*/
129 
130 /*----------------------------------------------------------------------------
131 ; DEFINES
132 ; Include all pre-processor statements here. Include conditional
133 ; compile variables also.
134 ----------------------------------------------------------------------------*/
135 
136 /*----------------------------------------------------------------------------
137 ; LOCAL FUNCTION DEFINITIONS
138 ; Function Prototype declaration
139 ----------------------------------------------------------------------------*/
140 
141 /*----------------------------------------------------------------------------
142 ; LOCAL VARIABLE DEFINITIONS
143 ; Variable declaration - defined here and used outside this module
144 ----------------------------------------------------------------------------*/
145 
146 /*----------------------------------------------------------------------------
147 ; EXTERNAL FUNCTION REFERENCES
148 ; Declare functions defined elsewhere and referenced in this module
149 ----------------------------------------------------------------------------*/
150 
151 /*----------------------------------------------------------------------------
152 ; EXTERNAL VARIABLES REFERENCES
153 ; Declare variables used in this module but defined elsewhere
154 ----------------------------------------------------------------------------*/
155 
fwd_short_complex_rot(Int32 * Data_in,Int32 * Data_out,Int32 max)156 Int fwd_short_complex_rot(
157     Int32 *Data_in,
158     Int32 *Data_out,
159     Int32  max)
160 
161 {
162     Int     i;
163     Int16     I;
164     const   Int16 *pTable;
165     const   Int32 *p_rotate;
166 
167     Int32   *pData_in_1;
168     Int     exp;
169     Int32   temp_re;
170     Int32   temp_im;
171 
172     Int32   cos_n;
173     Int32   sin_n;
174     Int32   temp_re_32;
175     Int32   temp_im_32;
176 
177     Int32   *pData_in_ref;
178 
179     Int32   *pData_out_1;
180     Int32   *pData_out_2;
181     Int32   *pData_out_3;
182     Int32   *pData_out_4;
183 
184     pTable    =  digit_reverse_64;
185     p_rotate  =  exp_rotation_N_256;
186 
187     pData_in_ref  =  Data_in;
188 
189     exp = 16 - pv_normalize(max);
190 
191     if (exp < 0)
192     {
193         exp = 0;
194     }
195 
196     pData_out_1 = Data_out;
197     pData_out_2 = &Data_out[TWICE_FWD_SHORT_CX_ROT_LENGTH_m_1];
198     pData_out_3 = &Data_out[TWICE_FWD_SHORT_CX_ROT_LENGTH];
199     pData_out_4 = &Data_out[FOUR_FWD_SHORT_CX_ROT_LENGTH_m_1];
200 
201     /*
202      *  Data_out
203      *                                   >>>>                   <<<<
204      *                                pData_out_3             pData_out_4
205      *      |             |             |             |             |
206      * pData_out_1               pData_out_2
207      *      >>>>                     <<<<
208      */
209 
210 
211     for (i = FWD_SHORT_CX_ROT_LENGTH; i != 0; i--)
212     {
213         /*
214          *   Perform digit reversal by accessing index I from table
215          */
216 
217         I = *pTable++;
218         pData_in_1 = pData_in_ref + I;
219 
220         /*
221          * cos_n + j*sin_n == exp(j(2pi/N)(k+1/8))
222          */
223 
224         sin_n = *p_rotate++;
225         cos_n = sin_n >> 16;
226         sin_n = sin_n & 0xFFFF;
227 
228         /*
229          *  Use auxiliary variables to avoid double accesses to memory.
230          *  Data in is scaled to use only lower 16 bits.
231          */
232 
233         temp_re =  *(pData_in_1++) >> exp;
234         temp_im =  *(pData_in_1) >> exp;
235 
236         /*
237          *   Pre-rotation
238          */
239 
240         temp_re_32 = (temp_re * cos_n + temp_im * sin_n) >> 16;
241         temp_im_32 = (temp_im * cos_n - temp_re * sin_n) >> 16;
242 
243         *(pData_out_1++) = - temp_re_32;
244         *(pData_out_2--) =   temp_im_32;
245         *(pData_out_3++) = - temp_im_32;
246         *(pData_out_4--) =   temp_re_32;
247 
248         /*
249          *   Pointer increment to jump over imag (1 & 4) or real parts
250          *   (2 & 3)
251          */
252 
253         pData_out_1++;
254         pData_out_2--;
255         pData_out_3++;
256         pData_out_4--;
257 
258     } /* for(i) */
259 
260     return (exp);
261 }
262