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: fft_rx8.c 21 Funtions: ps_fft_rx8 22 23 ------------------------------------------------------------------------------ 24 REVISION HISTORY 25 26 27 28 Who: Date: 29 Description: 30 31 ------------------------------------------------------------------------------ 32 INPUT AND OUTPUT DEFINITIONS 33 34 Inputs: 35 Real Vector of Real components size 8 36 37 Imag Vector of Imag components size 8 38 type Int32 39 40 41 Local Stores/Buffers/Pointers Needed: 42 None 43 44 Global Stores/Buffers/Pointers Needed: 45 scratch_mem size 32 46 47 Outputs: 48 In-place calculation of a 8-point FFT (radix-8) 49 50 Pointers and Buffers Modified: 51 calculation are done in-place and returned in Data 52 53 Local Stores Modified: 54 None 55 56 Global Stores Modified: 57 None 58 59 ------------------------------------------------------------------------------ 60 FUNCTION DESCRIPTION 61 62 8-point DFT, radix 8 with Decimation in Frequency 63 64 ------------------------------------------------------------------------------ 65 REQUIREMENTS 66 67 This function should provide a fixed point FFT for any input array 68 of size power of 8. 69 70 ------------------------------------------------------------------------------ 71 REFERENCES 72 73 [1] Advance Digital Signal Processing, J. Proakis, C. Rader, F. Ling, 74 C. Nikias, Macmillan Pub. Co. 75 76 ------------------------------------------------------------------------------ 77 PSEUDO-CODE 78 79 80 MODIFY( x[] ) 81 RETURN( exponent ) 82 83 ------------------------------------------------------------------------------ 84 RESOURCES USED 85 When the code is written for a specific target processor the 86 the resources used should be documented below. 87 88 STACK USAGE: [stack count for this module] + [variable to represent 89 stack usage for each subroutine called] 90 91 where: [stack usage variable] = stack usage for [subroutine 92 name] (see [filename].ext) 93 94 DATA MEMORY USED: x words 95 96 PROGRAM MEMORY USED: x words 97 98 CLOCK CYCLES: [cycle count equation for this module] + [variable 99 used to represent cycle count for each subroutine 100 called] 101 102 where: [cycle count variable] = cycle count for [subroutine 103 name] (see [filename].ext) 104 105 ------------------------------------------------------------------------------ 106 */ 107 /*---------------------------------------------------------------------------- 108 ; INCLUDES 109 ----------------------------------------------------------------------------*/ 110 111 #ifdef AAC_PLUS 112 113 114 #ifdef PARAMETRICSTEREO 115 116 117 #include "pv_audio_type_defs.h" 118 #include "ps_fft_rx8.h" 119 120 #include "fxp_mul32.h" 121 122 /*---------------------------------------------------------------------------- 123 ; MACROS 124 ; Define module specific macros here 125 ----------------------------------------------------------------------------*/ 126 127 /*---------------------------------------------------------------------------- 128 ; DEFINES 129 ; Include all pre-processor statements here. Include conditional 130 ; compile variables also. 131 ----------------------------------------------------------------------------*/ 132 #define R_SHIFT 29 133 #define Q29_fmt(x) (Int32)(x*((Int32)1<<R_SHIFT) + (x>=0?0.5F:-0.5F)) 134 135 /*---------------------------------------------------------------------------- 136 ; LOCAL FUNCTION DEFINITIONS 137 ; Function Prototype declaration 138 ----------------------------------------------------------------------------*/ 139 140 /*---------------------------------------------------------------------------- 141 ; LOCAL VARIABLE DEFINITIONS 142 ; Variable declaration - defined here and used outside this module 143 ----------------------------------------------------------------------------*/ 144 145 /*---------------------------------------------------------------------------- 146 ; EXTERNAL FUNCTION REFERENCES 147 ; Declare functions defined elsewhere and referenced in this module 148 ----------------------------------------------------------------------------*/ 149 150 /*---------------------------------------------------------------------------- 151 ; EXTERNAL VARIABLES REFERENCES 152 ; Declare variables used in this module but defined elsewhere 153 ----------------------------------------------------------------------------*/ 154 155 /*---------------------------------------------------------------------------- 156 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 157 ; Declare variables used in this module but defined elsewhere 158 ----------------------------------------------------------------------------*/ 159 160 /*---------------------------------------------------------------------------- 161 ; FUNCTION CODE 162 ----------------------------------------------------------------------------*/ 163 164 void ps_fft_rx8(Int32 Re[], Int32 Im[], Int32 scratch_mem[]) 165 166 /* scratch_mem size 32 */ 167 { 168 169 Int i; 170 Int32 *Q = &scratch_mem[0]; 171 Int32 *Z = &scratch_mem[16]; 172 Int32 temp1; 173 Int32 temp2; 174 Int32 temp3; 175 Int32 temp4; 176 Int32 aux_r[2]; 177 Int32 aux_i[2]; 178 Int32 *pt_r1 = &Re[0]; 179 Int32 *pt_r2 = &Re[4]; 180 Int32 *pt_i1 = &Im[0]; 181 Int32 *pt_i2 = &Im[4]; 182 183 Int32 *pt_Q = Q; 184 Int32 *pt_Z = Z; 185 186 187 temp1 = *(pt_r1++); /* Real */ 188 temp2 = *(pt_r2++); /* Real */ 189 temp3 = *(pt_i1++); /* Imag */ 190 temp4 = *(pt_i2++); /* Imag */ 191 /* 192 * Vector Q stores data as Real, Imag, Real, Imag,.... 193 */ 194 195 *(pt_Q++) = temp1 + temp2; /* Q(0) = v(0) + v(4) */ 196 *(pt_Q++) = temp3 + temp4; 197 *(pt_Q++) = temp1 - temp2; /* Q(1) = v(0) - v(4) */ 198 *(pt_Q++) = temp3 - temp4; 199 200 temp1 = *(pt_r1++); 201 temp2 = *(pt_r2++); 202 temp3 = *(pt_i1++); 203 temp4 = *(pt_i2++); 204 205 *(pt_Q++) = temp1 + temp2; /* Q(2) = v(1) + v(5) */ 206 *(pt_Q++) = temp3 + temp4; 207 aux_r[0] = temp1 - temp2; /* aux[0] = v(1) - v(5) */ 208 aux_i[0] = temp3 - temp4; 209 210 temp1 = *(pt_r1++); 211 temp2 = *(pt_r2++); 212 temp3 = *(pt_i1++); 213 temp4 = *(pt_i2++); 214 215 *(pt_Q++) = temp1 + temp2; /* Q(3) = v(2) + v(6) */ 216 *(pt_Q++) = temp3 + temp4; 217 *(pt_Q++) = temp4 - temp3; /* Q(4) = (v(2) - v(6))*j */ 218 *(pt_Q++) = temp1 - temp2; 219 220 temp1 = *(pt_r1++); 221 temp2 = *(pt_r2++); 222 temp3 = *(pt_i1++); 223 temp4 = *(pt_i2++); 224 225 226 *(pt_Q++) = temp1 + temp2; /* Q(5) = v(3) + v(7) */ 227 *(pt_Q++) = temp3 + temp4; 228 aux_r[1] = temp1 - temp2; /* aux[1] = v(3) - v(7) */ 229 aux_i[1] = temp3 - temp4; 230 /* Q(6) = (aux[0] - aux[1])/sqrt(2); */ 231 *(pt_Q++) = fxp_mul32_Q29((aux_r[0] - aux_r[1]), Q29_fmt(0.70710678118655f)); 232 *(pt_Q++) = fxp_mul32_Q29((aux_i[0] - aux_i[1]), Q29_fmt(0.70710678118655f)); 233 234 /* Q(7) = (aux[0] + aux[1])*j/sqrt(2); */ 235 *(pt_Q++) = fxp_mul32_Q29((aux_i[0] + aux_i[1]), Q29_fmt(-0.70710678118655f)); 236 *(pt_Q) = fxp_mul32_Q29((aux_r[0] + aux_r[1]), Q29_fmt(0.70710678118655f)); 237 238 pt_r1 = &Q[0]; /* reset pointer */ 239 pt_r2 = &Q[6]; /* reset pointer */ 240 241 temp1 = *(pt_r1++); 242 temp2 = *(pt_r2++); 243 temp3 = *(pt_r1++); 244 temp4 = *(pt_r2++); 245 246 /* 247 * Vector Z stores data as Real, Imag, Real, Imag,.... 248 */ 249 250 *(pt_Z++) = temp1 + temp2; /* Q(0) + Q(3) */ 251 *(pt_Z++) = temp3 + temp4; 252 aux_r[0] = temp1 - temp2; 253 aux_i[0] = temp3 - temp4; 254 255 temp1 = *(pt_r1++); 256 temp2 = *(pt_r2++); 257 temp3 = *(pt_r1++); 258 temp4 = *(pt_r2++); 259 260 *(pt_Z++) = temp1 + temp2; /* Q(1) + Q(4) */ 261 *(pt_Z++) = temp3 + temp4; 262 *(pt_Z++) = aux_r[0]; /* Q(0) - Q(3) */ 263 *(pt_Z++) = aux_i[0]; 264 *(pt_Z++) = temp1 - temp2; /* Q(1) - Q(4) */ 265 *(pt_Z++) = temp3 - temp4; 266 267 temp1 = *(pt_r1++); 268 temp2 = *(pt_r2++); 269 temp3 = *(pt_r1); 270 temp4 = *(pt_r2++); 271 272 *(pt_Z++) = temp1 + temp2; /* Q(2) + Q(5) */ 273 *(pt_Z++) = temp3 + temp4; 274 aux_r[0] = temp1 - temp2; 275 aux_i[0] = temp3 - temp4; 276 277 temp1 = *(pt_r2++); 278 temp3 = *(pt_r2++); 279 temp2 = *(pt_r2++); 280 temp4 = *(pt_r2); 281 282 *(pt_Z++) = temp1 + temp2; /* Q(6) + Q(7) */ 283 *(pt_Z++) = temp3 + temp4; 284 285 *(pt_Z++) = -aux_i[0]; /* (Q(2) - Q(5))*j */ 286 *(pt_Z++) = aux_r[0]; 287 288 *(pt_Z++) = temp2 - temp1; /* -Q(6) + Q(7) */ 289 *(pt_Z) = temp4 - temp3; 290 291 pt_Z = &Z[0]; /* reset pointer */ 292 pt_Q = &Z[8]; /* reset pointer */ 293 294 pt_r1 = &Re[0]; 295 pt_r2 = &Re[4]; 296 pt_i1 = &Im[0]; 297 pt_i2 = &Im[4]; 298 299 300 for (i = 4; i != 0; i--) 301 { 302 temp1 = *(pt_Z++); 303 temp2 = *(pt_Q++); 304 temp3 = *(pt_Z++); 305 temp4 = *(pt_Q++); 306 307 *(pt_r1++) = temp1 + temp2; /* Z(n) + Z(n+4) */ 308 *(pt_i1++) = temp3 + temp4; 309 *(pt_r2++) = temp1 - temp2; /* Z(n) - Z(n+4) */ 310 *(pt_i2++) = temp3 - temp4; 311 } 312 313 } 314 315 #endif /* PARAMETRICSTEREO */ 316 317 318 #endif /* AAC_PLUS */ 319