summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnuradio-core/src/lib/filter/Makefile.am4
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc143
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h21
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc157
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_fff.h22
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc15
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h4
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.cc15
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.h6
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc167
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h82
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.cc186
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.h82
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc158
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h80
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.cc184
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.h81
-rw-r--r--gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc27
-rw-r--r--gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h8
-rw-r--r--gnuradio-core/src/python/gnuradio/Makefile.am1
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am2
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/dbpsk.py10
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py66
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py60
-rw-r--r--gnuradio-core/src/python/gnuradio/modulation_utils2.py81
-rw-r--r--gnuradio-core/src/python/gnuradio/packet_utils.py2
-rw-r--r--gnuradio-examples/grc/demod/digital_freq_lock.grc210
-rw-r--r--gnuradio-examples/grc/demod/pam_sync.grc222
-rwxr-xr-xgnuradio-examples/python/digital/benchmark_loopback.py5
-rwxr-xr-xgnuradio-examples/python/digital/benchmark_qt_loopback2.py37
-rwxr-xr-xgnuradio-examples/python/digital/benchmark_qt_rx2.py23
-rwxr-xr-xgnuradio-examples/python/digital/benchmark_rx2.py114
-rwxr-xr-xgnuradio-examples/python/digital/benchmark_tx2.py135
-rw-r--r--gnuradio-examples/python/digital/pick_bitrate2.py154
-rw-r--r--gnuradio-examples/python/digital/receive_path.py4
-rw-r--r--gnuradio-examples/python/digital/transmit_path.py4
-rw-r--r--gnuradio-examples/python/digital/usrp_receive_path.py30
-rw-r--r--gnuradio-examples/python/digital/usrp_receive_path2.py96
-rw-r--r--gnuradio-examples/python/digital/usrp_transmit_path.py32
-rw-r--r--gnuradio-examples/python/digital/usrp_transmit_path2.py101
-rw-r--r--gr-gpio/src/python/gpio.py2
-rw-r--r--gr-howto-write-a-block/Makefile.common16
-rw-r--r--gr-howto-write-a-block/Makefile.swig.gen.t30
-rwxr-xr-xgr-howto-write-a-block/apps/howto_square.py2
-rw-r--r--gr-howto-write-a-block/grc/howto_square2_ff.xml2
-rw-r--r--gr-howto-write-a-block/grc/howto_square_ff.xml2
-rw-r--r--gr-howto-write-a-block/lib/Makefile.am32
-rw-r--r--gr-howto-write-a-block/python/Makefile.am6
-rw-r--r--gr-howto-write-a-block/swig/Makefile.am11
-rw-r--r--gr-howto-write-a-block/swig/Makefile.swig.gen14
-rw-r--r--gr-utils/src/python/Makefile.am1
-rwxr-xr-xgr-utils/src/python/create-gnuradio-out-of-tree-project69
-rw-r--r--grc/gui/DrawingArea.py12
-rw-r--r--grc/gui/FlowGraph.py41
-rw-r--r--gruel/src/include/gruel/pmt.h21
-rw-r--r--gruel/src/lib/pmt/pmt.cc176
-rw-r--r--gruel/src/lib/pmt/pmt_int.h27
-rw-r--r--gruel/src/lib/pmt/qa_pmt_prims.cc112
58 files changed, 2510 insertions, 897 deletions
diff --git a/gnuradio-core/src/lib/filter/Makefile.am b/gnuradio-core/src/lib/filter/Makefile.am
index 9cd6e9f38..23c1dadc3 100644
--- a/gnuradio-core/src/lib/filter/Makefile.am
+++ b/gnuradio-core/src/lib/filter/Makefile.am
@@ -184,6 +184,8 @@ libfilter_la_common_SOURCES = \
$(GENERATED_CC) \
gr_adaptive_fir_ccf.cc \
gr_cma_equalizer_cc.cc \
+ gri_fft_filter_fff_generic.cc \
+ gri_fft_filter_ccc_generic.cc \
gr_fft_filter_ccc.cc \
gr_fft_filter_fff.cc \
gr_goertzel_fc.cc \
@@ -259,6 +261,8 @@ grinclude_HEADERS = \
gr_altivec.h \
gr_cma_equalizer_cc.h \
gr_cpu.h \
+ gri_fft_filter_fff_generic.h \
+ gri_fft_filter_ccc_generic.h \
gr_fft_filter_ccc.h \
gr_fft_filter_fff.h \
gr_filter_delay_fc.h \
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc
index 3dd40d56d..4540c6e4a 100644
--- a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc
@@ -30,6 +30,8 @@
#endif
#include <gr_fft_filter_ccc.h>
+//#include <gri_fft_filter_ccc_sse.h>
+#include <gri_fft_filter_ccc_generic.h>
#include <gr_io_signature.h>
#include <gri_fft.h>
#include <math.h>
@@ -52,32 +54,23 @@ gr_fft_filter_ccc::gr_fft_filter_ccc (int decimation, const std::vector<gr_compl
gr_make_io_signature (1, 1, sizeof (gr_complex)),
gr_make_io_signature (1, 1, sizeof (gr_complex)),
decimation),
- d_fftsize(-1), d_fwdfft(0), d_invfft(0), d_updated(false)
+ d_updated(false)
{
- // if (decimation != 1)
- // throw std::invalid_argument("gr_fft_filter_ccc: decimation must be 1");
-
set_history(1);
- actual_set_taps(taps);
+#if 1 // don't enable the sse version until handling it is worked out
+ d_filter = new gri_fft_filter_ccc_generic(decimation, taps);
+#else
+ d_filter = new gri_fft_filter_ccc_sse(decimation, taps);
+#endif
+ d_nsamples = d_filter->set_taps(taps);
+ set_output_multiple(d_nsamples);
}
gr_fft_filter_ccc::~gr_fft_filter_ccc ()
{
- delete d_fwdfft;
- delete d_invfft;
+ delete d_filter;
}
-#if 0
-static void
-print_vector_complex(const std::string label, const std::vector<gr_complex> &x)
-{
- std::cout << label;
- for (unsigned i = 0; i < x.size(); i++)
- std::cout << x[i] << " ";
- std::cout << "\n";
-}
-#endif
-
void
gr_fft_filter_ccc::set_taps (const std::vector<gr_complex> &taps)
{
@@ -85,130 +78,26 @@ gr_fft_filter_ccc::set_taps (const std::vector<gr_complex> &taps)
d_updated = true;
}
-/*
- * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
- */
-void
-gr_fft_filter_ccc::actual_set_taps (const std::vector<gr_complex> &taps)
-{
- int i = 0;
- compute_sizes(taps.size());
-
- d_tail.resize(tailsize());
- for (i = 0; i < tailsize(); i++)
- d_tail[i] = 0;
-
- gr_complex *in = d_fwdfft->get_inbuf();
- gr_complex *out = d_fwdfft->get_outbuf();
-
- float scale = 1.0 / d_fftsize;
-
- // Compute forward xform of taps.
- // Copy taps into first ntaps slots, then pad with zeros
- for (i = 0; i < d_ntaps; i++)
- in[i] = taps[i] * scale;
-
- for (; i < d_fftsize; i++)
- in[i] = 0;
-
- d_fwdfft->execute(); // do the xform
-
- // now copy output to d_xformed_taps
- for (i = 0; i < d_fftsize; i++)
- d_xformed_taps[i] = out[i];
-
- //print_vector_complex("transformed taps:", d_xformed_taps);
-}
-
-// determine and set d_ntaps, d_nsamples, d_fftsize
-
-void
-gr_fft_filter_ccc::compute_sizes(int ntaps)
-{
- int old_fftsize = d_fftsize;
- d_ntaps = ntaps;
- d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
- d_nsamples = d_fftsize - d_ntaps + 1;
-
- if (0)
- fprintf(stderr, "gr_fft_filter: ntaps = %d, fftsize = %d, nsamples = %d\n",
- d_ntaps, d_fftsize, d_nsamples);
-
- assert(d_fftsize == d_ntaps + d_nsamples -1 );
-
- if (d_fftsize != old_fftsize){ // compute new plans
- delete d_fwdfft;
- delete d_invfft;
- d_fwdfft = new gri_fft_complex(d_fftsize, true);
- d_invfft = new gri_fft_complex(d_fftsize, false);
- d_xformed_taps.resize(d_fftsize);
- }
-
- set_output_multiple(d_nsamples);
-}
-
int
gr_fft_filter_ccc::work (int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
- gr_complex *in = (gr_complex *) input_items[0];
+ const gr_complex *in = (const gr_complex *) input_items[0];
gr_complex *out = (gr_complex *) output_items[0];
if (d_updated){
- actual_set_taps(d_new_taps);
+ d_nsamples = d_filter->set_taps(d_new_taps);
d_updated = false;
+ set_output_multiple(d_nsamples);
return 0; // output multiple may have changed
}
assert(noutput_items % d_nsamples == 0);
- int dec_ctr = 0;
- int j = 0;
- int ninput_items = noutput_items * decimation();
-
- for (int i = 0; i < ninput_items; i += d_nsamples){
-
- memcpy(d_fwdfft->get_inbuf(), &in[i], d_nsamples * sizeof(gr_complex));
-
- for (j = d_nsamples; j < d_fftsize; j++)
- d_fwdfft->get_inbuf()[j] = 0;
-
- d_fwdfft->execute(); // compute fwd xform
-
- gr_complex *a = d_fwdfft->get_outbuf();
- gr_complex *b = &d_xformed_taps[0];
- gr_complex *c = d_invfft->get_inbuf();
-
- for (j = 0; j < d_fftsize; j++) // filter in the freq domain
- c[j] = a[j] * b[j];
-
- d_invfft->execute(); // compute inv xform
-
- // add in the overlapping tail
-
- for (j = 0; j < tailsize(); j++)
- d_invfft->get_outbuf()[j] += d_tail[j];
-
- // copy nsamples to output
-
- //memcpy(out, d_invfft->get_outbuf(), d_nsamples * sizeof(gr_complex));
- //out += d_nsamples;
-
- j = dec_ctr;
- while (j < d_nsamples) {
- *out++ = d_invfft->get_outbuf()[j];
- j += decimation();
- }
- dec_ctr = (j - d_nsamples);
-
- // stash the tail
- memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
- tailsize() * sizeof(gr_complex));
- }
+ d_filter->filter(noutput_items, in, out);
- assert((out - (gr_complex *) output_items[0]) == noutput_items);
- assert(dec_ctr == 0);
+ //assert((out - (gr_complex *) output_items[0]) == noutput_items);
return noutput_items;
}
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h
index c5363dcbb..68b19e775 100644
--- a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h
@@ -28,8 +28,8 @@ class gr_fft_filter_ccc;
typedef boost::shared_ptr<gr_fft_filter_ccc> gr_fft_filter_ccc_sptr;
gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps);
-class gr_fir_ccc;
-class gri_fft_complex;
+//class gri_fft_filter_ccc_sse;
+class gri_fft_filter_ccc_generic;
/*!
* \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
@@ -40,15 +40,14 @@ class gr_fft_filter_ccc : public gr_sync_decimator
private:
friend gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps);
- int d_ntaps;
int d_nsamples;
- int d_fftsize; // fftsize = ntaps + nsamples - 1
- gri_fft_complex *d_fwdfft; // forward "plan"
- gri_fft_complex *d_invfft; // inverse "plan"
- std::vector<gr_complex> d_tail; // state carried between blocks for overlap-add
- std::vector<gr_complex> d_xformed_taps; // Fourier xformed taps
- std::vector<gr_complex> d_new_taps;
bool d_updated;
+#if 1 // don't enable the sse version until handling it is worked out
+ gri_fft_filter_ccc_generic *d_filter;
+#else
+ gri_fft_filter_ccc_sse *d_filter;
+#endif
+ std::vector<gr_complex> d_new_taps;
/*!
* Construct a FFT filter with the given taps
@@ -58,10 +57,6 @@ class gr_fft_filter_ccc : public gr_sync_decimator
*/
gr_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps);
- void compute_sizes(int ntaps);
- int tailsize() const { return d_ntaps - 1; }
- void actual_set_taps (const std::vector<gr_complex> &taps);
-
public:
~gr_fft_filter_ccc ();
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc
index 57232f3fb..e8857fe8c 100644
--- a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -25,13 +25,11 @@
#endif
#include <gr_fft_filter_fff.h>
+#include <gri_fft_filter_fff_generic.h>
+//#include <gri_fft_filter_fff_sse.h>
#include <gr_io_signature.h>
-#include <gri_fft.h>
-#include <math.h>
#include <assert.h>
#include <stdexcept>
-#include <gr_firdes.h>
-
#include <cstdio>
#include <iostream>
@@ -48,37 +46,24 @@ gr_fft_filter_fff::gr_fft_filter_fff (int decimation, const std::vector<float> &
gr_make_io_signature (1, 1, sizeof (float)),
gr_make_io_signature (1, 1, sizeof (float)),
decimation),
- d_fftsize(-1), d_fwdfft(0), d_invfft(0), d_updated(false)
+ d_updated(false)
{
set_history(1);
- actual_set_taps(taps);
-}
-
-gr_fft_filter_fff::~gr_fft_filter_fff ()
-{
- delete d_fwdfft;
- delete d_invfft;
-}
+
+#if 1 // don't enable the sse version until handling it is worked out
+ d_filter = new gri_fft_filter_fff_generic(decimation, taps);
+#else
+ d_filter = new gri_fft_filter_fff_sse(decimation, taps);
+#endif
-#if 0
-static void
-print_vector_complex(const std::string label, const std::vector<gr_complex> &x)
-{
- std::cout << label;
- for (unsigned i = 0; i < x.size(); i++)
- std::cout << x[i] << " ";
- std::cout << "\n";
+ d_nsamples = d_filter->set_taps(taps);
+ set_output_multiple(d_nsamples);
}
-static void
-print_vector_float(const std::string label, const std::vector<float> &x)
+gr_fft_filter_fff::~gr_fft_filter_fff ()
{
- std::cout << label;
- for (unsigned i = 0; i < x.size(); i++)
- std::cout << x[i] << " ";
- std::cout << "\n";
+ delete d_filter;
}
-#endif
void
gr_fft_filter_fff::set_taps (const std::vector<float> &taps)
@@ -87,68 +72,6 @@ gr_fft_filter_fff::set_taps (const std::vector<float> &taps)
d_updated = true;
}
-/*
- * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
- */
-void
-gr_fft_filter_fff::actual_set_taps (const std::vector<float> &taps)
-{
- int i = 0;
- compute_sizes(taps.size());
-
- d_tail.resize(tailsize());
- for (i = 0; i < tailsize(); i++)
- d_tail[i] = 0;
-
- float *in = d_fwdfft->get_inbuf();
- gr_complex *out = d_fwdfft->get_outbuf();
-
- float scale = 1.0 / d_fftsize;
-
- // Compute forward xform of taps.
- // Copy taps into first ntaps slots, then pad with zeros
- for (i = 0; i < d_ntaps; i++)
- in[i] = taps[i] * scale;
-
- for (; i < d_fftsize; i++)
- in[i] = 0;
-
- d_fwdfft->execute(); // do the xform
-
- // now copy output to d_xformed_taps
- for (i = 0; i < d_fftsize/2+1; i++)
- d_xformed_taps[i] = out[i];
-
- //print_vector_complex("transformed taps:", d_xformed_taps);
-}
-
-// determine and set d_ntaps, d_nsamples, d_fftsize
-
-void
-gr_fft_filter_fff::compute_sizes(int ntaps)
-{
- int old_fftsize = d_fftsize;
- d_ntaps = ntaps;
- d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
- d_nsamples = d_fftsize - d_ntaps + 1;
-
- if (0)
- fprintf(stderr, "gr_fft_filter: ntaps = %d, fftsize = %d, nsamples = %d\n",
- d_ntaps, d_fftsize, d_nsamples);
-
- assert(d_fftsize == d_ntaps + d_nsamples -1 );
-
- if (d_fftsize != old_fftsize){ // compute new plans
- delete d_fwdfft;
- delete d_invfft;
- d_fwdfft = new gri_fft_real_fwd(d_fftsize);
- d_invfft = new gri_fft_real_rev(d_fftsize);
- d_xformed_taps.resize(d_fftsize/2+1);
- }
-
- set_output_multiple(d_nsamples);
-}
-
int
gr_fft_filter_fff::work (int noutput_items,
gr_vector_const_void_star &input_items,
@@ -158,59 +81,17 @@ gr_fft_filter_fff::work (int noutput_items,
float *out = (float *) output_items[0];
if (d_updated){
- actual_set_taps(d_new_taps);
+ d_nsamples = d_filter->set_taps(d_new_taps);
d_updated = false;
+ set_output_multiple(d_nsamples);
return 0; // output multiple may have changed
}
assert(noutput_items % d_nsamples == 0);
+
+ d_filter->filter(noutput_items, in, out);
- int dec_ctr = 0;
- int j = 0;
- int ninput_items = noutput_items * decimation();
-
- for (int i = 0; i < ninput_items; i += d_nsamples){
-
- memcpy(d_fwdfft->get_inbuf(), &in[i], d_nsamples * sizeof(float));
-
- for (j = d_nsamples; j < d_fftsize; j++)
- d_fwdfft->get_inbuf()[j] = 0;
-
- d_fwdfft->execute(); // compute fwd xform
-
- gr_complex *a = d_fwdfft->get_outbuf();
- gr_complex *b = &d_xformed_taps[0];
- gr_complex *c = d_invfft->get_inbuf();
-
- for (j = 0; j < d_fftsize/2+1; j++) // filter in the freq domain
- c[j] = a[j] * b[j];
-
- d_invfft->execute(); // compute inv xform
-
- // add in the overlapping tail
-
- for (j = 0; j < tailsize(); j++)
- d_invfft->get_outbuf()[j] += d_tail[j];
-
- // copy nsamples to output
-
- //memcpy(out, d_invfft->get_outbuf(), d_nsamples * sizeof(float));
- //out += d_nsamples;
-
- j = dec_ctr;
- while (j < d_nsamples) {
- *out++ = d_invfft->get_outbuf()[j];
- j += decimation();
- }
- dec_ctr = (j - d_nsamples);
-
- // stash the tail
- memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
- tailsize() * sizeof(float));
- }
-
- assert((out - (float *) output_items[0]) == noutput_items);
- assert(dec_ctr == 0);
+ //assert((out - (float *) output_items[0]) == noutput_items);
return noutput_items;
}
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h
index b26361107..6eaa21500 100644
--- a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h
@@ -28,9 +28,8 @@ class gr_fft_filter_fff;
typedef boost::shared_ptr<gr_fft_filter_fff> gr_fft_filter_fff_sptr;
gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps);
-class gr_fir_fff;
-class gri_fft_real_fwd;
-class gri_fft_real_rev;
+class gri_fft_filter_fff_generic;
+//class gri_fft_filter_fff_sse;
/*!
* \brief Fast FFT filter with float input, float output and float taps
@@ -41,15 +40,14 @@ class gr_fft_filter_fff : public gr_sync_decimator
private:
friend gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps);
- int d_ntaps;
int d_nsamples;
- int d_fftsize; // fftsize = ntaps + nsamples - 1
- gri_fft_real_fwd *d_fwdfft; // forward "plan"
- gri_fft_real_rev *d_invfft; // inverse "plan"
- std::vector<float> d_tail; // state carried between blocks for overlap-add
- std::vector<gr_complex> d_xformed_taps; // Fourier xformed taps
- std::vector<float> d_new_taps;
bool d_updated;
+#if 1 // don't enable the sse version until handling it is worked out
+ gri_fft_filter_fff_generic *d_filter;
+#else
+ gri_fft_filter_fff_sse *d_filter;
+#endif
+ std::vector<float> d_new_taps;
/*!
* Construct a FFT filter with the given taps
@@ -58,10 +56,6 @@ class gr_fft_filter_fff : public gr_sync_decimator
* \param taps float filter taps
*/
gr_fft_filter_fff (int decimation, const std::vector<float> &taps);
-
- void compute_sizes(int ntaps);
- int tailsize() const { return d_ntaps - 1; }
- void actual_set_taps (const std::vector<float> &taps);
public:
~gr_fft_filter_fff ();
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc
index 59454afe5..ff4fb70a3 100644
--- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc
+++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2009 Free Software Foundation, Inc.
+ * Copyright 2009,2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -93,9 +93,16 @@ gr_pfb_clock_sync_ccf::~gr_pfb_clock_sync_ccf ()
{
for(int i = 0; i < d_nfilters; i++) {
delete d_filters[i];
+ delete d_diff_filters[i];
}
}
+bool
+gr_pfb_clock_sync_ccf::check_topology(int ninputs, int noutputs)
+{
+ return noutputs == 1 || noutputs == 4;
+}
+
void
gr_pfb_clock_sync_ccf::set_taps (const std::vector<float> &newtaps,
std::vector< std::vector<float> > &ourtaps,
@@ -219,8 +226,8 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items,
gr_complex *in = (gr_complex *) input_items[0];
gr_complex *out = (gr_complex *) output_items[0];
- float *err, *outrate, *outk;
- if(output_items.size() > 2) {
+ float *err = 0, *outrate = 0, *outk = 0;
+ if(output_items.size() == 4) {
err = (float *) output_items[1];
outrate = (float*)output_items[2];
outk = (float*)output_items[3];
@@ -271,7 +278,7 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items,
i++;
count += (int)floor(d_sps);
- if(output_items.size() > 2) {
+ if(output_items.size() == 4) {
err[i] = error;
outrate[i] = d_rate_f;
outk[i] = d_k;
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h
index a07192a7f..70857173b 100644
--- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h
+++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2009 Free Software Foundation, Inc.
+ * Copyright 2009,2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -119,6 +119,8 @@ public:
d_max_dev = m;
}
+ bool check_topology(int ninputs, int noutputs);
+
int general_work (int noutput_items,
gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items,
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.cc b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.cc
index d1d2f05db..86de3b5a1 100644
--- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.cc
+++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2009 Free Software Foundation, Inc.
+ * Copyright 2009,2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -93,9 +93,16 @@ gr_pfb_clock_sync_fff::~gr_pfb_clock_sync_fff ()
{
for(int i = 0; i < d_nfilters; i++) {
delete d_filters[i];
+ delete d_diff_filters[i];
}
}
+bool
+gr_pfb_clock_sync_fff::check_topology(int ninputs, int noutputs)
+{
+ return noutputs == 1 || noutputs == 4;
+}
+
void
gr_pfb_clock_sync_fff::set_taps (const std::vector<float> &newtaps,
std::vector< std::vector<float> > &ourtaps,
@@ -219,8 +226,8 @@ gr_pfb_clock_sync_fff::general_work (int noutput_items,
float *in = (float *) input_items[0];
float *out = (float *) output_items[0];
- float *err, *outrate, *outk;
- if(output_items.size() > 2) {
+ float *err = 0, *outrate = 0, *outk = 0;
+ if(output_items.size() == 4) {
err = (float *) output_items[1];
outrate = (float*)output_items[2];
outk = (float*)output_items[3];
@@ -269,7 +276,7 @@ gr_pfb_clock_sync_fff::general_work (int noutput_items,
i++;
count += (int)floor(d_sps);
- if(output_items.size() > 2) {
+ if(output_items.size() == 4) {
err[i] = error;
outrate[i] = d_rate_f;
outk[i] = d_k;
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.h b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.h
index 913f798fe..10eec4f54 100644
--- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.h
+++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2009 Free Software Foundation, Inc.
+ * Copyright 2009,2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -118,7 +118,9 @@ public:
{
d_max_dev = m;
}
-
+
+ bool check_topology(int ninputs, int noutputs);
+
int general_work (int noutput_items,
gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items,
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc
new file mode 100644
index 000000000..1bf4a6f4b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc
@@ -0,0 +1,167 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_fft_filter_ccc_generic.h>
+#include <gri_fft.h>
+#include <assert.h>
+#include <stdexcept>
+#include <cstdio>
+#include <cstring>
+#include <fftw3.h>
+
+gri_fft_filter_ccc_generic::gri_fft_filter_ccc_generic (int decimation,
+ const std::vector<gr_complex> &taps)
+ : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0)
+{
+ set_taps(taps);
+}
+
+gri_fft_filter_ccc_generic::~gri_fft_filter_ccc_generic ()
+{
+ delete d_fwdfft;
+ delete d_invfft;
+}
+
+#if 0
+static void
+print_vector_complex(const std::string label, const std::vector<gr_complex> &x)
+{
+ std::cout << label;
+ for (unsigned i = 0; i < x.size(); i++)
+ std::cout << x[i] << " ";
+ std::cout << "\n";
+}
+#endif
+
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+int
+gri_fft_filter_ccc_generic::set_taps (const std::vector<gr_complex> &taps)
+{
+ int i = 0;
+ compute_sizes(taps.size());
+
+ d_tail.resize(tailsize());
+ for (i = 0; i < tailsize(); i++)
+ d_tail[i] = 0;
+
+ gr_complex *in = d_fwdfft->get_inbuf();
+ gr_complex *out = d_fwdfft->get_outbuf();
+
+ float scale = 1.0 / d_fftsize;
+
+ // Compute forward xform of taps.
+ // Copy taps into first ntaps slots, then pad with zeros
+ for (i = 0; i < d_ntaps; i++)
+ in[i] = taps[i] * scale;
+
+ for (; i < d_fftsize; i++)
+ in[i] = 0;
+
+ d_fwdfft->execute(); // do the xform
+
+ // now copy output to d_xformed_taps
+ for (i = 0; i < d_fftsize; i++)
+ d_xformed_taps[i] = out[i];
+
+ return d_nsamples;
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gri_fft_filter_ccc_generic::compute_sizes(int ntaps)
+{
+ int old_fftsize = d_fftsize;
+ d_ntaps = ntaps;
+ d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
+ d_nsamples = d_fftsize - d_ntaps + 1;
+
+ if (0)
+ fprintf(stderr, "gri_fft_filter_ccc_generic: ntaps = %d, fftsize = %d, nsamples = %d\n",
+ d_ntaps, d_fftsize, d_nsamples);
+
+ assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+ if (d_fftsize != old_fftsize){ // compute new plans
+ delete d_fwdfft;
+ delete d_invfft;
+ d_fwdfft = new gri_fft_complex(d_fftsize, true);
+ d_invfft = new gri_fft_complex(d_fftsize, false);
+ d_xformed_taps.resize(d_fftsize);
+ }
+}
+
+int
+gri_fft_filter_ccc_generic::filter (int nitems, const gr_complex *input, gr_complex *output)
+{
+ int dec_ctr = 0;
+ int j = 0;
+ int ninput_items = nitems * d_decimation;
+
+ for (int i = 0; i < ninput_items; i += d_nsamples){
+
+ memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(gr_complex));
+
+ for (j = d_nsamples; j < d_fftsize; j++)
+ d_fwdfft->get_inbuf()[j] = 0;
+
+ d_fwdfft->execute(); // compute fwd xform
+
+ gr_complex *a = d_fwdfft->get_outbuf();
+ gr_complex *b = &d_xformed_taps[0];
+ gr_complex *c = d_invfft->get_inbuf();
+
+ for (j = 0; j < d_fftsize; j+=1) { // filter in the freq domain
+ c[j] = a[j] * b[j];
+ }
+
+ d_invfft->execute(); // compute inv xform
+
+ // add in the overlapping tail
+
+ for (j = 0; j < tailsize(); j++)
+ d_invfft->get_outbuf()[j] += d_tail[j];
+
+ // copy nsamples to output
+ j = dec_ctr;
+ while (j < d_nsamples) {
+ *output++ = d_invfft->get_outbuf()[j];
+ j += d_decimation;
+ }
+ dec_ctr = (j - d_nsamples);
+
+ // stash the tail
+ memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+ tailsize() * sizeof(gr_complex));
+ }
+
+ assert(dec_ctr == 0);
+
+ return nitems;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h
new file mode 100644
index 000000000..3cd9105c7
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_FFT_FILTER_CCC_GENERIC_H
+#define INCLUDED_GRI_FFT_FILTER_CCC_GENERIC_H
+
+#include <gr_complex.h>
+#include <vector>
+
+class gri_fft_complex;
+
+/*!
+ * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
+ * \ingroup filter_blk
+ */
+class gri_fft_filter_ccc_generic
+{
+ private:
+ int d_ntaps;
+ int d_nsamples;
+ int d_fftsize; // fftsize = ntaps + nsamples - 1
+ int d_decimation;
+ gri_fft_complex *d_fwdfft; // forward "plan"
+ gri_fft_complex *d_invfft; // inverse "plan"
+ std::vector<gr_complex> d_tail; // state carried between blocks for overlap-add
+ std::vector<gr_complex> d_xformed_taps; // Fourier xformed taps
+ std::vector<gr_complex> d_new_taps;
+
+ void compute_sizes(int ntaps);
+ int tailsize() const { return d_ntaps - 1; }
+
+ public:
+ /*!
+ * \brief Construct an FFT filter for complex vectors with the given taps and decimation rate.
+ *
+ * This is the basic implementation for performing FFT filter for fast convolution
+ * in other blocks for complex vectors (such as gr_fft_filter_ccc).
+ * \param decimation The decimation rate of the filter (int)
+ * \param taps The filter taps (complex)
+ */
+ gri_fft_filter_ccc_generic (int decimation, const std::vector<gr_complex> &taps);
+ ~gri_fft_filter_ccc_generic ();
+
+ /*!
+ * \brief Set new taps for the filter.
+ *
+ * Sets new taps and resets the class properties to handle different sizes
+ * \param taps The filter taps (complex)
+ */
+ int set_taps (const std::vector<gr_complex> &taps);
+
+ /*!
+ * \brief Perform the filter operation
+ *
+ * \param nitems The number of items to produce
+ * \param input The input vector to be filtered
+ * \param output The result of the filter operation
+ */
+ int filter (int nitems, const gr_complex *input, gr_complex *output);
+
+};
+
+#endif /* INCLUDED_GRI_FFT_FILTER_CCC_GENERIC_H */
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.cc
new file mode 100644
index 000000000..b7d925ff3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.cc
@@ -0,0 +1,186 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_fft_filter_ccc_sse.h>
+#include <gri_fft.h>
+#include <assert.h>
+#include <stdexcept>
+#include <cstdio>
+#include <xmmintrin.h>
+#include <fftw3.h>
+
+gri_fft_filter_ccc_sse::gri_fft_filter_ccc_sse (int decimation,
+ const std::vector<gr_complex> &taps)
+ : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0)
+{
+ d_xformed_taps = (gr_complex*)fftwf_malloc(1*sizeof(gr_complex));
+ set_taps(taps);
+}
+
+gri_fft_filter_ccc_sse::~gri_fft_filter_ccc_sse ()
+{
+ fftwf_free(d_xformed_taps);
+ delete d_fwdfft;
+ delete d_invfft;
+}
+
+#if 0
+static void
+print_vector_complex(const std::string label, const std::vector<gr_complex> &x)
+{
+ std::cout << label;
+ for (unsigned i = 0; i < x.size(); i++)
+ std::cout << x[i] << " ";
+ std::cout << "\n";
+}
+#endif
+
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+int
+gri_fft_filter_ccc_sse::set_taps (const std::vector<gr_complex> &taps)
+{
+ int i = 0;
+ compute_sizes(taps.size());
+
+ d_tail.resize(tailsize());
+ for (i = 0; i < tailsize(); i++)
+ d_tail[i] = 0;
+
+ gr_complex *in = d_fwdfft->get_inbuf();
+ gr_complex *out = d_fwdfft->get_outbuf();
+
+ float scale = 1.0 / d_fftsize;
+
+ // Compute forward xform of taps.
+ // Copy taps into first ntaps slots, then pad with zeros
+ for (i = 0; i < d_ntaps; i++)
+ in[i] = taps[i] * scale;
+
+ for (; i < d_fftsize; i++)
+ in[i] = 0;
+
+ d_fwdfft->execute(); // do the xform
+
+ // now copy output to d_xformed_taps
+ for (i = 0; i < d_fftsize; i++)
+ d_xformed_taps[i] = out[i];
+
+ return d_nsamples;
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gri_fft_filter_ccc_sse::compute_sizes(int ntaps)
+{
+ int old_fftsize = d_fftsize;
+ d_ntaps = ntaps;
+ d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
+ d_nsamples = d_fftsize - d_ntaps + 1;
+
+ if (0)
+ fprintf(stderr, "gri_fft_filter_ccc_sse: ntaps = %d, fftsize = %d, nsamples = %d\n",
+ d_ntaps, d_fftsize, d_nsamples);
+
+ assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+ if (d_fftsize != old_fftsize){ // compute new plans
+ delete d_fwdfft;
+ delete d_invfft;
+ d_fwdfft = new gri_fft_complex(d_fftsize, true);
+ d_invfft = new gri_fft_complex(d_fftsize, false);
+
+ fftwf_free(d_xformed_taps);
+ d_xformed_taps = (gr_complex*)fftwf_malloc((d_fftsize)*sizeof(gr_complex));
+ }
+}
+
+int
+gri_fft_filter_ccc_sse::filter (int nitems, const gr_complex *input, gr_complex *output)
+{
+ int dec_ctr = 0;
+ int j = 0;
+ int ninput_items = nitems * d_decimation;
+
+ for (int i = 0; i < ninput_items; i += d_nsamples){
+
+ memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(gr_complex));
+
+ for (j = d_nsamples; j < d_fftsize; j++)
+ d_fwdfft->get_inbuf()[j] = 0;
+
+ d_fwdfft->execute(); // compute fwd xform
+
+ float *a = (float*)(d_fwdfft->get_outbuf());
+ float *b = (float*)(&d_xformed_taps[0]);
+ float *c = (float*)(d_invfft->get_inbuf());
+
+ __m128 x0, x1, x2, t0, t1, m;
+ m = _mm_set_ps(-1, 1, -1, 1);
+ for (j = 0; j < 2*d_fftsize; j+=4) { // filter in the freq domain
+ x0 = _mm_load_ps(&a[j]);
+ t0 = _mm_load_ps(&b[j]);
+
+ t1 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(3, 3, 1, 1));
+ t0 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(2, 2, 0, 0));
+ t1 = _mm_mul_ps(t1, m);
+
+ x1 = _mm_mul_ps(x0, t0);
+ x2 = _mm_mul_ps(x0, t1);
+
+ x2 = _mm_shuffle_ps(x2, x2, _MM_SHUFFLE(2, 3, 0, 1));
+ x2 = _mm_add_ps(x1, x2);
+
+ _mm_store_ps(&c[j], x2);
+ }
+
+ d_invfft->execute(); // compute inv xform
+
+ // add in the overlapping tail
+
+ for (j = 0; j < tailsize(); j++)
+ d_invfft->get_outbuf()[j] += d_tail[j];
+
+ // copy nsamples to output
+ j = dec_ctr;
+ while (j < d_nsamples) {
+ *output++ = d_invfft->get_outbuf()[j];
+ j += d_decimation;
+ }
+ dec_ctr = (j - d_nsamples);
+
+ // stash the tail
+ memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+ tailsize() * sizeof(gr_complex));
+ }
+
+ assert(dec_ctr == 0);
+
+ return nitems;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.h b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.h
new file mode 100644
index 000000000..d1c54f01f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.h
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_FFT_FILTER_CCC_SSE_H
+#define INCLUDED_GRI_FFT_FILTER_CCC_SSE_H
+
+#include <gr_complex.h>
+#include <vector>
+
+class gri_fft_complex;
+
+/*!
+ * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
+ * \ingroup filter_blk
+ */
+class gri_fft_filter_ccc_sse
+{
+ private:
+ int d_ntaps;
+ int d_nsamples;
+ int d_fftsize; // fftsize = ntaps + nsamples - 1
+ int d_decimation;
+ gri_fft_complex *d_fwdfft; // forward "plan"
+ gri_fft_complex *d_invfft; // inverse "plan"
+ std::vector<gr_complex> d_tail; // state carried between blocks for overlap-add
+ gr_complex *d_xformed_taps;
+ std::vector<gr_complex> d_new_taps;
+
+ void compute_sizes(int ntaps);
+ int tailsize() const { return d_ntaps - 1; }
+
+ public:
+ /*!
+ * \brief Construct an FFT filter for complex vectors with the given taps and decimation rate.
+ *
+ * This is the basic implementation for performing FFT filter for fast convolution
+ * in other blocks for complex vectors (such as gr_fft_filter_ccc).
+ * \param decimation The decimation rate of the filter (int)
+ * \param taps The filter taps (complex)
+ */
+ gri_fft_filter_ccc_sse (int decimation, const std::vector<gr_complex> &taps);
+ ~gri_fft_filter_ccc_sse ();
+
+ /*!
+ * \brief Set new taps for the filter.
+ *
+ * Sets new taps and resets the class properties to handle different sizes
+ * \param taps The filter taps (complex)
+ */
+ int set_taps (const std::vector<gr_complex> &taps);
+
+ /*!
+ * \brief Perform the filter operation
+ *
+ * \param nitems The number of items to produce
+ * \param input The input vector to be filtered
+ * \param output The result of the filter operation
+ */
+ int filter (int nitems, const gr_complex *input, gr_complex *output);
+
+};
+
+#endif /* INCLUDED_GRI_FFT_FILTER_CCC_SSE_H */
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc
new file mode 100644
index 000000000..74058fa93
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc
@@ -0,0 +1,158 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_fft_filter_fff_generic.h>
+#include <gri_fft.h>
+#include <assert.h>
+#include <stdexcept>
+#include <cstdio>
+#include <cstring>
+
+gri_fft_filter_fff_generic::gri_fft_filter_fff_generic (int decimation,
+ const std::vector<float> &taps)
+ : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0)
+{
+ set_taps(taps);
+}
+
+gri_fft_filter_fff_generic::~gri_fft_filter_fff_generic ()
+{
+ delete d_fwdfft;
+ delete d_invfft;
+}
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+int
+gri_fft_filter_fff_generic::set_taps (const std::vector<float> &taps)
+{
+ int i = 0;
+ compute_sizes(taps.size());
+
+ d_tail.resize(tailsize());
+ for (i = 0; i < tailsize(); i++)
+ d_tail[i] = 0;
+
+ float *in = d_fwdfft->get_inbuf();
+ gr_complex *out = d_fwdfft->get_outbuf();
+
+ float scale = 1.0 / d_fftsize;
+
+ // Compute forward xform of taps.
+ // Copy taps into first ntaps slots, then pad with zeros
+ for (i = 0; i < d_ntaps; i++)
+ in[i] = taps[i] * scale;
+
+ for (; i < d_fftsize; i++)
+ in[i] = 0;
+
+ d_fwdfft->execute(); // do the xform
+
+ // now copy output to d_xformed_taps
+ for (i = 0; i < d_fftsize/2+1; i++)
+ d_xformed_taps[i] = out[i];
+
+ return d_nsamples;
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gri_fft_filter_fff_generic::compute_sizes(int ntaps)
+{
+ int old_fftsize = d_fftsize;
+ d_ntaps = ntaps;
+ d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
+ d_nsamples = d_fftsize - d_ntaps + 1;
+
+ if (0)
+ fprintf(stderr, "gri_fft_filter_fff_generic: ntaps = %d, fftsize = %d, nsamples = %d\n",
+ d_ntaps, d_fftsize, d_nsamples);
+
+ assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+ if (d_fftsize != old_fftsize){ // compute new plans
+ delete d_fwdfft;
+ delete d_invfft;
+ d_fwdfft = new gri_fft_real_fwd(d_fftsize);
+ d_invfft = new gri_fft_real_rev(d_fftsize);
+ d_xformed_taps.resize(d_fftsize/2+1);
+ }
+}
+
+int
+gri_fft_filter_fff_generic::filter (int nitems, const float *input, float *output)
+{
+ int dec_ctr = 0;
+ int j = 0;
+ int ninput_items = nitems * d_decimation;
+
+ for (int i = 0; i < ninput_items; i += d_nsamples){
+
+ memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(float));
+
+ for (j = d_nsamples; j < d_fftsize; j++)
+ d_fwdfft->get_inbuf()[j] = 0;
+
+ d_fwdfft->execute(); // compute fwd xform
+
+ gr_complex *a = d_fwdfft->get_outbuf();
+ gr_complex *b = &d_xformed_taps[0];
+ gr_complex *c = d_invfft->get_inbuf();
+
+ for (j = 0; j < d_fftsize/2+1; j++) { // filter in the freq domain
+ c[j] = a[j] * b[j];
+ }
+
+ d_invfft->execute(); // compute inv xform
+
+ // add in the overlapping tail
+
+ for (j = 0; j < tailsize(); j++)
+ d_invfft->get_outbuf()[j] += d_tail[j];
+
+ // copy nsamples to output
+
+ //memcpy(out, d_invfft->get_outbuf(), d_nsamples * sizeof(float));
+ //out += d_nsamples;
+
+ j = dec_ctr;
+ while (j < d_nsamples) {
+ *output++ = d_invfft->get_outbuf()[j];
+ j += d_decimation;
+ }
+ dec_ctr = (j - d_nsamples);
+
+ // stash the tail
+ memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+ tailsize() * sizeof(float));
+ }
+
+ assert(dec_ctr == 0);
+
+ return nitems;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h
new file mode 100644
index 000000000..6c31632d5
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_FFT_FILTER_FFF_GENERIC_H
+#define INCLUDED_GRI_FFT_FILTER_FFF_GENERIC_H
+
+#include <gr_complex.h>
+#include <vector>
+
+class gri_fft_real_fwd;
+class gri_fft_real_rev;
+
+class gri_fft_filter_fff_generic
+{
+ private:
+ int d_ntaps;
+ int d_nsamples;
+ int d_fftsize; // fftsize = ntaps + nsamples - 1
+ int d_decimation;
+ gri_fft_real_fwd *d_fwdfft; // forward "plan"
+ gri_fft_real_rev *d_invfft; // inverse "plan"
+ std::vector<float> d_tail; // state carried between blocks for overlap-add
+ std::vector<gr_complex> d_xformed_taps; // Fourier xformed taps
+ std::vector<float> d_new_taps;
+
+
+ void compute_sizes(int ntaps);
+ int tailsize() const { return d_ntaps - 1; }
+
+ public:
+ /*!
+ * \brief Construct a FFT filter for float vectors with the given taps and decimation rate.
+ *
+ * This is the basic implementation for performing FFT filter for fast convolution
+ * in other blocks for floating point vectors (such as gr_fft_filter_fff).
+ * \param decimation The decimation rate of the filter (int)
+ * \param taps The filter taps (float)
+ */
+ gri_fft_filter_fff_generic (int decimation, const std::vector<float> &taps);
+ ~gri_fft_filter_fff_generic ();
+
+ /*!
+ * \brief Set new taps for the filter.
+ *
+ * Sets new taps and resets the class properties to handle different sizes
+ * \param taps The filter taps (float)
+ */
+ int set_taps (const std::vector<float> &taps);
+
+ /*!
+ * \brief Perform the filter operation
+ *
+ * \param nitems The number of items to produce
+ * \param input The input vector to be filtered
+ * \param output The result of the filter operation
+ */
+ int filter (int nitems, const float *input, float *output);
+
+};
+
+#endif /* INCLUDED_GRI_FFT_FILTER_FFF_GENERIC_H */
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.cc
new file mode 100644
index 000000000..2680e6594
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.cc
@@ -0,0 +1,184 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_fft_filter_fff_sse.h>
+#include <gri_fft.h>
+#include <assert.h>
+#include <stdexcept>
+#include <cstdio>
+#include <xmmintrin.h>
+#include <fftw3.h>
+
+gri_fft_filter_fff_sse::gri_fft_filter_fff_sse (int decimation,
+ const std::vector<float> &taps)
+ : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0)
+{
+ d_xformed_taps = (gr_complex*)fftwf_malloc(1*sizeof(gr_complex));
+ set_taps(taps);
+}
+
+gri_fft_filter_fff_sse::~gri_fft_filter_fff_sse ()
+{
+ fftwf_free(d_xformed_taps);
+ delete d_fwdfft;
+ delete d_invfft;
+}
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+int
+gri_fft_filter_fff_sse::set_taps (const std::vector<float> &taps)
+{
+ int i = 0;
+ compute_sizes(taps.size());
+
+ d_tail.resize(tailsize());
+ for (i = 0; i < tailsize(); i++)
+ d_tail[i] = 0;
+
+ float *in = d_fwdfft->get_inbuf();
+ gr_complex *out = d_fwdfft->get_outbuf();
+
+ float scale = 1.0 / d_fftsize;
+
+ // Compute forward xform of taps.
+ // Copy taps into first ntaps slots, then pad with zeros
+ for (i = 0; i < d_ntaps; i++)
+ in[i] = taps[i] * scale;
+
+ for (; i < d_fftsize; i++)
+ in[i] = 0;
+
+ d_fwdfft->execute(); // do the xform
+
+ // now copy output to d_xformed_taps
+ for (i = 0; i < d_fftsize/2+1; i++)
+ d_xformed_taps[i] = out[i];
+
+ return d_nsamples;
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gri_fft_filter_fff_sse::compute_sizes(int ntaps)
+{
+ int old_fftsize = d_fftsize;
+ d_ntaps = ntaps;
+ d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
+ d_nsamples = d_fftsize - d_ntaps + 1;
+
+ if (0)
+ fprintf(stderr, "gri_fft_filter_fff_sse: ntaps = %d, fftsize = %d, nsamples = %d\n",
+ d_ntaps, d_fftsize, d_nsamples);
+
+ assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+ if (d_fftsize != old_fftsize){ // compute new plans
+ delete d_fwdfft;
+ delete d_invfft;
+ d_fwdfft = new gri_fft_real_fwd(d_fftsize);
+ d_invfft = new gri_fft_real_rev(d_fftsize);
+ //d_xformed_taps.resize(d_fftsize/2+1);
+
+ fftwf_free(d_xformed_taps);
+ d_xformed_taps = (gr_complex*)fftwf_malloc((d_fftsize/2+1)*sizeof(gr_complex));
+ }
+}
+
+int
+gri_fft_filter_fff_sse::filter (int nitems, const float *input, float *output)
+{
+ int dec_ctr = 0;
+ int j = 0;
+ int ninput_items = nitems * d_decimation;
+
+ for (int i = 0; i < ninput_items; i += d_nsamples){
+
+ memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(float));
+
+ for (j = d_nsamples; j < d_fftsize; j++)
+ d_fwdfft->get_inbuf()[j] = 0;
+
+ d_fwdfft->execute(); // compute fwd xform
+
+ float *a = (float*)(d_fwdfft->get_outbuf());
+ float *b = (float*)(&d_xformed_taps[0]);
+ float *c = (float*)(d_invfft->get_inbuf());
+
+ __m128 x0, x1, x2, t0, t1, m;
+ m = _mm_set_ps(-1, 1, -1, 1);
+ for (j = 0; j < d_fftsize; j+=4) { // filter in the freq domain
+ x0 = _mm_load_ps(&a[j]);
+ t0 = _mm_load_ps(&b[j]);
+
+ t1 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(3, 3, 1, 1));
+ t0 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(2, 2, 0, 0));
+ t1 = _mm_mul_ps(t1, m);
+
+ x1 = _mm_mul_ps(x0, t0);
+ x2 = _mm_mul_ps(x0, t1);
+
+ x2 = _mm_shuffle_ps(x2, x2, _MM_SHUFFLE(2, 3, 0, 1));
+ x2 = _mm_add_ps(x1, x2);
+
+ _mm_store_ps(&c[j], x2);
+ }
+
+ // Finish off the last one; do the complex multiply as floats
+ j = d_fftsize/2;
+ c[j] = (a[j] * b[j]) - (a[j+1] * b[j+1]);
+ c[j+1] = (a[j] * b[j+1]) + (a[j+1] * b[j]);
+
+ d_invfft->execute(); // compute inv xform
+
+ // add in the overlapping tail
+
+ for (j = 0; j < tailsize(); j++)
+ d_invfft->get_outbuf()[j] += d_tail[j];
+
+ // copy nsamples to output
+
+ //memcpy(out, d_invfft->get_outbuf(), d_nsamples * sizeof(float));
+ //out += d_nsamples;
+
+ j = dec_ctr;
+ while (j < d_nsamples) {
+ *output++ = d_invfft->get_outbuf()[j];
+ j += d_decimation;
+ }
+ dec_ctr = (j - d_nsamples);
+
+ // stash the tail
+ memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+ tailsize() * sizeof(float));
+ }
+
+ assert(dec_ctr == 0);
+
+ return nitems;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.h b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.h
new file mode 100644
index 000000000..8258bb824
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.h
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_FFT_FILTER_FFF_SSE_H
+#define INCLUDED_GRI_FFT_FILTER_FFF_SSE_H
+
+#include <gr_complex.h>
+#include <vector>
+
+class gri_fft_real_fwd;
+class gri_fft_real_rev;
+
+class gri_fft_filter_fff_sse
+{
+ private:
+ int d_ntaps;
+ int d_nsamples;
+ int d_fftsize; // fftsize = ntaps + nsamples - 1
+ int d_decimation;
+ gri_fft_real_fwd *d_fwdfft; // forward "plan"
+ gri_fft_real_rev *d_invfft; // inverse "plan"
+ std::vector<float> d_tail; // state carried between blocks for overlap-add
+ //std::vector<gr_complex> d_xformed_taps; // Fourier xformed taps
+ gr_complex *d_xformed_taps;
+ std::vector<float> d_new_taps;
+
+
+ void compute_sizes(int ntaps);
+ int tailsize() const { return d_ntaps - 1; }
+
+ public:
+ /*!
+ * \brief Construct a FFT filter for float vectors with the given taps and decimation rate.
+ *
+ * This is the basic implementation for performing FFT filter for fast convolution
+ * in other blocks for floating point vectors (such as gr_fft_filter_fff).
+ * \param decimation The decimation rate of the filter (int)
+ * \param taps The filter taps (float)
+ */
+ gri_fft_filter_fff_sse (int decimation, const std::vector<float> &taps);
+ ~gri_fft_filter_fff_sse ();
+
+ /*!
+ * \brief Set new taps for the filter.
+ *
+ * Sets new taps and resets the class properties to handle different sizes
+ * \param taps The filter taps (float)
+ */
+ int set_taps (const std::vector<float> &taps);
+
+ /*!
+ * \brief Perform the filter operation
+ *
+ * \param nitems The number of items to produce
+ * \param input The input vector to be filtered
+ * \param output The result of the filter operation
+ */
+ int filter (int nitems, const float *input, float *output);
+
+};
+
+#endif /* INCLUDED_GRI_FFT_FILTER_FFF_SSE_H */
diff --git a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc
index 030e45ddf..7f2c468b7 100644
--- a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc
+++ b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc
@@ -53,7 +53,7 @@ gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float ro
}
-static int ios[] = {sizeof(gr_complex), sizeof(float), sizeof(float), sizeof(float)};
+static int ios[] = {sizeof(gr_complex), sizeof(float), sizeof(float), sizeof(gr_complex)};
static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int));
gr_fll_band_edge_cc::gr_fll_band_edge_cc (float samps_per_sym, float rolloff,
int filter_size, float alpha, float beta)
@@ -83,10 +83,11 @@ gr_fll_band_edge_cc::~gr_fll_band_edge_cc ()
void
gr_fll_band_edge_cc::set_alpha(float alpha)
{
- float eta = sqrt(2.0)/2.0;
- float theta = alpha;
- d_alpha = (4*eta*theta) / (1.0 + 2.0*eta*theta + theta*theta);
- d_beta = (4*theta*theta) / (1.0 + 2.0*eta*theta + theta*theta);
+ //float eta = sqrt(2.0)/2.0;
+ //float theta = alpha;
+ //d_alpha = (4*eta*theta) / (1.0 + 2.0*eta*theta + theta*theta);
+ //d_beta = (4*theta*theta) / (1.0 + 2.0*eta*theta + theta*theta);
+ d_alpha = alpha;
}
void
@@ -160,11 +161,12 @@ gr_fll_band_edge_cc::work (int noutput_items,
const gr_complex *in = (const gr_complex *) input_items[0];
gr_complex *out = (gr_complex *) output_items[0];
- float *frq, *phs, *err;
+ float *frq, *phs;
+ gr_complex *err;
if(output_items.size() > 2) {
frq = (float *) output_items[1];
phs = (float *) output_items[2];
- err = (float *) output_items[3];
+ err = (gr_complex *) output_items[3];
}
if (d_updated) {
@@ -174,16 +176,17 @@ gr_fll_band_edge_cc::work (int noutput_items,
int i;
gr_complex nco_out;
- float out_upper, out_lower;
+ gr_complex out_upper, out_lower;
float error;
+ float avg_k = 0.1;
for(i = 0; i < noutput_items; i++) {
nco_out = gr_expj(d_phase);
out[i] = in[i] * nco_out;
- out_upper = norm(d_filter_upper->filter(&out[i]));
- out_lower = norm(d_filter_lower->filter(&out[i]));
- error = out_lower - out_upper;
- d_error = 0.01*error + 0.99*d_error; // average error
+ out_upper = (d_filter_upper->filter(&out[i]));
+ out_lower = (d_filter_lower->filter(&out[i]));
+ error = -real((out_upper + out_lower) * conj(out_upper - out_lower));
+ d_error = avg_k*error + avg_k*d_error; // average error
d_freq = d_freq + d_beta * d_error;
d_phase = d_phase + d_freq + d_alpha * d_error;
diff --git a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h
index 09baf7fde..178e18f3e 100644
--- a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h
+++ b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h
@@ -45,8 +45,12 @@ class gri_fft_complex;
* (e.g., rolloff factor) of the modulated signal. The placement in frequency of the band-edges
* is determined by the oversampling ratio (number of samples per symbol) and the excess bandwidth.
* The size of the filters should be fairly large so as to average over a number of symbols.
- * The FLL works by calculating the power in both the upper and lower bands and comparing them. The
- * difference in power between the filters is proportional to the frequency offset.
+ *
+ * The FLL works by filtering the upper and lower band edges into x_u(t) and x_l(t), respectively.
+ * These are combined to form cc(t) = x_u(t) + x_l(t) and ss(t) = x_u(t) - x_l(t). Combining
+ * these to form the signal e(t) = Re{cc(t) \times ss(t)^*} (where ^* is the complex conjugate)
+ * provides an error signal at the DC term that is directly proportional to the carrier frequency.
+ * We then make a second-order loop using the error signal that is the running average of e(t).
*
* In theory, the band-edge filter is the derivative of the matched filter in frequency,
* (H_be(f) = \frac{H(f)}{df}. In practice, this comes down to a quarter sine wave at the point
diff --git a/gnuradio-core/src/python/gnuradio/Makefile.am b/gnuradio-core/src/python/gnuradio/Makefile.am
index dcc0017b3..f0516f2fd 100644
--- a/gnuradio-core/src/python/gnuradio/Makefile.am
+++ b/gnuradio-core/src/python/gnuradio/Makefile.am
@@ -30,6 +30,7 @@ grpython_PYTHON = \
eng_notation.py \
eng_option.py \
modulation_utils.py \
+ modulation_utils2.py \
ofdm_packet_utils.py \
packet_utils.py \
gr_unittest.py \
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am b/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am
index 68d683623..7b24fb69d 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2005,2007,2009 Free Software Foundation, Inc.
+# Copyright 2005,2007,2009,2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk.py b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk.py
index 860015c3f..55e4890f3 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk.py
@@ -233,10 +233,10 @@ class dbpsk_demod(gr.hier_block2):
arity = pow(2,self.bits_per_symbol())
# Automatic gain control
- scale = (1.0/16384.0)
- self.pre_scaler = gr.multiply_const_cc(scale) # scale the signal from full-range to +-1
- #self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100)
- self.agc = gr.feedforward_agc_cc(16, 2.0)
+ #scale = (1.0/16384.0)
+ #self.pre_scaler = gr.multiply_const_cc(scale) # scale the signal from full-range to +-1
+ self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100)
+ #self.agc = gr.feedforward_agc_cc(16, 2.0)
# RRC data filter
ntaps = 11 * samples_per_symbol
@@ -288,7 +288,7 @@ class dbpsk_demod(gr.hier_block2):
self._setup_logging()
# Connect and Initialize base class
- self.connect(self, self.pre_scaler, self.agc, self.rrc_filter, self.receiver,
+ self.connect(self, self.agc, self.rrc_filter, self.receiver,
self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self)
def samples_per_symbol(self):
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py
index e9fb3df89..d7bcf5390 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py
@@ -1,5 +1,5 @@
#
-# Copyright 2005,2006,2007 Free Software Foundation, Inc.
+# Copyright 2009,2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -25,7 +25,7 @@
differential BPSK modulation and demodulation.
"""
-from gnuradio import gr, gru, modulation_utils
+from gnuradio import gr, gru, modulation_utils2
from math import pi, sqrt, ceil
import psk
import cmath
@@ -38,8 +38,8 @@ _def_gray_code = True
_def_verbose = False
_def_log = False
-_def_freq_alpha = 4e-3
-_def_costas_alpha = 0.1
+_def_freq_alpha = 0.010
+_def_phase_alpha = 0.1
_def_timing_alpha = 0.100
_def_timing_beta = 0.010
_def_timing_max_dev = 1.5
@@ -83,7 +83,7 @@ class dbpsk2_mod(gr.hier_block2):
self._excess_bw = excess_bw
self._gray_code = gray_code
- if not isinstance(self._samples_per_symbol, int) or self._samples_per_symbol < 2:
+ if self._samples_per_symbol < 2:
raise TypeError, ("sbp must be an integer >= 2, is %d" % self._samples_per_symbol)
arity = pow(2,self.bits_per_symbol())
@@ -103,7 +103,7 @@ class dbpsk2_mod(gr.hier_block2):
# pulse shaping filter
nfilts = 32
- ntaps = nfilts * 11 * self._samples_per_symbol # make nfilts filters of ntaps each
+ ntaps = nfilts * 11 * int(self._samples_per_symbol) # make nfilts filters of ntaps each
self.rrc_taps = gr.firdes.root_raised_cosine(
nfilts, # gain
nfilts, # sampling rate based on 32 filters in resampler
@@ -145,7 +145,7 @@ class dbpsk2_mod(gr.hier_block2):
"""
Given command line options, create dictionary suitable for passing to __init__
"""
- return modulation_utils.extract_kwargs_from_options(dbpsk2_mod.__init__,
+ return modulation_utils2.extract_kwargs_from_options(dbpsk2_mod.__init__,
('self',), options)
extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
@@ -182,7 +182,7 @@ class dbpsk2_demod(gr.hier_block2):
samples_per_symbol=_def_samples_per_symbol,
excess_bw=_def_excess_bw,
freq_alpha=_def_freq_alpha,
- costas_alpha=_def_costas_alpha,
+ phase_alpha=_def_phase_alpha,
timing_alpha=_def_timing_alpha,
timing_max_dev=_def_timing_max_dev,
gray_code=_def_gray_code,
@@ -201,8 +201,8 @@ class dbpsk2_demod(gr.hier_block2):
@type excess_bw: float
@param freq_alpha: loop filter gain for frequency recovery
@type freq_alpha: float
- @param costas_alpha: loop filter gain for phase/fine frequency recovery
- @type costas_alpha: float
+ @param phase_alpha: loop filter gain for phase/fine frequency recovery
+ @type phase_alpha: float
@param timing_alpha: loop alpha gain for timing recovery
@type timing_alpha: float
@param timing_max: timing loop maximum rate deviations
@@ -226,8 +226,8 @@ class dbpsk2_demod(gr.hier_block2):
self._samples_per_symbol = samples_per_symbol
self._excess_bw = excess_bw
self._freq_alpha = freq_alpha
- self._freq_beta = 0.25*self._freq_alpha**2
- self._costas_alpha = costas_alpha
+ self._freq_beta = 0.10*self._freq_alpha
+ self._phase_alpha = phase_alpha
self._timing_alpha = timing_alpha
self._timing_beta = _def_timing_beta
self._timing_max_dev=timing_max_dev
@@ -259,13 +259,13 @@ class dbpsk2_demod(gr.hier_block2):
self.time_recov.set_beta(self._timing_beta)
# Perform phase / fine frequency correction
- self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha
+ self._phase_beta = 0.25 * self._phase_alpha * self._phase_alpha
# Allow a frequency swing of +/- half of the sample rate
fmin = -0.5
fmax = 0.5
- self.phase_recov = gr.costas_loop_cc(self._costas_alpha,
- self._costas_beta,
+ self.phase_recov = gr.costas_loop_cc(self._phase_alpha,
+ self._phase_beta,
fmax, fmin, arity)
# Do differential decoding based on phase change of symbols
@@ -308,29 +308,27 @@ class dbpsk2_demod(gr.hier_block2):
print "bits per symbol: %d" % self.bits_per_symbol()
print "Gray code: %s" % self._gray_code
print "RRC roll-off factor: %.2f" % self._excess_bw
- print "FLL gain: %.2f" % self._freq_alpha
- print "Costas Loop alpha: %.2f" % self._costas_alpha
- print "Costas Loop beta: %.2f" % self._costas_beta
- print "Timing alpha gain: %.2f" % self._timing_alpha
- print "Timing beta gain: %.2f" % self._timing_beta
+ print "FLL gain: %.2e" % self._freq_alpha
+ print "Timing alpha gain: %.2e" % self._timing_alpha
+ print "Timing beta gain: %.2e" % self._timing_beta
print "Timing max dev: %.2f" % self._timing_max_dev
+ print "Phase track alpha: %.2e" % self._phase_alpha
+ print "Phase track beta: %.2e" % self._phase_beta
def _setup_logging(self):
print "Modulation logging turned on."
- self.connect(self.pre_scaler,
- gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat"))
self.connect(self.agc,
gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat"))
- self.connect(self.rrc_filter,
- gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat"))
- self.connect(self.clock_recov,
- gr.file_sink(gr.sizeof_gr_complex, "rx_clock_recov.dat"))
+ self.connect(self.freq_recov,
+ gr.file_sink(gr.sizeof_gr_complex, "rx_freq_recov.dat"))
self.connect(self.time_recov,
gr.file_sink(gr.sizeof_gr_complex, "rx_time_recov.dat"))
+ self.connect(self.phase_recov,
+ gr.file_sink(gr.sizeof_gr_complex, "rx_phase_recov.dat"))
self.connect(self.diffdec,
gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat"))
self.connect(self.slicer,
- gr.file_sink(gr.sizeof_char, "rx_slicer.dat"))
+ gr.file_sink(gr.sizeof_char, "rx_slicer.dat"))
self.connect(self.symbol_mapper,
gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.dat"))
self.connect(self.unpack,
@@ -347,11 +345,11 @@ class dbpsk2_demod(gr.hier_block2):
help="disable gray coding on modulated bits (PSK)")
parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha,
help="set frequency lock loop alpha gain value [default=%default] (PSK)")
- parser.add_option("", "--costas-alpha", type="float", default=None,
- help="set Costas loop alpha value [default=%default] (PSK)")
- parser.add_option("", "--gain-alpha", type="float", default=_def_timing_alpha,
+ parser.add_option("", "--phase-alpha", type="float", default=_def_phase_alpha,
+ help="set phase tracking loop alpha value [default=%default] (PSK)")
+ parser.add_option("", "--timing-alpha", type="float", default=_def_timing_alpha,
help="set timing symbol sync loop gain alpha value [default=%default] (GMSK/PSK)")
- parser.add_option("", "--gain-beta", type="float", default=_def_timing_beta,
+ parser.add_option("", "--timing-beta", type="float", default=_def_timing_beta,
help="set timing symbol sync loop gain beta value [default=%default] (GMSK/PSK)")
parser.add_option("", "--timing-max-dev", type="float", default=_def_timing_max_dev,
help="set timing symbol sync loop maximum deviation [default=%default] (GMSK/PSK)")
@@ -361,11 +359,11 @@ class dbpsk2_demod(gr.hier_block2):
"""
Given command line options, create dictionary suitable for passing to __init__
"""
- return modulation_utils.extract_kwargs_from_options(
+ return modulation_utils2.extract_kwargs_from_options(
dbpsk2_demod.__init__, ('self',), options)
extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
#
# Add these to the mod/demod registry
#
-modulation_utils.add_type_1_mod('dbpsk2', dbpsk2_mod)
-modulation_utils.add_type_1_demod('dbpsk2', dbpsk2_demod)
+modulation_utils2.add_type_1_mod('dbpsk2', dbpsk2_mod)
+modulation_utils2.add_type_1_demod('dbpsk2', dbpsk2_demod)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py b/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py
index 9fae6acca..e1e627707 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py
@@ -1,5 +1,5 @@
#
-# Copyright 2005,2006,2007,2009 Free Software Foundation, Inc.
+# Copyright 2009,2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -25,7 +25,7 @@
differential QPSK modulation and demodulation.
"""
-from gnuradio import gr, gru, modulation_utils
+from gnuradio import gr, gru, modulation_utils2
from math import pi, sqrt
import psk
import cmath
@@ -38,8 +38,8 @@ _def_gray_code = True
_def_verbose = False
_def_log = False
-_def_freq_alpha = 4e-3
-_def_costas_alpha = 0.01
+_def_freq_alpha = 0.010
+_def_phase_alpha = 0.01
_def_timing_alpha = 0.100
_def_timing_beta = 0.010
_def_timing_max_dev = 1.5
@@ -83,8 +83,8 @@ class dqpsk2_mod(gr.hier_block2):
self._excess_bw = excess_bw
self._gray_code = gray_code
- if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2:
- raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol)
+ if samples_per_symbol < 2:
+ raise TypeError, ("sbp must be >= 2, is %f" % samples_per_symbol)
ntaps = 11 * samples_per_symbol
@@ -107,7 +107,7 @@ class dqpsk2_mod(gr.hier_block2):
# pulse shaping filter
nfilts = 32
- ntaps = nfilts * 11 * self._samples_per_symbol # make nfilts filters of ntaps each
+ ntaps = 11 * int(nfilts * self._samples_per_symbol) # make nfilts filters of ntaps each
self.rrc_taps = gr.firdes.root_raised_cosine(
nfilts, # gain
nfilts, # sampling rate based on 32 filters in resampler
@@ -168,7 +168,7 @@ class dqpsk2_mod(gr.hier_block2):
"""
Given command line options, create dictionary suitable for passing to __init__
"""
- return modulation_utils.extract_kwargs_from_options(dqpsk2_mod.__init__,
+ return modulation_utils2.extract_kwargs_from_options(dqpsk2_mod.__init__,
('self',), options)
extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
@@ -185,7 +185,7 @@ class dqpsk2_demod(gr.hier_block2):
samples_per_symbol=_def_samples_per_symbol,
excess_bw=_def_excess_bw,
freq_alpha=_def_freq_alpha,
- costas_alpha=_def_costas_alpha,
+ phase_alpha=_def_phase_alpha,
timing_alpha=_def_timing_alpha,
timing_max_dev=_def_timing_max_dev,
gray_code=_def_gray_code,
@@ -204,8 +204,8 @@ class dqpsk2_demod(gr.hier_block2):
@type excess_bw: float
@param freq_alpha: loop filter gain for frequency recovery
@type freq_alpha: float
- @param costas_alpha: loop filter gain
- @type costas_alphas: float
+ @param phase_alpha: loop filter gain
+ @type phase_alphas: float
@param timing_alpha: timing loop alpha gain
@type timing_alpha: float
@param timing_max: timing loop maximum rate deviations
@@ -230,7 +230,7 @@ class dqpsk2_demod(gr.hier_block2):
self._excess_bw = excess_bw
self._freq_alpha = freq_alpha
self._freq_beta = 0.25*self._freq_alpha**2
- self._costas_alpha = costas_alpha
+ self._phase_alpha = phase_alpha
self._timing_alpha = timing_alpha
self._timing_beta = _def_timing_beta
self._timing_max_dev=timing_max_dev
@@ -264,13 +264,13 @@ class dqpsk2_demod(gr.hier_block2):
# Perform phase / fine frequency correction
- self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha
+ self._phase_beta = 0.25 * self._phase_alpha * self._phase_alpha
# Allow a frequency swing of +/- half of the sample rate
fmin = -0.5
fmax = 0.5
- self.phase_recov = gr.costas_loop_cc(self._costas_alpha,
- self._costas_beta,
+ self.phase_recov = gr.costas_loop_cc(self._phase_alpha,
+ self._phase_beta,
fmax, fmin, arity)
@@ -315,24 +315,22 @@ class dqpsk2_demod(gr.hier_block2):
print "Gray code: %s" % self._gray_code
print "RRC roll-off factor: %.2f" % self._excess_bw
print "FLL gain: %.2f" % self._freq_alpha
- print "Costas Loop alpha: %.2e" % self._costas_alpha
- print "Costas Loop beta: %.2e" % self._costas_beta
print "Timing alpha gain: %.2f" % self._timing_alpha
print "Timing beta gain: %.2f" % self._timing_beta
print "Timing max dev: %.2f" % self._timing_max_dev
+ print "Phase track alpha: %.2e" % self._phase_alpha
+ print "Phase track beta: %.2e" % self._phase_beta
def _setup_logging(self):
print "Modulation logging turned on."
- self.connect(self.pre_scaler,
- gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat"))
self.connect(self.agc,
gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat"))
- self.connect(self.rrc_filter,
- gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat"))
- self.connect(self.clock_recov,
- gr.file_sink(gr.sizeof_gr_complex, "rx_clock_recov.dat"))
+ self.connect(self.freq_recov,
+ gr.file_sink(gr.sizeof_gr_complex, "rx_freq_recov.dat"))
self.connect(self.time_recov,
gr.file_sink(gr.sizeof_gr_complex, "rx_time_recov.dat"))
+ self.connect(self.phase_recov,
+ gr.file_sink(gr.sizeof_gr_complex, "rx_phase_recov.dat"))
self.connect(self.diffdec,
gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat"))
self.connect(self.slicer,
@@ -344,7 +342,7 @@ class dqpsk2_demod(gr.hier_block2):
def add_options(parser):
"""
- Adds modulation-specific options to the standard parser
+ Adds DQPSK demodulation-specific options to the standard parser
"""
parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw,
help="set RRC excess bandwith factor [default=%default] (PSK)")
@@ -353,11 +351,11 @@ class dqpsk2_demod(gr.hier_block2):
help="disable gray coding on modulated bits (PSK)")
parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha,
help="set frequency lock loop alpha gain value [default=%default] (PSK)")
- parser.add_option("", "--costas-alpha", type="float", default=_def_costas_alpha,
- help="set Costas loop alpha value [default=%default] (PSK)")
- parser.add_option("", "--gain-alpha", type="float", default=_def_timing_alpha,
+ parser.add_option("", "--phase-alpha", type="float", default=_def_phase_alpha,
+ help="set phase tracking loop alpha value [default=%default] (PSK)")
+ parser.add_option("", "--timing-alpha", type="float", default=_def_timing_alpha,
help="set timing symbol sync loop gain alpha value [default=%default] (GMSK/PSK)")
- parser.add_option("", "--gain-beta", type="float", default=_def_timing_beta,
+ parser.add_option("", "--timing-beta", type="float", default=_def_timing_beta,
help="set timing symbol sync loop gain beta value [default=%default] (GMSK/PSK)")
parser.add_option("", "--timing-max-dev", type="float", default=_def_timing_max_dev,
help="set timing symbol sync loop maximum deviation [default=%default] (GMSK/PSK)")
@@ -367,7 +365,7 @@ class dqpsk2_demod(gr.hier_block2):
"""
Given command line options, create dictionary suitable for passing to __init__
"""
- return modulation_utils.extract_kwargs_from_options(
+ return modulation_utils2.extract_kwargs_from_options(
dqpsk2_demod.__init__, ('self',), options)
extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
@@ -375,5 +373,5 @@ class dqpsk2_demod(gr.hier_block2):
#
# Add these to the mod/demod registry
#
-modulation_utils.add_type_1_mod('dqpsk2', dqpsk2_mod)
-modulation_utils.add_type_1_demod('dqpsk2', dqpsk2_demod)
+modulation_utils2.add_type_1_mod('dqpsk2', dqpsk2_mod)
+modulation_utils2.add_type_1_demod('dqpsk2', dqpsk2_demod)
diff --git a/gnuradio-core/src/python/gnuradio/modulation_utils2.py b/gnuradio-core/src/python/gnuradio/modulation_utils2.py
new file mode 100644
index 000000000..c5dba3e79
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/modulation_utils2.py
@@ -0,0 +1,81 @@
+#
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+"""
+Miscellaneous utilities for managing mods and demods, as well as other items
+useful in dealing with generalized handling of different modulations and demods.
+"""
+
+import inspect
+
+
+# Type 1 modulators accept a stream of bytes on their input and produce complex baseband output
+_type_1_modulators = {}
+
+def type_1_mods():
+ return _type_1_modulators
+
+def add_type_1_mod(name, mod_class):
+ _type_1_modulators[name] = mod_class
+
+
+# Type 1 demodulators accept complex baseband input and produce a stream of bits, packed
+# 1 bit / byte as their output. Their output is completely unambiguous. There is no need
+# to resolve phase or polarity ambiguities.
+_type_1_demodulators = {}
+
+def type_1_demods():
+ return _type_1_demodulators
+
+def add_type_1_demod(name, demod_class):
+ _type_1_demodulators[name] = demod_class
+
+
+def extract_kwargs_from_options(function, excluded_args, options):
+ """
+ Given a function, a list of excluded arguments and the result of
+ parsing command line options, create a dictionary of key word
+ arguments suitable for passing to the function. The dictionary
+ will be populated with key/value pairs where the keys are those
+ that are common to the function's argument list (minus the
+ excluded_args) and the attributes in options. The values are the
+ corresponding values from options unless that value is None.
+ In that case, the corresponding dictionary entry is not populated.
+
+ (This allows different modulations that have the same parameter
+ names, but different default values to coexist. The downside is
+ that --help in the option parser will list the default as None,
+ but in that case the default provided in the __init__ argument
+ list will be used since there is no kwargs entry.)
+
+ @param function: the function whose parameter list will be examined
+ @param excluded_args: function arguments that are NOT to be added to the dictionary
+ @type excluded_args: sequence of strings
+ @param options: result of command argument parsing
+ @type options: optparse.Values
+ """
+ # Try this in C++ ;)
+ args, varargs, varkw, defaults = inspect.getargspec(function)
+ d = {}
+ for kw in [a for a in args if a not in excluded_args]:
+ if hasattr(options, kw):
+ if getattr(options, kw) is not None:
+ d[kw] = getattr(options, kw)
+ return d
diff --git a/gnuradio-core/src/python/gnuradio/packet_utils.py b/gnuradio-core/src/python/gnuradio/packet_utils.py
index 1417c17fa..e36b05413 100644
--- a/gnuradio-core/src/python/gnuradio/packet_utils.py
+++ b/gnuradio-core/src/python/gnuradio/packet_utils.py
@@ -143,7 +143,7 @@ def make_packet(payload, samples_per_symbol, bits_per_symbol,
(payload_with_crc), '\x55'))
if pad_for_usrp:
- pkt = pkt + (_npadding_bytes(len(pkt), samples_per_symbol, bits_per_symbol) * '\x55')
+ pkt = pkt + (_npadding_bytes(len(pkt), int(samples_per_symbol), bits_per_symbol) * '\x55')
#print "make_packet: len(pkt) =", len(pkt)
return pkt
diff --git a/gnuradio-examples/grc/demod/digital_freq_lock.grc b/gnuradio-examples/grc/demod/digital_freq_lock.grc
index 37ee8123e..36037febb 100644
--- a/gnuradio-examples/grc/demod/digital_freq_lock.grc
+++ b/gnuradio-examples/grc/demod/digital_freq_lock.grc
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='ASCII'?>
<flow_graph>
- <timestamp>Fri Jan 29 18:10:00 2010</timestamp>
+ <timestamp>Sat Mar 6 17:17:12 2010</timestamp>
<block>
<key>options</key>
<param>
@@ -980,54 +980,50 @@
</param>
</block>
<block>
- <key>variable_slider</key>
+ <key>root_raised_cosine_filter</key>
<param>
<key>id</key>
- <value>alpha</value>
+ <value>root_raised_cosine_filter_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>label</key>
- <value>Freq Alpha</value>
- </param>
- <param>
- <key>value</key>
- <value>0</value>
+ <key>type</key>
+ <value>interp_fir_filter_ccf</value>
</param>
<param>
- <key>min</key>
- <value>0</value>
+ <key>decim</key>
+ <value>1</value>
</param>
<param>
- <key>max</key>
- <value>0.001</value>
+ <key>interp</key>
+ <value>spb_gen</value>
</param>
<param>
- <key>num_steps</key>
- <value>1000</value>
+ <key>gain</key>
+ <value>2*spb_gen</value>
</param>
<param>
- <key>style</key>
- <value>wx.SL_HORIZONTAL</value>
+ <key>samp_rate</key>
+ <value>1.0</value>
</param>
<param>
- <key>converver</key>
- <value>float_converter</value>
+ <key>sym_rate</key>
+ <value>1./spb_gen</value>
</param>
<param>
- <key>grid_pos</key>
- <value></value>
+ <key>alpha</key>
+ <value>rolloff</value>
</param>
<param>
- <key>notebook</key>
- <value></value>
+ <key>ntaps</key>
+ <value>44</value>
</param>
<param>
<key>_coordinate</key>
- <value>(552, 4)</value>
+ <value>(978, 157)</value>
</param>
<param>
<key>_rotation</key>
@@ -1035,105 +1031,81 @@
</param>
</block>
<block>
- <key>variable_slider</key>
+ <key>gr_fll_band_edge_cc</key>
<param>
<key>id</key>
- <value>beta</value>
+ <value>gr_fll_band_edge_cc_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>label</key>
- <value>Freq Beta</value>
- </param>
- <param>
- <key>value</key>
- <value>0</value>
- </param>
- <param>
- <key>min</key>
- <value>0.0</value>
- </param>
- <param>
- <key>max</key>
- <value>0.0001</value>
+ <key>type</key>
+ <value>cc</value>
</param>
<param>
- <key>num_steps</key>
- <value>1000</value>
+ <key>samps_per_sym</key>
+ <value>spb_gen</value>
</param>
<param>
- <key>style</key>
- <value>wx.SL_HORIZONTAL</value>
+ <key>rolloff</key>
+ <value>rolloff</value>
</param>
<param>
- <key>converver</key>
- <value>float_converter</value>
+ <key>filter_size</key>
+ <value>44</value>
</param>
<param>
- <key>grid_pos</key>
- <value></value>
+ <key>alpha</key>
+ <value>alpha</value>
</param>
<param>
- <key>notebook</key>
- <value></value>
+ <key>beta</key>
+ <value>beta</value>
</param>
<param>
<key>_coordinate</key>
- <value>(668, 5)</value>
+ <value>(874, 664)</value>
</param>
<param>
<key>_rotation</key>
- <value>180</value>
+ <value>0</value>
</param>
</block>
<block>
- <key>root_raised_cosine_filter</key>
+ <key>gr_channel_model</key>
<param>
<key>id</key>
- <value>root_raised_cosine_filter_0</value>
+ <value>gr_channel_model_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>interp_fir_filter_ccf</value>
- </param>
- <param>
- <key>decim</key>
- <value>1</value>
- </param>
- <param>
- <key>interp</key>
- <value>spb_gen</value>
+ <key>noise_voltage</key>
+ <value>noise_amp</value>
</param>
<param>
- <key>gain</key>
- <value>2*spb_gen</value>
+ <key>freq_offset</key>
+ <value>freq_offset</value>
</param>
<param>
- <key>samp_rate</key>
+ <key>epsilon</key>
<value>1.0</value>
</param>
<param>
- <key>sym_rate</key>
- <value>1./spb_gen</value>
- </param>
- <param>
- <key>alpha</key>
- <value>rolloff</value>
+ <key>taps</key>
+ <value>1.0</value>
</param>
<param>
- <key>ntaps</key>
- <value>44</value>
+ <key>seed</key>
+ <value>42</value>
</param>
<param>
<key>_coordinate</key>
- <value>(978, 157)</value>
+ <value>(618, 376)</value>
</param>
<param>
<key>_rotation</key>
@@ -1141,81 +1113,109 @@
</param>
</block>
<block>
- <key>gr_fll_band_edge_cc</key>
+ <key>variable_slider</key>
<param>
<key>id</key>
- <value>gr_fll_band_edge_cc_0</value>
+ <value>beta</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>cc</value>
+ <key>label</key>
+ <value>Freq Beta</value>
</param>
<param>
- <key>samps_per_sym</key>
- <value>spb_gen</value>
+ <key>value</key>
+ <value>0</value>
</param>
<param>
- <key>rolloff</key>
- <value>rolloff</value>
+ <key>min</key>
+ <value>0.0</value>
</param>
<param>
- <key>filter_size</key>
- <value>44</value>
+ <key>max</key>
+ <value>0.01</value>
</param>
<param>
- <key>alpha</key>
- <value>alpha</value>
+ <key>num_steps</key>
+ <value>1000</value>
</param>
<param>
- <key>beta</key>
- <value>beta</value>
+ <key>style</key>
+ <value>wx.SL_HORIZONTAL</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(874, 664)</value>
+ <value>(668, 5)</value>
</param>
<param>
<key>_rotation</key>
- <value>0</value>
+ <value>180</value>
</param>
</block>
<block>
- <key>gr_channel_model</key>
+ <key>variable_slider</key>
<param>
<key>id</key>
- <value>gr_channel_model_0</value>
+ <value>alpha</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>noise_voltage</key>
- <value>noise_amp</value>
+ <key>label</key>
+ <value>Freq Alpha</value>
</param>
<param>
- <key>freq_offset</key>
- <value>freq_offset</value>
+ <key>value</key>
+ <value>0</value>
</param>
<param>
- <key>epsilon</key>
- <value>1.0</value>
+ <key>min</key>
+ <value>0</value>
</param>
<param>
- <key>taps</key>
- <value>1.0</value>
+ <key>max</key>
+ <value>0.1</value>
</param>
<param>
- <key>seed</key>
- <value>42</value>
+ <key>num_steps</key>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>style</key>
+ <value>wx.SL_HORIZONTAL</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(618, 376)</value>
+ <value>(552, 4)</value>
</param>
<param>
<key>_rotation</key>
diff --git a/gnuradio-examples/grc/demod/pam_sync.grc b/gnuradio-examples/grc/demod/pam_sync.grc
index 80a7aef0c..8571995a5 100644
--- a/gnuradio-examples/grc/demod/pam_sync.grc
+++ b/gnuradio-examples/grc/demod/pam_sync.grc
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='ASCII'?>
<flow_graph>
- <timestamp>Mon Feb 1 18:58:32 2010</timestamp>
+ <timestamp>Sat Mar 6 17:17:22 2010</timestamp>
<block>
<key>options</key>
<param>
@@ -713,116 +713,6 @@
<key>variable_slider</key>
<param>
<key>id</key>
- <value>freq_beta</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>label</key>
- <value>Freq Beta</value>
- </param>
- <param>
- <key>value</key>
- <value>0</value>
- </param>
- <param>
- <key>min</key>
- <value>0.0</value>
- </param>
- <param>
- <key>max</key>
- <value>0.0001</value>
- </param>
- <param>
- <key>num_steps</key>
- <value>1000</value>
- </param>
- <param>
- <key>style</key>
- <value>wx.SL_HORIZONTAL</value>
- </param>
- <param>
- <key>converver</key>
- <value>float_converter</value>
- </param>
- <param>
- <key>grid_pos</key>
- <value></value>
- </param>
- <param>
- <key>notebook</key>
- <value></value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(836, 9)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>180</value>
- </param>
- </block>
- <block>
- <key>variable_slider</key>
- <param>
- <key>id</key>
- <value>freq_alpha</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>label</key>
- <value>Freq Alpha</value>
- </param>
- <param>
- <key>value</key>
- <value>0</value>
- </param>
- <param>
- <key>min</key>
- <value>0</value>
- </param>
- <param>
- <key>max</key>
- <value>0.001</value>
- </param>
- <param>
- <key>num_steps</key>
- <value>1000</value>
- </param>
- <param>
- <key>style</key>
- <value>wx.SL_HORIZONTAL</value>
- </param>
- <param>
- <key>converver</key>
- <value>float_converter</value>
- </param>
- <param>
- <key>grid_pos</key>
- <value></value>
- </param>
- <param>
- <key>notebook</key>
- <value></value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(734, 10)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>variable_slider</key>
- <param>
- <key>id</key>
<value>phase_alpha</value>
</param>
<param>
@@ -1621,6 +1511,116 @@
<value>0</value>
</param>
</block>
+ <block>
+ <key>variable_slider</key>
+ <param>
+ <key>id</key>
+ <value>freq_alpha</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Freq Alpha</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>min</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>max</key>
+ <value>0.1</value>
+ </param>
+ <param>
+ <key>num_steps</key>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>style</key>
+ <value>wx.SL_HORIZONTAL</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(734, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_slider</key>
+ <param>
+ <key>id</key>
+ <value>freq_beta</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Freq Beta</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>min</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>max</key>
+ <value>0.01</value>
+ </param>
+ <param>
+ <key>num_steps</key>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>style</key>
+ <value>wx.SL_HORIZONTAL</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(836, 9)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
<connection>
<source_block_id>random_source_x_0</source_block_id>
<sink_block_id>gr_uchar_to_float_0</sink_block_id>
diff --git a/gnuradio-examples/python/digital/benchmark_loopback.py b/gnuradio-examples/python/digital/benchmark_loopback.py
index 4cc4a7bee..47e4f2028 100755
--- a/gnuradio-examples/python/digital/benchmark_loopback.py
+++ b/gnuradio-examples/python/digital/benchmark_loopback.py
@@ -44,6 +44,11 @@ class my_top_block(gr.top_block):
noise_power = power_in_signal/SNR
noise_voltage = math.sqrt(noise_power)
+ # With new interface, sps does not get set by default, but
+ # in the loopback, we don't recalculate it; so just force it here
+ if(options.samples_per_symbol == None):
+ options.samples_per_symbol = 2
+
self.txpath = transmit_path(mod_class, options)
self.throttle = gr.throttle(gr.sizeof_gr_complex, options.sample_rate)
self.rxpath = receive_path(demod_class, rx_callback, options)
diff --git a/gnuradio-examples/python/digital/benchmark_qt_loopback2.py b/gnuradio-examples/python/digital/benchmark_qt_loopback2.py
index 1cb95198e..56c6c7f52 100755
--- a/gnuradio-examples/python/digital/benchmark_qt_loopback2.py
+++ b/gnuradio-examples/python/digital/benchmark_qt_loopback2.py
@@ -1,6 +1,26 @@
#!/usr/bin/env python
-
-from gnuradio import gr, gru, modulation_utils
+#
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gru, modulation_utils2
from gnuradio import eng_notation
from gnuradio.eng_option import eng_option
from optparse import OptionParser
@@ -223,6 +243,11 @@ class my_top_block(gr.top_block):
self._noise_voltage = self.get_noise_voltage(self._snr_dB)
+ # With new interface, sps does not get set by default, but
+ # in the loopback, we don't recalculate it; so just force it here
+ if(options.samples_per_symbol == None):
+ options.samples_per_symbol = 2
+
self.txpath = transmit_path(mod_class, options)
self.throttle = gr.throttle(gr.sizeof_gr_complex, self.sample_rate())
self.rxpath = receive_path(demod_class, rx_callback, options)
@@ -269,6 +294,7 @@ class my_top_block(gr.top_block):
self.phase_recov = self.rxpath.packet_receiver._demodulator.phase_recov
self.time_recov = self.rxpath.packet_receiver._demodulator.time_recov
self.freq_recov.set_alpha(self._gain_freq)
+ self.freq_recov.set_beta(self._gain_freq/10.0)
self.phase_recov.set_alpha(self._gain_phase)
self.phase_recov.set_beta(0.25*self._gain_phase*self._gain_phase)
self.time_recov.set_alpha(self._gain_clock)
@@ -367,6 +393,7 @@ class my_top_block(gr.top_block):
self._gain_freq = gain_freq
#self._gain_freq_beta = .25 * self._gain_freq * self._gain_freq
self.rxpath.packet_receiver._demodulator.freq_recov.set_alpha(self._gain_freq)
+ self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_freq/10.0)
#self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_fre_beta)
@@ -431,15 +458,15 @@ def main():
def send_pkt(payload='', eof=False):
return tb.txpath.send_pkt(payload, eof)
- mods = modulation_utils.type_1_mods()
- demods = modulation_utils.type_1_demods()
+ mods = modulation_utils2.type_1_mods()
+ demods = modulation_utils2.type_1_demods()
parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
expert_grp = parser.add_option_group("Expert")
channel_grp = parser.add_option_group("Channel")
parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(),
- default='dbpsk',
+ default='dbpsk2',
help="Select modulation from: %s [default=%%default]"
% (', '.join(mods.keys()),))
diff --git a/gnuradio-examples/python/digital/benchmark_qt_rx2.py b/gnuradio-examples/python/digital/benchmark_qt_rx2.py
index cabbecb6f..0c37f4c6a 100755
--- a/gnuradio-examples/python/digital/benchmark_qt_rx2.py
+++ b/gnuradio-examples/python/digital/benchmark_qt_rx2.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2005,2006,2007,2009 Free Software Foundation, Inc.
+# Copyright 2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -20,7 +20,7 @@
# Boston, MA 02110-1301, USA.
#
-from gnuradio import gr, gru, modulation_utils
+from gnuradio import gr, gru, modulation_utils2
from gnuradio import usrp
from gnuradio import eng_notation
from gnuradio.eng_option import eng_option
@@ -33,7 +33,7 @@ import sys
# from current dir
from receive_path import receive_path
-from pick_bitrate import pick_rx_bitrate
+from pick_bitrate2 import pick_rx_bitrate
try:
from gnuradio.qtgui import qtgui
@@ -219,7 +219,7 @@ class my_top_block(gr.top_block):
# FIXME: do better exposure to lower issues for control
self._gain_clock = self.rxpath.packet_receiver._demodulator._timing_alpha
- self._gain_phase = self.rxpath.packet_receiver._demodulator._costas_alpha
+ self._gain_phase = self.rxpath.packet_receiver._demodulator._phase_alpha
self._gain_freq = self.rxpath.packet_receiver._demodulator._freq_alpha
self.connect(self.u, self.rxpath)
@@ -242,8 +242,8 @@ class my_top_block(gr.top_block):
# Connect to the QT sinks
# FIXME: make better exposure to receiver from rxpath
- #self.receiver = self.rxpath.packet_receiver._demodulator.phase_recov
- self.receiver = self.rxpath.packet_receiver._demodulator.freq_recov
+ self.receiver = self.rxpath.packet_receiver._demodulator.phase_recov
+ #self.receiver = self.rxpath.packet_receiver._demodulator.freq_recov
self.connect(self.u, self.snk_rxin)
self.connect(self.receiver, self.snk_rx)
@@ -267,9 +267,9 @@ class my_top_block(gr.top_block):
self.u.set_decim(self._decim)
(self._bitrate, self._samples_per_symbol, self._decim) = \
- pick_rx_bitrate(self._bitrate, self._demod_class.bits_per_symbol(), \
- self._samples_per_symbol, self._decim, adc_rate, \
- self.u.get_decim_rates())
+ pick_rx_bitrate(options.bitrate, self._demod_class.bits_per_symbol(), \
+ options.samples_per_symbol, options.decim, \
+ adc_rate, self.u.get_decim_rates())
self.u.set_decim(self._decim)
self.set_auto_tr(True) # enable Auto Transmit/Receive switching
@@ -353,6 +353,7 @@ class my_top_block(gr.top_block):
self._gain_freq = gain_freq
#self._gain_freq_beta = .25 * self._gain_freq * self._gain_freq
self.rxpath.packet_receiver._demodulator.freq_recov.set_alpha(self._gain_freq)
+ self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_freq/10.0)
#self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_fre_beta)
@@ -423,14 +424,14 @@ def main():
ok, pktno, n_rcvd, n_right)
- demods = modulation_utils.type_1_demods()
+ demods = modulation_utils2.type_1_demods()
# Create Options Parser:
parser = OptionParser (option_class=eng_option, conflict_handler="resolve")
expert_grp = parser.add_option_group("Expert")
parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(),
- default='dbpsk',
+ default='dbpsk2',
help="Select modulation from: %s [default=%%default]"
% (', '.join(demods.keys()),))
diff --git a/gnuradio-examples/python/digital/benchmark_rx2.py b/gnuradio-examples/python/digital/benchmark_rx2.py
new file mode 100755
index 000000000..fe422be83
--- /dev/null
+++ b/gnuradio-examples/python/digital/benchmark_rx2.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gru, modulation_utils2
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+import random
+import struct
+import sys
+
+# from current dir
+import usrp_receive_path2
+
+#import os
+#print os.getpid()
+#raw_input('Attach and press enter: ')
+
+class my_top_block(gr.top_block):
+ def __init__(self, demodulator, rx_callback, options):
+ gr.top_block.__init__(self)
+
+ # Set up receive path
+ self.rxpath = usrp_receive_path2.usrp_receive_path(demodulator, rx_callback, options)
+
+ self.connect(self.rxpath)
+
+# /////////////////////////////////////////////////////////////////////////////
+# main
+# /////////////////////////////////////////////////////////////////////////////
+
+global n_rcvd, n_right
+
+def main():
+ global n_rcvd, n_right
+
+ n_rcvd = 0
+ n_right = 0
+
+ def rx_callback(ok, payload):
+ global n_rcvd, n_right
+ (pktno,) = struct.unpack('!H', payload[0:2])
+ n_rcvd += 1
+ if ok:
+ n_right += 1
+
+ print "ok = %5s pktno = %4d n_rcvd = %4d n_right = %4d" % (
+ ok, pktno, n_rcvd, n_right)
+
+
+ demods = modulation_utils2.type_1_demods()
+
+ # Create Options Parser:
+ parser = OptionParser (option_class=eng_option, conflict_handler="resolve")
+ expert_grp = parser.add_option_group("Expert")
+
+ parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(),
+ default='dbpsk2',
+ help="Select modulation from: %s [default=%%default]"
+ % (', '.join(demods.keys()),))
+
+ usrp_receive_path2.add_options(parser, expert_grp)
+
+ for mod in demods.values():
+ mod.add_options(expert_grp)
+
+ (options, args) = parser.parse_args ()
+
+ if len(args) != 0:
+ parser.print_help(sys.stderr)
+ sys.exit(1)
+
+ if options.rx_freq is None:
+ sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
+ parser.print_help(sys.stderr)
+ sys.exit(1)
+
+
+ # build the graph
+ tb = my_top_block(demods[options.modulation], rx_callback, options)
+
+ r = gr.enable_realtime_scheduling()
+ if r != gr.RT_OK:
+ print "Warning: Failed to enable realtime scheduling."
+
+ tb.start() # start flow graph
+ tb.wait() # wait for it to finish
+
+if __name__ == '__main__':
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
diff --git a/gnuradio-examples/python/digital/benchmark_tx2.py b/gnuradio-examples/python/digital/benchmark_tx2.py
new file mode 100755
index 000000000..6093dba61
--- /dev/null
+++ b/gnuradio-examples/python/digital/benchmark_tx2.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gru, modulation_utils2
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+import random, time, struct, sys
+
+# from current dir
+import usrp_transmit_path2
+
+#import os
+#print os.getpid()
+#raw_input('Attach and press enter')
+
+class my_top_block(gr.top_block):
+ def __init__(self, modulator, options):
+ gr.top_block.__init__(self)
+
+ self.txpath = usrp_transmit_path2.usrp_transmit_path(modulator, options)
+
+ self.connect(self.txpath)
+
+# /////////////////////////////////////////////////////////////////////////////
+# main
+# /////////////////////////////////////////////////////////////////////////////
+
+def main():
+
+ def send_pkt(payload='', eof=False):
+ return tb.txpath.send_pkt(payload, eof)
+
+ def rx_callback(ok, payload):
+ print "ok = %r, payload = '%s'" % (ok, payload)
+
+ mods = modulation_utils2.type_1_mods()
+
+ parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
+ expert_grp = parser.add_option_group("Expert")
+
+ parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(),
+ default='dbpsk2',
+ help="Select modulation from: %s [default=%%default]"
+ % (', '.join(mods.keys()),))
+
+ parser.add_option("-s", "--size", type="eng_float", default=1500,
+ help="set packet size [default=%default]")
+ parser.add_option("-M", "--megabytes", type="eng_float", default=1.0,
+ help="set megabytes to transmit [default=%default]")
+ parser.add_option("","--discontinuous", action="store_true", default=False,
+ help="enable discontinous transmission (bursts of 5 packets)")
+ parser.add_option("","--from-file", default=None,
+ help="use file for packet contents")
+
+ usrp_transmit_path2.add_options(parser, expert_grp)
+
+ for mod in mods.values():
+ mod.add_options(expert_grp)
+
+ (options, args) = parser.parse_args ()
+
+ if len(args) != 0:
+ parser.print_help()
+ sys.exit(1)
+
+ if options.tx_freq is None:
+ sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
+ parser.print_help(sys.stderr)
+ sys.exit(1)
+
+ if options.from_file is not None:
+ source_file = open(options.from_file, 'r')
+
+ # build the graph
+ tb = my_top_block(mods[options.modulation], options)
+
+ r = gr.enable_realtime_scheduling()
+ if r != gr.RT_OK:
+ print "Warning: failed to enable realtime scheduling"
+
+ tb.start() # start flow graph
+
+ # generate and send packets
+ nbytes = int(1e6 * options.megabytes)
+ n = 0
+ pktno = 0
+ pkt_size = int(options.size)
+
+ while n < nbytes:
+ if options.from_file is None:
+ data = (pkt_size - 2) * chr(pktno & 0xff)
+ else:
+ data = source_file.read(pkt_size - 2)
+ if data == '':
+ break;
+
+ payload = struct.pack('!H', pktno & 0xffff) + data
+ send_pkt(payload)
+ n += len(payload)
+ sys.stderr.write('.')
+ if options.discontinuous and pktno % 5 == 4:
+ time.sleep(1)
+ pktno += 1
+
+ send_pkt(eof=True)
+
+ tb.wait() # wait for it to finish
+
+if __name__ == '__main__':
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
diff --git a/gnuradio-examples/python/digital/pick_bitrate2.py b/gnuradio-examples/python/digital/pick_bitrate2.py
new file mode 100644
index 000000000..92539560c
--- /dev/null
+++ b/gnuradio-examples/python/digital/pick_bitrate2.py
@@ -0,0 +1,154 @@
+#
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import eng_notation
+
+_default_bitrate = 500e3
+_sps_min = 2
+_sps_max = 100
+
+def _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+ xrate, converter_rate, xrates):
+ """
+ @returns tuple (bitrate, samples_per_symbol, interp_rate_or_decim_rate)
+ """
+
+ if not isinstance(bits_per_symbol, int) or bits_per_symbol < 1:
+ raise ValueError, "bits_per_symbol must be an int >= 1"
+
+ converter_rate = float(converter_rate)
+ bits_per_symbol = float(bits_per_symbol)
+
+ # completely determined; if bitrate is specified, this overwrites it
+ if (samples_per_symbol is not None) and (xrate is not None):
+ bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol
+
+ # If only SPS is given
+ if (bitrate is None) and (samples_per_symbol is not None) and (xrate is None):
+ xrate = max(xrates)
+ bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol
+
+ # If only xrate is given, just set SPS to 2 and calculate bitrate
+ if (bitrate is None) and (samples_per_symbol is None) and (xrate is not None):
+ samples_per_symbol = 2.0
+ bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol
+
+ # If no parameters are give, use the default bit rate
+ if (bitrate is None) and (samples_per_symbol is None) and (xrate is None):
+ bitrate = _default_bitrate
+
+ # If only bitrate is specified, return max xrate and appropriate
+ # samples per symbol (minimum of 2.0) to reach bit rate
+ if (samples_per_symbol is None) and (xrate is None):
+ xrates.sort()
+ for i in xrange(len(xrates)):
+ if((converter_rate / bits_per_symbol / xrates[i]) >= 2*bitrate):
+ rate = xrates[i]
+ else:
+ break
+
+ try:
+ xrate = rate
+ except UnboundLocalError:
+ raise ValueError("Requested bitrate out of bounds")
+
+ samples_per_symbol = converter_rate / bits_per_symbol / rate / bitrate
+ bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol
+
+ # If bitrate and xrate are specified
+ if(samples_per_symbol is None):
+ samples_per_symbol = converter_rate / xrate / bits_per_symbol / bitrate
+
+ # If bitrate and SPS are specified
+ if(xrate is None):
+ xrate = converter_rate / samples_per_symbol / bits_per_symbol / bitrate
+ if((xrate in xrates) == False):
+ # Find the closest avaiable rate larger than the calculated one
+ xrates.sort()
+ for x in xrates:
+ if(x > xrate):
+ xrate = x
+ break
+ if(xrate > max(xrates)):
+ xrate = max(xrates)
+
+ bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol
+ print "Could not find suitable rate for specified SPS and Bitrate"
+ print "Using rate = %d for bitrate of %sbps" % \
+ (xrate, (eng_notation.num_to_str(bitrate)))
+
+ if((xrate in xrates) == False):
+ raise ValueError(("Invalid rate (rate = %d)" % xrate))
+ if((samples_per_symbol < _sps_min) or (samples_per_symbol > _sps_max)):
+ raise ValueError(("Invalid samples per symbol (sps = %.2f). Must be in [%.0f, %.0f]." \
+ % (samples_per_symbol, _sps_min, _sps_max)))
+
+ return (bitrate, samples_per_symbol, int(xrate))
+
+
+def pick_tx_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+ interp_rate, converter_rate, possible_interps):
+ """
+ Given the 4 input parameters, return at configuration that matches
+
+ @param bitrate: desired bitrate or None
+ @type bitrate: number or None
+ @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3
+ @type bits_per_symbol: integer >= 1
+ @param samples_per_symbol: samples/baud (aka samples/symbol)
+ @type samples_per_symbol: number or None
+ @param interp_rate: USRP interpolation factor
+ @type interp_rate: integer or None
+ @param converter_rate: converter sample rate in Hz
+ @type converter_rate: number
+ @param possible_interps: a list of possible rates
+ @type possible_interps: a list of integers
+
+ @returns tuple (bitrate, samples_per_symbol, interp_rate)
+ """
+
+ return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+ interp_rate, converter_rate, possible_interps)
+
+
+def pick_rx_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+ decim_rate, converter_rate, possible_decims):
+ """
+ Given the 4 input parameters, return at configuration that matches
+
+ @param bitrate: desired bitrate or None
+ @type bitrate: number or None
+ @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3
+ @type bits_per_symbol: integer >= 1
+ @param samples_per_symbol: samples/baud (aka samples/symbol)
+ @type samples_per_symbol: number or None
+ @param decim_rate: USRP decimation factor
+ @type decim_rate: integer or None
+ @param converter_rate: converter sample rate in Hz
+ @type converter_rate: number
+ @param possible_decims: a list of possible rates
+ @type possible_decims: a list of integers
+
+ @returns tuple (bitrate, samples_per_symbol, decim_rate)
+ """
+
+ return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol,
+ decim_rate, converter_rate, possible_decims)
diff --git a/gnuradio-examples/python/digital/receive_path.py b/gnuradio-examples/python/digital/receive_path.py
index c229aa9e4..0024d6941 100644
--- a/gnuradio-examples/python/digital/receive_path.py
+++ b/gnuradio-examples/python/digital/receive_path.py
@@ -119,7 +119,7 @@ class receive_path(gr.hier_block2):
normal.add_option("-r", "--bitrate", type="eng_float", default=100e3,
help="specify bitrate [default=%default].")
normal.add_option("-v", "--verbose", action="store_true", default=False)
- expert.add_option("-S", "--samples-per-symbol", type="int", default=2,
+ expert.add_option("-S", "--samples-per-symbol", type="float", default=None,
help="set samples/symbol [default=%default]")
expert.add_option("", "--log", action="store_true", default=False,
help="Log all parts of flow graph to files (CAUTION: lots of data)")
@@ -135,4 +135,4 @@ class receive_path(gr.hier_block2):
print "\nReceive Path:"
print "modulation: %s" % (self._demod_class.__name__)
print "bitrate: %sb/s" % (eng_notation.num_to_str(self._bitrate))
- print "samples/symbol: %3d" % (self._samples_per_symbol)
+ print "samples/symbol: %.4f" % (self._samples_per_symbol)
diff --git a/gnuradio-examples/python/digital/transmit_path.py b/gnuradio-examples/python/digital/transmit_path.py
index 9badcdc08..86ebf75c3 100644
--- a/gnuradio-examples/python/digital/transmit_path.py
+++ b/gnuradio-examples/python/digital/transmit_path.py
@@ -99,7 +99,7 @@ class transmit_path(gr.hier_block2):
help="set transmitter digital amplitude: 0 <= AMPL < 1 [default=%default]")
normal.add_option("-v", "--verbose", action="store_true", default=False)
- expert.add_option("-S", "--samples-per-symbol", type="int", default=2,
+ expert.add_option("-S", "--samples-per-symbol", type="float", default=None,
help="set samples/symbol [default=%default]")
expert.add_option("", "--log", action="store_true", default=False,
help="Log all parts of flow graph to file (CAUTION: lots of data)")
@@ -114,5 +114,5 @@ class transmit_path(gr.hier_block2):
print "Tx amplitude %s" % (self._tx_amplitude)
print "modulation: %s" % (self._modulator_class.__name__)
print "bitrate: %sb/s" % (eng_notation.num_to_str(self._bitrate))
- print "samples/symbol: %3d" % (self._samples_per_symbol)
+ print "samples/symbol: %.4f" % (self._samples_per_symbol)
diff --git a/gnuradio-examples/python/digital/usrp_receive_path.py b/gnuradio-examples/python/digital/usrp_receive_path.py
index 517825cc1..a8f16e28a 100644
--- a/gnuradio-examples/python/digital/usrp_receive_path.py
+++ b/gnuradio-examples/python/digital/usrp_receive_path.py
@@ -59,37 +59,35 @@ class usrp_receive_path(gr.hier_block2):
if options.rx_freq is None:
sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n")
raise SystemExit
- rx_path = receive_path.receive_path(demod_class, rx_callback, options)
- for attr in dir(rx_path): #forward the methods
- if not attr.startswith('_') and not hasattr(self, attr):
- setattr(self, attr, getattr(rx_path, attr))
#setup usrp
self._demod_class = demod_class
self._setup_usrp_source(options)
- # Set up resampler based on rate determined by _setup_usrp_source
- rs_taps = gr.firdes.low_pass_2(32, 32, 0.45, 0.1, 60)
- self.resampler = gr.pfb_arb_resampler_ccf(self.rs_rate, rs_taps)
+ rx_path = receive_path.receive_path(demod_class, rx_callback, options)
+ for attr in dir(rx_path): #forward the methods
+ if not attr.startswith('_') and not hasattr(self, attr):
+ setattr(self, attr, getattr(rx_path, attr))
#connect
- self.connect(self.u, self.resampler, rx_path)
+ self.connect(self.u, rx_path)
def _setup_usrp_source(self, options):
self.u = usrp_options.create_usrp_source(options)
adc_rate = self.u.adc_rate()
self.rs_rate = options.bitrate
- if options.verbose:
- print 'USRP Source:', self.u
+
(self._bitrate, self._samples_per_symbol, self._decim) = \
pick_rx_bitrate(options.bitrate, self._demod_class.bits_per_symbol(), \
- options.samples_per_symbol, options.decim, adc_rate, \
- self.u.get_decim_rates())
+ options.samples_per_symbol, options.decim,
+ adc_rate, self.u.get_decim_rates())
- # Calculate resampler rate based on requested and actual rates
- self.rs_rate = 1.0 /(self._bitrate / self.rs_rate)
-
- print "Resampling by %f to get bitrate of %ssps" % ( self.rs_rate, eng_notation.num_to_str(self._bitrate/self.rs_rate))
+ if options.verbose:
+ print 'USRP Source:', self.u
+ print 'Decimation: ', self._decim
+
+ options.samples_per_symbol = self._samples_per_symbol
+ options.decim = self._decim
self.u.set_decim(self._decim)
diff --git a/gnuradio-examples/python/digital/usrp_receive_path2.py b/gnuradio-examples/python/digital/usrp_receive_path2.py
new file mode 100644
index 000000000..d20017204
--- /dev/null
+++ b/gnuradio-examples/python/digital/usrp_receive_path2.py
@@ -0,0 +1,96 @@
+#
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio import usrp_options
+import receive_path
+from pick_bitrate2 import pick_rx_bitrate
+from gnuradio import eng_notation
+
+def add_freq_option(parser):
+ """
+ Hackery that has the -f / --freq option set both tx_freq and rx_freq
+ """
+ def freq_callback(option, opt_str, value, parser):
+ parser.values.rx_freq = value
+ parser.values.tx_freq = value
+
+ if not parser.has_option('--freq'):
+ parser.add_option('-f', '--freq', type="eng_float",
+ action="callback", callback=freq_callback,
+ help="set Tx and/or Rx frequency to FREQ [default=%default]",
+ metavar="FREQ")
+
+def add_options(parser, expert):
+ add_freq_option(parser)
+ usrp_options.add_rx_options(parser)
+ receive_path.receive_path.add_options(parser, expert)
+ expert.add_option("", "--rx-freq", type="eng_float", default=None,
+ help="set Rx frequency to FREQ [default=%default]", metavar="FREQ")
+ parser.add_option("-v", "--verbose", action="store_true", default=False)
+
+class usrp_receive_path(gr.hier_block2):
+
+ def __init__(self, demod_class, rx_callback, options):
+ '''
+ See below for what options should hold
+ '''
+ gr.hier_block2.__init__(self, "usrp_receive_path",
+ gr.io_signature(0, 0, 0), # Input signature
+ gr.io_signature(0, 0, 0)) # Output signature
+ if options.rx_freq is None:
+ sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n")
+ raise SystemExit
+
+ #setup usrp
+ self._demod_class = demod_class
+ self._setup_usrp_source(options)
+
+ rx_path = receive_path.receive_path(demod_class, rx_callback, options)
+ for attr in dir(rx_path): #forward the methods
+ if not attr.startswith('_') and not hasattr(self, attr):
+ setattr(self, attr, getattr(rx_path, attr))
+
+ #connect
+ self.connect(self.u, rx_path)
+
+ def _setup_usrp_source(self, options):
+ self.u = usrp_options.create_usrp_source(options)
+ adc_rate = self.u.adc_rate()
+ self.rs_rate = options.bitrate
+
+ (self._bitrate, self._samples_per_symbol, self._decim) = \
+ pick_rx_bitrate(options.bitrate, self._demod_class.bits_per_symbol(), \
+ options.samples_per_symbol, options.decim,
+ adc_rate, self.u.get_decim_rates())
+
+ if options.verbose:
+ print 'USRP Source:', self.u
+ print 'Decimation: ', self._decim
+
+ options.samples_per_symbol = self._samples_per_symbol
+ options.decim = self._decim
+
+ self.u.set_decim(self._decim)
+
+ if not self.u.set_center_freq(options.rx_freq):
+ print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.rx_freq))
+ raise ValueError, eng_notation.num_to_str(options.rx_freq)
diff --git a/gnuradio-examples/python/digital/usrp_transmit_path.py b/gnuradio-examples/python/digital/usrp_transmit_path.py
index ee63dcd2b..f0f467599 100644
--- a/gnuradio-examples/python/digital/usrp_transmit_path.py
+++ b/gnuradio-examples/python/digital/usrp_transmit_path.py
@@ -58,21 +58,18 @@ class usrp_transmit_path(gr.hier_block2):
if options.tx_freq is None:
sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be specified\n")
raise SystemExit
- tx_path = transmit_path.transmit_path(modulator_class, options)
- for attr in dir(tx_path): #forward the methods
- if not attr.startswith('_') and not hasattr(self, attr):
- setattr(self, attr, getattr(tx_path, attr))
#setup usrp
self._modulator_class = modulator_class
self._setup_usrp_sink(options)
- # Set up resampler based on rate determined by _setup_usrp_sink
- rs_taps = gr.firdes.low_pass_2(32, 32, 0.45, 0.1, 60)
- self.resampler = gr.pfb_arb_resampler_ccf(self.rs_rate, rs_taps)
+ tx_path = transmit_path.transmit_path(modulator_class, options)
+ for attr in dir(tx_path): #forward the methods
+ if not attr.startswith('_') and not hasattr(self, attr):
+ setattr(self, attr, getattr(tx_path, attr))
#connect
- self.connect(tx_path, self.resampler, self.u)
+ self.connect(tx_path, self.u)
def _setup_usrp_sink(self, options):
"""
@@ -82,17 +79,20 @@ class usrp_transmit_path(gr.hier_block2):
self.u = usrp_options.create_usrp_sink(options)
dac_rate = self.u.dac_rate()
self.rs_rate = options.bitrate # Store requested bit rate
- if options.verbose:
- print 'USRP Sink:', self.u
+
(self._bitrate, self._samples_per_symbol, self._interp) = \
- pick_tx_bitrate(options.bitrate, self._modulator_class.bits_per_symbol(), \
- options.samples_per_symbol, options.interp, dac_rate, \
- self.u.get_interp_rates())
+ pick_tx_bitrate(options.bitrate, self._modulator_class.bits_per_symbol(),
+ options.samples_per_symbol, options.interp,
+ dac_rate, self.u.get_interp_rates())
- # Calculate resampler rate based on requested and actual rates
- self.rs_rate = self._bitrate / self.rs_rate
- print "Resampling by %f to get bitrate of %ssps" % (self.rs_rate, eng_notation.num_to_str(self._bitrate/self.rs_rate))
+ options.interp = self._interp
+ options.samples_per_symbol = self._samples_per_symbol
+ options.bitrate = self._bitrate
+ if options.verbose:
+ print 'USRP Sink:', self.u
+ print "Interpolation Rate: ", self._interp
+
self.u.set_interp(self._interp)
self.u.set_auto_tr(True)
diff --git a/gnuradio-examples/python/digital/usrp_transmit_path2.py b/gnuradio-examples/python/digital/usrp_transmit_path2.py
new file mode 100644
index 000000000..54930e5a0
--- /dev/null
+++ b/gnuradio-examples/python/digital/usrp_transmit_path2.py
@@ -0,0 +1,101 @@
+#
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio import usrp_options
+import transmit_path
+from pick_bitrate2 import pick_tx_bitrate
+from gnuradio import eng_notation
+
+def add_freq_option(parser):
+ """
+ Hackery that has the -f / --freq option set both tx_freq and rx_freq
+ """
+ def freq_callback(option, opt_str, value, parser):
+ parser.values.rx_freq = value
+ parser.values.tx_freq = value
+
+ if not parser.has_option('--freq'):
+ parser.add_option('-f', '--freq', type="eng_float",
+ action="callback", callback=freq_callback,
+ help="set Tx and/or Rx frequency to FREQ [default=%default]",
+ metavar="FREQ")
+
+def add_options(parser, expert):
+ add_freq_option(parser)
+ usrp_options.add_tx_options(parser)
+ transmit_path.transmit_path.add_options(parser, expert)
+ expert.add_option("", "--tx-freq", type="eng_float", default=None,
+ help="set transmit frequency to FREQ [default=%default]", metavar="FREQ")
+ parser.add_option("-v", "--verbose", action="store_true", default=False)
+
+class usrp_transmit_path(gr.hier_block2):
+ def __init__(self, modulator_class, options):
+ '''
+ See below for what options should hold
+ '''
+ gr.hier_block2.__init__(self, "usrp_transmit_path",
+ gr.io_signature(0, 0, 0), # Input signature
+ gr.io_signature(0, 0, 0)) # Output signature
+ if options.tx_freq is None:
+ sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be specified\n")
+ raise SystemExit
+
+ #setup usrp
+ self._modulator_class = modulator_class
+ self._setup_usrp_sink(options)
+
+ tx_path = transmit_path.transmit_path(modulator_class, options)
+ for attr in dir(tx_path): #forward the methods
+ if not attr.startswith('_') and not hasattr(self, attr):
+ setattr(self, attr, getattr(tx_path, attr))
+
+ #connect
+ self.connect(tx_path, self.u)
+
+ def _setup_usrp_sink(self, options):
+ """
+ Creates a USRP sink, determines the settings for best bitrate,
+ and attaches to the transmitter's subdevice.
+ """
+ self.u = usrp_options.create_usrp_sink(options)
+ dac_rate = self.u.dac_rate()
+ self.rs_rate = options.bitrate # Store requested bit rate
+
+ (self._bitrate, self._samples_per_symbol, self._interp) = \
+ pick_tx_bitrate(options.bitrate, self._modulator_class.bits_per_symbol(),
+ options.samples_per_symbol, options.interp,
+ dac_rate, self.u.get_interp_rates())
+
+ options.interp = self._interp
+ options.samples_per_symbol = self._samples_per_symbol
+ options.bitrate = self._bitrate
+
+ if options.verbose:
+ print 'USRP Sink:', self.u
+ print "Interpolation Rate: ", self._interp
+
+ self.u.set_interp(self._interp)
+ self.u.set_auto_tr(True)
+
+ if not self.u.set_center_freq(options.tx_freq):
+ print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.tx_freq))
+ raise ValueError, eng_notation.num_to_str(options.tx_freq)
diff --git a/gr-gpio/src/python/gpio.py b/gr-gpio/src/python/gpio.py
index 2ef495589..a315e166b 100644
--- a/gr-gpio/src/python/gpio.py
+++ b/gr-gpio/src/python/gpio.py
@@ -1,3 +1 @@
-from gpio_swig import *
-
fpga_filename = 'std_2rxint_2tx_dig.rbf'
diff --git a/gr-howto-write-a-block/Makefile.common b/gr-howto-write-a-block/Makefile.common
index c81bc780d..e628d6b16 100644
--- a/gr-howto-write-a-block/Makefile.common
+++ b/gr-howto-write-a-block/Makefile.common
@@ -1,6 +1,6 @@
# -*- Makefile -*-
#
-# Copyright 2004,2006,2009 Free Software Foundation, Inc.
+# Copyright 2004,2006,2009,2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -20,6 +20,9 @@
# Boston, MA 02110-1301, USA.
#
+# The name of this "out-of-tree" module
+modname = howto
+
# these flags are used when compiling non-SWIG-wrapper files
# when going in to non-SWIG libraries
AM_CXXFLAGS = @autoconf_default_CXXFLAGS@
@@ -34,21 +37,22 @@ AM_CPPFLAGS = \
# these are used by both SWIG and CXX
STD_DEFINES_AND_INCLUDES = \
$(DEFINES) \
+ -I$(abs_top_srcdir)/include \
-I$(GNURADIO_CORE_INCLUDEDIR) \
-I$(GNURADIO_CORE_INCLUDEDIR)/swig
# includes
-grincludedir = $(includedir)/gnuradio
+modincludedir = $(includedir)/$(modname)
# swig includes
-swigincludedir = $(grincludedir)/swig
+swigincludedir = $(modincludedir)/swig
# Install this stuff in the appropriate subdirectory
# This usually ends up at:
-# ${prefix}/lib/python${python_version}/site-packages/gnuradio
+# ${prefix}/lib/python${python_version}/site-packages/$(modname)
-grpythondir = $(pythondir)/gnuradio
-grpyexecdir = $(pyexecdir)/gnuradio
+modpythondir = $(pythondir)/$(modname)
+modpyexecdir = $(pyexecdir)/$(modname)
# Data directory for grc block wrappers
grc_blocksdir = $(prefix)/share/gnuradio/grc/blocks
diff --git a/gr-howto-write-a-block/Makefile.swig.gen.t b/gr-howto-write-a-block/Makefile.swig.gen.t
index c15a81721..686117f83 100644
--- a/gr-howto-write-a-block/Makefile.swig.gen.t
+++ b/gr-howto-write-a-block/Makefile.swig.gen.t
@@ -25,18 +25,16 @@
## Default install locations for these files:
##
## Default location for the Python directory is:
-## ${prefix}/lib/python${python_version}/site-packages/[category]/@NAME@
+## ${prefix}/lib/python${python_version}/site-packages/@NAME@
## Default location for the Python exec directory is:
-## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/@NAME@
+## ${exec_prefix}/lib/python${python_version}/site-packages/@NAME@
##
## The following can be overloaded to change the install location, but
## this has to be done in the including Makefile.am -before-
## Makefile.swig is included.
-@NAME@_pythondir_category ?= gnuradio/@NAME@
-@NAME@_pylibdir_category ?= $(@NAME@_pythondir_category)
-@NAME@_pythondir = $(pythondir)/$(@NAME@_pythondir_category)
-@NAME@_pylibdir = $(pyexecdir)/$(@NAME@_pylibdir_category)
+@NAME@_pythondir = $(pythondir)/@NAME@
+@NAME@_pylibdir = $(pyexecdir)/@NAME@
## SWIG headers are always installed into the same directory.
@@ -72,7 +70,7 @@ MOSTLYCLEANFILES += $(DEPDIR)/*.S*
## .h file is sometimes built, but not always ... so that one has to
## be added manually by the including Makefile.am .
-swig_built_sources += @NAME@.py @NAME@.cc
+swig_built_sources += @NAME@_swig.py @NAME@_swig.cc
## Various SWIG variables. These can be overloaded in the including
## Makefile.am by setting the variable value there, then including
@@ -83,31 +81,31 @@ swig_built_sources += @NAME@.py @NAME@.cc
$(@NAME@_swiginclude_headers)
@NAME@_pylib_LTLIBRARIES = \
- _@NAME@.la
+ _@NAME@_swig.la
-_@NAME@_la_SOURCES = \
- @NAME@.cc \
+_@NAME@_swig_la_SOURCES = \
+ @NAME@_swig.cc \
$(@NAME@_la_swig_sources)
-_@NAME@_la_LIBADD = \
+_@NAME@_swig_la_LIBADD = \
$(STD_SWIG_LA_LIB_ADD) \
$(@NAME@_la_swig_libadd)
-_@NAME@_la_LDFLAGS = \
+_@NAME@_swig_la_LDFLAGS = \
$(STD_SWIG_LA_LD_FLAGS) \
$(@NAME@_la_swig_ldflags)
-_@NAME@_la_CXXFLAGS = \
+_@NAME@_swig_la_CXXFLAGS = \
$(STD_SWIG_CXX_FLAGS) \
$(@NAME@_la_swig_cxxflags)
@NAME@_python_PYTHON = \
- @NAME@.py \
+ @NAME@_swig.py \
$(@NAME@_python)
## Entry rule for running SWIG
-@NAME@.h @NAME@.py @NAME@.cc: @NAME@.i
+@NAME@.h @NAME@_swig.py @NAME@_swig.cc: @NAME@.i
## This rule will get called only when MAKE decides that one of the
## targets needs to be created or re-created, because:
##
@@ -202,7 +200,7 @@ $(DEPDIR)/@NAME@-generate-stamp:
##
if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(@NAME@_swig_args) \
-MD -MF $(DEPDIR)/@NAME@.Std \
- -module @NAME@ -o @NAME@.cc $(WHAT); then \
+ -module @NAME@_swig -o @NAME@_swig.cc $(WHAT); then \
if test $(host_os) = mingw32; then \
$(RM) $(DEPDIR)/@NAME@.Sd; \
$(SED) 's,\\\\,/,g' < $(DEPDIR)/@NAME@.Std \
diff --git a/gr-howto-write-a-block/apps/howto_square.py b/gr-howto-write-a-block/apps/howto_square.py
index 8d3d870d8..f14e28325 100755
--- a/gr-howto-write-a-block/apps/howto_square.py
+++ b/gr-howto-write-a-block/apps/howto_square.py
@@ -5,9 +5,9 @@
# Generated: Thu Nov 12 11:26:07 2009
##################################################
+import howto
from gnuradio import eng_notation
from gnuradio import gr
-from gnuradio import howto
from gnuradio.eng_option import eng_option
from gnuradio.gr import firdes
from gnuradio.wxgui import scopesink2
diff --git a/gr-howto-write-a-block/grc/howto_square2_ff.xml b/gr-howto-write-a-block/grc/howto_square2_ff.xml
index 2b46106e8..c58ef0047 100644
--- a/gr-howto-write-a-block/grc/howto_square2_ff.xml
+++ b/gr-howto-write-a-block/grc/howto_square2_ff.xml
@@ -3,7 +3,7 @@
<name>Square2</name>
<key>howto_square2_ff</key>
<category>HOWTO</category>
- <import>from gnuradio import howto</import>
+ <import>import howto</import>
<make>howto.square2_ff()</make>
<sink>
diff --git a/gr-howto-write-a-block/grc/howto_square_ff.xml b/gr-howto-write-a-block/grc/howto_square_ff.xml
index ed318bfc6..34a0b0a3f 100644
--- a/gr-howto-write-a-block/grc/howto_square_ff.xml
+++ b/gr-howto-write-a-block/grc/howto_square_ff.xml
@@ -3,7 +3,7 @@
<name>Square</name>
<key>howto_square_ff</key>
<category>HOWTO</category>
- <import>from gnuradio import howto</import>
+ <import>import howto</import>
<make>howto.square_ff()</make>
<sink>
diff --git a/gr-howto-write-a-block/lib/Makefile.am b/gr-howto-write-a-block/lib/Makefile.am
index 336cb8a20..2e76ee453 100644
--- a/gr-howto-write-a-block/lib/Makefile.am
+++ b/gr-howto-write-a-block/lib/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2004,2005,2006,2008,2009 Free Software Foundation, Inc.
+# Copyright 2004,2005,2006,2008,2009,2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -28,21 +28,21 @@ TESTS = test_all
# howto C++ library: libgnuradio-howto.so
# ----------------------------------------------------------------
-# C/C++ headers get installed in ${prefix}/include/gnuradio
-grinclude_HEADERS = \
- howto_square_ff.h \
+# C/C++ headers get installed in ${prefix}/include/$(modname)
+modinclude_HEADERS = \
+ howto_square_ff.h \
howto_square2_ff.h
lib_LTLIBRARIES = libgnuradio-howto.la
-libgnuradio_howto_la_SOURCES = \
- howto_square_ff.cc \
+libgnuradio_howto_la_SOURCES = \
+ howto_square_ff.cc \
howto_square2_ff.cc
-libgnuradio_howto_la_LIBADD = \
+libgnuradio_howto_la_LIBADD = \
$(GNURADIO_CORE_LA)
-libgnuradio_howto_la_LDFLAGS = \
+libgnuradio_howto_la_LDFLAGS = \
$(NO_UNDEFINED)
# ----------------------------------------------------------------
@@ -51,23 +51,23 @@ libgnuradio_howto_la_LDFLAGS = \
noinst_LTLIBRARIES = libgnuradio-howto-qa.la
-libgnuradio_howto_qa_la_SOURCES = \
- qa_howto.cc \
- qa_howto_square_ff.cc \
+libgnuradio_howto_qa_la_SOURCES = \
+ qa_howto.cc \
+ qa_howto_square_ff.cc \
qa_howto_square2_ff.cc
libgnuradio_howto_qa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
-libgnuradio_howto_qa_la_LIBADD = \
- libgnuradio-howto.la \
+libgnuradio_howto_qa_la_LIBADD = \
+ libgnuradio-howto.la \
$(CPPUNIT_LIBS)
# ----------------------------------------------------------------
# headers that don't get installed
# ----------------------------------------------------------------
-noinst_HEADERS = \
- qa_howto.h \
- qa_howto_square_ff.h \
+noinst_HEADERS = \
+ qa_howto.h \
+ qa_howto_square_ff.h \
qa_howto_square2_ff.h
# ----------------------------------------------------------------
diff --git a/gr-howto-write-a-block/python/Makefile.am b/gr-howto-write-a-block/python/Makefile.am
index 4ef5fc964..ae36ea665 100644
--- a/gr-howto-write-a-block/python/Makefile.am
+++ b/gr-howto-write-a-block/python/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2004 Free Software Foundation, Inc.
+# Copyright 2004,2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,12 +21,10 @@
include $(top_srcdir)/Makefile.common
-ourpythondir = $(grpythondir)/howto
-
EXTRA_DIST = run_tests.in
TESTS = run_tests
-ourpython_PYTHON = \
+modpython_PYTHON = \
__init__.py
noinst_PYTHON = \
diff --git a/gr-howto-write-a-block/swig/Makefile.am b/gr-howto-write-a-block/swig/Makefile.am
index fc40109d0..4737ad619 100644
--- a/gr-howto-write-a-block/swig/Makefile.am
+++ b/gr-howto-write-a-block/swig/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2004,2005,2006,2008,2009 Free Software Foundation, Inc.
+# Copyright 2004,2005,2006,2008,2009,2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -27,14 +27,13 @@ if PYTHON
###################################
# SWIG Python interface and library
-TOP_SWIG_IFILES = \
+TOP_SWIG_IFILES = \
howto.i
# Install so that they end up available as:
-# import gnuradio.howto
+# import howto
# This ends up at:
-# ${prefix}/lib/python${python_version}/site-packages/gnuradio
-howto_pythondir_category = gnuradio/howto
+# ${prefix}/lib/python${python_version}/site-packages/$(modname)
howto_la_swig_libadd = \
$(top_builddir)/lib/libgnuradio-howto.la
@@ -48,7 +47,7 @@ BUILT_SOURCES = $(swig_built_sources)
no_dist_files = $(swig_built_sources)
# additional SWIG files to be installed
-howto_swiginclude_headers = \
+howto_swiginclude_headers = \
howto_square_ff.i \
howto_square2_ff.i
diff --git a/gr-howto-write-a-block/swig/Makefile.swig.gen b/gr-howto-write-a-block/swig/Makefile.swig.gen
index c62e5aa3e..6c6e66290 100644
--- a/gr-howto-write-a-block/swig/Makefile.swig.gen
+++ b/gr-howto-write-a-block/swig/Makefile.swig.gen
@@ -25,18 +25,16 @@
## Default install locations for these files:
##
## Default location for the Python directory is:
-## ${prefix}/lib/python${python_version}/site-packages/[category]/howto
+## ${prefix}/lib/python${python_version}/site-packages/howto
## Default location for the Python exec directory is:
-## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/howto
+## ${exec_prefix}/lib/python${python_version}/site-packages/howto
##
## The following can be overloaded to change the install location, but
## this has to be done in the including Makefile.am -before-
## Makefile.swig is included.
-howto_pythondir_category ?= gnuradio/howto
-howto_pylibdir_category ?= $(howto_pythondir_category)
-howto_pythondir = $(pythondir)/$(howto_pythondir_category)
-howto_pylibdir = $(pyexecdir)/$(howto_pylibdir_category)
+howto_pythondir = $(pythondir)/howto
+howto_pylibdir = $(pyexecdir)/howto
## SWIG headers are always installed into the same directory.
@@ -79,7 +77,7 @@ swig_built_sources += howto_swig.py howto_swig.cc
## Makefile.swig .
howto_swiginclude_HEADERS = \
- howto.i \
+ howto.i \
$(howto_swiginclude_headers)
howto_pylib_LTLIBRARIES = \
@@ -89,7 +87,7 @@ _howto_swig_la_SOURCES = \
howto_swig.cc \
$(howto_la_swig_sources)
-_howto_swig_la_LIBADD = \
+_howto_swig_la_LIBADD = \
$(STD_SWIG_LA_LIB_ADD) \
$(howto_la_swig_libadd)
diff --git a/gr-utils/src/python/Makefile.am b/gr-utils/src/python/Makefile.am
index fb21e4f44..9c4e222c8 100644
--- a/gr-utils/src/python/Makefile.am
+++ b/gr-utils/src/python/Makefile.am
@@ -35,6 +35,7 @@ ourpython_PYTHON = \
pyqt_filter.py
bin_SCRIPTS = \
+ create-gnuradio-out-of-tree-project \
gr_plot_char.py \
gr_plot_const.py \
gr_plot_fft.py \
diff --git a/gr-utils/src/python/create-gnuradio-out-of-tree-project b/gr-utils/src/python/create-gnuradio-out-of-tree-project
new file mode 100755
index 000000000..1f512b219
--- /dev/null
+++ b/gr-utils/src/python/create-gnuradio-out-of-tree-project
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+
+from optparse import OptionParser
+import os
+import re
+import sys
+import subprocess
+
+tarball_url="http://gnuradio.org/releases/gnuradio/gr-howto-write-a-block-3.3git-651-g642252d8.tar.gz"
+
+def open_tarball(tarball_name=None):
+ """Return a readable fileobject that references the tarball.
+ If tarball_name is None, download from the net
+ """
+ if tarball_name:
+ return open(tarball_name, 'r')
+ p = subprocess.Popen(["wget", "-O", "-", tarball_url],
+ close_fds=True, stdout=subprocess.PIPE)
+ return p.stdout
+
+def extract_and_rename_files(tarball, module_name):
+ # Requires GNU tar.
+ tar_cmd = 'tar xz --strip-components=1 --transform="s/howto/%s/g"' % (module_name,)
+ p = subprocess.Popen(tar_cmd, shell=True, stdin=tarball, close_fds=True)
+ sts = os.waitpid(p.pid, 0)
+ return sts == 0
+
+def main():
+ usage = "%prog: [options] new_module_name"
+ description="Create a prototype 'out of tree' GNU Radio project"
+ parser = OptionParser(usage=usage, description=description)
+ parser.add_option("-T", "--tarball", type="string", default=None,
+ help="path to gr-howto-build-a-block gzipped tarball [default=<get from web>]")
+ (options, args) = parser.parse_args()
+ if len(args) != 1:
+ parser.print_help()
+ raise SystemExit,2
+ module_name = args[0]
+ if not re.match(r'[_a-z][_a-z0-9]*$', module_name):
+ sys.stderr.write("module_name '%s' may only contain [a-z0-9_]\n" % (module_name))
+ raise SystemExit, 1
+
+ # Ensure there's no file or directory called <module_name>
+ if os.path.exists(module_name):
+ sys.stderr.write("A file or directory named '%s' already exists\n" % (module_name,))
+ raise SystemExit, 1
+
+ os.mkdir(module_name)
+ os.chdir(module_name)
+
+ ok = extract_and_rename_files(open_tarball(options.tarball), module_name)
+
+ # rename file contents
+ upper_module_name = module_name.upper()
+ sed_cmd = 'sed -i -e "s/howto/%s/g" -e "s/HOWTO/%s/g"' % (module_name,
+ upper_module_name)
+ os.system('find . -type f -print0 | xargs -0 ' + sed_cmd)
+
+ sys.stdout.write("""
+Project '%s' is now ready to build.
+
+ $ ./bootstrap
+ $ ./configure --prefix=/home/[user]/install
+ $ (make && make check && make install) 2>&1 | tee make.log
+
+""" % (module_name,))
+
+if __name__ == '__main__':
+ main()
diff --git a/grc/gui/DrawingArea.py b/grc/gui/DrawingArea.py
index b70468ed0..790df7c3f 100644
--- a/grc/gui/DrawingArea.py
+++ b/grc/gui/DrawingArea.py
@@ -1,5 +1,5 @@
"""
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -82,19 +82,21 @@ class DrawingArea(gtk.DrawingArea):
Forward button click information to the flow graph.
"""
self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
- self._flow_graph.handle_mouse_button_press(
- left_click=(event.button == 1),
+ if event.button == 1: self._flow_graph.handle_mouse_selector_press(
double_click=(event.type == gtk.gdk._2BUTTON_PRESS),
coordinate=(event.x, event.y),
)
+ if event.button == 3: self._flow_graph.handle_mouse_context_press(
+ coordinate=(event.x, event.y),
+ event=event,
+ )
def _handle_mouse_button_release(self, widget, event):
"""
Forward button release information to the flow graph.
"""
self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
- self._flow_graph.handle_mouse_button_release(
- left_click=(event.button == 1),
+ if event.button == 1: self._flow_graph.handle_mouse_selector_release(
coordinate=(event.x, event.y),
)
diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py
index 5adecccc1..897145a1d 100644
--- a/grc/gui/FlowGraph.py
+++ b/grc/gui/FlowGraph.py
@@ -1,5 +1,5 @@
"""
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -51,6 +51,19 @@ class FlowGraph(Element):
#selected ports
self._old_selected_port = None
self._new_selected_port = None
+ #context menu
+ self._context_menu = gtk.Menu()
+ for action in [
+ Actions.BLOCK_CUT,
+ Actions.BLOCK_COPY,
+ Actions.BLOCK_PASTE,
+ Actions.ELEMENT_DELETE,
+ Actions.BLOCK_ROTATE_CCW,
+ Actions.BLOCK_ROTATE_CW,
+ Actions.BLOCK_ENABLE,
+ Actions.BLOCK_DISABLE,
+ Actions.BLOCK_PARAM_MODIFY,
+ ]: self._context_menu.append(action.create_menu_item())
###########################################################################
# Access Drawing Area
@@ -425,14 +438,27 @@ class FlowGraph(Element):
##########################################################################
## Event Handlers
##########################################################################
- def handle_mouse_button_press(self, left_click, double_click, coordinate):
+ def handle_mouse_context_press(self, coordinate, event):
"""
- A mouse button is pressed, only respond to left clicks.
+ The context mouse button was pressed:
+ If no elements were selected, perform re-selection at this coordinate.
+ Then, show the context menu at the mouse click location.
+ """
+ selections = self.what_is_selected(coordinate)
+ if not set(selections).intersection(self.get_selected_elements()):
+ self.set_coordinate(coordinate)
+ self.mouse_pressed = True
+ self.update_selected_elements()
+ self.mouse_pressed = False
+ self._context_menu.popup(None, None, None, event.button, event.time)
+
+ def handle_mouse_selector_press(self, double_click, coordinate):
+ """
+ The selector mouse button was pressed:
Find the selected element. Attempt a new connection if possible.
Open the block params window on a double click.
Update the selection state of the flow graph.
"""
- if not left_click: return
self.press_coor = coordinate
self.set_coordinate(coordinate)
self.time = 0
@@ -444,11 +470,12 @@ class FlowGraph(Element):
self.mouse_pressed = False
Actions.BLOCK_PARAM_MODIFY()
- def handle_mouse_button_release(self, left_click, coordinate):
+ def handle_mouse_selector_release(self, coordinate):
"""
- A mouse button is released, record the state.
+ The selector mouse button was released:
+ Update the state, handle motion (dragging).
+ And update the selected flowgraph elements.
"""
- if not left_click: return
self.set_coordinate(coordinate)
self.time = 0
self.mouse_pressed = False
diff --git a/gruel/src/include/gruel/pmt.h b/gruel/src/include/gruel/pmt.h
index 3188aad1d..c371b023b 100644
--- a/gruel/src/include/gruel/pmt.h
+++ b/gruel/src/include/gruel/pmt.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006,2009 Free Software Foundation, Inc.
+ * Copyright 2006,2009,2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -465,23 +465,30 @@ std::complex<double> *pmt_c64vector_writable_elements(pmt_t v, size_t &len); //<
/*
* ------------------------------------------------------------------------
* Dictionary (a.k.a associative array, hash, map)
+ *
+ * This is a functional data structure that is persistent. Updating a
+ * functional data structure does not destroy the existing version, but
+ * rather creates a new version that coexists with the old.
* ------------------------------------------------------------------------
*/
//! Return true if \p obj is a dictionary
-bool pmt_is_dict(pmt_t obj);
+bool pmt_is_dict(const pmt_t &obj);
-//! make an empty dictionary
+//! Make an empty dictionary
pmt_t pmt_make_dict();
-//! dict[key] = value
-void pmt_dict_set(pmt_t dict, pmt_t key, pmt_t value);
+//! Return a new dictionary with \p key associated with \p value.
+pmt_t pmt_dict_add(const pmt_t &dict, const pmt_t &key, const pmt_t &value);
+
+//! Return a new dictionary with \p key removed.
+pmt_t pmt_dict_delete(const pmt_t &dict, const pmt_t &key);
//! Return true if \p key exists in \p dict
-bool pmt_dict_has_key(pmt_t dict, pmt_t key);
+bool pmt_dict_has_key(const pmt_t &dict, const pmt_t &key);
//! If \p key exists in \p dict, return associated value; otherwise return \p not_found.
-pmt_t pmt_dict_ref(pmt_t dict, pmt_t key, pmt_t not_found);
+pmt_t pmt_dict_ref(const pmt_t &dict, const pmt_t &key, const pmt_t &not_found);
//! Return list of (key . value) pairs
pmt_t pmt_dict_items(pmt_t dict);
diff --git a/gruel/src/lib/pmt/pmt.cc b/gruel/src/lib/pmt/pmt.cc
index e50e21838..aa1688d24 100644
--- a/gruel/src/lib/pmt/pmt.cc
+++ b/gruel/src/lib/pmt/pmt.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006,2009 Free Software Foundation, Inc.
+ * Copyright 2006,2009,2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -141,12 +141,6 @@ _uniform_vector(pmt_t x)
return dynamic_cast<pmt_uniform_vector*>(x.get());
}
-static pmt_dict *
-_dict(pmt_t x)
-{
- return dynamic_cast<pmt_dict*>(x.get());
-}
-
static pmt_any *
_any(pmt_t x)
{
@@ -728,124 +722,91 @@ pmt_uniform_vector_writable_elements(pmt_t vector, size_t &len)
// Dictionaries
////////////////////////////////////////////////////////////////////////////
-pmt_dict::pmt_dict()
- : d_alist(PMT_NIL)
-{
-}
-
-void
-pmt_dict::set(pmt_t key, pmt_t value)
-{
- pmt_t p = pmt_assv(key, d_alist); // look for (key . value) pair
- if (pmt_is_pair(p)){ // found existing pair...
- pmt_set_cdr(p, value); // overrwrite cdr with new value
- }
- else { // not in the dict
- d_alist = pmt_cons(pmt_cons(key, value), d_alist); // add new (key . value) pair
- }
-}
-
-pmt_t
-pmt_dict::ref(pmt_t key, pmt_t not_found) const
-{
- pmt_t p = pmt_assv(key, d_alist); // look for (key . value) pair
- if (pmt_is_pair(p))
- return pmt_cdr(p);
- else
- return not_found;
-}
+/*
+ * This is an a-list implementation.
+ *
+ * When we need better performance for large dictionaries, consider implementing
+ * persistent Red-Black trees as described in "Purely Functional Data Structures",
+ * Chris Okasaki, 1998, section 3.3.
+ */
bool
-pmt_dict::has_key(pmt_t key) const
+pmt_is_dict(const pmt_t &obj)
{
- return pmt_is_pair(pmt_assv(key, d_alist));
+ return pmt_is_null(obj) || pmt_is_pair(obj);
}
pmt_t
-pmt_dict::items() const
+pmt_make_dict()
{
- return d_alist;
+ return PMT_NIL;
}
pmt_t
-pmt_dict::keys() const
+pmt_dict_add(const pmt_t &dict, const pmt_t &key, const pmt_t &value)
{
- return pmt_map(pmt_car, d_alist);
-}
+ if (pmt_is_null(dict))
+ return pmt_acons(key, value, PMT_NIL);
-pmt_t
-pmt_dict::values() const
-{
- return pmt_map(pmt_cdr, d_alist);
-}
+ if (pmt_dict_has_key(dict, key))
+ return pmt_acons(key, value, pmt_dict_delete(dict, key));
-bool
-pmt_is_dict(pmt_t obj)
-{
- return obj->is_dict();
+ return pmt_acons(key, value, dict);
}
pmt_t
-pmt_make_dict()
+pmt_dict_delete(const pmt_t &dict, const pmt_t &key)
{
- return pmt_t(new pmt_dict());
+ if (pmt_is_null(dict))
+ return dict;
+
+ if (pmt_eqv(pmt_caar(dict), key))
+ return pmt_cdr(dict);
+
+ return pmt_cons(pmt_car(dict), pmt_dict_delete(pmt_cdr(dict), key));
}
-void
-pmt_dict_set(pmt_t dict, pmt_t key, pmt_t value)
+pmt_t
+pmt_dict_ref(const pmt_t &dict, const pmt_t &key, const pmt_t &not_found)
{
- pmt_dict* d = _dict(dict);
- if (!d)
- throw pmt_wrong_type("pmt_dict_set", dict);
-
- d->set(key, value);
+ pmt_t p = pmt_assv(key, dict); // look for (key . value) pair
+ if (pmt_is_pair(p))
+ return pmt_cdr(p);
+ else
+ return not_found;
}
bool
-pmt_dict_has_key(pmt_t dict, pmt_t key)
+pmt_dict_has_key(const pmt_t &dict, const pmt_t &key)
{
- pmt_dict* d = _dict(dict);
- if (!d)
- throw pmt_wrong_type("pmt_dict_has_key", dict);
-
- return d->has_key(key);
-}
-
-pmt_t
-pmt_dict_ref(pmt_t dict, pmt_t key, pmt_t not_found)
-{
- pmt_dict* d = _dict(dict);
- if (!d)
- throw pmt_wrong_type("pmt_dict_ref", dict);
-
- return d->ref(key, not_found);
+ return pmt_is_pair(pmt_assv(key, dict));
}
pmt_t
pmt_dict_items(pmt_t dict)
{
- if (!dict->is_dict())
- throw pmt_wrong_type("pmt_dict_items", dict);
+ if (!pmt_is_dict(dict))
+ throw pmt_wrong_type("pmt_dict_values", dict);
- return _dict(dict)->items();
+ return dict; // equivalent to dict in the a-list case
}
pmt_t
pmt_dict_keys(pmt_t dict)
{
- if (!dict->is_dict())
+ if (!pmt_is_dict(dict))
throw pmt_wrong_type("pmt_dict_keys", dict);
- return _dict(dict)->keys();
+ return pmt_map(pmt_car, dict);
}
pmt_t
pmt_dict_values(pmt_t dict)
{
- if (!dict->is_dict())
- throw pmt_wrong_type("pmt_dict_values", dict);
+ if (!pmt_is_dict(dict))
+ throw pmt_wrong_type("pmt_dict_keys", dict);
- return _dict(dict)->values();
+ return pmt_map(pmt_cdr, dict);
}
////////////////////////////////////////////////////////////////////////////
@@ -978,6 +939,24 @@ pmt_eqv(const pmt_t& x, const pmt_t& y)
}
bool
+pmt_eqv_raw(pmt_base *x, pmt_base *y)
+{
+ if (x == y)
+ return true;
+
+ if (x->is_integer() && y->is_integer())
+ return _integer(x)->value() == _integer(y)->value();
+
+ if (x->is_real() && y->is_real())
+ return _real(x)->value() == _real(y)->value();
+
+ if (x->is_complex() && y->is_complex())
+ return _complex(x)->value() == _complex(y)->value();
+
+ return false;
+}
+
+bool
pmt_equal(const pmt_t& x, const pmt_t& y)
{
if (pmt_eqv(x, y))
@@ -1082,6 +1061,35 @@ pmt_assq(pmt_t obj, pmt_t alist)
return PMT_F;
}
+/*
+ * This avoids a bunch of shared_pointer reference count manipulation.
+ */
+pmt_t
+pmt_assv_raw(pmt_base *obj, pmt_base *alist)
+{
+ while (alist->is_pair()){
+ pmt_base *p = ((pmt_pair *)alist)->d_car.get();
+ if (!p->is_pair()) // malformed alist
+ return PMT_F;
+
+ if (pmt_eqv_raw(obj, ((pmt_pair *)p)->d_car.get()))
+ return ((pmt_pair *)alist)->d_car;
+
+ alist = (((pmt_pair *)alist)->d_cdr).get();
+ }
+ return PMT_F;
+}
+
+#if 1
+
+pmt_t
+pmt_assv(pmt_t obj, pmt_t alist)
+{
+ return pmt_assv_raw(obj.get(), alist.get());
+}
+
+#else
+
pmt_t
pmt_assv(pmt_t obj, pmt_t alist)
{
@@ -1098,6 +1106,9 @@ pmt_assv(pmt_t obj, pmt_t alist)
return PMT_F;
}
+#endif
+
+
pmt_t
pmt_assoc(pmt_t obj, pmt_t alist)
{
@@ -1322,7 +1333,6 @@ pmt_dump_sizeof()
printf("sizeof(pmt_null) = %3zd\n", sizeof(pmt_null));
printf("sizeof(pmt_pair) = %3zd\n", sizeof(pmt_pair));
printf("sizeof(pmt_vector) = %3zd\n", sizeof(pmt_vector));
- printf("sizeof(pmt_dict) = %3zd\n", sizeof(pmt_dict));
printf("sizeof(pmt_uniform_vector) = %3zd\n", sizeof(pmt_uniform_vector));
}
diff --git a/gruel/src/lib/pmt/pmt_int.h b/gruel/src/lib/pmt/pmt_int.h
index 7581845f8..50683ffb5 100644
--- a/gruel/src/lib/pmt/pmt_int.h
+++ b/gruel/src/lib/pmt/pmt_int.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006,2009 Free Software Foundation, Inc.
+ * Copyright 2006,2009,2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -107,9 +107,9 @@ public:
class pmt_integer : public pmt_base
{
+public:
long d_value;
-public:
pmt_integer(long value);
//~pmt_integer(){}
@@ -120,9 +120,9 @@ public:
class pmt_real : public pmt_base
{
+public:
double d_value;
-public:
pmt_real(double value);
//~pmt_real(){}
@@ -133,9 +133,9 @@ public:
class pmt_complex : public pmt_base
{
+public:
std::complex<double> d_value;
-public:
pmt_complex(std::complex<double> value);
//~pmt_complex(){}
@@ -155,10 +155,10 @@ public:
class pmt_pair : public pmt_base
{
+public:
pmt_t d_car;
pmt_t d_cdr;
-public:
pmt_pair(const pmt_t& car, const pmt_t& cdr);
//~pmt_pair(){};
@@ -203,23 +203,6 @@ public:
void _set(size_t k, pmt_t v) { d_v[k] = v; }
};
-class pmt_dict : public pmt_base
-{
- pmt_t d_alist; // list of (key . value) pairs
-
-public:
- pmt_dict();
- //~pmt_dict();
-
- bool is_dict() const { return true; }
- void set(pmt_t key, pmt_t value);
- pmt_t ref(pmt_t key, pmt_t default_value) const;
- bool has_key(pmt_t key) const;
- pmt_t items() const;
- pmt_t keys() const;
- pmt_t values() const;
-};
-
class pmt_any : public pmt_base
{
boost::any d_any;
diff --git a/gruel/src/lib/pmt/qa_pmt_prims.cc b/gruel/src/lib/pmt/qa_pmt_prims.cc
index 59d9e14d3..f2414c72c 100644
--- a/gruel/src/lib/pmt/qa_pmt_prims.cc
+++ b/gruel/src/lib/pmt/qa_pmt_prims.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006,2009 Free Software Foundation, Inc.
+ * Copyright 2006,2009,2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -36,14 +36,14 @@ qa_pmt_prims::test_symbols()
CPPUNIT_ASSERT(!pmt_is_symbol(PMT_F));
CPPUNIT_ASSERT_THROW(pmt_symbol_to_string(PMT_F), pmt_wrong_type);
- pmt_t sym1 = pmt_string_to_symbol("test");
+ pmt_t sym1 = mp("test");
CPPUNIT_ASSERT(pmt_is_symbol(sym1));
CPPUNIT_ASSERT_EQUAL(std::string("test"), pmt_symbol_to_string(sym1));
CPPUNIT_ASSERT(pmt_is_true(sym1));
CPPUNIT_ASSERT(!pmt_is_false(sym1));
- pmt_t sym2 = pmt_string_to_symbol("foo");
- pmt_t sym3 = pmt_string_to_symbol("test");
+ pmt_t sym2 = mp("foo");
+ pmt_t sym3 = mp("test");
CPPUNIT_ASSERT_EQUAL(sym1, sym3);
CPPUNIT_ASSERT(sym1 != sym2);
CPPUNIT_ASSERT(sym1 == sym3);
@@ -56,7 +56,7 @@ qa_pmt_prims::test_symbols()
for (int i = 0; i < N; i++){
char buf[100];
snprintf(buf, sizeof(buf), "test-%d", i);
- v1[i] = pmt_string_to_symbol(buf);
+ v1[i] = mp(buf);
}
// confirm that they are all unique
@@ -68,7 +68,7 @@ qa_pmt_prims::test_symbols()
for (int i = 0; i < N; i++){
char buf[100];
snprintf(buf, sizeof(buf), "test-%d", i);
- v2[i] = pmt_string_to_symbol(buf);
+ v2[i] = mp(buf);
}
// confirm that we get the same ones back
@@ -79,7 +79,7 @@ qa_pmt_prims::test_symbols()
void
qa_pmt_prims::test_booleans()
{
- pmt_t sym = pmt_string_to_symbol("test");
+ pmt_t sym = mp("test");
CPPUNIT_ASSERT(pmt_is_bool(PMT_T));
CPPUNIT_ASSERT(pmt_is_bool(PMT_F));
CPPUNIT_ASSERT(!pmt_is_bool(sym));
@@ -137,9 +137,9 @@ qa_pmt_prims::test_pairs()
{
CPPUNIT_ASSERT(pmt_is_null(PMT_NIL));
CPPUNIT_ASSERT(!pmt_is_pair(PMT_NIL));
- pmt_t s1 = pmt_string_to_symbol("s1");
- pmt_t s2 = pmt_string_to_symbol("s2");
- pmt_t s3 = pmt_string_to_symbol("s3");
+ pmt_t s1 = mp("s1");
+ pmt_t s2 = mp("s2");
+ pmt_t s3 = mp("s3");
CPPUNIT_ASSERT_EQUAL((size_t)0, pmt_length(PMT_NIL));
@@ -174,9 +174,9 @@ qa_pmt_prims::test_vectors()
static const size_t N = 3;
pmt_t v1 = pmt_make_vector(N, PMT_NIL);
CPPUNIT_ASSERT_EQUAL(N, pmt_length(v1));
- pmt_t s0 = pmt_string_to_symbol("s0");
- pmt_t s1 = pmt_string_to_symbol("s1");
- pmt_t s2 = pmt_string_to_symbol("s2");
+ pmt_t s0 = mp("s0");
+ pmt_t s1 = mp("s1");
+ pmt_t s2 = mp("s2");
pmt_vector_set(v1, 0, s0);
pmt_vector_set(v1, 1, s1);
@@ -213,7 +213,7 @@ qa_pmt_prims::test_tuples()
for (size_t i = 0; i < 10; i++){
std::ostringstream os;
os << "s" << i;
- s[i] = pmt_string_to_symbol(os.str());
+ s[i] = mp(os.str());
pmt_vector_set(v, i, s[i]);
}
@@ -282,9 +282,9 @@ qa_pmt_prims::test_tuples()
void
qa_pmt_prims::test_equivalence()
{
- pmt_t s0 = pmt_string_to_symbol("s0");
- pmt_t s1 = pmt_string_to_symbol("s1");
- pmt_t s2 = pmt_string_to_symbol("s2");
+ pmt_t s0 = mp("s0");
+ pmt_t s1 = mp("s1");
+ pmt_t s2 = mp("s2");
pmt_t list0 = pmt_cons(s0, pmt_cons(s1, pmt_cons(s2, PMT_NIL)));
pmt_t list1 = pmt_cons(s0, pmt_cons(s1, pmt_cons(s2, PMT_NIL)));
pmt_t i0 = pmt_from_long(42);
@@ -324,13 +324,13 @@ qa_pmt_prims::test_equivalence()
void
qa_pmt_prims::test_misc()
{
- pmt_t k0 = pmt_string_to_symbol("k0");
- pmt_t k1 = pmt_string_to_symbol("k1");
- pmt_t k2 = pmt_string_to_symbol("k2");
- pmt_t k3 = pmt_string_to_symbol("k3");
- pmt_t v0 = pmt_string_to_symbol("v0");
- pmt_t v1 = pmt_string_to_symbol("v1");
- pmt_t v2 = pmt_string_to_symbol("v2");
+ pmt_t k0 = mp("k0");
+ pmt_t k1 = mp("k1");
+ pmt_t k2 = mp("k2");
+ pmt_t k3 = mp("k3");
+ pmt_t v0 = mp("v0");
+ pmt_t v1 = mp("v1");
+ pmt_t v2 = mp("v2");
pmt_t p0 = pmt_cons(k0, v0);
pmt_t p1 = pmt_cons(k1, v1);
pmt_t p2 = pmt_cons(k2, v2);
@@ -351,29 +351,31 @@ qa_pmt_prims::test_dict()
pmt_t dict = pmt_make_dict();
CPPUNIT_ASSERT(pmt_is_dict(dict));
- pmt_t k0 = pmt_string_to_symbol("k0");
- pmt_t k1 = pmt_string_to_symbol("k1");
- pmt_t k2 = pmt_string_to_symbol("k2");
- pmt_t k3 = pmt_string_to_symbol("k3");
- pmt_t v0 = pmt_string_to_symbol("v0");
- pmt_t v1 = pmt_string_to_symbol("v1");
- pmt_t v2 = pmt_string_to_symbol("v2");
- pmt_t v3 = pmt_string_to_symbol("v3");
+ pmt_t k0 = mp("k0");
+ pmt_t k1 = mp("k1");
+ pmt_t k2 = mp("k2");
+ pmt_t k3 = mp("k3");
+ pmt_t v0 = mp("v0");
+ pmt_t v1 = mp("v1");
+ pmt_t v2 = mp("v2");
+ pmt_t v3 = mp("v3");
pmt_t not_found = pmt_cons(PMT_NIL, PMT_NIL);
CPPUNIT_ASSERT(!pmt_dict_has_key(dict, k0));
- pmt_dict_set(dict, k0, v0);
+ dict = pmt_dict_add(dict, k0, v0);
CPPUNIT_ASSERT(pmt_dict_has_key(dict, k0));
CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k0, not_found), v0));
CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k1, not_found), not_found));
- pmt_dict_set(dict, k1, v1);
- pmt_dict_set(dict, k2, v2);
+ dict = pmt_dict_add(dict, k1, v1);
+ dict = pmt_dict_add(dict, k2, v2);
CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k1, not_found), v1));
- pmt_dict_set(dict, k1, v3);
+ dict = pmt_dict_add(dict, k1, v3);
CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k1, not_found), v3));
- pmt_t keys = pmt_cons(k2, pmt_cons(k1, pmt_cons(k0, PMT_NIL)));
- pmt_t vals = pmt_cons(v2, pmt_cons(v3, pmt_cons(v0, PMT_NIL)));
+ pmt_t keys = pmt_list3(k1, k2, k0);
+ pmt_t vals = pmt_list3(v3, v2, v0);
+ //std::cout << "pmt_dict_keys: " << pmt_dict_keys(dict) << std::endl;
+ //std::cout << "pmt_dict_values: " << pmt_dict_values(dict) << std::endl;
CPPUNIT_ASSERT(pmt_equal(keys, pmt_dict_keys(dict)));
CPPUNIT_ASSERT(pmt_equal(vals, pmt_dict_values(dict)));
}
@@ -381,10 +383,10 @@ qa_pmt_prims::test_dict()
void
qa_pmt_prims::test_io()
{
- pmt_t k0 = pmt_string_to_symbol("k0");
- pmt_t k1 = pmt_string_to_symbol("k1");
- pmt_t k2 = pmt_string_to_symbol("k2");
- pmt_t k3 = pmt_string_to_symbol("k3");
+ pmt_t k0 = mp("k0");
+ pmt_t k1 = mp("k1");
+ pmt_t k2 = mp("k2");
+ pmt_t k3 = mp("k3");
CPPUNIT_ASSERT_EQUAL(std::string("k0"), pmt_write_string(k0));
}
@@ -392,10 +394,10 @@ qa_pmt_prims::test_io()
void
qa_pmt_prims::test_lists()
{
- pmt_t s0 = pmt_intern("s0");
- pmt_t s1 = pmt_intern("s1");
- pmt_t s2 = pmt_intern("s2");
- pmt_t s3 = pmt_intern("s3");
+ pmt_t s0 = mp("s0");
+ pmt_t s1 = mp("s1");
+ pmt_t s2 = mp("s2");
+ pmt_t s3 = mp("s3");
pmt_t l1 = pmt_list4(s0, s1, s2, s3);
pmt_t l2 = pmt_list3(s0, s1, s2);
@@ -466,7 +468,7 @@ qa_pmt_msg_accepter_nop::~qa_pmt_msg_accepter_nop(){}
void
qa_pmt_prims::test_msg_accepter()
{
- pmt_t sym = pmt_intern("my-symbol");
+ pmt_t sym = mp("my-symbol");
boost::any a0;
a0 = std::string("Hello!");
@@ -493,16 +495,16 @@ void
qa_pmt_prims::test_serialize()
{
std::stringbuf sb; // fake channel
- pmt_t a = pmt_intern("a");
- pmt_t b = pmt_intern("b");
- pmt_t c = pmt_intern("c");
+ pmt_t a = mp("a");
+ pmt_t b = mp("b");
+ pmt_t c = mp("c");
sb.str(""); // reset channel to empty
// write stuff to channel
pmt_serialize(PMT_NIL, sb);
- pmt_serialize(pmt_intern("foobarvia"), sb);
+ pmt_serialize(mp("foobarvia"), sb);
pmt_serialize(pmt_from_long(123456789), sb);
pmt_serialize(pmt_from_long(-123456789), sb);
pmt_serialize(pmt_cons(PMT_NIL, PMT_NIL), sb);
@@ -517,7 +519,7 @@ qa_pmt_prims::test_serialize()
// read it back
CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), PMT_NIL));
- CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_intern("foobarvia")));
+ CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), mp("foobarvia")));
CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_from_long(123456789)));
CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_from_long(-123456789)));
CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_cons(PMT_NIL, PMT_NIL)));
@@ -540,9 +542,9 @@ qa_pmt_prims::test_serialize()
void
qa_pmt_prims::test_sets()
{
- pmt_t s1 = pmt_intern("s1");
- pmt_t s2 = pmt_intern("s2");
- pmt_t s3 = pmt_intern("s3");
+ pmt_t s1 = mp("s1");
+ pmt_t s2 = mp("s2");
+ pmt_t s3 = mp("s3");
pmt_t l1 = pmt_list1(s1);
pmt_t l2 = pmt_list2(s2,s3);