Hi all,
We were talking about a month ago about building an averager of ffts using fir filters (see "new peakfinding and averaging wxgui fft code") and Martin's comments.
I thought I'd try the fft route out so have built some blocks that should do this. The flow graph is supposed to operate like this:
=============================
fft_output
take complex magnitude of each fft
split parallel fftw in-order output into separate streams
take fir of each stream (an averager, something with taps like [1/N,...,1/N] where N is number of items to average over)
combine separate streams back into a single stream, in-order
display
=============================
In python, the code to build the flow graph to split, take the fir (average over 2in this example), and combine looks like this:
for i in range(0,fft_size): averagefir = gr.fir_filter_fff(1, [1/2,1/2]) fg.connect((separator,i),averagefir) fg.connect(averagefir,(combiner,i))
(BTW, doing the above, in python, is "averagefir" a new instance at every iteration as I expect it to be?)
I have built the complex magnitude block, separator, and combiner.
Given the way fftw works, would you say that I've done this correctly? Running this code, I just get a single spike around 0. Not cool. Maybe I have the "channel" and "index" switched?
Anyway, I've pasted the important combiner/separator guts below.
=========================================================
gr_separate_streams_ff::gr_separate_streams_ff (int num_streams)
: gr_sync_block ("separate_streams_ff",
gr_make_io_signature (MIN_IN, MAX_IN, num_streams * sizeof (float)),
gr_make_io_signature (num_streams, num_streams, sizeof (float))),
d_num_streams(num_streams)
{
}
int gr_separate_streams_ff::work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { const float *in = (const float *) input_items[0]; float **out = (float **) &output_items[0];
unsigned long floats_size = noutput_items * d_num_streams;
for (unsigned long i = 0; i < floats_size; i++) { long chan = (long) (i/d_num_streams); long index = (long) (i % d_num_streams);
out[chan][index] = in[i]; }
return noutput_items; }
=============================================================
gr_combine_streams_ff::gr_combine_streams_ff (int num_streams)
: gr_sync_block ("combine_streams_ff",
gr_make_io_signature (num_streams, num_streams, sizeof (float)),
gr_make_io_signature (MIN_OUT, MAX_OUT, num_streams * sizeof (float))),
d_num_streams(num_streams)
{
}
int gr_combine_streams_ff::work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { const float **in = (const float **) &input_items[0]; float *out = (float *) output_items[0];
unsigned long floats_size = noutput_items * d_num_streams;
for (unsigned long i = 0; i < floats_size; i++) { long chan = (long) (i/d_num_streams); long index = (long) (i % d_num_streams);
out[i] = in[chan][index]; }
return noutput_items; }
_______________________________________________ Discuss-gnuradio mailing list Discuss-gnuradio@gnu.org http://lists.gnu.org/mailman/listinfo/discuss-gnuradio