1313#include "user/fft.h"
1414
1515static int bitrev [FFT_N ] = {0.0 };
16- static float window [FFT_N ] = {0.0 };
16+ static float window [FFT_N * 2 ] = {0.0 };
1717static float complex data [FFT_N ] = {0.0 };
1818static float complex root [FFT_N / 2 ] = {0.0 };
1919
@@ -35,24 +35,26 @@ static int bit_reverse(int x)
3535
3636static void compute_fft_tables (void )
3737{
38+ // bit reversal
3839 for (int i = 0 ; i < FFT_N ; i ++ ) {
3940 bitrev [i ] = bit_reverse (i );
4041 }
4142
42- // Hanning window
43- for (int i = 0 ; i < FFT_N ; i ++ ) {
44- window [i ] = 0.5 * ( 1 - cosf (i * ( TWO_PI / FFT_N ) ));
43+ // hamming window
44+ for (int i = 0 ; i < FFT_N * 2 ; i ++ ) {
45+ window [i ] = 0.53836 - 0.46164 * cosf (i * TWO_PI / ( FFT_N * 2 - 1 ));
4546 }
4647
48+ // twiddle factor
4749 for (int i = 0 ; i < FFT_N / 2 ; i ++ ) {
48- root [i ] = cexpf (- i * ( TWO_PI / FFT_N ) * I );
50+ root [i ] = cexpf (- i * TWO_PI / ( FFT_N - 1 ) * I );
4951 }
5052}
5153
5254static void compute_log_xscale (float * xscale , int bands )
5355{
5456 for (int i = 0 ; i <= bands ; i ++ ) {
55- xscale [i ] = powf (FFT_N / 2 , (float )i / bands ) - 0.5f ;
57+ xscale [i ] = powf (FFT_N , (float )i / bands ) - 0.5 ;
5658 }
5759}
5860
@@ -71,30 +73,30 @@ static float compute_freq_band(const float *freq, const float *xscale, int band,
7173 for (; a < b ; a ++ ) {
7274 n += freq [a ];
7375 }
74- if (b < FFT_N / 2 ) {
76+ if (b < FFT_N ) {
7577 n += freq [b ] * (xscale [band + 1 ] - b );
7678 }
7779 }
7880
79- n *= ( float ) bands / 12 ;
81+ n *= bands / 12.0 ;
8082
8183 return 20 * log10f (n );
8284}
8385
8486void fft_compute_lin (uint16_t * data_out , uint16_t scale_factor , uint16_t max_val , uint16_t min_val )
8587{
86- data_out [0 ] += cabsf (data [0 ]) / FFT_N * (max_val * scale_factor / 16384.0 );
87- data_out [0 ] /= 2 ;
88+ float freq [FFT_N ] = {0.0 };
8889
89- if (data_out [0 ] > max_val ) {
90- data_out [0 ] = max_val ;
91- } else if (data_out [0 ] < min_val ) {
92- data_out [0 ] = min_val ;
90+ for (int i = 0 ; i < FFT_N / 2 ; i ++ ) {
91+ freq [i * 2 ] = cabsf (data [i ] + conjf (data [FFT_N - 1 - i ])) / 4.0 / FFT_N * (scale_factor / 512.0 );
92+ freq [i * 2 + 1 ] = cabsf (data [i ] - conjf (data [FFT_N - 1 - i ])) / 4.0 / FFT_N * (scale_factor / 512.0 );
9393 }
9494
95- for (int i = 1 ; i < FFT_OUT_N ; i ++ ) {
96- data_out [i ] += cabsf (data [(FFT_N / 2 / FFT_OUT_N ) * i ]) / FFT_N * 2 * (max_val * scale_factor / 16384.0 );
97- data_out [i ] /= 2 ;
95+ freq [0 ] /= 2.0 ;
96+
97+ for (int i = 0 ; i < FFT_OUT_N ; i ++ ) {
98+ data_out [i ] += freq [FFT_N / FFT_OUT_N * i ] * (max_val / 32.0 );
99+ data_out [i ] /= 2.0 ;
98100
99101 if (data_out [i ] > max_val ) {
100102 data_out [i ] = max_val ;
@@ -106,18 +108,18 @@ void fft_compute_lin(uint16_t *data_out, uint16_t scale_factor, uint16_t max_val
106108
107109void fft_compute_log (uint16_t * data_out , uint16_t scale_factor , uint16_t max_val , uint16_t min_val )
108110{
109- data_out [0 ] += 20 * log10f (1 + cabsf (data [0 ]) / FFT_N ) * (max_val * scale_factor / 16384.0 );
110- data_out [0 ] /= 2 ;
111+ float freq [FFT_N ] = {0.0 };
111112
112- if (data_out [0 ] > max_val ) {
113- data_out [0 ] = max_val ;
114- } else if (data_out [0 ] < min_val ) {
115- data_out [0 ] = min_val ;
113+ for (int i = 0 ; i < FFT_N / 2 ; i ++ ) {
114+ freq [i * 2 ] = cabsf (data [i ] + conjf (data [FFT_N - 1 - i ])) / 4.0 / FFT_N * (scale_factor / 512.0 );
115+ freq [i * 2 + 1 ] = cabsf (data [i ] - conjf (data [FFT_N - 1 - i ])) / 4.0 / FFT_N * (scale_factor / 512.0 );
116116 }
117117
118- for (int i = 1 ; i < FFT_OUT_N ; i ++ ) {
119- data_out [i ] += 20 * log10f (1 + cabsf (data [(FFT_N / 2 / FFT_OUT_N ) * i ]) / FFT_N * 2 ) * (max_val * scale_factor / 16384.0 );
120- data_out [i ] /= 2 ;
118+ freq [0 ] /= 2.0 ;
119+
120+ for (int i = 0 ; i < FFT_OUT_N ; i ++ ) {
121+ data_out [i ] += 20 * log10f (1 + freq [FFT_N / FFT_OUT_N * i ]) * (max_val / 32.0 );
122+ data_out [i ] /= 2.0 ;
121123
122124 if (data_out [i ] > max_val ) {
123125 data_out [i ] = max_val ;
@@ -129,14 +131,15 @@ void fft_compute_log(uint16_t *data_out, uint16_t scale_factor, uint16_t max_val
129131
130132void fft_compute_bands (uint16_t * data_out , uint16_t scale_factor , uint16_t max_val , uint16_t min_val )
131133{
132- float freq [FFT_N / 2 ] = {0.0 };
134+ float freq [FFT_N ] = {0.0 };
133135
134- freq [0 ] = cabsf (data [0 ]) / FFT_N * (scale_factor / 2.0 / 65536.0 );
135-
136- for (int i = 1 ; i < FFT_N / 2 ; i ++ ) {
137- freq [i ] = 2 * cabsf (data [i ]) / FFT_N * (scale_factor / 2.0 / 65536.0 );
136+ for (int i = 0 ; i < FFT_N / 2 ; i ++ ) {
137+ freq [i * 2 ] = cabsf (data [i ] + conjf (data [FFT_N - 1 - i ])) / 4.0 / FFT_N * (scale_factor / 512.0 / FFT_N );
138+ freq [i * 2 + 1 ] = cabsf (data [i ] - conjf (data [FFT_N - 1 - i ])) / 4.0 / FFT_N * (scale_factor / 512.0 / FFT_N );
138139 }
139140
141+ freq [0 ] /= 2.0 ;
142+
140143 for (int i = 0 ; i < BAND_N ; i ++ ) {
141144 float x = (40 + compute_freq_band (freq , xscale , i , BAND_N )) * (max_val / 64.0 );
142145
@@ -164,14 +167,14 @@ void fft_execute(void)
164167{
165168 int half = 1 ;
166169
167- // Cooley–Tukey Fast Fourier Transform , radix-2 case
170+ // fast fourier transform , radix-2 case
168171 for (int i = FFT_N >> 1 ; i > 0 ; i >>= 1 ) {
169172 for (int g = 0 ; g < FFT_N ; g += half << 1 ) {
170173 for (int b = 0 , r = 0 ; b < half ; b ++ , r += i ) {
171174 float complex even = data [g + b ];
172175 float complex odd = data [g + b + half ] * root [r ];
173176
174- data [g + b ] = even + odd ;
177+ data [g + b ] = even + odd ;
175178 data [g + b + half ] = even - odd ;
176179 }
177180 }
@@ -182,29 +185,37 @@ void fft_execute(void)
182185
183186void fft_load_data (const uint8_t * data_in , fft_channel_t channel )
184187{
185- int16_t data_l = 0 , data_r = 0 ;
186-
187188 switch (channel ) {
188189 case FFT_CHANNEL_L :
189190 for (int i = 0 ; i < FFT_N ; i ++ ) {
190- data_l = data_in [i * 4 + 1 ] << 8 | data_in [i * 4 ];
191+ int16_t data_re_l = data_in [i * 8 + 1 ] << 8 | data_in [i * 8 ];
192+ int16_t data_im_l = data_in [i * 8 + 5 ] << 8 | data_in [i * 8 + 4 ];
193+ float data_re = data_re_l * window [i * 2 ];
194+ float data_im = data_im_l * window [i * 2 + 1 ];
191195
192- data [bitrev [i ]] = ( float ) data_l * window [ i ] ;
196+ data [bitrev [i ]] = data_re + data_im * I ;
193197 }
194198 break ;
195199 case FFT_CHANNEL_R :
196200 for (int i = 0 ; i < FFT_N ; i ++ ) {
197- data_r = data_in [i * 4 + 3 ] << 8 | data_in [i * 4 + 2 ];
201+ int16_t data_re_r = data_in [i * 8 + 3 ] << 8 | data_in [i * 8 + 2 ];
202+ int16_t data_im_r = data_in [i * 8 + 7 ] << 8 | data_in [i * 8 + 6 ];
203+ float data_re = data_re_r * window [i * 2 ];
204+ float data_im = data_im_r * window [i * 2 + 1 ];
198205
199- data [bitrev [i ]] = ( float ) data_r * window [ i ] ;
206+ data [bitrev [i ]] = data_re + data_im * I ;
200207 }
201208 break ;
202209 case FFT_CHANNEL_LR :
203210 for (int i = 0 ; i < FFT_N ; i ++ ) {
204- data_l = data_in [i * 4 + 1 ] << 8 | data_in [i * 4 ];
205- data_r = data_in [i * 4 + 3 ] << 8 | data_in [i * 4 + 2 ];
206-
207- data [bitrev [i ]] = (float )((data_l + data_r ) / 2 ) * window [i ];
211+ int16_t data_re_l = data_in [i * 8 + 1 ] << 8 | data_in [i * 8 ];
212+ int16_t data_re_r = data_in [i * 8 + 3 ] << 8 | data_in [i * 8 + 2 ];
213+ int16_t data_im_l = data_in [i * 8 + 5 ] << 8 | data_in [i * 8 + 4 ];
214+ int16_t data_im_r = data_in [i * 8 + 7 ] << 8 | data_in [i * 8 + 6 ];
215+ float data_re = (data_re_l + data_re_r ) / 2.0 * window [i * 2 ];
216+ float data_im = (data_im_l + data_im_r ) / 2.0 * window [i * 2 + 1 ];
217+
218+ data [bitrev [i ]] = data_re + data_im * I ;
208219 }
209220 break ;
210221 default :
0 commit comments