Hi Al,
That really clears things up conceptually. Thanks for the insight.
Given that, I went back and modified the dsp test case to use a
scaling factor of 15, normalized input, and normalized output, so
the block invocation was "dsp.fir_ccf (src_coeff, 15, 1, 0, 0, 0,
0)". Running the test provides:
-0.0102 - 0.0102i
-0.0104 - 0.0103i
-0.0105 - 0.0105i
-0.0106 - 0.0106i
-0.0107 + 0.0010i
0.0111 + 0.0031i
0.0334 + 0.0061i
0.0671 + 0.0102i
0.1122 + 0.0154i
However, this differs from the output of the gr.fir_filter_ccf block
and the result of direct computation in MATLAB:
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
I've checked the magnitude and phase of each of these results, and
it doesn't look like they're a simple rotation or multiple of each
other.
I thought that it might just not work for decimal
sources/coefficients, so I adjusted the tests so that src =
"" and src_coeff = (1,1,1,1,1).
Since we no longer needed to scale it before or after, our block
invocation is "dsp.fir_ccf (src_coeff, 15, 1, 1, 1, 0, 0)". This
gives the output:
1.0e+04 *
3.2748 + 3.2751i
3.2762 + 3.2752i
3.2762 + 3.2767i
3.2763 - 3.2768i
-3.2768 - 0.0001i
0 - 0.0002i
0 - 0.0003i
0 - 0.0004i
0 - 0.0005i
0
0
0
0
0
2.8678 - 3.2752i
-3.2757 - 3.2751i
-3.2757 + 0.0001i
0.0005 - 3.2768i
-3.2768
The output from the gr.fir_filter_ccf test is the first nine
elements of the MATLAB output:
1
2
3
4
5
5
5
5
5
Finally, I thought that the issue might be that I'm not normalizing
my source coefficients. So, I normalized them in MATLAB, yielding
src_coeff = (0.4472, 0.4472, 0.4472, 0.4472, 0.4472), which provided
the output:
1.0e+03 *
6.5440 + 6.5450i
6.5500 + 6.5460i
6.5500 + 6.5520i
6.5510 + 6.5530i
6.5530 - 0.0010i
0 - 0.0010i
0 - 0.0020i
0 - 0.0020i
0 - 0.0030i
What am I doing wrong?
Thanks,
Chris
On 7/13/2011 7:14 PM, Almohanad Fayez wrote:
Hey Chris, if
you reached this far I'm assuming that the new packages
have solved your issues ... Since you're passing
normalized values to the DSP you will need to scale them
or they will be converted to zeros when moved to the DSP
float fixed
0.3333 = 0
3.3333 = 3
33.333 = 33
so your scaling factor should be 15. Regarding
input/output signature it allows you to define if the
input is normalized (signature = 0) meaning that the
easycom-gpp library would need to scale it before
transferring it to the dsp and the same for the output
you'll tell it if it should scale it back to normalized
numbers or should it keep it as fixed point numbers. The
motivation for this is the USRP1 with non-uhd drivers
would provide fixed point data during receive mode and
normalized data for transmit mode.
al
src_coeff, 0, 1, 0, 0, 0, 0)
-----Original Message-----
From: Christopher Dean <address@hidden>
To: Almohanad Fayez <address@hidden>
Cc: discuss-gnuradio <address@hidden>
Sent: Wed, Jul 13, 2011 3:37 pm
Subject: gr-dsp Library Block Parameters
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.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, 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()
|