summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rondeau <tom@trondeau.com>2013-08-23 16:40:48 -0400
committerTom Rondeau <tom@trondeau.com>2013-08-26 17:07:10 -0400
commit9c03a0d2aab4705c37645c87af1ec591e9a515cd (patch)
tree57816523e12e8b58fa84596578bd550954fff813
parent52cffbabaef816ba7e723cf53c69a8cfa2a39849 (diff)
filter: added optional second input that dynamically adjusts resampling rate.
-rw-r--r--gr-filter/grc/filter_fractional_resampler_xx.xml5
-rw-r--r--gr-filter/lib/fractional_resampler_cc_impl.cc43
-rw-r--r--gr-filter/lib/fractional_resampler_ff_impl.cc44
-rw-r--r--gr-filter/python/filter/qa_fractional_resampler.py61
4 files changed, 127 insertions, 26 deletions
diff --git a/gr-filter/grc/filter_fractional_resampler_xx.xml b/gr-filter/grc/filter_fractional_resampler_xx.xml
index 48d624d432..40957b889d 100644
--- a/gr-filter/grc/filter_fractional_resampler_xx.xml
+++ b/gr-filter/grc/filter_fractional_resampler_xx.xml
@@ -39,6 +39,11 @@
<name>in</name>
<type>$type</type>
</sink>
+ <sink>
+ <name>rate</name>
+ <type>float</type>
+ <optional>1</optional>
+ </sink>
<source>
<name>out</name>
<type>$type</type>
diff --git a/gr-filter/lib/fractional_resampler_cc_impl.cc b/gr-filter/lib/fractional_resampler_cc_impl.cc
index 27f139d813..b17e13638b 100644
--- a/gr-filter/lib/fractional_resampler_cc_impl.cc
+++ b/gr-filter/lib/fractional_resampler_cc_impl.cc
@@ -41,8 +41,8 @@ namespace gr {
fractional_resampler_cc_impl::fractional_resampler_cc_impl
(float phase_shift, float resamp_ratio)
: block("fractional_resampler_cc",
- io_signature::make(1, 1, sizeof(gr_complex)),
- io_signature::make(1, 1, sizeof(gr_complex))),
+ io_signature::make2(1, 2, sizeof(gr_complex), sizeof(float)),
+ io_signature::make(1, 1, sizeof(gr_complex))),
d_mu(phase_shift), d_mu_inc(resamp_ratio),
d_resamp(new mmse_fir_interpolator_cc())
{
@@ -82,19 +82,38 @@ namespace gr {
int ii = 0; // input index
int oo = 0; // output index
- while(oo < noutput_items) {
- out[oo++] = d_resamp->interpolate(&in[ii], d_mu);
+ if(ninput_items.size() == 1) {
+ while(oo < noutput_items) {
+ out[oo++] = d_resamp->interpolate(&in[ii], d_mu);
- double s = d_mu + d_mu_inc;
- double f = floor(s);
- int incr = (int)f;
- d_mu = s - f;
- ii += incr;
- }
+ double s = d_mu + d_mu_inc;
+ double f = floor(s);
+ int incr = (int)f;
+ d_mu = s - f;
+ ii += incr;
+ }
- consume_each(ii);
+ consume_each(ii);
+ return noutput_items;
+ }
- return noutput_items;
+ else {
+ const float *rr = (const float*)input_items[1];
+ while(oo < noutput_items) {
+ out[oo++] = d_resamp->interpolate(&in[ii], d_mu);
+ d_mu_inc = rr[ii];
+
+ double s = d_mu + d_mu_inc;
+ double f = floor(s);
+ int incr = (int)f;
+ d_mu = s - f;
+ ii += incr;
+ }
+
+ set_relative_rate(1.0 / d_mu_inc);
+ consume_each(ii);
+ return noutput_items;
+ }
}
float
diff --git a/gr-filter/lib/fractional_resampler_ff_impl.cc b/gr-filter/lib/fractional_resampler_ff_impl.cc
index 61950d92c0..131ccaae4e 100644
--- a/gr-filter/lib/fractional_resampler_ff_impl.cc
+++ b/gr-filter/lib/fractional_resampler_ff_impl.cc
@@ -41,8 +41,8 @@ namespace gr {
fractional_resampler_ff_impl::fractional_resampler_ff_impl
(float phase_shift, float resamp_ratio)
: block("fractional_resampler_ff",
- io_signature::make(1, 1, sizeof(float)),
- io_signature::make(1, 1, sizeof(float))),
+ io_signature::make(1, 2, sizeof(float)),
+ io_signature::make(1, 1, sizeof(float))),
d_mu (phase_shift), d_mu_inc (resamp_ratio),
d_resamp(new mmse_fir_interpolator_ff())
{
@@ -82,19 +82,37 @@ namespace gr {
int ii = 0; // input index
int oo = 0; // output index
- while(oo < noutput_items) {
- out[oo++] = d_resamp->interpolate(&in[ii], d_mu);
+ if(ninput_items.size() == 1) {
+ while(oo < noutput_items) {
+ out[oo++] = d_resamp->interpolate(&in[ii], d_mu);
- double s = d_mu + d_mu_inc;
- double f = floor(s);
- int incr = (int)f;
- d_mu = s - f;
- ii += incr;
- }
-
- consume_each(ii);
+ double s = d_mu + d_mu_inc;
+ double f = floor(s);
+ int incr = (int)f;
+ d_mu = s - f;
+ ii += incr;
+ }
- return noutput_items;
+ consume_each(ii);
+ return noutput_items;
+ }
+ else {
+ const float *rr = (const float*)input_items[1];
+ while(oo < noutput_items) {
+ out[oo++] = d_resamp->interpolate(&in[ii], d_mu);
+ d_mu_inc = rr[ii];
+
+ double s = d_mu + d_mu_inc;
+ double f = floor(s);
+ int incr = (int)f;
+ d_mu = s - f;
+ ii += incr;
+ }
+
+ set_relative_rate(1.0 / d_mu_inc);
+ consume_each(ii);
+ return noutput_items;
+ }
}
float
diff --git a/gr-filter/python/filter/qa_fractional_resampler.py b/gr-filter/python/filter/qa_fractional_resampler.py
index 220ebd9e30..ea01cf7eef 100644
--- a/gr-filter/python/filter/qa_fractional_resampler.py
+++ b/gr-filter/python/filter/qa_fractional_resampler.py
@@ -35,6 +35,10 @@ def sig_source_c(samp_rate, freq, amp, N):
1j*math.sin(2.*math.pi*freq*x), t)
return y
+def const_source_f(amp, N):
+ y = N*[amp,]
+ return y
+
class test_fractional_resampler(gr_unittest.TestCase):
def setUp(self):
@@ -68,7 +72,6 @@ class test_fractional_resampler(gr_unittest.TestCase):
self.assertFloatTuplesAlmostEqual(expected_data[-Ntest:], dst_data[-Ntest:], 3)
-
def test_002_cc(self):
N = 10000 # number of samples to use
fs = 1000 # baseband sampling rate
@@ -95,6 +98,62 @@ class test_fractional_resampler(gr_unittest.TestCase):
self.assertComplexTuplesAlmostEqual(expected_data[-Ntest:], dst_data[-Ntest:], 3)
+ def test_003_ff(self):
+ N = 10000 # number of samples to use
+ fs = 1000 # baseband sampling rate
+ rrate = 1.123 # resampling rate
+
+ freq = 10
+ data = sig_source_f(fs, freq, 1, N)
+ ctrl = const_source_f(rrate, N)
+ signal = blocks.vector_source_f(data)
+ control = blocks.vector_source_f(ctrl)
+ op = filter.fractional_resampler_ff(0, 1)
+ snk = blocks.vector_sink_f()
+
+ self.tb.connect(signal, op, snk)
+ self.tb.connect(control, (op,1))
+ self.tb.run()
+
+ Ntest = 5000
+ L = len(snk.data())
+ t = map(lambda x: float(x)/(fs/rrate), xrange(L))
+
+ phase = 0.1884
+ expected_data = map(lambda x: math.sin(2.*math.pi*freq*x+phase), t)
+
+ dst_data = snk.data()
+
+ self.assertFloatTuplesAlmostEqual(expected_data[-Ntest:], dst_data[-Ntest:], 3)
+
+ def test_004_cc(self):
+ N = 10000 # number of samples to use
+ fs = 1000 # baseband sampling rate
+ rrate = 1.123 # resampling rate
+
+ freq = 10
+ data = sig_source_c(fs, freq, 1, N)
+ ctrl = const_source_f(rrate, N)
+ signal = blocks.vector_source_c(data)
+ control = blocks.vector_source_f(ctrl)
+ op = filter.fractional_resampler_cc(0.0, 1)
+ snk = blocks.vector_sink_c()
+
+ self.tb.connect(signal, op, snk)
+ self.tb.connect(control, (op,1))
+ self.tb.run()
+
+ Ntest = 5000
+ L = len(snk.data())
+ t = map(lambda x: float(x)/(fs/rrate), xrange(L))
+
+ phase = 0.1884
+ expected_data = map(lambda x: math.cos(2.*math.pi*freq*x+phase) + \
+ 1j*math.sin(2.*math.pi*freq*x+phase), t)
+
+ dst_data = snk.data()
+
+ self.assertComplexTuplesAlmostEqual(expected_data[-Ntest:], dst_data[-Ntest:], 3)
if __name__ == '__main__':
gr_unittest.run(test_fractional_resampler, "test_fractional_resampler.xml")