• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 
12 /*
13  * This file contains the function WebRtcSpl_ComplexFFT().
14  * The description header can be found in signal_processing_library.h
15  *
16  */
17 
18 #include "signal_processing_library.h"
19 
20 #define CFFTSFT 14
21 #define CFFTRND 1
22 #define CFFTRND2 16384
23 
24 #if (defined ARM9E_GCC) || (defined ARM_WINM) || (defined ANDROID_AECOPT)
25 extern "C" int FFT_4OFQ14(void *src, void *dest, int NC, int shift);
26 
27 // For detailed description of the fft functions, check the readme files in fft_ARM9E folder.
WebRtcSpl_ComplexFFT2(WebRtc_Word16 frfi[],WebRtc_Word16 frfiOut[],int stages,int mode)28 int WebRtcSpl_ComplexFFT2(WebRtc_Word16 frfi[], WebRtc_Word16 frfiOut[], int stages, int mode)
29 {
30     return FFT_4OFQ14(frfi, frfiOut, 1 << stages, 0);
31 }
32 #endif
33 
WebRtcSpl_ComplexFFT(WebRtc_Word16 frfi[],int stages,int mode)34 int WebRtcSpl_ComplexFFT(WebRtc_Word16 frfi[], int stages, int mode)
35 {
36     int i, j, l, k, istep, n, m;
37     WebRtc_Word16 wr, wi;
38     WebRtc_Word32 tr32, ti32, qr32, qi32;
39 
40     /* The 1024-value is a constant given from the size of WebRtcSpl_kSinTable1024[],
41      * and should not be changed depending on the input parameter 'stages'
42      */
43     n = 1 << stages;
44     if (n > 1024)
45         return -1;
46 
47     l = 1;
48     k = 10 - 1; /* Constant for given WebRtcSpl_kSinTable1024[]. Do not change
49          depending on the input parameter 'stages' */
50 
51     if (mode == 0)
52     {
53         // mode==0: Low-complexity and Low-accuracy mode
54         while (l < n)
55         {
56             istep = l << 1;
57 
58             for (m = 0; m < l; ++m)
59             {
60                 j = m << k;
61 
62                 /* The 256-value is a constant given as 1/4 of the size of
63                  * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input
64                  * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
65                  */
66                 wr = WebRtcSpl_kSinTable1024[j + 256];
67                 wi = -WebRtcSpl_kSinTable1024[j];
68 
69                 for (i = m; i < n; i += istep)
70                 {
71                     j = i + l;
72 
73                     tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
74                             - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1])), 15);
75 
76                     ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
77                             + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j])), 15);
78 
79                     qr32 = (WebRtc_Word32)frfi[2 * i];
80                     qi32 = (WebRtc_Word32)frfi[2 * i + 1];
81                     frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 - tr32, 1);
82                     frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 - ti32, 1);
83                     frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qr32 + tr32, 1);
84                     frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(qi32 + ti32, 1);
85                 }
86             }
87 
88             --k;
89             l = istep;
90 
91         }
92 
93     } else
94     {
95         // mode==1: High-complexity and High-accuracy mode
96         while (l < n)
97         {
98             istep = l << 1;
99 
100             for (m = 0; m < l; ++m)
101             {
102                 j = m << k;
103 
104                 /* The 256-value is a constant given as 1/4 of the size of
105                  * WebRtcSpl_kSinTable1024[], and should not be changed depending on the input
106                  * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
107                  */
108                 wr = WebRtcSpl_kSinTable1024[j + 256];
109                 wi = -WebRtcSpl_kSinTable1024[j];
110 
111                 for (i = m; i < n; i += istep)
112                 {
113                     j = i + l;
114 
115                     tr32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j])
116                             - WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j + 1]) + CFFTRND),
117                             15 - CFFTSFT);
118 
119                     ti32 = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(wr, frfi[2 * j + 1])
120                             + WEBRTC_SPL_MUL_16_16(wi, frfi[2 * j]) + CFFTRND), 15 - CFFTSFT);
121 
122                     qr32 = ((WebRtc_Word32)frfi[2 * i]) << CFFTSFT;
123                     qi32 = ((WebRtc_Word32)frfi[2 * i + 1]) << CFFTSFT;
124                     frfi[2 * j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
125                             (qr32 - tr32 + CFFTRND2), 1 + CFFTSFT);
126                     frfi[2 * j + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
127                             (qi32 - ti32 + CFFTRND2), 1 + CFFTSFT);
128                     frfi[2 * i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
129                             (qr32 + tr32 + CFFTRND2), 1 + CFFTSFT);
130                     frfi[2 * i + 1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
131                             (qi32 + ti32 + CFFTRND2), 1 + CFFTSFT);
132                 }
133             }
134 
135             --k;
136             l = istep;
137         }
138     }
139     return 0;
140 }
141