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