diff options
author | Tom Rondeau <tom@trondeau.com> | 2013-08-23 16:40:48 -0400 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2013-08-26 17:07:10 -0400 |
commit | 9c03a0d2aab4705c37645c87af1ec591e9a515cd (patch) | |
tree | 57816523e12e8b58fa84596578bd550954fff813 | |
parent | 52cffbabaef816ba7e723cf53c69a8cfa2a39849 (diff) |
filter: added optional second input that dynamically adjusts resampling rate.
-rw-r--r-- | gr-filter/grc/filter_fractional_resampler_xx.xml | 5 | ||||
-rw-r--r-- | gr-filter/lib/fractional_resampler_cc_impl.cc | 43 | ||||
-rw-r--r-- | gr-filter/lib/fractional_resampler_ff_impl.cc | 44 | ||||
-rw-r--r-- | gr-filter/python/filter/qa_fractional_resampler.py | 61 |
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") |