Skip to content

Commit 5a46f15

Browse files
committed
Add fft_fc: FFT for real input signal
1 parent 38d567d commit 5a46f15

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

csdr.c

+91
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,97 @@ int main(int argc, char *argv[])
13141314
TRY_YIELD;
13151315
}
13161316
}
1317+
1318+
if(!strcmp(argv[1],"fft_fc"))
1319+
{
1320+
/* For real FFT, the parameter is the number of output complex bins
1321+
instead of the actual FFT size.
1322+
Thus, the number of input samples used for each FFT is twice the given parameter
1323+
and for this reason, out_of_every_n_samples is also doubled
1324+
to get correct amount of overlap.
1325+
This is not very neat but makes it easier to replace fft_cc by fft_fc
1326+
in some applications. */
1327+
if(argc<=3) return badsyntax("need required parameters (fft_out_size, out_of_every_n_samples)");
1328+
int fft_in_size=0, fft_out_size=0;
1329+
sscanf(argv[2],"%d",&fft_out_size);
1330+
if(log2n(fft_out_size)==-1) return badsyntax("fft_out_size should be power of 2");
1331+
fft_in_size = 2*fft_out_size;
1332+
int every_n_samples;
1333+
sscanf(argv[3],"%d",&every_n_samples);
1334+
every_n_samples *= 2;
1335+
int benchmark=0;
1336+
int octave=0;
1337+
window_t window = WINDOW_DEFAULT;
1338+
if(argc>=5)
1339+
{
1340+
window=firdes_get_window_from_string(argv[4]);
1341+
}
1342+
if(argc>=6)
1343+
{
1344+
benchmark|=!strcmp("--benchmark",argv[5]);
1345+
octave|=!strcmp("--octave",argv[5]);
1346+
}
1347+
if(argc>=7)
1348+
{
1349+
benchmark|=!strcmp("--benchmark",argv[6]);
1350+
octave|=!strcmp("--octave",argv[6]);
1351+
}
1352+
1353+
if(!initialize_buffers()) return -2;
1354+
sendbufsize(fft_out_size);
1355+
1356+
//make FFT plan
1357+
float* input=(float*)fft_malloc(sizeof(float)*fft_in_size);
1358+
float* windowed=(float*)fft_malloc(sizeof(float)*fft_in_size);
1359+
complexf* output=(complexf*)fft_malloc(sizeof(complexf)*fft_out_size);
1360+
if(benchmark) fprintf(stderr,"fft_cc: benchmarking...");
1361+
FFT_PLAN_T* plan=make_fft_r2c(fft_in_size, windowed, output, benchmark);
1362+
if(benchmark) fprintf(stderr," done\n");
1363+
//if(octave) printf("setenv(\"GNUTERM\",\"X11 noraise\");y=zeros(1,%d);semilogy(y,\"ydatasource\",\"y\");\n",fft_size); // TODO
1364+
float *windowt;
1365+
windowt = precalculate_window(fft_in_size, window);
1366+
for(;;)
1367+
{
1368+
FEOF_CHECK;
1369+
if(every_n_samples>fft_in_size)
1370+
{
1371+
fread(input, sizeof(float), fft_in_size, stdin);
1372+
//skipping samples before next FFT (but fseek doesn't work for pipes)
1373+
for(int seek_remain=every_n_samples-fft_in_size;seek_remain>0;seek_remain-=the_bufsize)
1374+
{
1375+
fread(temp_f, sizeof(complexf), MIN_M(the_bufsize,seek_remain), stdin);
1376+
}
1377+
}
1378+
else
1379+
{
1380+
//overlapped FFT
1381+
for(int i=0;i<fft_in_size-every_n_samples;i++) input[i]=input[i+every_n_samples];
1382+
fread(input+fft_in_size-every_n_samples, sizeof(float), every_n_samples, stdin);
1383+
}
1384+
//apply_window_c(input,windowed,fft_size,window);
1385+
apply_precalculated_window_f(input,windowed,fft_in_size,windowt);
1386+
fft_execute(plan);
1387+
if(octave)
1388+
{
1389+
#if 0
1390+
// TODO
1391+
printf("fftdata=[");
1392+
//we have to swap the two parts of the array to get a valid spectrum
1393+
for(int i=fft_size/2;i<fft_size;i++) printf("(%g)+(%g)*i ",iof(output,i),qof(output,i));
1394+
for(int i=0;i<fft_size/2;i++) printf("(%g)+(%g)*i ",iof(output,i),qof(output,i));
1395+
printf(
1396+
"];\n"
1397+
"y=abs(fftdata);\n"
1398+
"refreshdata;\n"
1399+
);
1400+
#endif
1401+
}
1402+
else fwrite(output, sizeof(complexf), fft_out_size, stdout);
1403+
TRY_YIELD;
1404+
}
1405+
}
1406+
1407+
13171408
#define LOGPOWERCF_BUFSIZE 64
13181409
if(!strcmp(argv[1],"logpower_cf"))
13191410
{

fft_fftw.h

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct fft_plan_s
2222
#include "libcsdr.h"
2323

2424
FFT_PLAN_T* make_fft_c2c(int size, complexf* input, complexf* output, int forward, int benchmark);
25+
FFT_PLAN_T* make_fft_r2c(int size, float* input, complexf* output, int benchmark);
2526
void fft_execute(FFT_PLAN_T* plan);
2627
void fft_destroy(FFT_PLAN_T* plan);
2728

libcsdr.c

+7
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,13 @@ void apply_precalculated_window_c(complexf* input, complexf* output, int size, f
952952
}
953953
}
954954

955+
void apply_precalculated_window_f(float* input, float* output, int size, float *windowt)
956+
{
957+
for(int i=0;i<size;i++) //@apply_precalculated_window_f
958+
{
959+
output[i] = input[i] * windowt[i];
960+
}
961+
}
955962

956963
void apply_window_f(float* input, float* output, int size, window_t window)
957964
{

libcsdr.h

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ void rational_resampler_get_lowpass_f(float* output, int output_size, int interp
138138
float *precalculate_window(int size, window_t window);
139139
void apply_window_c(complexf* input, complexf* output, int size, window_t window);
140140
void apply_precalculated_window_c(complexf* input, complexf* output, int size, float *windowt);
141+
void apply_precalculated_window_f(float* input, float* output, int size, float *windowt);
141142
void apply_window_f(float* input, float* output, int size, window_t window);
142143
void logpower_cf(complexf* input, float* output, int size, float add_db);
143144
void accumulate_power_cf(complexf* input, float* output, int size);

0 commit comments

Comments
 (0)