Implementing a FIR Filter

Hi all,

Would someone please recommend a good starting point in C++ source code
that demonstrates how one uses the kernel::fir_filter. I started
following
the pfb_clock_sync method of implementing it, but then realized this had
been customized a bit for the polyphase approach.

I’m not doing anything fancy, I’m building a modulator and need to pass
symbols through a shaping filter. The shaping filter is what I need the
FIR
filter for.

Appreciated,
Rich

Rich,

hilbert_fc.cc and filter_delay_fc both use kernel::fir_filter in a
relatively easy to understand way.

Jeff

Thank you Jeff. Those are perfect.

Rich

On Wed, Aug 19, 2015 at 2:17 PM, Richard B. [email protected]
wrote:

    kernel::fir_filter_ccf *d_shape_filter;

To my CMakeLists.txt file I added FILTER to the dependency list:
set(GR_REQUIRED_COMPONENTS RUNTIME FILTER)

I’m not sure where to go from here. What else needs to happen to call
kernel::fir_filter_ccf?

Thanks,
Rich

Probably a namespace issue. You’ve included the fir_filter.h, I’m
assuming.
Now, instead of referencing it as “kernel::fir_filter_ccf” use the full
namespace “gr::filter::kernel::fir_filter_ccf”.

Tom

I have a fundamental misunderstanding of the filter system in gnuradio.
I
would appreciate some help. I wrote a simple C++ testbench to help me
figure out what’s going on, but it continues to not behave as I expect.
I
am using fir_filter_fff with 29 taps that I set. I send an impulse into
the
filter and want to see the filter taps at the output in response. The
first
sample that comes out is correct, but every sample after the first is
either the smallest or largest number representable by float. The code
that
does this is below.

float impulse[29] =
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // 29
samples
long

float filter_taps[29] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1,
1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1}
//
input to filter

shape_filter = new gr::filter::kernel::fir_filter_fff(1, filter_taps);

for(int i = 0; i < 29; i++) {
filter_out[i] = shape_filter->filter(&impulse[i]);
}

Printing filter_out to the screen produces:
0.1 0 8.12753e-44 1.61149e-43 -4.16205e-20 -8.32411e-20
-1.24862e-19 -1.66482e-19 1.13358e+21

When I expect to see
0.1 0.2 0.3 0.4 etc…, the taps of the filter that I set above

You can see only the first output matches the expected.

What am I doing wrong here?

Thanks,
Rich

On Wed, Aug 19, 2015 at 12:02 PM, Richard B. [email protected]

That fixed the problem. Thank you.

Rich

I got this working. For completeness, I’ll answer my own questions and
sum
up what I’ve learned about filtering.

  1. You need to call set_history(num_filter_taps) so that block
    boundaries
    are handled smoothly
  2. You input samples one at a time to fir_filter_xxf
  3. fir_filter_xxf does not store data in it’s own memory space, it uses
    the
    address of the array element you give it to figure out the rest of the
    data
    it should use to process around it, this is why history is necessary

The last problem I was having was related to converting an array of char
to
float before feeding it into the filter. Not realizing how
fir_filter_xxf
figured out what data to use, I was typecasting each char to float
sample
by sample as the loop progressed and assigning the single float to a new
variable that was not an array. I then passed the address of this
variable
to filter. This would cause the filter to use values in addresses around
that variable in its calculations, leading to ridiculous results. Don’t
do
this!

Rich

On Thu, Aug 20, 2015 at 12:37 PM, Richard B. [email protected]

I’m having some trouble getting my code to compile. I get the following
error:

error: ‘kernel’ does not name a type
kernel::fir_filter_ccf *d_shape_filter;

To my *_impl.h file I added the following:
#include <gnuradio/filter/fir_filter.h>

private:
kernel::fir_filter_ccf *d_shape_filter;

To my CMakeLists.txt file I added FILTER to the dependency list:
set(GR_REQUIRED_COMPONENTS RUNTIME FILTER)

I’m not sure where to go from here. What else needs to happen to call
kernel::fir_filter_ccf?

Thanks,
Rich

On Wed, Aug 19, 2015 at 9:39 AM, Richard B. [email protected]