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: mdct_fxp.c 21 Funtions: fft_rx2 22 23 ------------------------------------------------------------------------------ 24 INPUT AND OUTPUT DEFINITIONS 25 26 Inputs: 27 data_quant = Input vector, with quantized Q15 spectral lines: 28 type Int32 29 30 Q_FFTarray = Scratch memory used for in-place IFFT calculation, 31 min size required 1024, type Int32 32 33 n = Length of input vector "data_quant". Currently 256 or 2048. 34 type const Int 35 36 Local Stores/Buffers/Pointers Needed: 37 None 38 39 Global Stores/Buffers/Pointers Needed: 40 None 41 42 Outputs: 43 shift = shift factor to reflect scaling introduced by FFT and mdct_fxp, 44 45 Pointers and Buffers Modified: 46 calculation are done in-place and returned in "data_quant" 47 48 Local Stores Modified: 49 None 50 51 Global Stores Modified: 52 None 53 54 ------------------------------------------------------------------------------ 55 FUNCTION DESCRIPTION 56 57 The MDCT is a linear orthogonal lapped transform, based on the idea of 58 time domain aliasing cancellation (TDAC). 59 MDCT is critically sampled, which means that though it is 50% overlapped, 60 a sequence data after MDCT has the same number of coefficients as samples 61 before the transform (after overlap-and-add). This means, that a single 62 block of MDCT data does not correspond to the original block on which the 63 MDCT was performed. When subsequent blocks of data are added (still using 64 50% overlap), the errors introduced by the transform cancels out. 65 Thanks to the overlapping feature, the MDCT is very useful for 66 quantization. It effectively removes the otherwise easily detectable 67 blocking artifact between transform blocks. 68 N = length of input vector X 69 X = vector of length N/2, will hold fixed point DCT 70 k = 0:1:N-1 71 72 N-1 73 X(m) = 2 SUM x(k)*cos(pi/(2*N)*(2*k+1+N/2)*(2*m+1)) 74 k=0 75 76 77 The window that completes the TDAC is applied before calling this function. 78 The MDCT can be calculated using an FFT, for this, the MDCT needs to be 79 rewritten as an odd-time odd-frequency discrete Fourier transform. Thus, 80 the MDCT can be calculated using only one n/4 point FFT and some pre and 81 post-rotation of the sample points. 82 83 Computation of the MDCT implies computing 84 85 x = ( y - y ) + j( y + y ) 86 n 2n N/2-1-2n N-1-2n N/2+2n 87 88 using the Fast discrete cosine transform as described in [2] 89 90 where x(n) is an input with N points 91 92 x(n) ---------------------------- 93 | 94 | 95 Pre-rotation by exp(j(2pi/N)(n+1/8)) 96 | 97 | 98 N/4- point FFT 99 | 100 | 101 Post-rotation by exp(j(2pi/N)(k+1/8)) 102 | 103 | 104 ------------- DCT 105 106 By considering the N/2 overlap, a relation between successive input blocks 107 is found: 108 109 x (2n) = x (N/2 + 2n) 110 m+1 m 111 ------------------------------------------------------------------------------ 112 REQUIREMENTS 113 114 This function should provide a fixed point MDCT with an average 115 quantization error less than 1 %. 116 117 ------------------------------------------------------------------------------ 118 REFERENCES 119 120 [1] Analysis/Synthesis Filter Bank design based on time domain 121 aliasing cancellation 122 Jhon Princen, et. al. 123 IEEE Transactions on ASSP, vol ASSP-34, No. 5 October 1986 124 Pg 1153 - 1161 125 126 [2] Regular FFT-related transform kernels for DCT/DST based 127 polyphase filterbanks 128 Rolf Gluth 129 Proc. ICASSP 1991, pg. 2205 - 2208 130 131 ------------------------------------------------------------------------------ 132 PSEUDO-CODE 133 134 Cx, Cy are complex number 135 136 137 exp = log2(n)-1 138 139 FOR ( k=0; k< n/4; k +=2) 140 141 Cx = (data_quant[3n/4 + k] + data_quant[3n/4 - 1 - k]) + 142 j (data_quant[ n/4 + k] - data_quant[ n/4 - 1 - k]) 143 144 Q_FFTarray = Cx * exp(-j(2pi/n)(k+1/8)) 145 146 ENDFOR 147 148 FOR ( k=n/4; k< n/2; k +=2) 149 150 Cx = (data_quant[3n/4 - 1 - k] + data_quant[ - n/4 + k]) + 151 j (data_quant[5n/4 - 1 - k] - data_quant[ n/4 + k]) 152 153 Q_FFTarray = Cx * exp(-j(2pi/n)(k+1/8)) 154 155 ENDFOR 156 157 CALL FFT( Q_FFTarray, n/4) 158 159 MODIFYING( Q_FFTarray ) 160 161 RETURNING( shift ) 162 163 FOR ( k=0; k< n/2; k +=2) 164 165 Cx = Q_FFTarray[ k] + j Q_FFTarray[ k+1] 166 167 Cy = 2 * Cx * exp(-j(2pi/n)(k+1/8)) 168 169 data_quant[ k ] = - Real(Cy) 170 data_quant[ n/2 - 1 - k ] = Imag(Cy) 171 data_quant[ n/2 + k ] = - Imag(Cy) 172 data_quant[ n - k ] = Real(Cy) 173 174 ENDFOR 175 176 MODIFIED data_quant[] 177 178 RETURN (-shift-1) 179 180 ------------------------------------------------------------------------------ 181 RESOURCES USED 182 When the code is written for a specific target processor the 183 the resources used should be documented below. 184 185 STACK USAGE: [stack count for this module] + [variable to represent 186 stack usage for each subroutine called] 187 188 where: [stack usage variable] = stack usage for [subroutine 189 name] (see [filename].ext) 190 191 DATA MEMORY USED: x words 192 193 PROGRAM MEMORY USED: x words 194 195 CLOCK CYCLES: [cycle count equation for this module] + [variable 196 used to represent cycle count for each subroutine 197 called] 198 199 where: [cycle count variable] = cycle count for [subroutine 200 name] (see [filename].ext) 201 202 ------------------------------------------------------------------------------ 203 */ 204 205 206 /*---------------------------------------------------------------------------- 207 ; INCLUDES 208 ----------------------------------------------------------------------------*/ 209 210 #include "pv_audio_type_defs.h" 211 #include "mdct_fxp.h" 212 #include "fft_rx4.h" 213 #include "mix_radix_fft.h" 214 #include "fwd_long_complex_rot.h" 215 #include "fwd_short_complex_rot.h" 216 217 218 /*---------------------------------------------------------------------------- 219 ; MACROS 220 ; Define module specific macros here 221 ----------------------------------------------------------------------------*/ 222 223 /*---------------------------------------------------------------------------- 224 ; DEFINES 225 ; Include all pre-processor statements here. Include conditional 226 ; compile variables also. 227 ----------------------------------------------------------------------------*/ 228 #define ERROR_IN_FRAME_SIZE 10 229 230 231 /*---------------------------------------------------------------------------- 232 ; LOCAL FUNCTION DEFINITIONS 233 ; Function Prototype declaration 234 ----------------------------------------------------------------------------*/ 235 236 /*---------------------------------------------------------------------------- 237 ; LOCAL VARIABLE DEFINITIONS 238 ; Variable declaration - defined here and used outside this module 239 ----------------------------------------------------------------------------*/ 240 241 242 /*---------------------------------------------------------------------------- 243 ; EXTERNAL FUNCTION REFERENCES 244 ; Declare functions defined elsewhere and referenced in this module 245 ----------------------------------------------------------------------------*/ 246 247 /*---------------------------------------------------------------------------- 248 ; EXTERNAL VARIABLES REFERENCES 249 ; Declare variables used in this module but defined elsewhere 250 ----------------------------------------------------------------------------*/ 251 252 /*---------------------------------------------------------------------------- 253 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 254 ; Declare variables used in this module but defined elsewhere 255 ----------------------------------------------------------------------------*/ 256 257 258 /*---------------------------------------------------------------------------- 259 ; FUNCTION CODE 260 ----------------------------------------------------------------------------*/ 261 262 263 Int mdct_fxp( 264 Int32 data_quant[], 265 Int32 Q_FFTarray[], 266 Int n) 267 { 268 269 Int32 temp_re; 270 Int32 temp_im; 271 272 Int32 temp_re_32; 273 Int32 temp_im_32; 274 275 Int16 cos_n; 276 Int16 sin_n; 277 Int32 exp_jw; 278 Int shift; 279 280 281 const Int32 *p_rotate; 282 283 284 Int32 *p_data_1; 285 Int32 *p_data_2; 286 Int32 *p_data_3; 287 Int32 *p_data_4; 288 289 Int32 *p_Q_FFTarray; 290 291 Int32 max1; 292 293 Int k; 294 Int n_2 = n >> 1; 295 Int n_4 = n >> 2; 296 Int n_8 = n >> 3; 297 Int n_3_4 = 3 * n_4; 298 299 switch (n) 300 { 301 case SHORT_WINDOW_TYPE: 302 p_rotate = (Int32 *)exp_rotation_N_256; 303 break; 304 305 case LONG_WINDOW_TYPE: 306 p_rotate = (Int32 *)exp_rotation_N_2048; 307 break; 308 309 default: 310 /* 311 * There is no defined behavior for a non supported frame 312 * size. By returning a fixed scaling factor, the input will 313 * scaled down and this will be heard as a low level noise 314 */ 315 return(ERROR_IN_FRAME_SIZE); 316 317 } 318 319 /*--- Reordering and Pre-rotation by exp(-j(2pi/N)(r+1/8)) */ 320 p_data_1 = &data_quant[n_3_4]; 321 p_data_2 = &data_quant[n_3_4 - 1]; 322 p_data_3 = &data_quant[n_4]; 323 p_data_4 = &data_quant[n_4 - 1]; 324 325 p_Q_FFTarray = Q_FFTarray; 326 327 max1 = 0; 328 329 for (k = n_8; k > 0; k--) 330 { 331 /* 332 * scale down to ensure numbers are Q15 333 * temp_re and temp_im are 32-bit but 334 * only the lower 16 bits are used 335 */ 336 337 temp_re = (*(p_data_1++) + *(p_data_2--)) >> 1; 338 temp_im = (*(p_data_3++) - *(p_data_4--)) >> 1; 339 340 341 /* 342 * cos_n + j*sin_n == exp(j(2pi/N)(k+1/8)) 343 */ 344 345 exp_jw = *p_rotate++; 346 347 cos_n = (Int16)(exp_jw >> 16); 348 sin_n = (Int16)(exp_jw & 0xFFFF); 349 350 temp_re_32 = temp_re * cos_n + temp_im * sin_n; 351 temp_im_32 = temp_im * cos_n - temp_re * sin_n; 352 *(p_Q_FFTarray++) = temp_re_32; 353 *(p_Q_FFTarray++) = temp_im_32; 354 max1 |= (temp_re_32 >> 31) ^ temp_re_32; 355 max1 |= (temp_im_32 >> 31) ^ temp_im_32; 356 357 358 p_data_1++; 359 p_data_2--; 360 p_data_4--; 361 p_data_3++; 362 } 363 364 365 p_data_1 = &data_quant[n - 1]; 366 p_data_2 = &data_quant[n_2 - 1]; 367 p_data_3 = &data_quant[n_2]; 368 p_data_4 = data_quant; 369 370 for (k = n_8; k > 0; k--) 371 { 372 /* 373 * scale down to ensure numbers are Q15 374 */ 375 temp_re = (*(p_data_2--) - *(p_data_4++)) >> 1; 376 temp_im = (*(p_data_1--) + *(p_data_3++)) >> 1; 377 378 p_data_2--; 379 p_data_1--; 380 p_data_4++; 381 p_data_3++; 382 383 /* 384 * cos_n + j*sin_n == exp(j(2pi/N)(k+1/8)) 385 */ 386 387 exp_jw = *p_rotate++; 388 389 cos_n = (Int16)(exp_jw >> 16); 390 sin_n = (Int16)(exp_jw & 0xFFFF); 391 392 temp_re_32 = temp_re * cos_n + temp_im * sin_n; 393 temp_im_32 = temp_im * cos_n - temp_re * sin_n; 394 395 *(p_Q_FFTarray++) = temp_re_32; 396 *(p_Q_FFTarray++) = temp_im_32; 397 max1 |= (temp_re_32 >> 31) ^ temp_re_32; 398 max1 |= (temp_im_32 >> 31) ^ temp_im_32; 399 400 401 } /* for(k) */ 402 403 404 405 p_Q_FFTarray = Q_FFTarray; 406 407 if (max1) 408 { 409 410 if (n != SHORT_WINDOW_TYPE) 411 { 412 413 shift = mix_radix_fft( 414 Q_FFTarray, 415 &max1); 416 417 shift += fwd_long_complex_rot( 418 Q_FFTarray, 419 data_quant, 420 max1); 421 422 } 423 else /* n_4 is 64 */ 424 { 425 426 shift = fft_rx4_short( 427 Q_FFTarray, 428 &max1); 429 430 shift += fwd_short_complex_rot( 431 Q_FFTarray, 432 data_quant, 433 max1); 434 } 435 436 } 437 else 438 { 439 shift = -31; 440 } 441 442 /* 443 * returns shift introduced by FFT and mdct_fxp, 12 accounts for 444 * regular downshift (14) and MDCT scale factor (-2) 445 * number are returned as 16 bits 446 */ 447 return (12 - shift); 448 449 } /* mdct_fxp */ 450 451