Hi Al,

We’re trying to use your gr-dsp library and are having difficulty

verifying the output of your DSP.fir_ccf blocks. To allow for easy

comparison to the standard filter type, gr.fir_filter_ccf, we generated

a very simple block diagram in GRC. This consisted of a vector source,

an fir_filter_ccf block, and a file sink. All of the original data and

filter taps are the same, but the outputs are not lining up with their

expected values.

I have included the full script file at the bottom of this email. The

relevant calls to the filter constructors are shown in the text.

For instance:

We have:

src = (0.01+0.11j,

0.02+0.22j,

0.03+0.33j,

0.04+0.44j,

0.05+0.55j,

0.06+0.66j,

0.07+0.77j,

0.08+0.88j,

0.09+0.99j)

src_coeff = (0.101, 0.102, 0.103, 0.104, 0.105)

Without scaling (scaling_factor = 0, so scaling by 2^0 = 1):

```
gr.fir_filter_ccf(1, src_coeff)
This produces output:
0.0010 + 0.0111i
0.0030 + 0.0334i
0.0061 + 0.0671i
0.0102 + 0.1122i
0.0154 + 0.1689i
0.0205 + 0.2255i
0.0257 + 0.2822i
0.0308 + 0.3388i
0.0360 + 0.3954i
What we thought would be the equivalent call using the fir_ccf
```

block is:

```
self.gr_fir_filter_xxx_0 = dsp.fir_ccf (src_coeff, 0, 1, 0, 0, 0,
```

```
This produces output:
0
0
0
0
0
0
0
0
0
```

With scaling (scaling_factor = 15, so scaling by 2^15):

```
gr.fir_filter_ccf(1, src_coeff)
The data was manually scaled by 2^15 in MATLAB, producing output:
1.0e+04 *
0.0033 + 0.0364i
0.0100 + 0.1096i
0.0200 + 0.2199i
0.0334 + 0.3677i
0.0503 + 0.5533i
0.0672 + 0.7389i
0.0840 + 0.9245i
0.1009 + 1.1102i
0.1178 + 1.2958i
dsp.fir_ccf (src_coeff, 15, 1, 0, 1, 0, 0)
* output-signature = 1, so we want the output to be have the same
```

scale factor that it is on the DSP.

```
This produces output:
1.0e+03 *
0.3350 + 0.3350i
0.3400 + 0.3390i
0.3430 + 0.3440i
0.3470 + 0.3470i
0.3500 - 0.0340i
-0.3650 - 0.1000i
-1.0960 - 0.2000i
-2.1990 - 0.3350i
-3.6770 - 0.5030i
```

In neither of these cases do the dsp implementation and the gpp

implementation give the same output.

I’m pretty sure that the issue is in my interpretation of your

parameters. I’ve already been using the online documentation to figure

out what the parameters do, so I know the basic jist of it, but

obviously I haven’t got it figured out yet. Could you please explain

the use of the scaling_factor, input_signature, and output_signature

parameters in more detail?

Also, for the input_signature parameter to be 0, like it is in the

examples qa_fir_ccf2.py and qa_fir_ccf3.py, doesn’t the input need to be

normalized? By my understanding, normalized vectors are unit vectors,

so they should have length 1. But src (above) has length 9, so it’s not

normalized and the input_signature parameter should be 1. Is that

correct?

Thanks,

Chris

#!/usr/bin/env python

##################################################

# Gnuradio Python Flow Graph

# Title: Top Block

# Generated: Wed Jul 13 11:09:34 2011

##################################################

from gnuradio import eng_notation

from gnuradio import gr

from gnuradio.eng_option import eng_option

from gnuradio.gr import firdes

from optparse import OptionParser

from gnuradio import dsp

class top_block(gr.top_block):

```
def __init__(self):
gr.top_block.__init__(self, "Top Block")
##################################################
# Variables
##################################################
self.samp_rate = samp_rate = 32000
##################################################
# Blocks
##################################################
self.gr_vector_source_x_0 =
```

gr.vector_source_c((0.01+0.11j,0.02+0.22j,0.03+0.33j,0.04+0.44j,0.05+0.55j,

0.06+0.66j, .07+0.77j, 0.08+0.88j, 0.09+0.99j), False, 1)

#self.gr_fir_filter_xxx_0 = gr.fir_filter_ccf(1,

(0.101, 0.102, 0.103, 0.104, 0.105))

# Uncomment the previous line, comment in the next

three lines to switch from dsp-based to gpp-based filter.

src_coeff = (0.101, 0.102, 0.103, 0.104, 0.105)

dsp.init()

self.gr_fir_filter_xxx_0 = dsp.fir_ccf (src_coeff, 15,

1, 0, 1, 0, 0)

```
self.gr_file_sink_0 =
```

gr.file_sink(gr.sizeof_gr_complex*1, “filtertest-dsp2.dat”)

self.gr_file_sink_0.set_unbuffered(False)

```
##################################################
# Connections
##################################################
self.connect((self.gr_vector_source_x_0, 0),
```

(self.gr_fir_filter_xxx_0, 0))

self.connect((self.gr_fir_filter_xxx_0, 0),

(self.gr_file_sink_0, 0))

```
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
```

if **name** == ‘**main**’:

parser = OptionParser(option_class=eng_option, usage="%prog:

[options]")

(options, args) = parser.parse_args()

if gr.enable_realtime_scheduling() != gr.RT_OK:

print “Error: failed to enable realtime scheduling.”

tb = top_block()

tb.start()

raw_input('Press Enter to quit: ')

tb.stop()