1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
33 ------------------------------------------------------------------------------
36 /*----------------------------------------------------------------------------
38 ----------------------------------------------------------------------------*/
52 #include "l_deposit_h.h"
55 /*----------------------------------------------------------------------------
57 ; Define module specific macros here
58 ----------------------------------------------------------------------------*/
61 /*----------------------------------------------------------------------------
63 ; Include all pre-processor statements here. Include conditional
64 ; compile variables also.
65 ----------------------------------------------------------------------------*/
67 #define SIZE_BY_TWO 64
72 /*----------------------------------------------------------------------------
73 ; LOCAL FUNCTION DEFINITIONS
74 ; Function Prototype declaration
75 ----------------------------------------------------------------------------*/
77 /*----------------------------------------------------------------------------
78 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
79 ; Variable declaration - defined here and used outside this module
80 ----------------------------------------------------------------------------*/
82 const Word16 phs_tbl[] =
85 32767, 0, 32729, -1608, 32610, -3212, 32413, -4808,
86 32138, -6393, 31786, -7962, 31357, -9512, 30853, -11039,
87 30274, -12540, 29622, -14010, 28899, -15447, 28106, -16846,
88 27246, -18205, 26320, -19520, 25330, -20788, 24279, -22006,
89 23170, -23170, 22006, -24279, 20788, -25330, 19520, -26320,
90 18205, -27246, 16846, -28106, 15447, -28899, 14010, -29622,
91 12540, -30274, 11039, -30853, 9512, -31357, 7962, -31786,
92 6393, -32138, 4808, -32413, 3212, -32610, 1608, -32729,
93 0, -32768, -1608, -32729, -3212, -32610, -4808, -32413,
94 -6393, -32138, -7962, -31786, -9512, -31357, -11039, -30853,
95 -12540, -30274, -14010, -29622, -15447, -28899, -16846, -28106,
96 -18205, -27246, -19520, -26320, -20788, -25330, -22006, -24279,
97 -23170, -23170, -24279, -22006, -25330, -20788, -26320, -19520,
98 -27246, -18205, -28106, -16846, -28899, -15447, -29622, -14010,
99 -30274, -12540, -30853, -11039, -31357, -9512, -31786, -7962,
100 -32138, -6393, -32413, -4808, -32610, -3212, -32729, -1608
104 const Word16 ii_table[] =
105 {SIZE / 2, SIZE / 4, SIZE / 8, SIZE / 16, SIZE / 32, SIZE / 64};
108 ------------------------------------------------------------------------------
110 ------------------------------------------------------------------------------
111 INPUT AND OUTPUT DEFINITIONS
114 farray_ptr = pointer to complex array that the FFT operates on of type
116 pOverflow = pointer to overflow (Flag)
119 pOverflow = 1 if the math functions called by cor_h_x2 result in overflow
125 Global Variables Used:
128 Local Variables Needed:
131 ------------------------------------------------------------------------------
134 This is an implementation of decimation-in-time FFT algorithm for
135 real sequences. The techniques used here can be found in several
136 books, e.g., i) Proakis and Manolakis, "Digital Signal Processing",
137 2nd Edition, Chapter 9, and ii) W.H. Press et. al., "Numerical
138 Recipes in C", 2nd Ediiton, Chapter 12.
140 Input - There is one input to this function:
142 1) An integer pointer to the input data array
144 Output - There is no return value.
145 The input data are replaced with transformed data. If the
146 input is a real time domain sequence, it is replaced with
147 the complex FFT for positive frequencies. The FFT value
148 for DC and the foldover frequency are combined to form the
149 first complex number in the array. The remaining complex
150 numbers correspond to increasing frequencies. If the input
151 is a complex frequency domain sequence arranged as above,
152 it is replaced with the corresponding time domain sequence.
156 1) This function is designed to be a part of a VAD
157 algorithm that requires 128-point FFT of real
158 sequences. This is achieved here through a 64-point
159 complex FFT. Consequently, the FFT size information is
160 not transmitted explicitly. However, some flexibility
161 is provided in the function to change the size of the
162 FFT by specifying the size information through "define"
165 2) The values of the complex sinusoids used in the FFT
166 algorithm are stored in a ROM table.
168 3) In the c_fft function, the FFT values are divided by
169 2 after each stage of computation thus dividing the
170 final FFT values by 64. This is somewhat different
171 from the usual definition of FFT where the factor 1/N,
172 i.e., 1/64, used for the IFFT and not the FFT. No factor
173 is used in the r_fft function.
175 ------------------------------------------------------------------------------
180 ------------------------------------------------------------------------------
183 r_fft.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
185 ------------------------------------------------------------------------------
188 The original etsi reference code uses a global flag Overflow. However, in the
189 actual implementation a pointer to a the overflow flag is passed in.
191 void c_fft(Word16 * farray_ptr)
193 Word16 i, j, k, ii, jj, kk, ji, kj, ii2;
194 Word32 ftmp, ftmp_real, ftmp_imag;
195 Word16 tmp, tmp1, tmp2;
197 // Rearrange the input array in bit reversed order
198 for (i = 0, j = 0; i < SIZE - 2; i = i + 2)
202 ftmp = *(farray_ptr + i);
203 *(farray_ptr + i) = *(farray_ptr + j);
204 *(farray_ptr + j) = ftmp;
206 ftmp = *(farray_ptr + i + 1);
207 *(farray_ptr + i + 1) = *(farray_ptr + j + 1);
208 *(farray_ptr + j + 1) = ftmp;
212 while (sub(j, k) >= 0)
221 for (i = 0; i < NUM_STAGE; i++)
222 { // i is stage counter
223 jj = shl(2, i); // FFT size
224 kk = shl(jj, 1); // 2 * FFT size
225 ii = ii_table[i]; // 2 * number of FFT's
227 ji = 0; // ji is phase table index
229 for (j = 0; j < jj; j = j + 2)
230 { // j is sample counter
232 for (k = j; k < SIZE; k = k + kk)
233 { // k is butterfly top
234 kj = add(k, jj); // kj is butterfly bottom
236 // Butterfly computations
237 ftmp_real = L_mult(*(farray_ptr + kj), phs_tbl[ji]);
238 ftmp_real = L_msu(ftmp_real, *(farray_ptr + kj + 1), phs_tbl[ji + 1]);
240 ftmp_imag = L_mult(*(farray_ptr + kj + 1), phs_tbl[ji]);
241 ftmp_imag = L_mac(ftmp_imag, *(farray_ptr + kj), phs_tbl[ji + 1]);
243 tmp1 = pv_round(ftmp_real);
244 tmp2 = pv_round(ftmp_imag);
246 tmp = sub(*(farray_ptr + k), tmp1);
247 *(farray_ptr + kj) = shr(tmp, 1);
249 tmp = sub(*(farray_ptr + k + 1), tmp2);
250 *(farray_ptr + kj + 1) = shr(tmp, 1);
252 tmp = add(*(farray_ptr + k), tmp1);
253 *(farray_ptr + k) = shr(tmp, 1);
255 tmp = add(*(farray_ptr + k + 1), tmp2);
256 *(farray_ptr + k + 1) = shr(tmp, 1);
265 ------------------------------------------------------------------------------
267 [State any special notes, constraints or cautions for users of this function]
269 ------------------------------------------------------------------------------
272 /* FFT function for complex sequences */
274 * The decimation-in-time complex FFT is implemented below.
275 * The input complex numbers are presented as real part followed by
276 * imaginary part for each sample. The counters are therefore
277 * incremented by two to access the complex valued samples.
280 void c_fft(Word16 * farray_ptr, Flag *pOverflow)
299 /* Rearrange the input array in bit reversed order */
300 for (i = 0, j = 0; i < SIZE - 2; i = i + 2)
304 ftmp = *(farray_ptr + i);
305 *(farray_ptr + i) = *(farray_ptr + j);
306 *(farray_ptr + j) = (Word16)ftmp;
308 ftmp = *(farray_ptr + i + 1);
309 *(farray_ptr + i + 1) = *(farray_ptr + j + 1);
310 *(farray_ptr + j + 1) = (Word16)ftmp;
316 j = sub(j, k, pOverflow);
317 k = shr(k, 1, pOverflow);
319 j = add(j, k, pOverflow);
323 for (i = 0; i < NUM_STAGE; i++)
324 { /* i is stage counter */
325 jj = shl(2, i, pOverflow); /* FFT size */
326 kk = shl(jj, 1, pOverflow); /* 2 * FFT size */
327 ii = ii_table[i]; /* 2 * number of FFT's */
328 ii2 = shl(ii, 1, pOverflow);
329 ji = 0; /* ji is phase table index */
331 for (j = 0; j < jj; j = j + 2)
332 { /* j is sample counter */
334 for (k = j; k < SIZE; k = k + kk)
335 { /* k is butterfly top */
336 kj = add(k, jj, pOverflow); /* kj is butterfly bottom */
338 /* Butterfly computations */
339 ftmp_real = L_mult(*(farray_ptr + kj), phs_tbl[ji], pOverflow);
340 ftmp_real = L_msu(ftmp_real, *(farray_ptr + kj + 1),
341 phs_tbl[ji + 1], pOverflow);
343 ftmp_imag = L_mult(*(farray_ptr + kj + 1),
344 phs_tbl[ji], pOverflow);
345 ftmp_imag = L_mac(ftmp_imag, *(farray_ptr + kj),
346 phs_tbl[ji + 1], pOverflow);
348 tmp1 = pv_round(ftmp_real, pOverflow);
349 tmp2 = pv_round(ftmp_imag, pOverflow);
351 tmp = sub(*(farray_ptr + k), tmp1, pOverflow);
352 *(farray_ptr + kj) = shr(tmp, 1, pOverflow);
354 tmp = sub(*(farray_ptr + k + 1), tmp2, pOverflow);
355 *(farray_ptr + kj + 1) = shr(tmp, 1, pOverflow);
357 tmp = add(*(farray_ptr + k), tmp1, pOverflow);
358 *(farray_ptr + k) = shr(tmp, 1, pOverflow);
360 tmp = add(*(farray_ptr + k + 1), tmp2, pOverflow);
361 *(farray_ptr + k + 1) = shr(tmp, 1, pOverflow);
364 ji = add(ji, ii2, pOverflow);
367 } /* end of c_fft () */
371 ------------------------------------------------------------------------------
373 ------------------------------------------------------------------------------
374 INPUT AND OUTPUT DEFINITIONS
377 farray_ptr = pointer to complex array that the FFT operates on of type
379 pOverflow = pointer to overflow (Flag)
382 pOverflow = 1 if the math functions called by cor_h_x2 result in overflow
388 Global Variables Used:
391 Local Variables Needed:
394 ------------------------------------------------------------------------------
397 This is an implementation of decimation-in-time FFT algorithm for
398 real sequences. The techniques used here can be found in several
399 books, e.g., i) Proakis and Manolakis, "Digital Signal Processing",
400 2nd Edition, Chapter 9, and ii) W.H. Press et. al., "Numerical
401 Recipes in C", 2nd Ediiton, Chapter 12.
403 Input - There is one input to this function:
405 1) An integer pointer to the input data array
407 Output - There is no return value.
408 The input data are replaced with transformed data. If the
409 input is a real time domain sequence, it is replaced with
410 the complex FFT for positive frequencies. The FFT value
411 for DC and the foldover frequency are combined to form the
412 first complex number in the array. The remaining complex
413 numbers correspond to increasing frequencies. If the input
414 is a complex frequency domain sequence arranged as above,
415 it is replaced with the corresponding time domain sequence.
419 1) This function is designed to be a part of a VAD
420 algorithm that requires 128-point FFT of real
421 sequences. This is achieved here through a 64-point
422 complex FFT. Consequently, the FFT size information is
423 not transmitted explicitly. However, some flexibility
424 is provided in the function to change the size of the
425 FFT by specifying the size information through "define"
428 2) The values of the complex sinusoids used in the FFT
429 algorithm are stored in a ROM table.
431 3) In the c_fft function, the FFT values are divided by
432 2 after each stage of computation thus dividing the
433 final FFT values by 64. This is somewhat different
434 from the usual definition of FFT where the factor 1/N,
435 i.e., 1/64, used for the IFFT and not the FFT. No factor
436 is used in the r_fft function.
438 ------------------------------------------------------------------------------
443 ------------------------------------------------------------------------------
446 r_fft.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
448 ------------------------------------------------------------------------------
451 The original etsi reference code uses a global flag Overflow. However, in the
452 actual implementation a pointer to a the overflow flag is passed in.
454 void r_fft(Word16 * farray_ptr)
457 Word16 ftmp1_real, ftmp1_imag, ftmp2_real, ftmp2_imag;
458 Word32 Lftmp1_real, Lftmp1_imag;
462 // Perform the complex FFT
465 // First, handle the DC and foldover frequencies
466 ftmp1_real = *farray_ptr;
467 ftmp2_real = *(farray_ptr + 1);
468 *farray_ptr = add(ftmp1_real, ftmp2_real);
469 *(farray_ptr + 1) = sub(ftmp1_real, ftmp2_real);
471 // Now, handle the remaining positive frequencies
472 for (i = 2, j = SIZE - i; i <= SIZE_BY_TWO; i = i + 2, j = SIZE - i)
474 ftmp1_real = add(*(farray_ptr + i), *(farray_ptr + j));
475 ftmp1_imag = sub(*(farray_ptr + i + 1), *(farray_ptr + j + 1));
476 ftmp2_real = add(*(farray_ptr + i + 1), *(farray_ptr + j + 1));
477 ftmp2_imag = sub(*(farray_ptr + j), *(farray_ptr + i));
479 Lftmp1_real = L_deposit_h(ftmp1_real);
480 Lftmp1_imag = L_deposit_h(ftmp1_imag);
482 Ltmp1 = L_mac(Lftmp1_real, ftmp2_real, phs_tbl[i]);
483 Ltmp1 = L_msu(Ltmp1, ftmp2_imag, phs_tbl[i + 1]);
484 *(farray_ptr + i) = pv_round(L_shr(Ltmp1, 1));
486 Ltmp1 = L_mac(Lftmp1_imag, ftmp2_imag, phs_tbl[i]);
487 Ltmp1 = L_mac(Ltmp1, ftmp2_real, phs_tbl[i + 1]);
488 *(farray_ptr + i + 1) = pv_round(L_shr(Ltmp1, 1));
490 Ltmp1 = L_mac(Lftmp1_real, ftmp2_real, phs_tbl[j]);
491 Ltmp1 = L_mac(Ltmp1, ftmp2_imag, phs_tbl[j + 1]);
492 *(farray_ptr + j) = pv_round(L_shr(Ltmp1, 1));
494 Ltmp1 = L_negate(Lftmp1_imag);
495 Ltmp1 = L_msu(Ltmp1, ftmp2_imag, phs_tbl[j]);
496 Ltmp1 = L_mac(Ltmp1, ftmp2_real, phs_tbl[j + 1]);
497 *(farray_ptr + j + 1) = pv_round(L_shr(Ltmp1, 1));
502 ------------------------------------------------------------------------------
504 [State any special notes, constraints or cautions for users of this function]
506 ------------------------------------------------------------------------------
509 /* FFT function for complex sequences */
511 * The decimation-in-time complex FFT is implemented below.
512 * The input complex numbers are presented as real part followed by
513 * imaginary part for each sample. The counters are therefore
514 * incremented by two to access the complex valued samples.
516 void r_fft(Word16 * farray_ptr, Flag *pOverflow)
529 /* Perform the complex FFT */
530 c_fft(farray_ptr, pOverflow);
532 /* First, handle the DC and foldover frequencies */
533 ftmp1_real = *farray_ptr;
534 ftmp2_real = *(farray_ptr + 1);
535 *farray_ptr = add(ftmp1_real, ftmp2_real, pOverflow);
536 *(farray_ptr + 1) = sub(ftmp1_real, ftmp2_real, pOverflow);
538 /* Now, handle the remaining positive frequencies */
539 for (i = 2, j = SIZE - i; i <= SIZE_BY_TWO; i = i + 2, j = SIZE - i)
541 ftmp1_real = add(*(farray_ptr + i), *(farray_ptr + j), pOverflow);
542 ftmp1_imag = sub(*(farray_ptr + i + 1),
543 *(farray_ptr + j + 1), pOverflow);
544 ftmp2_real = add(*(farray_ptr + i + 1),
545 *(farray_ptr + j + 1), pOverflow);
546 ftmp2_imag = sub(*(farray_ptr + j),
547 *(farray_ptr + i), pOverflow);
549 Lftmp1_real = L_deposit_h(ftmp1_real);
550 Lftmp1_imag = L_deposit_h(ftmp1_imag);
552 Ltmp1 = L_mac(Lftmp1_real, ftmp2_real, phs_tbl[i], pOverflow);
553 Ltmp1 = L_msu(Ltmp1, ftmp2_imag, phs_tbl[i + 1], pOverflow);
554 *(farray_ptr + i) = pv_round(L_shr(Ltmp1, 1, pOverflow), pOverflow);
556 Ltmp1 = L_mac(Lftmp1_imag, ftmp2_imag, phs_tbl[i], pOverflow);
557 Ltmp1 = L_mac(Ltmp1, ftmp2_real, phs_tbl[i + 1], pOverflow);
558 *(farray_ptr + i + 1) = pv_round(L_shr(Ltmp1, 1, pOverflow), pOverflow);
560 Ltmp1 = L_mac(Lftmp1_real, ftmp2_real, phs_tbl[j], pOverflow);
561 Ltmp1 = L_mac(Ltmp1, ftmp2_imag, phs_tbl[j + 1], pOverflow);
562 *(farray_ptr + j) = pv_round(L_shr(Ltmp1, 1, pOverflow), pOverflow);
564 Ltmp1 = L_negate(Lftmp1_imag);
565 Ltmp1 = L_msu(Ltmp1, ftmp2_imag, phs_tbl[j], pOverflow);
566 Ltmp1 = L_mac(Ltmp1, ftmp2_real, phs_tbl[j + 1], pOverflow);
567 *(farray_ptr + j + 1) = pv_round(L_shr(Ltmp1, 1, pOverflow), pOverflow);