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 156Int 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