[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Discuss-gnuradio] Averaging FFT output using FIR filters
From: |
James Cooley |
Subject: |
[Discuss-gnuradio] Averaging FFT output using FIR filters |
Date: |
Tue, 08 Mar 2005 14:04:16 -0500 |
User-agent: |
Mozilla Thunderbird 1.0 (X11/20041206) |
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;
}