discuss-gnuradio
[Top][All Lists]
Advanced

[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;
}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]