From 970bb33df3e9dfe19d9cae49a95494b7e175644f Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sat, 20 Oct 2012 17:14:02 -0400 Subject: analog: adding squelch_base_ff and ctcss_squelch_ff to analog. This addresses the issues of inheriting from both gr_block and another block (squelch_base_ff, in this case). --- gr-analog/include/analog/CMakeLists.txt | 2 + gr-analog/include/analog/ctcss_squelch_ff.h | 69 ++++++++++++++ gr-analog/include/analog/squelch_base_ff.h | 56 +++++++++++ gr-analog/lib/CMakeLists.txt | 2 + gr-analog/lib/ctcss_squelch_ff_impl.cc | 130 ++++++++++++++++++++++++++ gr-analog/lib/ctcss_squelch_ff_impl.h | 82 ++++++++++++++++ gr-analog/lib/squelch_base_ff_impl.cc | 140 ++++++++++++++++++++++++++++ gr-analog/lib/squelch_base_ff_impl.h | 65 +++++++++++++ gr-analog/python/qa_ctcss_squelch.py | 110 ++++++++++++++++++++++ gr-analog/swig/analog_swig.i | 6 +- 10 files changed, 661 insertions(+), 1 deletion(-) create mode 100644 gr-analog/include/analog/ctcss_squelch_ff.h create mode 100644 gr-analog/include/analog/squelch_base_ff.h create mode 100644 gr-analog/lib/ctcss_squelch_ff_impl.cc create mode 100644 gr-analog/lib/ctcss_squelch_ff_impl.h create mode 100644 gr-analog/lib/squelch_base_ff_impl.cc create mode 100644 gr-analog/lib/squelch_base_ff_impl.h create mode 100644 gr-analog/python/qa_ctcss_squelch.py diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index 0b5dd28e0..d688d2c3d 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -77,6 +77,8 @@ install(FILES ${analog_generated_includes} api.h cpm.h + ctcss_squelch_ff.h + squelch_base_ff.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog COMPONENT "analog_devel" ) diff --git a/gr-analog/include/analog/ctcss_squelch_ff.h b/gr-analog/include/analog/ctcss_squelch_ff.h new file mode 100644 index 000000000..f88029917 --- /dev/null +++ b/gr-analog/include/analog/ctcss_squelch_ff.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_CTCSS_SQUELCH_FF_H +#define INCLUDED_ANALOG_CTCSS_SQUELCH_FF_H + +#include +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief gate or zero output if ctcss tone not present + * \ingroup level_blk + */ + class ANALOG_API ctcss_squelch_ff : + public squelch_base_ff, virtual public gr_block + { + protected: + virtual void update_state(const float &in) = 0; + virtual bool mute() const = 0; + + public: + // gr::analog::ctcss_squelch_ff::sptr + typedef boost::shared_ptr sptr; + + /*! + * \brief Make CTCSS tone squelch block. + */ + static sptr make(int rate, float freq, float level, + int len, int ramp, bool gate); + + virtual std::vector squelch_range() const = 0; + virtual float level() const = 0; + virtual void set_level(float level) = 0; + virtual int len() const = 0; + + virtual int ramp() const = 0; + virtual void set_ramp(int ramp) = 0; + virtual bool gate() const = 0; + virtual void set_gate(bool gate) = 0; + virtual bool unmuted() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_CTCSS_SQUELCH_FF_H */ diff --git a/gr-analog/include/analog/squelch_base_ff.h b/gr-analog/include/analog/squelch_base_ff.h new file mode 100644 index 000000000..2ce1f1a65 --- /dev/null +++ b/gr-analog/include/analog/squelch_base_ff.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_SQUELCH_BASE_FF_H +#define INCLUDED_ANALOG_SQUELCH_BASE_FF_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief basic squelch block; to be subclassed for other squelches. + * \ingroup level_blk + */ + class ANALOG_API squelch_base_ff : virtual public gr_block + { + protected: + virtual void update_state(const float &sample) = 0; + virtual bool mute() const = 0; + + public: + squelch_base_ff() {}; + virtual int ramp() const = 0; + virtual void set_ramp(int ramp) = 0; + virtual bool gate() const = 0; + virtual void set_gate(bool gate) = 0; + virtual bool unmuted() const = 0; + + virtual std::vector squelch_range() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SQUELCH_BASE_FF_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index f18c84274..b0f7a17de 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -104,6 +104,8 @@ endmacro(expand_cc) list(APPEND analog_sources ${generated_sources} cpm.cc + squelch_base_ff_impl.cc + ctcss_squelch_ff_impl.cc ) list(APPEND analog_libs diff --git a/gr-analog/lib/ctcss_squelch_ff_impl.cc b/gr-analog/lib/ctcss_squelch_ff_impl.cc new file mode 100644 index 000000000..db49b4f6e --- /dev/null +++ b/gr-analog/lib/ctcss_squelch_ff_impl.cc @@ -0,0 +1,130 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2010,2012 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 "ctcss_squelch_ff_impl.h" + +namespace gr { + namespace analog { + + static float ctcss_tones[] = { + 67.0, 71.9, 74.4, 77.0, 79.7, 82.5, 85.4, 88.5, 91.5, 94.8, + 97.4, 100.0, 103.5, 107.2, 110.9, 114.8, 118.8, 123.0, 127.3, 131.8, + 136.5, 141.3, 146.2, 151.4, 156.7, 162.2, 167.9, 173.8, 179.9, 186.2, + 192.8, 203.5, 210.7, 218.1, 225.7, 233.6, 241.8, 250.3 + }; + + static int max_tone_index = 37; + + ctcss_squelch_ff::sptr + ctcss_squelch_ff::make(int rate, float freq, float level, + int len, int ramp, bool gate) + { + return gnuradio::get_initial_sptr(new ctcss_squelch_ff_impl + (rate, freq, level, len, ramp, gate)); + } + + int + ctcss_squelch_ff_impl::find_tone(float freq) + { + for(int i = 0; i <= max_tone_index; i++) + if(ctcss_tones[i] == freq) // FIXME: make almost equal + return i; + return -1; + } + + ctcss_squelch_ff_impl::ctcss_squelch_ff_impl(int rate, float freq, float level, + int len, int ramp, bool gate) + : gr_block("ctcss_squelch_ff", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))), + squelch_base_ff_impl("ctcss_squelch_ff", ramp, gate) + { + d_freq = freq; + d_level = level; + + // Default is 100 ms detection time + if(len == 0) + d_len = (int)(rate/10.0); + else + d_len = len; + + int i = find_tone(freq); + + // Non-standard tones or edge tones get 2% guard band, otherwise + // guards are set at adjacent ctcss tone frequencies + float f_l, f_r; + if(i == -1 || i == 0) + f_l = freq*0.98; + else + f_l = ctcss_tones[i-1]; + + if(i == -1 || i == max_tone_index) + f_r = freq*1.02; + else + f_r = ctcss_tones[i+1]; + + d_goertzel_l = fft::goertzel(rate, d_len, f_l); + d_goertzel_c = fft::goertzel(rate, d_len, freq); + d_goertzel_r = fft::goertzel(rate, d_len, f_r); + + d_mute = true; + } + + ctcss_squelch_ff_impl::~ctcss_squelch_ff_impl() + { + } + + std::vector + ctcss_squelch_ff_impl::squelch_range() const + { + std::vector r(3); + r[0] = 0.0; + r[1] = 1.0; + r[2] = (r[1]-r[0])/100; // step size + + return r; + } + + void + ctcss_squelch_ff_impl::update_state(const float &in) + { + d_goertzel_l.input(in); + d_goertzel_c.input(in); + d_goertzel_r.input(in); + + float d_out_l, d_out_c, d_out_r; + if(d_goertzel_c.ready()) { + d_out_l = abs(d_goertzel_l.output()); + d_out_c = abs(d_goertzel_c.output()); + d_out_r = abs(d_goertzel_r.output()); + + //printf("d_out_l=%f d_out_c=%f d_out_r=%f\n", d_out_l, d_out_c, d_out_r); + d_mute = (d_out_c < d_level || d_out_c < d_out_l || d_out_c < d_out_r); + } + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/ctcss_squelch_ff_impl.h b/gr-analog/lib/ctcss_squelch_ff_impl.h new file mode 100644 index 000000000..0827fbafe --- /dev/null +++ b/gr-analog/lib/ctcss_squelch_ff_impl.h @@ -0,0 +1,82 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_CTCSS_SQUELCH_FF_IMPL_H +#define INCLUDED_ANALOG_CTCSS_SQUELCH_FF_IMPL_H + +#include +#include "squelch_base_ff_impl.h" +#include + +namespace gr { + namespace analog { + + class ctcss_squelch_ff_impl : public ctcss_squelch_ff, squelch_base_ff_impl + { + private: + float d_freq; + float d_level; + int d_len; + bool d_mute; + + fft::goertzel d_goertzel_l; + fft::goertzel d_goertzel_c; + fft::goertzel d_goertzel_r; + + int find_tone(float freq); + + protected: + virtual void update_state(const float &in); + virtual bool mute() const { return d_mute; } + + public: + ctcss_squelch_ff_impl(int rate, float freq, float level, + int len, int ramp, bool gate); + ~ctcss_squelch_ff_impl(); + + std::vector squelch_range() const; + float level() const { return d_level; } + void set_level(float level) { d_level = level; } + int len() const { return d_len; } + + int ramp() const { return squelch_base_ff_impl::ramp(); } + void set_ramp(int ramp) { squelch_base_ff_impl::set_ramp(ramp); } + bool gate() const { return squelch_base_ff_impl::gate(); } + void set_gate(bool gate) { squelch_base_ff_impl::set_gate(gate); } + bool unmuted() const { return squelch_base_ff_impl::unmuted(); } + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + return squelch_base_ff_impl::general_work(noutput_items, + ninput_items, + input_items, + output_items); + } + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_CTCSS_SQUELCH_FF_IMPL_H */ diff --git a/gr-analog/lib/squelch_base_ff_impl.cc b/gr-analog/lib/squelch_base_ff_impl.cc new file mode 100644 index 000000000..f9f07d36d --- /dev/null +++ b/gr-analog/lib/squelch_base_ff_impl.cc @@ -0,0 +1,140 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2012 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 "squelch_base_ff_impl.h" +#include + +namespace gr { + namespace analog { + + squelch_base_ff_impl::squelch_base_ff_impl(const char *name, int ramp, bool gate) + : gr_block(name, + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))) + { + set_ramp(ramp); + set_gate(gate); + d_state = ST_MUTED; + d_envelope = d_ramp ? 0.0 : 1.0; + d_ramped = 0; + } + + squelch_base_ff_impl::~squelch_base_ff_impl() + { + } + + int + squelch_base_ff_impl::ramp() const + { + return d_ramp; + } + + void + squelch_base_ff_impl::set_ramp(int ramp) + { + d_ramp = ramp; + } + + bool + squelch_base_ff_impl::gate() const + { + return d_gate; + } + + void + squelch_base_ff_impl::set_gate(bool gate) + { + d_gate = gate; + } + + bool + squelch_base_ff_impl::unmuted() const + { + return (d_state == ST_UNMUTED || d_state == ST_ATTACK); + } + + int + squelch_base_ff_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float *) input_items[0]; + float *out = (float *) output_items[0]; + + int j = 0; + + for(int i = 0; i < noutput_items; i++) { + update_state(in[i]); + + // Adjust envelope based on current state + switch(d_state) { + case ST_MUTED: + if(!mute()) + // If not ramping, go straight to unmuted + d_state = d_ramp ? ST_ATTACK : ST_UNMUTED; + break; + + case ST_UNMUTED: + if(mute()) + // If not ramping, go straight to muted + d_state = d_ramp ? ST_DECAY : ST_MUTED; + break; + + case ST_ATTACK: + // FIXME: precalculate window for speed + d_envelope = 0.5-std::cos(M_PI*(++d_ramped)/d_ramp)/2.0; + + // use >= in case d_ramp is set to lower value elsewhere + if(d_ramped >= d_ramp) { + d_state = ST_UNMUTED; + d_envelope = 1.0; + } + break; + + case ST_DECAY: + // FIXME: precalculate window for speed + d_envelope = 0.5-std::cos(M_PI*(--d_ramped)/d_ramp)/2.0; + if(d_ramped == 0.0) + d_state = ST_MUTED; + break; + }; + + // If unmuted, copy input times envelope to output + // Otherwise, if not gating, copy zero to output + if(d_state != ST_MUTED) + out[j++] = in[i]*d_envelope; + else + if(!d_gate) + out[j++] = 0.0; + } + + consume_each(noutput_items); // Use all the inputs + return j; // But only report outputs copied + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/squelch_base_ff_impl.h b/gr-analog/lib/squelch_base_ff_impl.h new file mode 100644 index 000000000..22659be74 --- /dev/null +++ b/gr-analog/lib/squelch_base_ff_impl.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_GR_SQUELCH_BASE_FF_IMPL_H +#define INCLUDED_GR_SQUELCH_BASE_FF_IMPL_H + +#include + +namespace gr { + namespace analog { + + class squelch_base_ff_impl : public squelch_base_ff + { + private: + int d_ramp; + int d_ramped; + bool d_gate; + double d_envelope; + enum { ST_MUTED, ST_ATTACK, ST_UNMUTED, ST_DECAY } d_state; + + protected: + virtual void update_state(const float &sample) {}; + virtual bool mute() const { return false; }; + + public: + squelch_base_ff_impl(const char *name, int ramp, bool gate); + ~squelch_base_ff_impl(); + + int ramp() const; + void set_ramp(int ramp); + bool gate() const; + void set_gate(bool gate); + bool unmuted() const; + + virtual std::vector squelch_range() const = 0; + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SQUELCH_BASE_IMPL_FF_H */ diff --git a/gr-analog/python/qa_ctcss_squelch.py b/gr-analog/python/qa_ctcss_squelch.py new file mode 100644 index 000000000..4d4fc3077 --- /dev/null +++ b/gr-analog/python/qa_ctcss_squelch.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# +# Copyright 2012 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, gr_unittest +import analog_swig as analog + +class test_ctcss_squelch(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_ctcss_squelch_001(self): + # Test set/gets + + rate = 1 + rate2 = 2 + freq = 100 + level = 0.5 + length = 1 + ramp = 1 + ramp2 = 2 + gate = True + gate2 = False + + op = analog.ctcss_squelch_ff(rate, freq, level, + length, ramp, gate) + + op.set_ramp(ramp2) + r = op.ramp() + self.assertEqual(rate2, r) + + op.set_gate(gate2) + g = op.gate() + self.assertEqual(gate2, g) + + def test_ctcss_squelch_002(self): + # Test runtime, gate=True + rate = 1 + freq = 100 + level = 0.0 + length = 1 + ramp = 1 + gate = True + + src_data = map(lambda x: float(x)/10.0, range(1, 40)) + expected_result = src_data + expected_result[0] = 0 + + src = gr.vector_source_f(src_data) + op = analog.ctcss_squelch_ff(rate, freq, level, + length, ramp, gate) + dst = gr.vector_sink_f() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 4) + + def test_ctcss_squelch_003(self): + # Test runtime, gate=False + rate = 1 + freq = 100 + level = 0.5 + length = 1 + ramp = 1 + gate = False + + src_data = map(lambda x: float(x)/10.0, range(1, 40)) + src = gr.vector_source_f(src_data) + op = analog.ctcss_squelch_ff(rate, freq, level, + length, ramp, gate) + dst = gr.vector_sink_f() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + expected_result = src_data + expected_result[0:5] = [0, 0, 0, 0, 0] + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_ctcss_squelch, "test_ctcss_squelch.xml") + diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 0ce6854ca..6d714dd0d 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -28,8 +28,12 @@ %{ #include "analog/cpm.h" +#include "analog/ctcss_squelch_ff.h" +#include "analog/squelch_base_ff.h" %} %include "analog/cpm.h" +%include "analog/ctcss_squelch_ff.h" +%include "analog/squelch_base_ff.h" -//GR_SWIG_BLOCK_MAGIC2(); +GR_SWIG_BLOCK_MAGIC2(analog, ctcss_squelch_ff); -- cgit From fce7c0c5e1b1648c03f453cff457116990268a7c Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 21 Oct 2012 14:06:45 -0400 Subject: analog: adding complex squelch base class. --- gr-analog/include/analog/squelch_base_cc.h | 56 ++++++++++++ gr-analog/lib/squelch_base_cc_impl.cc | 140 +++++++++++++++++++++++++++++ gr-analog/lib/squelch_base_cc_impl.h | 65 ++++++++++++++ 3 files changed, 261 insertions(+) create mode 100644 gr-analog/include/analog/squelch_base_cc.h create mode 100644 gr-analog/lib/squelch_base_cc_impl.cc create mode 100644 gr-analog/lib/squelch_base_cc_impl.h diff --git a/gr-analog/include/analog/squelch_base_cc.h b/gr-analog/include/analog/squelch_base_cc.h new file mode 100644 index 000000000..4c2a7b352 --- /dev/null +++ b/gr-analog/include/analog/squelch_base_cc.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_SQUELCH_BASE_CC_H +#define INCLUDED_ANALOG_SQUELCH_BASE_CC_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief basic squelch block; to be subclassed for other squelches. + * \ingroup level_blk + */ + class ANALOG_API squelch_base_cc : virtual public gr_block + { + protected: + virtual void update_state(const float &sample) = 0; + virtual bool mute() const = 0; + + public: + squelch_base_cc() {}; + virtual int ramp() const = 0; + virtual void set_ramp(int ramp) = 0; + virtual bool gate() const = 0; + virtual void set_gate(bool gate) = 0; + virtual bool unmuted() const = 0; + + virtual std::vector squelch_range() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SQUELCH_BASE_CC_H */ diff --git a/gr-analog/lib/squelch_base_cc_impl.cc b/gr-analog/lib/squelch_base_cc_impl.cc new file mode 100644 index 000000000..cba7b30db --- /dev/null +++ b/gr-analog/lib/squelch_base_cc_impl.cc @@ -0,0 +1,140 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2012 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 "squelch_base_cc_impl.h" +#include + +namespace gr { + namespace analog { + + squelch_base_cc_impl::squelch_base_cc_impl(const char *name, int ramp, bool gate) + : gr_block(name, + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))) + { + set_ramp(ramp); + set_gate(gate); + d_state = ST_MUTED; + d_envelope = d_ramp ? 0.0 : 1.0; + d_ramped = 0; + } + + squelch_base_cc_impl::~squelch_base_cc_impl() + { + } + + int + squelch_base_cc_impl::ramp() const + { + return d_ramp; + } + + void + squelch_base_cc_impl::set_ramp(int ramp) + { + d_ramp = ramp; + } + + bool + squelch_base_cc_impl::gate() const + { + return d_gate; + } + + void + squelch_base_cc_impl::set_gate(bool gate) + { + d_gate = gate; + } + + bool + squelch_base_cc_impl::unmuted() const + { + return (d_state == ST_UNMUTED || d_state == ST_ATTACK); + } + + int + squelch_base_cc_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + + int j = 0; + + for(int i = 0; i < noutput_items; i++) { + update_state(in[i]); + + // Adjust envelope based on current state + switch(d_state) { + case ST_MUTED: + if(!mute()) { + d_state = d_ramp ? ST_ATTACK : ST_UNMUTED; // If not ramping, go straight to unmuted + } + break; + + case ST_UNMUTED: + if(mute()) { + d_state = d_ramp ? ST_DECAY : ST_MUTED; // If not ramping, go straight to muted + } + break; + + case ST_ATTACK: + d_envelope = 0.5-std::cos(M_PI*(++d_ramped)/d_ramp)/2.0; // FIXME: precalculate window for speed + if(d_ramped >= d_ramp) { // use >= in case d_ramp is set to lower value elsewhere + d_state = ST_UNMUTED; + d_envelope = 1.0; + } + break; + + case ST_DECAY: + d_envelope = 0.5-std::cos(M_PI*(--d_ramped)/d_ramp)/2.0; // FIXME: precalculate window for speed + if(d_ramped == 0.0) { + d_state = ST_MUTED; + } + break; + }; + + // If unmuted, copy input times envelope to output + // Otherwise, if not gating, copy zero to output + if(d_state != ST_MUTED) { + out[j++] = in[i]*gr_complex(d_envelope, 0.0); + } + else { + if(!d_gate) { + out[j++] = 0.0; + } + } + } + + consume_each(noutput_items); // Use all the inputs + return j; // But only report outputs copied + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/squelch_base_cc_impl.h b/gr-analog/lib/squelch_base_cc_impl.h new file mode 100644 index 000000000..19dccaa10 --- /dev/null +++ b/gr-analog/lib/squelch_base_cc_impl.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_GR_SQUELCH_BASE_CC_IMPL_H +#define INCLUDED_GR_SQUELCH_BASE_CC_IMPL_H + +#include + +namespace gr { + namespace analog { + + class squelch_base_cc_impl : public squelch_base_cc + { + private: + int d_ramp; + int d_ramped; + bool d_gate; + double d_envelope; + enum { ST_MUTED, ST_ATTACK, ST_UNMUTED, ST_DECAY } d_state; + + protected: + virtual void update_state(const gr_complex &sample) {}; + virtual bool mute() const { return false; }; + + public: + squelch_base_cc_impl(const char *name, int ramp, bool gate); + ~squelch_base_cc_impl(); + + int ramp() const; + void set_ramp(int ramp); + bool gate() const; + void set_gate(bool gate); + bool unmuted() const; + + virtual std::vector squelch_range() const = 0; + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SQUELCH_BASE_IMPL_FF_H */ -- cgit From bce7518ae10c2514ae6d7c6edef3166c45c80782 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Sun, 21 Oct 2012 14:09:40 -0400 Subject: analog: implemented all AGC classes in gr-analog with QA code. --- gr-analog/include/analog/CMakeLists.txt | 10 +- gr-analog/include/analog/agc.h | 136 +++++++ gr-analog/include/analog/agc2.h | 160 +++++++++ gr-analog/include/analog/agc2_cc.h | 65 ++++ gr-analog/include/analog/agc2_ff.h | 65 ++++ gr-analog/include/analog/agc_cc.h | 62 ++++ gr-analog/include/analog/agc_ff.h | 62 ++++ gr-analog/include/analog/feedforward_agc_cc.h | 48 +++ gr-analog/lib/CMakeLists.txt | 6 + gr-analog/lib/agc2_cc_impl.cc | 70 ++++ gr-analog/lib/agc2_cc_impl.h | 59 +++ gr-analog/lib/agc2_ff_impl.cc | 71 ++++ gr-analog/lib/agc2_ff_impl.h | 59 +++ gr-analog/lib/agc_cc_impl.cc | 66 ++++ gr-analog/lib/agc_cc_impl.h | 56 +++ gr-analog/lib/agc_ff_impl.cc | 64 ++++ gr-analog/lib/agc_ff_impl.h | 56 +++ gr-analog/lib/feedforward_agc_cc_impl.cc | 99 ++++++ gr-analog/lib/feedforward_agc_cc_impl.h | 49 +++ gr-analog/python/qa_agc.py | 495 ++++++++++++++++++++++++++ gr-analog/swig/analog_swig.i | 17 + 21 files changed, 1774 insertions(+), 1 deletion(-) create mode 100644 gr-analog/include/analog/agc.h create mode 100644 gr-analog/include/analog/agc2.h create mode 100644 gr-analog/include/analog/agc2_cc.h create mode 100644 gr-analog/include/analog/agc2_ff.h create mode 100644 gr-analog/include/analog/agc_cc.h create mode 100644 gr-analog/include/analog/agc_ff.h create mode 100644 gr-analog/include/analog/feedforward_agc_cc.h create mode 100644 gr-analog/lib/agc2_cc_impl.cc create mode 100644 gr-analog/lib/agc2_cc_impl.h create mode 100644 gr-analog/lib/agc2_ff_impl.cc create mode 100644 gr-analog/lib/agc2_ff_impl.h create mode 100644 gr-analog/lib/agc_cc_impl.cc create mode 100644 gr-analog/lib/agc_cc_impl.h create mode 100644 gr-analog/lib/agc_ff_impl.cc create mode 100644 gr-analog/lib/agc_ff_impl.h create mode 100644 gr-analog/lib/feedforward_agc_cc_impl.cc create mode 100644 gr-analog/lib/feedforward_agc_cc_impl.h create mode 100755 gr-analog/python/qa_agc.py diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index d688d2c3d..7e95d88cd 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -77,8 +77,16 @@ install(FILES ${analog_generated_includes} api.h cpm.h - ctcss_squelch_ff.h + agc.h + agc2.h squelch_base_ff.h + agc_cc.h + agc_ff.h + agc2_cc.h + agc2_ff.h + ctcss_squelch_cc.h + ctcss_squelch_ff.h + feedforward_agc_cc.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog COMPONENT "analog_devel" ) diff --git a/gr-analog/include/analog/agc.h b/gr-analog/include/analog/agc.h new file mode 100644 index 000000000..92d777fa1 --- /dev/null +++ b/gr-analog/include/analog/agc.h @@ -0,0 +1,136 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_AGC_H +#define INCLUDED_ANALOG_AGC_H + +#include +#include +#include + +namespace gr { + namespace analog { + namespace kernel { + + /*! + * \brief high performance Automatic Gain Control class for complex signals. + * + * For Power the absolute value of the complex number is used. + */ + class ANALOG_API agc_cc + { + public: + agc_cc(float rate = 1e-4, float reference = 1.0, + float gain = 1.0, float max_gain = 0.0) + : _rate(rate), _reference(reference), + _gain(gain), _max_gain(max_gain) {}; + + virtual ~agc_cc() {}; + + float rate() const { return _rate; } + float reference() const { return _reference; } + float gain() const { return _gain; } + float max_gain() const { return _max_gain; } + + void set_rate(float rate) { _rate = rate; } + void set_reference(float reference) { _reference = reference; } + void set_gain(float gain) { _gain = gain; } + void set_max_gain(float max_gain) { _max_gain = max_gain; } + + gr_complex scale(gr_complex input) + { + gr_complex output = input * _gain; + + _gain += _rate * (_reference - sqrt(output.real()*output.real() + + output.imag()*output.imag())); + if(_max_gain > 0.0 && _gain > _max_gain) { + _gain = _max_gain; + } + return output; + } + + void scaleN(gr_complex output[], const gr_complex input[], unsigned n) + { + for(unsigned i = 0; i < n; i++) { + output[i] = scale (input[i]); + } + } + + protected: + float _rate; // adjustment rate + float _reference; // reference value + float _gain; // current gain + float _max_gain; // max allowable gain + }; + + /*! + * \brief high performance Automatic Gain Control class for float signals. + * + * Power is approximated by absolute value + */ + class ANALOG_API agc_ff + { + public: + agc_ff(float rate = 1e-4, float reference = 1.0, + float gain = 1.0, float max_gain = 0.0) + : _rate(rate), _reference(reference), _gain(gain), + _max_gain(max_gain) {}; + + ~agc_ff() {}; + + float rate () const { return _rate; } + float reference () const { return _reference; } + float gain () const { return _gain; } + float max_gain () const { return _max_gain; } + + void set_rate (float rate) { _rate = rate; } + void set_reference (float reference) { _reference = reference; } + void set_gain (float gain) { _gain = gain; } + void set_max_gain (float max_gain) { _max_gain = max_gain; } + + float scale (float input) + { + float output = input * _gain; + _gain += (_reference - fabsf (output)) * _rate; + if(_max_gain > 0.0 && _gain > _max_gain) + _gain = _max_gain; + return output; + } + + void scaleN(float output[], const float input[], unsigned n) + { + for(unsigned i = 0; i < n; i++) + output[i] = scale (input[i]); + } + + protected: + float _rate; // adjustment rate + float _reference; // reference value + float _gain; // current gain + float _max_gain; // maximum gain + }; + + } /* namespace kernel */ + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC_H */ diff --git a/gr-analog/include/analog/agc2.h b/gr-analog/include/analog/agc2.h new file mode 100644 index 000000000..75a203e9f --- /dev/null +++ b/gr-analog/include/analog/agc2.h @@ -0,0 +1,160 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_AGC2_H +#define INCLUDED_ANALOG_AGC2_H + +#include +#include +#include + +namespace gr { + namespace analog { + namespace kernel { + + /*! + * \brief high performance Automatic Gain Control class + * + * For Power the absolute value of the complex number is used. + */ + class ANALOG_API agc2_cc + { + public: + agc2_cc(float attack_rate = 1e-1, float decay_rate = 1e-2, + float reference = 1.0, + float gain = 1.0, float max_gain = 0.0) + : _attack_rate(attack_rate), _decay_rate(decay_rate), + _reference(reference), + _gain(gain), _max_gain(max_gain) {}; + + float decay_rate() const { return _decay_rate; } + float attack_rate() const { return _attack_rate; } + float reference() const { return _reference; } + float gain() const { return _gain; } + float max_gain() const { return _max_gain; } + + void set_decay_rate(float rate) { _decay_rate = rate; } + void set_attack_rate(float rate) { _attack_rate = rate; } + void set_reference(float reference) { _reference = reference; } + void set_gain(float gain) { _gain = gain; } + void set_max_gain(float max_gain) { _max_gain = max_gain; } + + gr_complex scale(gr_complex input) + { + gr_complex output = input * _gain; + + float tmp = -_reference + sqrt(output.real()*output.real() + + output.imag()*output.imag()); + float rate = _decay_rate; + if((tmp) > _gain) { + rate = _attack_rate; + } + _gain -= tmp*rate; + + // Not sure about this; will blow up if _gain < 0 (happens + // when rates are too high), but is this the solution? + if(_gain < 0.0) + _gain = 10e-5; + + if(_max_gain > 0.0 && _gain > _max_gain) { + _gain = _max_gain; + } + return output; + } + + void scaleN(gr_complex output[], const gr_complex input[], unsigned n) + { + for(unsigned i = 0; i < n; i++) + output[i] = scale (input[i]); + } + + protected: + float _attack_rate; // attack rate for fast changing signals + float _decay_rate; // decay rate for slow changing signals + float _reference; // reference value + float _gain; // current gain + float _max_gain; // max allowable gain + }; + + + class ANALOG_API agc2_ff + { + public: + agc2_ff(float attack_rate = 1e-1, float decay_rate = 1e-2, + float reference = 1.0, + float gain = 1.0, float max_gain = 0.0) + : _attack_rate(attack_rate), _decay_rate(decay_rate), + _reference(reference), + _gain(gain), _max_gain(max_gain) {}; + + float attack_rate() const { return _attack_rate; } + float decay_rate() const { return _decay_rate; } + float reference() const { return _reference; } + float gain() const { return _gain; } + float max_gain() const { return _max_gain; } + + void set_attack_rate(float rate) { _attack_rate = rate; } + void set_decay_rate(float rate) { _decay_rate = rate; } + void set_reference(float reference) { _reference = reference; } + void set_gain(float gain) { _gain = gain; } + void set_max_gain(float max_gain) { _max_gain = max_gain; } + + float scale(float input) + { + float output = input * _gain; + + float tmp = (fabsf(output)) - _reference; + float rate = _decay_rate; + if(fabsf(tmp) > _gain) { + rate = _attack_rate; + } + _gain -= tmp*rate; + + // Not sure about this + if(_gain < 0.0) + _gain = 10e-5; + + if(_max_gain > 0.0 && _gain > _max_gain) { + _gain = _max_gain; + } + return output; + } + + void scaleN(float output[], const float input[], unsigned n) + { + for(unsigned i = 0; i < n; i++) + output[i] = scale (input[i]); + } + + protected: + float _attack_rate; // attack_rate for fast changing signals + float _decay_rate; // decay rate for slow changing signals + float _reference; // reference value + float _gain; // current gain + float _max_gain; // maximum gain + }; + + } /* namespace kernel */ + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC2_H */ diff --git a/gr-analog/include/analog/agc2_cc.h b/gr-analog/include/analog/agc2_cc.h new file mode 100644 index 000000000..c922ccd4d --- /dev/null +++ b/gr-analog/include/analog/agc2_cc.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_AGC2_CC_H +#define INCLUDED_ANALOG_AGC2_CC_H + +#include +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief high performance Automatic Gain Control class + * \ingroup level_blk + * + * For Power the absolute value of the complex number is used. + */ + class ANALOG_API agc2_cc : virtual public gr_sync_block + { + public: + // gr::analog::agc2_cc::sptr + typedef boost::shared_ptr sptr; + + static sptr make(float attack_rate = 1e-1, float decay_rate = 1e-2, + float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + + virtual float attack_rate() const = 0; + virtual float decay_rate() const = 0; + virtual float reference() const = 0; + virtual float gain() const = 0; + virtual float max_gain() const = 0; + + virtual void set_attack_rate(float rate) = 0; + virtual void set_decay_rate(float rate) = 0; + virtual void set_reference(float reference) = 0; + virtual void set_gain(float gain) = 0; + virtual void set_max_gain(float max_gain) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC2_CC_H */ diff --git a/gr-analog/include/analog/agc2_ff.h b/gr-analog/include/analog/agc2_ff.h new file mode 100644 index 000000000..27dd6d92e --- /dev/null +++ b/gr-analog/include/analog/agc2_ff.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 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_ANALOG_AGC2_FF_H +#define INCLUDED_ANALOG_AGC2_FF_H + +#include +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief high performance Automatic Gain Control class + * + * \ingroup level_blk + * Power is approximated by absolute value + */ + class ANALOG_API agc2_ff : virtual public gr_sync_block + { + public: + // gr::analog::agc2_ff::sptr + typedef boost::shared_ptr sptr; + + static sptr make(float attack_rate = 1e-1, float decay_rate = 1e-2, + float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + + virtual float attack_rate() const = 0; + virtual float decay_rate() const = 0; + virtual float reference() const = 0; + virtual float gain() const = 0; + virtual float max_gain() const = 0; + + virtual void set_attack_rate(float rate) = 0; + virtual void set_decay_rate(float rate) = 0; + virtual void set_reference(float reference) = 0; + virtual void set_gain(float gain) = 0; + virtual void set_max_gain(float max_gain) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC2_FF_H */ diff --git a/gr-analog/include/analog/agc_cc.h b/gr-analog/include/analog/agc_cc.h new file mode 100644 index 000000000..b2b1a9b43 --- /dev/null +++ b/gr-analog/include/analog/agc_cc.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_AGC_CC_H +#define INCLUDED_ANALOG_AGC_CC_H + +#include +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief high performance Automatic Gain Control class + * \ingroup level_blk + * + * For Power the absolute value of the complex number is used. + */ + class ANALOG_API agc_cc : virtual public gr_sync_block + { + public: + // gr::analog::agc_cc::sptr + typedef boost::shared_ptr sptr; + + static sptr make(float rate = 1e-4, float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + + virtual float rate() const = 0; + virtual float reference() const = 0; + virtual float gain() const = 0; + virtual float max_gain() const = 0; + + virtual void set_rate(float rate) = 0; + virtual void set_reference(float reference) = 0; + virtual void set_gain(float gain) = 0; + virtual void set_max_gain(float max_gain) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC_CC_H */ diff --git a/gr-analog/include/analog/agc_ff.h b/gr-analog/include/analog/agc_ff.h new file mode 100644 index 000000000..30d1ae1fd --- /dev/null +++ b/gr-analog/include/analog/agc_ff.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 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_ANALOG_AGC_FF_H +#define INCLUDED_ANALOG_AGC_FF_H + +#include +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief high performance Automatic Gain Control class + * \ingroup level_blk + * + * Power is approximated by absolute value + */ + class ANALOG_API agc_ff : virtual public gr_sync_block + { + public: + // gr::analog::agc_ff::sptr + typedef boost::shared_ptr sptr; + + static sptr make(float rate = 1e-4, float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + + virtual float rate() const = 0; + virtual float reference() const = 0; + virtual float gain() const = 0; + virtual float max_gain() const = 0; + + virtual void set_rate(float rate) = 0; + virtual void set_reference(float reference) = 0; + virtual void set_gain(float gain) = 0; + virtual void set_max_gain(float max_gain) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC_FF_H */ diff --git a/gr-analog/include/analog/feedforward_agc_cc.h b/gr-analog/include/analog/feedforward_agc_cc.h new file mode 100644 index 000000000..9e259a4eb --- /dev/null +++ b/gr-analog/include/analog/feedforward_agc_cc.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_FEEDFORWARD_AGC_CC_H +#define INCLUDED_ANALOG_FEEDFORWARD_AGC_CC_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief Non-causal AGC which computes required gain based on max absolute value over nsamples + * \ingroup level_blk + */ + class ANALOG_API feedforward_agc_cc : virtual public gr_sync_block + { + public: + // gr::analog::feedforward_agc_cc::sptr + typedef boost::shared_ptr sptr; + + static sptr make(int nsamples, float reference); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_FEEDFORWARD_AGC_CC_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index b0f7a17de..468957d98 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -104,8 +104,14 @@ endmacro(expand_cc) list(APPEND analog_sources ${generated_sources} cpm.cc + squelch_base_cc_impl.cc squelch_base_ff_impl.cc + agc_cc_impl.cc + agc_ff_impl.cc + agc2_cc_impl.cc + agc2_ff_impl.cc ctcss_squelch_ff_impl.cc + feedforward_agc_cc_impl.cc ) list(APPEND analog_libs diff --git a/gr-analog/lib/agc2_cc_impl.cc b/gr-analog/lib/agc2_cc_impl.cc new file mode 100644 index 000000000..2ef18e5ab --- /dev/null +++ b/gr-analog/lib/agc2_cc_impl.cc @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2010,2012 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 "agc2_cc_impl.h" +#include + +namespace gr { + namespace analog { + + agc2_cc::sptr + agc2_cc::make(float attack_rate, float decay_rate, + float reference, + float gain, float max_gain) + { + return gnuradio::get_initial_sptr + (new agc2_cc_impl(attack_rate, decay_rate, + reference, gain, max_gain)); + } + + agc2_cc_impl::agc2_cc_impl(float attack_rate, float decay_rate, + float reference, + float gain, float max_gain) + : gr_sync_block("agc2_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + kernel::agc2_cc(attack_rate, decay_rate, + reference, gain, max_gain) + { + } + + agc2_cc_impl::~agc2_cc_impl() + { + } + + int + agc2_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + scaleN(out, in, noutput_items); + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/agc2_cc_impl.h b/gr-analog/lib/agc2_cc_impl.h new file mode 100644 index 000000000..98afc668a --- /dev/null +++ b/gr-analog/lib/agc2_cc_impl.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_AGC2_IMPL_CC_H +#define INCLUDED_ANALOG_AGC2_IMPL_CC_H + +#include + +namespace gr { + namespace analog { + + class agc2_cc_impl : public agc2_cc, kernel::agc2_cc + { + public: + agc2_cc_impl(float attack_rate = 1e-1, float decay_rate = 1e-2, + float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + ~agc2_cc_impl(); + + float attack_rate() const { return kernel::agc2_cc::attack_rate(); } + float decay_rate() const { return kernel::agc2_cc::decay_rate(); } + float reference() const { return kernel::agc2_cc::reference(); } + float gain() const { return kernel::agc2_cc::gain(); } + float max_gain() const { return kernel::agc2_cc::max_gain(); } + + void set_attack_rate(float rate) { kernel::agc2_cc::set_attack_rate(rate); } + void set_decay_rate(float rate) { kernel::agc2_cc::set_decay_rate(rate); } + void set_reference(float reference) { kernel::agc2_cc::set_reference(reference); } + void set_gain(float gain) { kernel::agc2_cc::set_gain(gain); } + void set_max_gain(float max_gain) { kernel::agc2_cc::set_max_gain(max_gain); } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC2_CC_IMPL_H */ diff --git a/gr-analog/lib/agc2_ff_impl.cc b/gr-analog/lib/agc2_ff_impl.cc new file mode 100644 index 000000000..e0cdd6c44 --- /dev/null +++ b/gr-analog/lib/agc2_ff_impl.cc @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2010,2012 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 "agc2_ff_impl.h" +#include + +namespace gr { + namespace analog { + + agc2_ff::sptr + agc2_ff::make(float attack_rate, float decay_rate, + float reference, + float gain, float max_gain) + { + return gnuradio::get_initial_sptr + (new agc2_ff_impl(attack_rate, decay_rate, + reference, + gain, max_gain)); + } + + agc2_ff_impl::~agc2_ff_impl() + { + } + + agc2_ff_impl::agc2_ff_impl(float attack_rate, float decay_rate, + float reference, + float gain, float max_gain) + : gr_sync_block("agc2_ff", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))) + , kernel::agc2_ff(attack_rate, decay_rate, + reference, gain, max_gain) + { + } + + int + agc2_ff_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + float *out = (float*)output_items[0]; + scaleN(out, in, noutput_items); + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/agc2_ff_impl.h b/gr-analog/lib/agc2_ff_impl.h new file mode 100644 index 000000000..df33c8e44 --- /dev/null +++ b/gr-analog/lib/agc2_ff_impl.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 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_ANALOG_AGC2_FF_IMPL_H +#define INCLUDED_ANALOG_AGC2_FF_IMPL_H + +#include + +namespace gr { + namespace analog { + + class agc2_ff_impl : public agc2_ff, kernel::agc2_ff + { + public: + agc2_ff_impl(float attack_rate = 1e-1, float decay_rate = 1e-2, + float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + ~agc2_ff_impl(); + + float attack_rate() const { return kernel::agc2_ff::attack_rate(); } + float decay_rate() const { return kernel::agc2_ff::decay_rate(); } + float reference() const { return kernel::agc2_ff::reference(); } + float gain() const { return kernel::agc2_ff::gain(); } + float max_gain() const { return kernel::agc2_ff::max_gain(); } + + void set_attack_rate(float rate) { kernel::agc2_ff::set_attack_rate(rate); } + void set_decay_rate(float rate) { kernel::agc2_ff::set_decay_rate(rate); } + void set_reference(float reference) { kernel::agc2_ff::set_reference(reference); } + void set_gain(float gain) { kernel::agc2_ff::set_gain(gain); } + void set_max_gain(float max_gain) { kernel::agc2_ff::set_max_gain(max_gain); } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC2_IMPL_FF_H */ diff --git a/gr-analog/lib/agc_cc_impl.cc b/gr-analog/lib/agc_cc_impl.cc new file mode 100644 index 000000000..81e1f67f8 --- /dev/null +++ b/gr-analog/lib/agc_cc_impl.cc @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2010,2012 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 "agc_cc_impl.h" +#include + +namespace gr { + namespace analog { + + agc_cc::sptr + agc_cc::make(float rate, float reference, + float gain, float max_gain) + { + return gnuradio::get_initial_sptr + (new agc_cc_impl(rate, reference, gain, max_gain)); + } + + agc_cc_impl::agc_cc_impl(float rate, float reference, + float gain, float max_gain) + : gr_sync_block("agc_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + kernel::agc_cc(rate, reference, gain, max_gain) + { + } + + agc_cc_impl::~agc_cc_impl() + { + } + + int + agc_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + scaleN(out, in, noutput_items); + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/agc_cc_impl.h b/gr-analog/lib/agc_cc_impl.h new file mode 100644 index 000000000..822f46ef2 --- /dev/null +++ b/gr-analog/lib/agc_cc_impl.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_AGC_CC_IMPL_H +#define INCLUDED_ANALOG_AGC_CC_IMPL_H + +#include + +namespace gr { + namespace analog { + + class agc_cc_impl : public agc_cc, kernel::agc_cc + { + public: + agc_cc_impl(float rate = 1e-4, float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + ~agc_cc_impl(); + + float rate() const { return kernel::agc_cc::rate(); } + float reference() const { return kernel::agc_cc::reference(); } + float gain() const { return kernel::agc_cc::gain(); } + float max_gain() const { return kernel::agc_cc::max_gain(); } + + void set_rate(float rate) { kernel::agc_cc::set_rate(rate); } + void set_reference(float reference) { kernel::agc_cc::set_reference(reference); } + void set_gain(float gain) { kernel::agc_cc::set_gain(gain); } + void set_max_gain(float max_gain) { kernel::agc_cc::set_max_gain(max_gain); } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC_CC_IMPL_H */ diff --git a/gr-analog/lib/agc_ff_impl.cc b/gr-analog/lib/agc_ff_impl.cc new file mode 100644 index 000000000..a80b90c12 --- /dev/null +++ b/gr-analog/lib/agc_ff_impl.cc @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2010,2012 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 "agc_ff_impl.h" +#include + +namespace gr { + namespace analog { + + agc_ff::sptr + agc_ff::make(float rate, float reference, float gain, float max_gain) + { + return gnuradio::get_initial_sptr + (new agc_ff_impl(rate, reference, gain, max_gain)); + } + + agc_ff_impl::agc_ff_impl(float rate, float reference, float gain, float max_gain) + : gr_sync_block("agc_ff", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))), + kernel::agc_ff(rate, reference, gain, max_gain) + { + } + + agc_ff_impl::~agc_ff_impl() + { + } + + int + agc_ff_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + float *out = (float*)output_items[0]; + scaleN(out, in, noutput_items); + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/agc_ff_impl.h b/gr-analog/lib/agc_ff_impl.h new file mode 100644 index 000000000..e309cca1b --- /dev/null +++ b/gr-analog/lib/agc_ff_impl.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 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_ANALOG_AGC_FF_IMPL_H +#define INCLUDED_ANALOG_AGC_FF_IMPL_H + +#include + +namespace gr { + namespace analog { + + class agc_ff_impl : public agc_ff, kernel::agc_ff + { + public: + agc_ff_impl(float rate = 1e-4, float reference = 1.0, + float gain = 1.0, float max_gain = 0.0); + ~agc_ff_impl(); + + float rate() const { return kernel::agc_ff::rate(); } + float reference() const { return kernel::agc_ff::reference(); } + float gain() const { return kernel::agc_ff::gain(); } + float max_gain() const { return kernel::agc_ff::max_gain(); } + + void set_rate(float rate) { kernel::agc_ff::set_rate(rate); } + void set_reference(float reference) { kernel::agc_ff::set_reference(reference); } + void set_gain(float gain) { kernel::agc_ff::set_gain(gain); } + void set_max_gain(float max_gain) { kernel::agc_ff::set_max_gain(max_gain); } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_AGC_FF_IMPL_H */ diff --git a/gr-analog/lib/feedforward_agc_cc_impl.cc b/gr-analog/lib/feedforward_agc_cc_impl.cc new file mode 100644 index 000000000..4796fdfc5 --- /dev/null +++ b/gr-analog/lib/feedforward_agc_cc_impl.cc @@ -0,0 +1,99 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2010,2012 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 "feedforward_agc_cc_impl.h" +#include +#include + +namespace gr { + namespace analog { + + feedforward_agc_cc::sptr + feedforward_agc_cc::make(int nsamples, float reference) + { + return gnuradio::get_initial_sptr + (new feedforward_agc_cc_impl(nsamples, reference)); + } + + feedforward_agc_cc_impl::feedforward_agc_cc_impl(int nsamples, float reference) + : gr_sync_block("feedforward_agc_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + d_nsamples(nsamples), d_reference(reference) + { + if(nsamples < 1) + throw std::invalid_argument("feedforward_agc_cc_impl: nsamples must be >= 1"); + + set_history(nsamples); + } + + feedforward_agc_cc_impl::~feedforward_agc_cc_impl() + { + } + + inline static float + mag_squared(gr_complex x) + { + return x.real() * x.real() + x.imag() * x.imag(); + } + + // approximate sqrt(x^2 + y^2) + inline static float + envelope(gr_complex x) + { + float r_abs = std::fabs(x.real()); + float i_abs = std::fabs(x.imag()); + + if(r_abs > i_abs) + return r_abs + 0.4 * i_abs; + else + return i_abs + 0.4 * r_abs; + } + + int + feedforward_agc_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + int nsamples = d_nsamples; + float gain; + + for(int i = 0; i < noutput_items; i++) { + //float max_env = 1e-12; // avoid divide by zero + float max_env = 1e-4; // avoid divide by zero, indirectly set max gain + for(int j = 0; j < nsamples; j++) { + max_env = std::max(max_env, envelope(in[i+j])); + } + gain = d_reference / max_env; + out[i] = gain * in[i]; + } + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/feedforward_agc_cc_impl.h b/gr-analog/lib/feedforward_agc_cc_impl.h new file mode 100644 index 000000000..60c7acada --- /dev/null +++ b/gr-analog/lib/feedforward_agc_cc_impl.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_FEEDFORWARD_AGC_CC_IMPL_H +#define INCLUDED_ANALOG_FEEDFORWARD_AGC_CC_IMPL_H + +#include + +namespace gr { + namespace analog { + + class feedforward_agc_cc_impl : public feedforward_agc_cc + { + private: + int d_nsamples; + float d_reference; + + public: + feedforward_agc_cc_impl(int nsamples, float reference); + ~feedforward_agc_cc_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_FEEDFORWARD_AGC_CC_IMPL_H */ diff --git a/gr-analog/python/qa_agc.py b/gr-analog/python/qa_agc.py new file mode 100755 index 000000000..dc4922cf8 --- /dev/null +++ b/gr-analog/python/qa_agc.py @@ -0,0 +1,495 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010,2012 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, gr_unittest +import analog_swig as analog +import math + +test_output = False + +class test_agc (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + + def test_001_sets(self): + agc = analog.agc_cc(1e-3, 1, 1, 1000) + + agc.set_rate(1) + agc.set_reference(1.1) + agc.set_gain(1.1) + agc.set_max_gain(100) + + self.assertAlmostEqual(agc.rate(), 1) + self.assertAlmostEqual(agc.reference(), 1.1) + self.assertAlmostEqual(agc.gain(), 1.1) + self.assertAlmostEqual(agc.max_gain(), 100) + + def test_001(self): + ''' Test the complex AGC loop (single rate input) ''' + tb = self.tb + + expected_result = ( + (100.000244140625+7.2191943445432116e-07j), + (72.892257690429688+52.959323883056641j), + (25.089065551757812+77.216217041015625j), + (-22.611061096191406+69.589706420898438j), + (-53.357715606689453+38.766635894775391j), + (-59.458671569824219+3.4792964243024471e-07j), + (-43.373462677001953-31.512666702270508j), + (-14.94139289855957-45.984889984130859j), + (13.478158950805664-41.48150634765625j), + (31.838506698608398-23.132022857666016j), + (35.519271850585938-3.1176801940091536e-07j), + (25.942903518676758+18.848621368408203j), + (8.9492912292480469+27.5430908203125j), + (-8.0852642059326172+24.883890151977539j), + (-19.131628036499023+13.899936676025391j), + (-21.383295059204102+3.1281737733479531e-07j), + (-15.650330543518066-11.370632171630859j), + (-5.4110145568847656-16.65339469909668j), + (4.9008159637451172-15.083160400390625j), + (11.628337860107422-8.4484796524047852j), + (13.036135673522949-2.288476110834381e-07j), + (9.5726661682128906+6.954948902130127j), + (3.3216962814331055+10.223132133483887j), + (-3.0204284191131592+9.2959251403808594j), + (-7.1977195739746094+5.2294478416442871j), + (-8.1072216033935547+1.8976157889483147e-07j), + (-5.9838657379150391-4.3475332260131836j), + (-2.0879747867584229-6.4261269569396973j), + (1.9100792407989502-5.8786196708679199j), + (4.5814824104309082-3.3286411762237549j), + (5.1967458724975586-1.3684227440080576e-07j), + (3.8647139072418213+2.8078789710998535j), + (1.3594740629196167+4.1840314865112305j), + (-1.2544282674789429+3.8607344627380371j), + (-3.0366206169128418+2.2062335014343262j), + (-3.4781389236450195+1.1194014604143376e-07j), + (-2.6133756637573242-1.8987287282943726j), + (-0.9293016791343689-2.8600969314575195j), + (0.86727333068847656-2.6691930294036865j), + (2.1243946552276611-1.5434627532958984j), + (2.4633183479309082-8.6486437567145913e-08j), + (1.8744727373123169+1.3618841171264648j), + (0.67528903484344482+2.0783262252807617j), + (-0.63866174221038818+1.965599536895752j), + (-1.5857341289520264+1.152103066444397j), + (-1.8640764951705933+7.6355092915036948e-08j), + (-1.4381576776504517-1.0448826551437378j), + (-0.52529704570770264-1.6166983842849731j), + (0.50366902351379395-1.5501341819763184j), + (1.26766037940979-0.92100900411605835j)) + + sampling_freq = 100 + src1 = gr.sig_source_c(sampling_freq, gr.GR_SIN_WAVE, + sampling_freq * 0.10, 100.0) + dst1 = gr.vector_sink_c() + head = gr.head(gr.sizeof_gr_complex, int (5*sampling_freq * 0.10)) + + agc = analog.agc_cc(1e-3, 1, 1, 1000) + + tb.connect(src1, head) + tb.connect(head, agc) + tb.connect(agc, dst1) + + if test_output == True: + tb.connect(agc, gr.file_sink(gr.sizeof_gr_complex, "test_agc_cc.dat")) + + tb.run() + dst_data = dst1.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) + + def test_002_sets(self): + agc = analog.agc_ff(1e-3, 1, 1, 1000) + + agc.set_rate(1) + agc.set_reference(1.1) + agc.set_gain(1.1) + agc.set_max_gain(100) + + self.assertAlmostEqual(agc.rate(), 1) + self.assertAlmostEqual(agc.reference(), 1.1) + self.assertAlmostEqual(agc.gain(), 1.1) + self.assertAlmostEqual(agc.max_gain(), 100) + + def test_002(self): + ''' Test the floating point AGC loop (single rate input) ''' + tb = self.tb + + expected_result = ( + 7.2191943445432116e-07, + 58.837181091308594, + 89.700050354003906, + 81.264183044433594, + 45.506141662597656, + 4.269894304798072e-07, + -42.948936462402344, + -65.50335693359375, + -59.368724822998047, + -33.261005401611328, + -4.683740257860336e-07, + 31.423542022705078, + 47.950984954833984, + 43.485683441162109, + 24.378345489501953, + 5.7254135299444897e-07, + -23.062990188598633, + -35.218441009521484, + -31.964075088500977, + -17.934831619262695, + -5.0591745548445033e-07, + 16.998210906982422, + 25.982204437255859, + 23.606258392333984, + 13.260685920715332, + 4.9936483037527069e-07, + -12.59880542755127, + -19.28221321105957, + -17.54347038269043, + -9.8700437545776367, + -4.188150626305287e-07, + 9.4074573516845703, + 14.422011375427246, + 13.145503044128418, + 7.41046142578125, + 3.8512698097292741e-07, + -7.0924453735351562, + -10.896408081054688, + -9.9552040100097656, + -5.6262712478637695, + -3.1982864356905338e-07, + 5.4131259918212891, + 8.3389215469360352, + 7.6409502029418945, + 4.3320145606994629, + 2.882407841298118e-07, + -4.194943904876709, + -6.4837145805358887, + -5.9621825218200684, + -3.3931560516357422) + + sampling_freq = 100 + src1 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE, + sampling_freq * 0.10, 100.0) + dst1 = gr.vector_sink_f () + head = gr.head (gr.sizeof_float, int (5*sampling_freq * 0.10)) + + agc = analog.agc_ff(1e-3, 1, 1, 1000) + + tb.connect (src1, head) + tb.connect (head, agc) + tb.connect (agc, dst1) + + if test_output == True: + tb.connect (agc, gr.file_sink(gr.sizeof_float, "test_agc_ff.dat")) + + tb.run () + dst_data = dst1.data () + self.assertFloatTuplesAlmostEqual (expected_result, dst_data, 4) + + def test_003_sets(self): + agc = analog.agc2_cc(1e-3, 1e-1, 1, 1, 1000) + + agc.set_attack_rate(1) + agc.set_decay_rate(2) + agc.set_reference(1.1) + agc.set_gain(1.1) + agc.set_max_gain(100) + + self.assertAlmostEqual(agc.attack_rate(), 1) + self.assertAlmostEqual(agc.decay_rate(), 2) + self.assertAlmostEqual(agc.reference(), 1.1) + self.assertAlmostEqual(agc.gain(), 1.1) + self.assertAlmostEqual(agc.max_gain(), 100) + + def test_003(self): + ''' Test the complex AGC loop (attack and decay rate inputs) ''' + tb = self.tb + + expected_result = \ + ((100.000244140625+7.2191943445432116e-07j), + (0.80881959199905396+0.58764183521270752j), + (0.30894950032234192+0.95084899663925171j), + (-0.30895623564720154+0.95086973905563354j), + (-0.80887287855148315+0.58768033981323242j), + (-0.99984413385391235+5.850709250410091e-09j), + (-0.80889981985092163-0.58770018815994263j), + (-0.30897706747055054-0.95093393325805664j), + (0.30898112058639526-0.95094609260559082j), + (0.80893135070800781-0.58772283792495728j), + (0.99990922212600708-8.7766354184282136e-09j), + (0.80894720554351807+0.58773452043533325j), + (0.30899339914321899+0.95098406076431274j), + (-0.30899572372436523+0.95099133253097534j), + (-0.80896598100662231+0.58774799108505249j), + (-0.99994778633117676+1.4628290578855285e-08j), + (-0.80897533893585205-0.58775502443313599j), + (-0.30900305509567261-0.95101380348205566j), + (0.30900448560714722-0.95101797580718994j), + (0.80898630619049072-0.58776277303695679j), + (0.99997037649154663-1.7554345532744264e-08j), + (0.80899184942245483+0.58776694536209106j), + (0.30900871753692627+0.95103120803833008j), + (-0.30900952219963074+0.95103377103805542j), + (-0.8089984655380249+0.58777159452438354j), + (-0.99998390674591064+2.3406109050938539e-08j), + (-0.809001624584198-0.58777409791946411j), + (-0.30901208519935608-0.95104163885116577j), + (0.30901262164115906-0.95104306936264038j), + (0.80900543928146362-0.587776780128479j), + (0.99999171495437622-2.6332081404234486e-08j), + (0.80900734663009644+0.58777821063995361j), + (0.30901408195495605+0.95104765892028809j), + (-0.30901429057121277+0.95104855298995972j), + (-0.80900967121124268+0.58777981996536255j), + (-0.99999648332595825+3.2183805842578295e-08j), + (-0.80901080369949341-0.58778077363967896j), + (-0.30901527404785156-0.95105135440826416j), + (0.30901545286178589-0.95105189085006714j), + (0.80901217460632324-0.58778166770935059j), + (0.99999916553497314-3.5109700036173308e-08j), + (0.809012770652771+0.58778214454650879j), + (0.30901595950126648+0.9510534405708313j), + (-0.30901598930358887+0.95105385780334473j), + (-0.80901366472244263+0.58778274059295654j), + (-1.0000008344650269+4.0961388947380328e-08j), + (-0.8090139627456665-0.58778303861618042j), + (-0.30901634693145752-0.95105475187301636j), + (0.30901640653610229-0.95105493068695068j), + (0.80901449918746948-0.5877833366394043j)) + + sampling_freq = 100 + src1 = gr.sig_source_c(sampling_freq, gr.GR_SIN_WAVE, + sampling_freq * 0.10, 100) + dst1 = gr.vector_sink_c() + head = gr.head(gr.sizeof_gr_complex, int(5*sampling_freq * 0.10)) + + agc = analog.agc2_cc(1e-2, 1e-3, 1, 1, 1000) + + tb.connect(src1, head) + tb.connect(head, agc) + tb.connect(agc, dst1) + + if test_output == True: + tb.connect(agc, gr.file_sink(gr.sizeof_gr_complex, "test_agc2_cc.dat")) + + tb.run() + dst_data = dst1.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) + + def test_004_sets(self): + agc = analog.agc2_ff(1e-3, 1e-1, 1, 1, 1000) + + agc.set_attack_rate(1) + agc.set_decay_rate(2) + agc.set_reference(1.1) + agc.set_gain(1.1) + agc.set_max_gain(100) + + self.assertAlmostEqual(agc.attack_rate(), 1) + self.assertAlmostEqual(agc.decay_rate(), 2) + self.assertAlmostEqual(agc.reference(), 1.1) + self.assertAlmostEqual(agc.gain(), 1.1) + self.assertAlmostEqual(agc.max_gain(), 100) + + def test_004(self): + ''' Test the floating point AGC loop (attack and decay rate inputs) ''' + tb = self.tb + + expected_result = \ + (7.2191943445432116e-07, + 58.837181091308594, + 40.194305419921875, + 2.9183335304260254, + 0.67606079578399658, + 8.6260438791896377e-09, + -1.4542514085769653, + -1.9210131168365479, + -1.0450780391693115, + -0.61939650774002075, + -1.2590258613442984e-08, + 1.4308931827545166, + 1.9054338932037354, + 1.0443156957626343, + 0.61937344074249268, + 2.0983527804219193e-08, + -1.4308838844299316, + -1.9054274559020996, + -1.0443152189254761, + -0.61937344074249268, + -2.5180233009791664e-08, + 1.4308837652206421, + 1.9054274559020996, + 1.0443154573440552, + 0.61937344074249268, + 3.3573645197293445e-08, + -1.4308838844299316, + -1.9054274559020996, + -1.0443152189254761, + -0.61937350034713745, + -3.7770352179222755e-08, + 1.4308837652206421, + 1.9054274559020996, + 1.0443154573440552, + 0.61937350034713745, + 4.6163762590367696e-08, + -1.4308838844299316, + -1.9054274559020996, + -1.0443153381347656, + -0.61937344074249268, + -5.0360466019583328e-08, + 1.4308837652206421, + 1.9054274559020996, + 1.0443155765533447, + 0.61937344074249268, + 5.8753879983441948e-08, + -1.4308837652206421, + -1.9054274559020996, + -1.0443153381347656, + -0.61937344074249268) + + sampling_freq = 100 + src1 = gr.sig_source_f(sampling_freq, gr.GR_SIN_WAVE, + sampling_freq * 0.10, 100) + dst1 = gr.vector_sink_f() + head = gr.head(gr.sizeof_float, int(5*sampling_freq * 0.10)) + + agc = analog.agc2_ff(1e-2, 1e-3, 1, 1, 1000) + + tb.connect(src1, head) + tb.connect(head, agc) + tb.connect(agc, dst1) + + if test_output == True: + tb.connect(agc, gr.file_sink(gr.sizeof_float, "test_agc2_ff.dat")) + + tb.run() + dst_data = dst1.data() + self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 4) + + + def test_005(self): + ''' Test the complex AGC loop (attack and decay rate inputs) ''' + tb = self.tb + + expected_result = \ + ((100.000244140625+7.2191943445432116e-07j), + (0.80881959199905396+0.58764183521270752j), + (0.30894950032234192+0.95084899663925171j), + (-0.30895623564720154+0.95086973905563354j), + (-0.80887287855148315+0.58768033981323242j), + (-0.99984413385391235+5.850709250410091e-09j), + (-0.80889981985092163-0.58770018815994263j), + (-0.30897706747055054-0.95093393325805664j), + (0.30898112058639526-0.95094609260559082j), + (0.80893135070800781-0.58772283792495728j), + (0.99990922212600708-8.7766354184282136e-09j), + (0.80894720554351807+0.58773452043533325j), + (0.30899339914321899+0.95098406076431274j), + (-0.30899572372436523+0.95099133253097534j), + (-0.80896598100662231+0.58774799108505249j), + (-0.99994778633117676+1.4628290578855285e-08j), + (-0.80897533893585205-0.58775502443313599j), + (-0.30900305509567261-0.95101380348205566j), + (0.30900448560714722-0.95101797580718994j), + (0.80898630619049072-0.58776277303695679j), + (0.99997037649154663-1.7554345532744264e-08j), + (0.80899184942245483+0.58776694536209106j), + (0.30900871753692627+0.95103120803833008j), + (-0.30900952219963074+0.95103377103805542j), + (-0.8089984655380249+0.58777159452438354j), + (-0.99998390674591064+2.3406109050938539e-08j), + (-0.809001624584198-0.58777409791946411j), + (-0.30901208519935608-0.95104163885116577j), + (0.30901262164115906-0.95104306936264038j), + (0.80900543928146362-0.587776780128479j), + (0.99999171495437622-2.6332081404234486e-08j), + (0.80900734663009644+0.58777821063995361j), + (0.30901408195495605+0.95104765892028809j), + (-0.30901429057121277+0.95104855298995972j), + (-0.80900967121124268+0.58777981996536255j), + (-0.99999648332595825+3.2183805842578295e-08j), + (-0.80901080369949341-0.58778077363967896j), + (-0.30901527404785156-0.95105135440826416j), + (0.30901545286178589-0.95105189085006714j), + (0.80901217460632324-0.58778166770935059j), + (0.99999916553497314-3.5109700036173308e-08j), + (0.809012770652771+0.58778214454650879j), + (0.30901595950126648+0.9510534405708313j), + (-0.30901598930358887+0.95105385780334473j), + (-0.80901366472244263+0.58778274059295654j), + (-1.0000008344650269+4.0961388947380328e-08j), + (-0.8090139627456665-0.58778303861618042j), + (-0.30901634693145752-0.95105475187301636j), + (0.30901640653610229-0.95105493068695068j), + (0.80901449918746948-0.5877833366394043j)) + + sampling_freq = 100 + src1 = gr.sig_source_c(sampling_freq, gr.GR_SIN_WAVE, + sampling_freq * 0.10, 100) + dst1 = gr.vector_sink_c() + head = gr.head(gr.sizeof_gr_complex, int(5*sampling_freq * 0.10)) + + agc = analog.agc2_cc(1e-2, 1e-3, 1, 1, 1000) + + tb.connect(src1, head) + tb.connect(head, agc) + tb.connect(agc, dst1) + + if test_output == True: + tb.connect(agc, gr.file_sink(gr.sizeof_gr_complex, "test_agc2_cc.dat")) + + tb.run() + dst_data = dst1.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) + + def test_100(self): + ''' Test complex feedforward agc with constant input ''' + + length = 8 + gain = 2 + + input_data = 8*(0.0,) + 24*(1.0,) + 24*(0.0,) + expected_result = (8+length-1)*(0.0,) + 24*(gain*1.0,) + (0,) + + src = gr.vector_source_c(input_data) + agc = analog.feedforward_agc_cc(8, 2.0) + dst = gr.vector_sink_c() + self.tb.connect(src, agc, dst) + + if test_output == True: + self.tb.connect(agc, gr.file_sink(gr.sizeof_gr_complex, + "test_feedforward_cc.dat")) + + self.tb.run() + dst_data = dst.data()[0:len(expected_result)] + + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) + + +if __name__ == '__main__': + gr_unittest.run(test_agc, "test_agc.xml") diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 6d714dd0d..96e904fd6 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -28,12 +28,29 @@ %{ #include "analog/cpm.h" +#include "analog/agc_cc.h" +#include "analog/agc_ff.h" +#include "analog/agc2_cc.h" +#include "analog/agc2_ff.h" #include "analog/ctcss_squelch_ff.h" +#include "analog/feedforward_agc_cc.h" +#include "analog/squelch_base_cc.h" #include "analog/squelch_base_ff.h" %} %include "analog/cpm.h" +%include "analog/agc_cc.h" +%include "analog/agc_ff.h" +%include "analog/agc2_cc.h" +%include "analog/agc2_ff.h" %include "analog/ctcss_squelch_ff.h" +%include "analog/feedforward_agc_cc.h" +%include "analog/squelch_base_cc.h" %include "analog/squelch_base_ff.h" +GR_SWIG_BLOCK_MAGIC2(analog, agc_cc); +GR_SWIG_BLOCK_MAGIC2(analog, agc_ff); +GR_SWIG_BLOCK_MAGIC2(analog, agc2_cc); +GR_SWIG_BLOCK_MAGIC2(analog, agc2_ff); GR_SWIG_BLOCK_MAGIC2(analog, ctcss_squelch_ff); +GR_SWIG_BLOCK_MAGIC2(analog, feedforward_agc_cc); -- cgit From f5bc994d85d020958d91111e82acf40262058686 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Mon, 22 Oct 2012 19:57:58 -0400 Subject: analog: added cpfsk to gr-analog. --- gr-analog/include/analog/CMakeLists.txt | 2 +- gr-analog/include/analog/cpfsk_bc.h | 59 ++++++++++++++++++++++ gr-analog/lib/CMakeLists.txt | 1 + gr-analog/lib/cpfsk_bc_impl.cc | 86 +++++++++++++++++++++++++++++++++ gr-analog/lib/cpfsk_bc_impl.h | 54 +++++++++++++++++++++ gr-analog/python/qa_cpfsk.py | 68 ++++++++++++++++++++++++++ gr-analog/swig/analog_swig.i | 3 ++ 7 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 gr-analog/include/analog/cpfsk_bc.h create mode 100644 gr-analog/lib/cpfsk_bc_impl.cc create mode 100644 gr-analog/lib/cpfsk_bc_impl.h create mode 100644 gr-analog/python/qa_cpfsk.py diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index 7e95d88cd..472f700d1 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -84,7 +84,7 @@ install(FILES agc_ff.h agc2_cc.h agc2_ff.h - ctcss_squelch_cc.h + cpfsk_bc.h ctcss_squelch_ff.h feedforward_agc_cc.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog diff --git a/gr-analog/include/analog/cpfsk_bc.h b/gr-analog/include/analog/cpfsk_bc.h new file mode 100644 index 000000000..904730e2b --- /dev/null +++ b/gr-analog/include/analog/cpfsk_bc.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2012 Free Software Foundation, Inc. + * + * 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_ANALOG_CPFSK_BC_H +#define INCLUDED_ANALOG_CPFSK_BC_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief Perform continuous phase 2-level frequency shift keying modulation + * on an input stream of unpacked bits. + * \ingroup modulation_blk + */ + class ANALOG_API cpfsk_bc : virtual public gr_sync_interpolator + { + public: + // gr::analog::cpfsk_bc::sptr + typedef boost::shared_ptr sptr; + + /*! + * \brief Make a CPFSK block. + * + * \param k modulation index + * \param ampl output amplitude + * \param samples_per_sym number of output samples per input bit + */ + static sptr make(float k, float ampl, int samples_per_sym); + + virtual void set_amplitude(float amplitude) = 0; + virtual float amplitude() = 0; + virtual float freq() = 0; + virtual float phase() = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_CPFSK_BC_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index 468957d98..f7281477e 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -110,6 +110,7 @@ list(APPEND analog_sources agc_ff_impl.cc agc2_cc_impl.cc agc2_ff_impl.cc + cpfsk_bc_impl.cc ctcss_squelch_ff_impl.cc feedforward_agc_cc_impl.cc ) diff --git a/gr-analog/lib/cpfsk_bc_impl.cc b/gr-analog/lib/cpfsk_bc_impl.cc new file mode 100644 index 000000000..1b7f25f6c --- /dev/null +++ b/gr-analog/lib/cpfsk_bc_impl.cc @@ -0,0 +1,86 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2010,2012 Free Software Foundation, Inc. + * + * 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 "cpfsk_bc_impl.h" +#include +#include + +namespace gr { + namespace analog { + +#define M_TWOPI (2*M_PI) + + cpfsk_bc::sptr + cpfsk_bc::make(float k, float ampl, int samples_per_sym) + { + return gnuradio::get_initial_sptr + (new cpfsk_bc_impl(k, ampl, samples_per_sym)); + } + + cpfsk_bc_impl::cpfsk_bc_impl(float k, float ampl, int samples_per_sym) + : gr_sync_interpolator("cpfsk_bc", + gr_make_io_signature(1, 1, sizeof(char)), + gr_make_io_signature(1, 1, sizeof(gr_complex)), + samples_per_sym) + { + d_samples_per_sym = samples_per_sym; + d_freq = k*M_PI/samples_per_sym; + d_ampl = ampl; + d_phase = 0.0; + } + + cpfsk_bc_impl::~cpfsk_bc_impl() + { + } + + int + cpfsk_bc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const char *in = (const char*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + for(int i = 0; i < noutput_items/d_samples_per_sym; i++) { + for(int j = 0; j < d_samples_per_sym; j++) { + if(in[i] == 1) + d_phase += d_freq; + else + d_phase -= d_freq; + + while(d_phase > M_TWOPI) + d_phase -= M_TWOPI; + while(d_phase < -M_TWOPI) + d_phase += M_TWOPI; + + *out++ = gr_expj(d_phase)*d_ampl; + } + } + + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ + diff --git a/gr-analog/lib/cpfsk_bc_impl.h b/gr-analog/lib/cpfsk_bc_impl.h new file mode 100644 index 000000000..9f6ec2c7f --- /dev/null +++ b/gr-analog/lib/cpfsk_bc_impl.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2012 Free Software Foundation, Inc. + * + * 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_ANALOG_CPFSK_BC_IMPL_H +#define INCLUDED_ANALOG_CPFSK_BC_IMPL_H + +#include + +namespace gr { + namespace analog { + + class cpfsk_bc_impl : public cpfsk_bc + { + private: + int d_samples_per_sym; // Samples per symbol, square pulse + float d_freq; // Modulation index*pi/samples_per_sym + float d_ampl; // Output amplitude + float d_phase; // Current phase + + public: + cpfsk_bc_impl(float k, float ampl, int samples_per_sym); + ~cpfsk_bc_impl(); + + void set_amplitude(float amplitude) { d_ampl = amplitude; } + float amplitude() { return d_ampl; } + float freq() { return d_freq; } + float phase() { return d_phase; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_CPFSK_BC_IMPL_H */ diff --git a/gr-analog/python/qa_cpfsk.py b/gr-analog/python/qa_cpfsk.py new file mode 100644 index 000000000..decf94ea3 --- /dev/null +++ b/gr-analog/python/qa_cpfsk.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# +# Copyright 2012 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, gr_unittest +import analog_swig as analog +import math + +class test_cpfsk_bc(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_cpfsk_bc_001(self): + # Test set/gets + + op = analog.cpfsk_bc(2, 1, 2) + + op.set_amplitude(2) + a = op.amplitude() + self.assertEqual(2, a) + + freq = 2*math.pi/2.0 + f = op.freq() + self.assertAlmostEqual(freq, f, 5) + + p = op.phase() + self.assertEqual(0, p) + + def test_cpfsk_bc_002(self): + src_data = 10*[0, 1] + expected_result = map(lambda x: complex(2*x-1,0), src_data) + + src = gr.vector_source_b(src_data) + op = analog.cpfsk_bc(2, 1, 2) + dst = gr.vector_sink_c() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data()[0:len(expected_result)] + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_cpfsk_bc, "test_cpfsk_bc.xml") + diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 96e904fd6..8cc166dd2 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -32,6 +32,7 @@ #include "analog/agc_ff.h" #include "analog/agc2_cc.h" #include "analog/agc2_ff.h" +#include "analog/cpfsk_bc.h" #include "analog/ctcss_squelch_ff.h" #include "analog/feedforward_agc_cc.h" #include "analog/squelch_base_cc.h" @@ -43,6 +44,7 @@ %include "analog/agc_ff.h" %include "analog/agc2_cc.h" %include "analog/agc2_ff.h" +%include "analog/cpfsk_bc.h" %include "analog/ctcss_squelch_ff.h" %include "analog/feedforward_agc_cc.h" %include "analog/squelch_base_cc.h" @@ -52,5 +54,6 @@ GR_SWIG_BLOCK_MAGIC2(analog, agc_cc); GR_SWIG_BLOCK_MAGIC2(analog, agc_ff); GR_SWIG_BLOCK_MAGIC2(analog, agc2_cc); GR_SWIG_BLOCK_MAGIC2(analog, agc2_ff); +GR_SWIG_BLOCK_MAGIC2(analog, cpfsk_bc); GR_SWIG_BLOCK_MAGIC2(analog, ctcss_squelch_ff); GR_SWIG_BLOCK_MAGIC2(analog, feedforward_agc_cc); -- cgit From 502eeffa9f5ebeec092be1954efeab4992ef9796 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Mon, 22 Oct 2012 20:33:05 -0400 Subject: analog: adding dpll_bb to gr-analog. --- gr-analog/include/analog/CMakeLists.txt | 1 + gr-analog/include/analog/dpll_bb.h | 59 ++++++++++++++++++++ gr-analog/lib/CMakeLists.txt | 1 + gr-analog/lib/dpll_bb_impl.cc | 98 +++++++++++++++++++++++++++++++++ gr-analog/lib/dpll_bb_impl.h | 58 +++++++++++++++++++ gr-analog/python/qa_dpll.py | 76 +++++++++++++++++++++++++ gr-analog/swig/analog_swig.i | 3 + 7 files changed, 296 insertions(+) create mode 100644 gr-analog/include/analog/dpll_bb.h create mode 100644 gr-analog/lib/dpll_bb_impl.cc create mode 100644 gr-analog/lib/dpll_bb_impl.h create mode 100644 gr-analog/python/qa_dpll.py diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index 472f700d1..40af6e55d 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -86,6 +86,7 @@ install(FILES agc2_ff.h cpfsk_bc.h ctcss_squelch_ff.h + dpll_bb.h feedforward_agc_cc.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog COMPONENT "analog_devel" diff --git a/gr-analog/include/analog/dpll_bb.h b/gr-analog/include/analog/dpll_bb.h new file mode 100644 index 000000000..78efb8fde --- /dev/null +++ b/gr-analog/include/analog/dpll_bb.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2012 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_ANALOG_DPLL_BB_H +#define INCLUDED_ANALOG_DPLL_BB_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief Detect the peak of a signal + * \ingroup level_blk + * + * If a peak is detected, this block outputs a 1, + * or it outputs 0's. + */ + class ANALOG_API dpll_bb : virtual public gr_sync_block + { + public: + // gr::analog::dpll_bb::sptr + typedef boost::shared_ptr sptr; + + static sptr make(float period, float gain); + + virtual void set_gain(float gain) = 0; + virtual void set_decision_threshold(float thresh) = 0; + + virtual float gain() const = 0; + virtual float freq() const = 0; + virtual float phase() const = 0; + virtual float decision_threshold() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_DPLL_BB_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index f7281477e..258d5d67c 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -112,6 +112,7 @@ list(APPEND analog_sources agc2_ff_impl.cc cpfsk_bc_impl.cc ctcss_squelch_ff_impl.cc + dpll_bb_impl.cc feedforward_agc_cc_impl.cc ) diff --git a/gr-analog/lib/dpll_bb_impl.cc b/gr-analog/lib/dpll_bb_impl.cc new file mode 100644 index 000000000..a199b66b4 --- /dev/null +++ b/gr-analog/lib/dpll_bb_impl.cc @@ -0,0 +1,98 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2009,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 "dpll_bb_impl.h" +#include +#include + +namespace gr { + namespace analog { + + dpll_bb::sptr + dpll_bb::make(float period, float gain) + { + return gnuradio::get_initial_sptr + (new dpll_bb_impl(period, gain)); + } + + dpll_bb_impl::dpll_bb_impl(float period, float gain) + : gr_sync_block("dpll_bb", + gr_make_io_signature(1, 1, sizeof(char)), + gr_make_io_signature(1, 1, sizeof(char))), + d_restart(0), d_pulse_phase(0) + { + d_pulse_frequency = 1.0/period; + d_gain = gain; + d_decision_threshold = 1.0 - 0.5*d_pulse_frequency; +#if 0 + fprintf(stderr,"frequency = %f period = %f gain = %f threshold = %f\n", + d_pulse_frequency, + period, + d_gain, + d_decision_threshold); +#endif + } + + dpll_bb_impl::~dpll_bb_impl() + { + } + + int + dpll_bb_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const char *iptr = (const char*)input_items[0]; + char *optr = (char*)output_items[0]; + + for(int i = 0; i < noutput_items; i++) { + optr[i]= 0; + if(iptr[i] == 1) { + if(d_restart == 0) { + d_pulse_phase = 1; + } + else { + if(d_pulse_phase > 0.5) + d_pulse_phase += d_gain*(1.0-d_pulse_phase); + else + d_pulse_phase -= d_gain*d_pulse_phase; + } + d_restart = 3; + } + if(d_pulse_phase > d_decision_threshold) { + d_pulse_phase -= 1.0; + if(d_restart > 0) { + d_restart -= 1; + optr[i] = 1; + } + } + d_pulse_phase += d_pulse_frequency; + } + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/dpll_bb_impl.h b/gr-analog/lib/dpll_bb_impl.h new file mode 100644 index 000000000..a1d8b7709 --- /dev/null +++ b/gr-analog/lib/dpll_bb_impl.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2012 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_ANALOG_DPLL_BB_IMPL_H +#define INCLUDED_ANALOG_DPLL_BB_IMPL_H + +#include + +namespace gr { + namespace analog { + + class dpll_bb_impl : public dpll_bb + { + private: + unsigned char d_restart; + float d_pulse_phase, d_pulse_frequency; + float d_gain, d_decision_threshold; + + public: + dpll_bb_impl(float period, float gain); + ~dpll_bb_impl(); + + void set_gain(float gain) { d_gain = gain; } + void set_decision_threshold(float thresh) { d_decision_threshold = thresh; } + + float gain() const { return d_gain; } + float freq() const { return d_pulse_frequency; } + float phase() const { return d_pulse_phase; } + float decision_threshold() const { return d_decision_threshold; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_DPLL_BB_IMPL_H */ diff --git a/gr-analog/python/qa_dpll.py b/gr-analog/python/qa_dpll.py new file mode 100644 index 000000000..3ef8a6e28 --- /dev/null +++ b/gr-analog/python/qa_dpll.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# +# Copyright 2012 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, gr_unittest +import analog_swig as analog +import math + +class test_dpll_bb(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_dpll_bb_001(self): + # Test set/gets + + period = 1.0 + gain = 0.1 + op = analog.dpll_bb(period, gain) + + op.set_gain(0.2) + g = op.gain() + self.assertAlmostEqual(g, 0.2) + + f = op.freq() + self.assertEqual(1/period, f) + + d0 = 1.0 - 0.5*f; + d1 = op.decision_threshold() + self.assertAlmostEqual(d0, d1) + + p = op.phase() + self.assertEqual(0, p) + + def test_dpll_bb_002(self): + period = 4 + gain = 0.1 + + src_data = 10*((period-1)*[0,] + [1,]) + expected_result = src_data + + src = gr.vector_source_b(src_data) + op = analog.dpll_bb(period, gain) + dst = gr.vector_sink_b() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_dpll_bb, "test_dpll_bb.xml") + diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 8cc166dd2..135bfb859 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -34,6 +34,7 @@ #include "analog/agc2_ff.h" #include "analog/cpfsk_bc.h" #include "analog/ctcss_squelch_ff.h" +#include "analog/dpll_bb.h" #include "analog/feedforward_agc_cc.h" #include "analog/squelch_base_cc.h" #include "analog/squelch_base_ff.h" @@ -46,6 +47,7 @@ %include "analog/agc2_ff.h" %include "analog/cpfsk_bc.h" %include "analog/ctcss_squelch_ff.h" +%include "analog/dpll_bb.h" %include "analog/feedforward_agc_cc.h" %include "analog/squelch_base_cc.h" %include "analog/squelch_base_ff.h" @@ -56,4 +58,5 @@ GR_SWIG_BLOCK_MAGIC2(analog, agc2_cc); GR_SWIG_BLOCK_MAGIC2(analog, agc2_ff); GR_SWIG_BLOCK_MAGIC2(analog, cpfsk_bc); GR_SWIG_BLOCK_MAGIC2(analog, ctcss_squelch_ff); +GR_SWIG_BLOCK_MAGIC2(analog, dpll_bb); GR_SWIG_BLOCK_MAGIC2(analog, feedforward_agc_cc); -- cgit From 0723682d4f99a8dbe379a9aed0558650a977663e Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Mon, 22 Oct 2012 21:35:04 -0400 Subject: analog: adding GRC blocks for: - AGC - AGC2 - Feedforward AGC - CPFSK - CTCSS squelch - DPLL --- gr-analog/grc/analog_agc2_xx.xml | 70 +++++++++++++++++++++++++ gr-analog/grc/analog_agc_xx.xml | 63 +++++++++++++++++++++++ gr-analog/grc/analog_block_tree.xml | 14 ++++- gr-analog/grc/analog_cpfsk_bc.xml | 37 ++++++++++++++ gr-analog/grc/analog_ctcss_squelch_ff.xml | 79 +++++++++++++++++++++++++++++ gr-analog/grc/analog_dpll_bb.xml | 31 +++++++++++ gr-analog/grc/analog_feedforward_agc_cc.xml | 32 ++++++++++++ 7 files changed, 325 insertions(+), 1 deletion(-) create mode 100644 gr-analog/grc/analog_agc2_xx.xml create mode 100644 gr-analog/grc/analog_agc_xx.xml create mode 100644 gr-analog/grc/analog_cpfsk_bc.xml create mode 100644 gr-analog/grc/analog_ctcss_squelch_ff.xml create mode 100644 gr-analog/grc/analog_dpll_bb.xml create mode 100644 gr-analog/grc/analog_feedforward_agc_cc.xml diff --git a/gr-analog/grc/analog_agc2_xx.xml b/gr-analog/grc/analog_agc2_xx.xml new file mode 100644 index 000000000..e57666873 --- /dev/null +++ b/gr-analog/grc/analog_agc2_xx.xml @@ -0,0 +1,70 @@ + + + + AGC2 + analog_agc2_xx + from gnuradio import analog + analog.agc2_$(type.fcn)($attack_rate, $decay_rate, $reference, $gain, $max_gain) + set_attack_rate($attack_rate) + set_decay_rate($decay_rate) + set_reference($reference) + set_gain($gain) + set_max_gain($max_gain) + + Type + type + enum + + + + + Attack Rate + attack_rate + 1e-1 + real + + + Decay Rate + decay_rate + 1e-2 + real + + + Reference + reference + 1.0 + real + + + Gain + gain + 1.0 + real + + + Max Gain + max_gain + 0.0 + real + + + in + $type + + + out + $type + + diff --git a/gr-analog/grc/analog_agc_xx.xml b/gr-analog/grc/analog_agc_xx.xml new file mode 100644 index 000000000..46797bff9 --- /dev/null +++ b/gr-analog/grc/analog_agc_xx.xml @@ -0,0 +1,63 @@ + + + + AGC + analog_agc_xx + from gnuradio import analog + analog.agc_$(type.fcn)($rate, $reference, $gain, $max_gain) + set_rate($rate) + set_reference($reference) + set_gain($gain) + set_max_gain($max_gain) + + Type + type + enum + + + + + Rate + rate + 1e-4 + real + + + Reference + reference + 1.0 + real + + + Gain + gain + 1.0 + real + + + Max Gain + max_gain + 0.0 + real + + + in + $type + + + out + $type + + diff --git a/gr-analog/grc/analog_block_tree.xml b/gr-analog/grc/analog_block_tree.xml index a924e8cda..53aba58c9 100644 --- a/gr-analog/grc/analog_block_tree.xml +++ b/gr-analog/grc/analog_block_tree.xml @@ -27,5 +27,17 @@ ################################################### --> - + + + Level Controls + analog_agc_xx + analog_agc2_xx + analog_feedforward_agc_cc + analog_ctcss_squelch_ff + analog_dpll_bb + + + Modulators + analog_cpfsk_bc + diff --git a/gr-analog/grc/analog_cpfsk_bc.xml b/gr-analog/grc/analog_cpfsk_bc.xml new file mode 100644 index 000000000..7eb85a2ec --- /dev/null +++ b/gr-analog/grc/analog_cpfsk_bc.xml @@ -0,0 +1,37 @@ + + + + CPFSK + analog_cpfsk_bc + from gnuradio import analog + analog.cpfsk_bc($k, $amplitude, $samples_per_symbol) + set_amplitude($amplitude) + + K + k + real + + + Amplitude + amplitude + real + + + Samples/Symbol + samples_per_symbol + 2 + int + + + in + byte + + + out + complex + + diff --git a/gr-analog/grc/analog_ctcss_squelch_ff.xml b/gr-analog/grc/analog_ctcss_squelch_ff.xml new file mode 100644 index 000000000..9585835e2 --- /dev/null +++ b/gr-analog/grc/analog_ctcss_squelch_ff.xml @@ -0,0 +1,79 @@ + + + + + + CTCSS Squelch + analog_ctcss_squelch_ff + from gnuradio import analog + analog.ctcss_squelch_ff($rate, $freq, $level, $len, $ramp, $gate) + set_level($level) + + Sampling Rate (Hz) + rate + samp_rate + real + + + Tone Frequency + freq + 100.0 + real + + + Level + level + 0.01 + real + + + Length + len + 0 + int + + + Ramp + ramp + 0 + int + + + Gate + gate + False + bool + + + in + float + + + out + float + + diff --git a/gr-analog/grc/analog_dpll_bb.xml b/gr-analog/grc/analog_dpll_bb.xml new file mode 100644 index 000000000..65a489414 --- /dev/null +++ b/gr-analog/grc/analog_dpll_bb.xml @@ -0,0 +1,31 @@ + + + + Detect Peak + analog_dpll_bb + from gnuradio import analog + analog.dpll_bb($period, $gain) + set_gain($gain) + + Period + period + real + + + Gain + gain + real + + + in + byte + + + out + byte + + diff --git a/gr-analog/grc/analog_feedforward_agc_cc.xml b/gr-analog/grc/analog_feedforward_agc_cc.xml new file mode 100644 index 000000000..66d200a84 --- /dev/null +++ b/gr-analog/grc/analog_feedforward_agc_cc.xml @@ -0,0 +1,32 @@ + + + + Feed Forward AGC + analog_feedforward_agc_cc + from gnuradio import analog + analog.feedforward_agc_cc($num_samples, $reference) + + Num Samples + num_samples + 1024 + int + + + Reference + reference + 1.0 + real + + + in + complex + + + out + complex + + -- cgit From 7b3ca29290f97388c3006959a91c24eea1116483 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 23 Oct 2012 11:48:06 -0400 Subject: analog: added fmdet block to gr-analog. --- gr-analog/include/analog/CMakeLists.txt | 1 + gr-analog/include/analog/fmdet_cf.h | 70 +++++++++++++++++ gr-analog/lib/CMakeLists.txt | 1 + gr-analog/lib/fmdet_cf_impl.cc | 129 ++++++++++++++++++++++++++++++++ gr-analog/lib/fmdet_cf_impl.h | 62 +++++++++++++++ gr-analog/python/qa_fmdet.py | 80 ++++++++++++++++++++ gr-analog/swig/analog_swig.i | 3 + 7 files changed, 346 insertions(+) create mode 100644 gr-analog/include/analog/fmdet_cf.h create mode 100644 gr-analog/lib/fmdet_cf_impl.cc create mode 100644 gr-analog/lib/fmdet_cf_impl.h create mode 100644 gr-analog/python/qa_fmdet.py diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index 40af6e55d..3c049bfd3 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -88,6 +88,7 @@ install(FILES ctcss_squelch_ff.h dpll_bb.h feedforward_agc_cc.h + fmdet_cf.j DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog COMPONENT "analog_devel" ) diff --git a/gr-analog/include/analog/fmdet_cf.h b/gr-analog/include/analog/fmdet_cf.h new file mode 100644 index 000000000..6878775e6 --- /dev/null +++ b/gr-analog/include/analog/fmdet_cf.h @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2012 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_ANALOG_FMDET_CF_H +#define INCLUDED_ANALOG_FMDET_CF_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief Implements an IQ slope detector + * + * input: stream of complex; output: stream of floats + * + * This implements a limiting slope detector. The limiter is in + * the normalization by the magnitude of the sample + */ + class ANALOG_API fmdet_cf : virtual public gr_sync_block + { + public: + // gr::analog::fmdet_cf::sptr + typedef boost::shared_ptr sptr; + + /*! + * \brief Make FM detector block. + * + * \param samplerate sample rate of signal (is not used; to be removed) + * \param freq_low lowest frequency of signal (Hz) + * \param freq_high highest frequency of signal (Hz) + * \param scl scale factor + */ + static sptr make(float samplerate, float freq_low, + float freq_high, float scl); + + virtual void set_scale(float scl) = 0; + virtual void set_freq_range(float freq_low, float freq_high) = 0; + + virtual float freq() const = 0; + virtual float freq_high() const = 0; + virtual float freq_low() const = 0; + virtual float scale() const = 0; + virtual float bias() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_FMDET_CF_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index 258d5d67c..abceed3e1 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -114,6 +114,7 @@ list(APPEND analog_sources ctcss_squelch_ff_impl.cc dpll_bb_impl.cc feedforward_agc_cc_impl.cc + fmdet_cf_impl.cc ) list(APPEND analog_libs diff --git a/gr-analog/lib/fmdet_cf_impl.cc b/gr-analog/lib/fmdet_cf_impl.cc new file mode 100644 index 000000000..d3a58966b --- /dev/null +++ b/gr-analog/lib/fmdet_cf_impl.cc @@ -0,0 +1,129 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2010,2012 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 "fmdet_cf_impl.h" +#include +#include + +namespace gr { + namespace analog { + +#define M_TWOPI (2*M_PI) + + fmdet_cf::sptr + fmdet_cf::make(float samplerate, float freq_low, + float freq_high, float scl) + { + return gnuradio::get_initial_sptr + (new fmdet_cf_impl(samplerate, freq_low, freq_high, scl)); + } + + fmdet_cf_impl::fmdet_cf_impl(float samplerate, float freq_low, + float freq_high, float scl) + : gr_sync_block("fmdet_cf", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(float))), + d_S1(0.1), d_S2(0.1), + d_S3(0.1), d_S4(0.1) + { + const float h[] = { 0.003118678733, -0.012139843428, 0.027270898036, + -0.051318579352, 0.090406910552, -0.162926865366, + 0.361885392563, 0.000000000000, -0.361885392563, + 0.162926865366, -0.090406910552, 0.051318579352, + -0.027270898036, 0.012139843428, -0.003118678733}; + + //std::vector taps(15); + + d_freq = 0; + d_freqhi = freq_high; + d_freqlo = freq_low; + set_scale(scl); + + //for(int i = 0; i < 15; i++) { + //taps[i] = h[i]; + //} + // d_filter = gr_fir_util::create_gr_fir_ccf(taps); + } + + fmdet_cf_impl::~fmdet_cf_impl() + { + } + + void + fmdet_cf_impl::set_scale(float scl) + { + float delta = d_freqhi - d_freqlo; + d_scl = scl; + d_bias = 0.5*scl*(d_freqhi + d_freqlo) / delta; + } + + void + fmdet_cf_impl::set_freq_range(float freq_low, float freq_high) + { + d_freqhi = freq_high; + d_freqlo = freq_low; + set_scale(d_scl); + } + + int + fmdet_cf_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *iptr = (gr_complex*)input_items[0]; + float *optr = (float*)output_items[0]; + //const gr_complex *scaleiptr = (gr_complex*)input_items[0]; + + int size = noutput_items; + + gr_complex Sdot, S0; + gr_complex S1=d_S1, S2=d_S2, S3=d_S3, S4=d_S4; + float d_8 = 8.0; + + while(size-- > 0) { + S0 = *iptr++; + + Sdot = d_scl * (-S0+d_8*S1-d_8*S1+S4); + + d_freq = (S2.real()*Sdot.imag()-S2.imag()*Sdot.real()) / + (S2.real()*S2.real()+S2.imag()*S2.imag()); + + S4 = S3; + S3 = S2; + S2 = S1; + S1 = S0; + + *optr++ = d_freq-d_bias; + } + d_S1 = S1; + d_S2 = S2; + d_S3 = S3; + d_S4 = S4; + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/fmdet_cf_impl.h b/gr-analog/lib/fmdet_cf_impl.h new file mode 100644 index 000000000..01fce09dd --- /dev/null +++ b/gr-analog/lib/fmdet_cf_impl.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008, 2012 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_ANALOG_FMDET_CF_IMPL_H +#define INCLUDED_ANALOG_FMDET_CF_IMPL_H + +#include +//#include +#include + +namespace gr { + namespace analog { + + class fmdet_cf_impl : public fmdet_cf + { + private: + gr_complex d_S1, d_S2, d_S3, d_S4; + float d_freq, d_freqlo, d_freqhi, d_scl, d_bias; + //kernel::fir_filter_ccf* d_filter; + + public: + fmdet_cf_impl(float samplerate, float freq_low, + float freq_high, float scl); + ~fmdet_cf_impl(); + + void set_scale(float scl); + void set_freq_range(float freq_low, float freq_high); + + float freq() const { return d_freq; } + float freq_high() const { return d_freqhi; } + float freq_low() const { return d_freqlo; } + float scale() const { return d_scl; } + float bias() const { return d_bias; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_FMDET_CF_IMPL_H */ diff --git a/gr-analog/python/qa_fmdet.py b/gr-analog/python/qa_fmdet.py new file mode 100644 index 000000000..b90ef2ffa --- /dev/null +++ b/gr-analog/python/qa_fmdet.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +# +# Copyright 2012 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, gr_unittest +import analog_swig as analog +import math + +class test_fmdet_cf(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_fmdet_cf_001(self): + # Test set/gets + + fh1 = 10 + fh2 = 20 + fl1 = 1 + fl2 = 2 + scale1 = 3 + scale2 = 4 + op = analog.fmdet_cf(1, fl1, fh1, scale1) + + op.set_freq_range(fl2, fh2) + lo = op.freq_low() + hi = op.freq_high() + f = op.freq() + self.assertEqual(fl2, lo) + self.assertEqual(fh2, hi) + self.assertEqual(0, f) + + op.set_scale(scale2) + s = op.scale() + b = op.bias() + eb = 0.5*scale2*(hi + lo) / (hi - lo); + self.assertEqual(scale2, s) + self.assertAlmostEqual(eb, b) + + # FIXME: This passes QA, but the it's only based off what the + # block is saying, not what the values should actually be. + def est_fmdet_cf_002(self): + N = 100 + src = gr.sig_source_c(1, gr.GR_SIN_WAVE, 0.2, 1) + head = gr.head(gr.sizeof_gr_complex, N) + op = analog.fmdet_cf(1, 0.1, 0.3, 0.1) + dst = gr.vector_sink_f() + + self.tb.connect(src, head, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data()[4:N] + expected_result = (100-4)*[-0.21755,] + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_fmdet_cf, "test_fmdet_cf.xml") + diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 135bfb859..fec099a6c 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -36,6 +36,7 @@ #include "analog/ctcss_squelch_ff.h" #include "analog/dpll_bb.h" #include "analog/feedforward_agc_cc.h" +#include "analog/fmdet_cf.h" #include "analog/squelch_base_cc.h" #include "analog/squelch_base_ff.h" %} @@ -49,6 +50,7 @@ %include "analog/ctcss_squelch_ff.h" %include "analog/dpll_bb.h" %include "analog/feedforward_agc_cc.h" +%include "analog/fmdet_cf.h" %include "analog/squelch_base_cc.h" %include "analog/squelch_base_ff.h" @@ -60,3 +62,4 @@ GR_SWIG_BLOCK_MAGIC2(analog, cpfsk_bc); GR_SWIG_BLOCK_MAGIC2(analog, ctcss_squelch_ff); GR_SWIG_BLOCK_MAGIC2(analog, dpll_bb); GR_SWIG_BLOCK_MAGIC2(analog, feedforward_agc_cc); +GR_SWIG_BLOCK_MAGIC2(analog, fmdet_cf); -- cgit From 8c9a5fdb19046c3cb8d25d6b77dbac87d49d8391 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Thu, 25 Oct 2012 21:44:36 -0400 Subject: analog: adding frequency_modulator_fc to gr-analog, with QA and GRC. --- gr-analog/grc/analog_block_tree.xml | 1 + gr-analog/grc/analog_frequency_modulator_fc.xml | 26 +++++++ gr-analog/include/analog/CMakeLists.txt | 3 +- gr-analog/include/analog/frequency_modulator_fc.h | 53 +++++++++++++++ gr-analog/lib/CMakeLists.txt | 1 + gr-analog/lib/frequency_modulator_fc_impl.cc | 82 +++++++++++++++++++++++ gr-analog/lib/frequency_modulator_fc_impl.h | 52 ++++++++++++++ gr-analog/python/qa_frequency_modulator.py | 56 ++++++++++++++++ gr-analog/swig/analog_swig.i | 3 + 9 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 gr-analog/grc/analog_frequency_modulator_fc.xml create mode 100644 gr-analog/include/analog/frequency_modulator_fc.h create mode 100644 gr-analog/lib/frequency_modulator_fc_impl.cc create mode 100644 gr-analog/lib/frequency_modulator_fc_impl.h create mode 100755 gr-analog/python/qa_frequency_modulator.py diff --git a/gr-analog/grc/analog_block_tree.xml b/gr-analog/grc/analog_block_tree.xml index 53aba58c9..bb7a9b067 100644 --- a/gr-analog/grc/analog_block_tree.xml +++ b/gr-analog/grc/analog_block_tree.xml @@ -35,6 +35,7 @@ analog_feedforward_agc_cc analog_ctcss_squelch_ff analog_dpll_bb + analog_frequency_modulator_fc Modulators diff --git a/gr-analog/grc/analog_frequency_modulator_fc.xml b/gr-analog/grc/analog_frequency_modulator_fc.xml new file mode 100644 index 000000000..3b6cd159a --- /dev/null +++ b/gr-analog/grc/analog_frequency_modulator_fc.xml @@ -0,0 +1,26 @@ + + + + Frequency Mod + analog_frequency_modulator_fc + from gnuradio import analog + analog.frequency_modulator_fc($sensitivity) + set_sensitivity($sensitivity) + + Sensitivity + sensitivity + real + + + in + float + + + out + complex + + diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index 3c049bfd3..6e4c40b46 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -88,7 +88,8 @@ install(FILES ctcss_squelch_ff.h dpll_bb.h feedforward_agc_cc.h - fmdet_cf.j + fmdet_cf.h + frequency_modulator_fc.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog COMPONENT "analog_devel" ) diff --git a/gr-analog/include/analog/frequency_modulator_fc.h b/gr-analog/include/analog/frequency_modulator_fc.h new file mode 100644 index 000000000..b163bac94 --- /dev/null +++ b/gr-analog/include/analog/frequency_modulator_fc.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 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_ANALOOG_FREQUENCY_MODULATOR_FC_H +#define INCLUDED_ANALOOG_FREQUENCY_MODULATOR_FC_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief Frequency modulator block + * \ingroup modulation_blk + * + * float input; complex baseband output + */ + class ANALOG_API frequency_modulator_fc : virtual public gr_sync_block + { + public: + // gr::analog::frequency_modulator_fc::sptr + typedef boost::shared_ptr sptr; + + static sptr make(double sensitivity); + + virtual void set_sensitivity(float sens) = 0; + virtual float sensitivity() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_FREQUENCY_MODULATOR_FC_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index abceed3e1..9faeaba80 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -115,6 +115,7 @@ list(APPEND analog_sources dpll_bb_impl.cc feedforward_agc_cc_impl.cc fmdet_cf_impl.cc + frequency_modulator_fc_impl.cc ) list(APPEND analog_libs diff --git a/gr-analog/lib/frequency_modulator_fc_impl.cc b/gr-analog/lib/frequency_modulator_fc_impl.cc new file mode 100644 index 000000000..2da7ee15f --- /dev/null +++ b/gr-analog/lib/frequency_modulator_fc_impl.cc @@ -0,0 +1,82 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010-2012 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 "frequency_modulator_fc_impl.h" +#include +#include +#include +#include + +namespace gr { + namespace analog { + + frequency_modulator_fc::sptr + frequency_modulator_fc::make(double sensitivity) + { + return gnuradio::get_initial_sptr + (new frequency_modulator_fc_impl(sensitivity)); + } + + frequency_modulator_fc_impl::frequency_modulator_fc_impl(double sensitivity) + : gr_sync_block("frequency_modulator_fc", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + d_sensitivity(sensitivity), d_phase(0) + { + } + + frequency_modulator_fc_impl::~frequency_modulator_fc_impl() + { + } + + int + frequency_modulator_fc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + for(int i = 0; i < noutput_items; i++) { + d_phase = d_phase + d_sensitivity * in[i]; + + while(d_phase > (float)(M_PI)) + d_phase -= (float)(2.0 * M_PI); + while(d_phase < (float)(-M_PI)) + d_phase += (float)(2.0 * M_PI); + + float oi, oq; + + gr_int32 angle = gr_fxpt::float_to_fixed (d_phase); + gr_fxpt::sincos(angle, &oq, &oi); + out[i] = gr_complex(oi, oq); + } + + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/frequency_modulator_fc_impl.h b/gr-analog/lib/frequency_modulator_fc_impl.h new file mode 100644 index 000000000..36512f516 --- /dev/null +++ b/gr-analog/lib/frequency_modulator_fc_impl.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 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_ANALOG_FREQUENCY_MODULATOR_FC_IMPL_H +#define INCLUDED_ANALOG_FREQUENCY_MODULATOR_FC_IMPL_H + +#include + +namespace gr { + namespace analog { + + class frequency_modulator_fc_impl : public frequency_modulator_fc + { + private: + float d_sensitivity; + float d_phase; + + public: + frequency_modulator_fc_impl(double sensitivity); + ~frequency_modulator_fc_impl(); + + void set_sensitivity(float sens) { d_sensitivity = sens; } + float sensitivity() const { return d_sensitivity; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_FREQUENCY_MODULATOR_FC_IMPL_H */ diff --git a/gr-analog/python/qa_frequency_modulator.py b/gr-analog/python/qa_frequency_modulator.py new file mode 100755 index 000000000..b673b3275 --- /dev/null +++ b/gr-analog/python/qa_frequency_modulator.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010,2012 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, gr_unittest +import analog_swig as analog +import math + +def sincos(x): + return math.cos(x) + math.sin(x) * 1j + + +class test_frequency_modulator(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_fm_001(self): + pi = math.pi + sensitivity = pi/4 + src_data = (1.0/4, 1.0/2, 1.0/4, -1.0/4, -1.0/2, -1/4.0) + running_sum = (pi/16, 3*pi/16, pi/4, 3*pi/16, pi/16, 0) + expected_result = tuple([sincos(x) for x in running_sum]) + src = gr.vector_source_f(src_data) + op = analog.frequency_modulator_fc(sensitivity) + dst = gr.vector_sink_c() + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_frequency_modulator, "test_frequency_modulator.xml") + diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index fec099a6c..8e1bb8058 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -37,6 +37,7 @@ #include "analog/dpll_bb.h" #include "analog/feedforward_agc_cc.h" #include "analog/fmdet_cf.h" +#include "analog/frequency_modulator_fc.h" #include "analog/squelch_base_cc.h" #include "analog/squelch_base_ff.h" %} @@ -51,6 +52,7 @@ %include "analog/dpll_bb.h" %include "analog/feedforward_agc_cc.h" %include "analog/fmdet_cf.h" +%include "analog/frequency_modulator_fc.h" %include "analog/squelch_base_cc.h" %include "analog/squelch_base_ff.h" @@ -63,3 +65,4 @@ GR_SWIG_BLOCK_MAGIC2(analog, ctcss_squelch_ff); GR_SWIG_BLOCK_MAGIC2(analog, dpll_bb); GR_SWIG_BLOCK_MAGIC2(analog, feedforward_agc_cc); GR_SWIG_BLOCK_MAGIC2(analog, fmdet_cf); +GR_SWIG_BLOCK_MAGIC2(analog, frequency_modulator_fc); -- cgit From d67c7948339b3d243449b54fa415e0dcfbf33988 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Thu, 25 Oct 2012 23:00:25 -0400 Subject: core: update to build_utils to help with '_i_impl' blocks. --- gnuradio-core/src/python/build_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnuradio-core/src/python/build_utils.py b/gnuradio-core/src/python/build_utils.py index cbf991aa5..cf58a9763 100644 --- a/gnuradio-core/src/python/build_utils.py +++ b/gnuradio-core/src/python/build_utils.py @@ -212,7 +212,7 @@ def standard_impl_dict2 (name, code3, package): d = {} d['NAME'] = name d['IMPL_NAME'] = name - d['BASE_NAME'] = name.rstrip("_impl") + d['BASE_NAME'] = name.rstrip("impl").rstrip("_") d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper()) d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten' d['COPYRIGHT'] = copyright -- cgit From d5306ee4f6f76fd85f84b5f023917179f780d26a Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Thu, 25 Oct 2012 23:01:35 -0400 Subject: analog: adding noise_source to gr-analog with GRC and QA. --- gr-analog/grc/analog_noise_source_x.xml | 77 ++++++++++++++++++ gr-analog/include/analog/CMakeLists.txt | 2 +- gr-analog/include/analog/noise_source_X.h.t | 68 ++++++++++++++++ gr-analog/include/analog/noise_type.h | 36 +++++++++ gr-analog/lib/CMakeLists.txt | 2 +- gr-analog/lib/noise_source_X_impl.cc.t | 116 ++++++++++++++++++++++++++++ gr-analog/lib/noise_source_X_impl.h.t | 58 ++++++++++++++ gr-analog/python/qa_noise.py | 52 +++++++++++++ gr-analog/swig/analog_swig.i | 14 ++++ 9 files changed, 423 insertions(+), 2 deletions(-) create mode 100644 gr-analog/grc/analog_noise_source_x.xml create mode 100644 gr-analog/include/analog/noise_source_X.h.t create mode 100644 gr-analog/include/analog/noise_type.h create mode 100644 gr-analog/lib/noise_source_X_impl.cc.t create mode 100644 gr-analog/lib/noise_source_X_impl.h.t create mode 100755 gr-analog/python/qa_noise.py diff --git a/gr-analog/grc/analog_noise_source_x.xml b/gr-analog/grc/analog_noise_source_x.xml new file mode 100644 index 000000000..72daaaa20 --- /dev/null +++ b/gr-analog/grc/analog_noise_source_x.xml @@ -0,0 +1,77 @@ + + + + Noise Source + gr_noise_source_x + from gnuradio import gr + gr.noise_source_$(type.fcn)($noise_type, $amp, $seed) + set_type($noise_type) + set_amplitude($amp) + + Output Type + type + enum + + + + + + + Noise Type + noise_type + gr.GR_GAUSSIAN + int + + + + + + + Amplitude + amp + 1 + real + + + Seed + seed + 0 + int + + + out + $type + + diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index 6e4c40b46..76a11a3ac 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -64,7 +64,7 @@ endmacro(expand_h) ######################################################################## # Invoke macro to generate various sources ####################################################################### -#expand_h(block bf bc sf sc if ic) +expand_h(noise_source_X s i f c) add_custom_target(analog_generated_includes DEPENDS ${generated_includes} diff --git a/gr-analog/include/analog/noise_source_X.h.t b/gr-analog/include/analog/noise_source_X.h.t new file mode 100644 index 000000000..9d1be6fed --- /dev/null +++ b/gr-analog/include/analog/noise_source_X.h.t @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 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. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include +#include +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief Random number source + * \ingroup source_blk + * + * \details + * Generate random values from different distributions. + * Currently, only Gaussian and uniform are enabled. + */ + class ANALOG_API @BASE_NAME@ : virtual public gr_sync_block + { + public: + // gr::analog::@BASE_NAME@::sptr + typedef boost::shared_ptr<@BASE_NAME@> sptr; + + /*! \brief Make a noise source + * \param type the random distribution to use (see analog/noise_type.h) + * \param ampl a scaling factor for the output + * \param seed seed for random generators. Note that for uniform and + * Gaussian distributions, this should be a negative number. + */ + static sptr make(noise_type_t type, float ampl, long seed); + + virtual void set_type(noise_type_t type) = 0; + virtual void set_amplitude(float ampl) = 0; + + virtual noise_type_t type() const = 0; + virtual float amplitude() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-analog/include/analog/noise_type.h b/gr-analog/include/analog/noise_type.h new file mode 100644 index 000000000..c3a2146b7 --- /dev/null +++ b/gr-analog/include/analog/noise_type.h @@ -0,0 +1,36 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 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_ANALOG_NOISE_TYPE_H +#define INCLUDED_ANALOG_NOISE_TYPE_H + +namespace gr { + namespace analog { + + typedef enum { + GR_UNIFORM = 200, GR_GAUSSIAN, GR_LAPLACIAN, GR_IMPULSE + } noise_type_t; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_NOISE_TYPE_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index 9faeaba80..cad0d7b91 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -96,7 +96,7 @@ endmacro(expand_cc) ######################################################################## # Invoke macro to generate various sources ######################################################################## -#expand_cc(block bf bc sf sc if ic) +expand_cc(noise_source_X_impl s i f c) ######################################################################## # Setup library diff --git a/gr-analog/lib/noise_source_X_impl.cc.t b/gr-analog/lib/noise_source_X_impl.cc.t new file mode 100644 index 000000000..35dda9c5d --- /dev/null +++ b/gr-analog/lib/noise_source_X_impl.cc.t @@ -0,0 +1,116 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012 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. + */ + +/* @WARNING@ */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "@IMPL_NAME@.h" +#include +#include + +namespace gr { + namespace analog { + + @BASE_NAME@::sptr + @BASE_NAME@::make(noise_type_t type, float ampl, long seed) + { + return gnuradio::get_initial_sptr + (new @IMPL_NAME@(type, ampl, seed)); + } + + @IMPL_NAME@::@IMPL_NAME@(noise_type_t type, float ampl, long seed) + : gr_sync_block("@BASE_NAME@", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, sizeof(@TYPE@))), + d_type(type), + d_ampl(ampl), + d_rng(seed) + { + } + + @IMPL_NAME@::~@IMPL_NAME@() + { + } + + int + @IMPL_NAME@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @TYPE@ *out = (@TYPE@*)output_items[0]; + + switch(d_type) { +#if @IS_COMPLEX@ // complex? + + case GR_UNIFORM: + for(int i = 0; i < noutput_items; i++) { + out[i] = gr_complex(d_ampl * ((d_rng.ran1() * 2.0) - 1.0), + d_ampl * ((d_rng.ran1() * 2.0) - 1.0)); + } + break; + + case GR_GAUSSIAN: + for(int i = 0; i < noutput_items; i++) { + out[i] = d_ampl * d_rng.rayleigh_complex(); + } + break; + +#else // nope... + + case GR_UNIFORM: + for(int i = 0; i < noutput_items; i++) { + out[i] = (@TYPE@)(d_ampl * ((d_rng.ran1() * 2.0) - 1.0)); + } + break; + + case GR_GAUSSIAN: + for(int i = 0; i < noutput_items; i++) { + out[i] = (@TYPE@)(d_ampl * d_rng.gasdev()); + } + break; + + case GR_LAPLACIAN: + for(int i = 0; i < noutput_items; i++) { + out[i] = (@TYPE@)(d_ampl * d_rng.laplacian()); + } + break; + + case GR_IMPULSE: // FIXME changeable impulse settings + for(int i = 0; i < noutput_items; i++) { + out[i] = (@TYPE@)(d_ampl * d_rng.impulse(9)); + } + break; +#endif + + default: + throw std::runtime_error("invalid type"); + } + + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ + diff --git a/gr-analog/lib/noise_source_X_impl.h.t b/gr-analog/lib/noise_source_X_impl.h.t new file mode 100644 index 000000000..8bcc1dfde --- /dev/null +++ b/gr-analog/lib/noise_source_X_impl.h.t @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 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. + */ + +/* @WARNING@ */ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include +#include + +namespace gr { + namespace analog { + + class @IMPL_NAME@ : public @BASE_NAME@ + { + noise_type_t d_type; + float d_ampl; + gr_random d_rng; + + public: + @IMPL_NAME@(noise_type_t type, float ampl, long seed = 0); + ~@IMPL_NAME@(); + + void set_type(noise_type_t type) { d_type = type; } + void set_amplitude(float ampl) { d_ampl = ampl; } + + noise_type_t type() const { return d_type; } + float amplitude() const { return d_ampl; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-analog/python/qa_noise.py b/gr-analog/python/qa_noise.py new file mode 100755 index 000000000..dd94fc231 --- /dev/null +++ b/gr-analog/python/qa_noise.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# +# Copyright 2007,2010,2012 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, gr_unittest +import analog_swig as analog + +class test_noise_source(gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001(self): + # Just confirm that we can instantiate a noise source + op = analog.noise_source_f(analog.GR_GAUSSIAN, 10, 10) + + def test_002(self): + # Test get methods + set_type = analog.GR_GAUSSIAN + set_ampl = 10 + op = analog.noise_source_f(set_type, set_ampl, 10) + get_type = op.type() + get_ampl = op.amplitude() + + self.assertEqual(get_type, set_type) + self.assertEqual(get_ampl, set_ampl) + + +if __name__ == '__main__': + gr_unittest.run(test_noise_source, "test_noise_source.xml") + diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 8e1bb8058..4c35f9b07 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -28,6 +28,7 @@ %{ #include "analog/cpm.h" +#include "analog/noise_type.h" #include "analog/agc_cc.h" #include "analog/agc_ff.h" #include "analog/agc2_cc.h" @@ -38,11 +39,16 @@ #include "analog/feedforward_agc_cc.h" #include "analog/fmdet_cf.h" #include "analog/frequency_modulator_fc.h" +#include "analog/noise_source_s.h" +#include "analog/noise_source_i.h" +#include "analog/noise_source_f.h" +#include "analog/noise_source_c.h" #include "analog/squelch_base_cc.h" #include "analog/squelch_base_ff.h" %} %include "analog/cpm.h" +%include "analog/noise_type.h" %include "analog/agc_cc.h" %include "analog/agc_ff.h" %include "analog/agc2_cc.h" @@ -53,6 +59,10 @@ %include "analog/feedforward_agc_cc.h" %include "analog/fmdet_cf.h" %include "analog/frequency_modulator_fc.h" +%include "analog/noise_source_s.h" +%include "analog/noise_source_i.h" +%include "analog/noise_source_f.h" +%include "analog/noise_source_c.h" %include "analog/squelch_base_cc.h" %include "analog/squelch_base_ff.h" @@ -66,3 +76,7 @@ GR_SWIG_BLOCK_MAGIC2(analog, dpll_bb); GR_SWIG_BLOCK_MAGIC2(analog, feedforward_agc_cc); GR_SWIG_BLOCK_MAGIC2(analog, fmdet_cf); GR_SWIG_BLOCK_MAGIC2(analog, frequency_modulator_fc); +GR_SWIG_BLOCK_MAGIC2(analog, noise_source_s); +GR_SWIG_BLOCK_MAGIC2(analog, noise_source_i); +GR_SWIG_BLOCK_MAGIC2(analog, noise_source_f); +GR_SWIG_BLOCK_MAGIC2(analog, noise_source_c); -- cgit From 0c47c920908bb8e1b42c8e2cc77346ccc9d28693 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 30 Oct 2012 11:23:38 -0400 Subject: analog: adding phase_modulator_fc to gr-analog with QA and GRC. --- gr-analog/grc/analog_block_tree.xml | 3 +- gr-analog/grc/analog_phase_modulator_fc.xml | 26 ++++++++++ gr-analog/include/analog/CMakeLists.txt | 1 + gr-analog/include/analog/phase_modulator_fc.h | 63 +++++++++++++++++++++++ gr-analog/lib/CMakeLists.txt | 1 + gr-analog/lib/phase_modulator_fc_impl.cc | 73 +++++++++++++++++++++++++++ gr-analog/lib/phase_modulator_fc_impl.h | 55 ++++++++++++++++++++ gr-analog/python/qa_phase_modulator.py | 58 +++++++++++++++++++++ gr-analog/swig/analog_swig.i | 3 ++ 9 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 gr-analog/grc/analog_phase_modulator_fc.xml create mode 100644 gr-analog/include/analog/phase_modulator_fc.h create mode 100644 gr-analog/lib/phase_modulator_fc_impl.cc create mode 100644 gr-analog/lib/phase_modulator_fc_impl.h create mode 100644 gr-analog/python/qa_phase_modulator.py diff --git a/gr-analog/grc/analog_block_tree.xml b/gr-analog/grc/analog_block_tree.xml index bb7a9b067..7927c1086 100644 --- a/gr-analog/grc/analog_block_tree.xml +++ b/gr-analog/grc/analog_block_tree.xml @@ -35,10 +35,11 @@ analog_feedforward_agc_cc analog_ctcss_squelch_ff analog_dpll_bb - analog_frequency_modulator_fc Modulators analog_cpfsk_bc + analog_frequency_modulator_fc + analog_phase_modulator_fc diff --git a/gr-analog/grc/analog_phase_modulator_fc.xml b/gr-analog/grc/analog_phase_modulator_fc.xml new file mode 100644 index 000000000..c13af769c --- /dev/null +++ b/gr-analog/grc/analog_phase_modulator_fc.xml @@ -0,0 +1,26 @@ + + + + Phase Mod + analog_phase_modulator_fc + from gnuradio import analog + analog.phase_modulator_fc($sensitivity) + set_sensitivity($sensitivity) + + Sensitivity + sensitivity + real + + + in + float + + + out + complex + + diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index 76a11a3ac..fded7501a 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -90,6 +90,7 @@ install(FILES feedforward_agc_cc.h fmdet_cf.h frequency_modulator_fc.h + phase_modulator_fc.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog COMPONENT "analog_devel" ) diff --git a/gr-analog/include/analog/phase_modulator_fc.h b/gr-analog/include/analog/phase_modulator_fc.h new file mode 100644 index 000000000..409de7804 --- /dev/null +++ b/gr-analog/include/analog/phase_modulator_fc.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 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_ANALOG_PHASE_MODULATOR_FC_H +#define INCLUDED_ANALOG_PHASE_MODULATOR_FC_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief Phase modulator block + * \ingroup modulation_blk + * + * output = complex(cos(in*sensitivity), sin(in*sensitivity)) + * + * Input stream 0: floats + * Ouput stream 0: complex + */ + class ANALOG_API phase_modulator_fc : virtual public gr_sync_block + { + public: + // gr::analog::phase_modulator_fc::sptr + typedef boost::shared_ptr sptr; + + /* \brief Make a phase modulator block. + * + * \param sensitivity Phase change sensitivity of input amplitude. + */ + static sptr make(double sensitivity); + + virtual double sensitivity() const = 0; + virtual double phase() const = 0; + + virtual void set_sensitivity(double s) = 0; + virtual void set_phase(double p) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PHASE_MODULATOR_FC_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index cad0d7b91..a151fbf76 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -116,6 +116,7 @@ list(APPEND analog_sources feedforward_agc_cc_impl.cc fmdet_cf_impl.cc frequency_modulator_fc_impl.cc + phase_modulator_fc_impl.cc ) list(APPEND analog_libs diff --git a/gr-analog/lib/phase_modulator_fc_impl.cc b/gr-analog/lib/phase_modulator_fc_impl.cc new file mode 100644 index 000000000..9e9e73f8c --- /dev/null +++ b/gr-analog/lib/phase_modulator_fc_impl.cc @@ -0,0 +1,73 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2010,2012 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 "phase_modulator_fc_impl.h" +#include +#include +#include + +namespace gr { + namespace analog { + + phase_modulator_fc::sptr + phase_modulator_fc::make(double sensitivity) + { + return gnuradio::get_initial_sptr + (new phase_modulator_fc_impl(sensitivity)); + } + + phase_modulator_fc_impl::phase_modulator_fc_impl(double sensitivity) + : gr_sync_block("phase_modulator_fc", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + d_sensitivity(sensitivity), d_phase(0) + { + } + + phase_modulator_fc_impl::~phase_modulator_fc_impl() + { + } + + int + phase_modulator_fc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + for(int i = 0; i < noutput_items; i++) { + d_phase = d_sensitivity * in[i]; + float oi, oq; + gr_sincosf(d_phase, &oq, &oi); + out[i] = gr_complex(oi, oq); + } + + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/phase_modulator_fc_impl.h b/gr-analog/lib/phase_modulator_fc_impl.h new file mode 100644 index 000000000..ac10bc891 --- /dev/null +++ b/gr-analog/lib/phase_modulator_fc_impl.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 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_ANALOG_PHASE_MODULATOR_FC_IMPL_H +#define INCLUDED_ANALOG_PHASE_MODULATOR_FC_IMPL_H + +#include + +namespace gr { + namespace analog { + + class phase_modulator_fc_impl : public phase_modulator_fc + { + private: + double d_sensitivity; + double d_phase; + + public: + phase_modulator_fc_impl(double sensitivity); + ~phase_modulator_fc_impl(); + + double sensitivity() const { return d_sensitivity; } + double phase() const { return d_phase; } + + void set_sensitivity(double s) { d_sensitivity = s; } + void set_phase(double p) { d_phase = p; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PHASE_MODULATOR_FC_IMPL_H */ diff --git a/gr-analog/python/qa_phase_modulator.py b/gr-analog/python/qa_phase_modulator.py new file mode 100644 index 000000000..a9c8c8459 --- /dev/null +++ b/gr-analog/python/qa_phase_modulator.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# +# Copyright 2012 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, gr_unittest +import analog_swig as analog +import math + +def sincos(x): + return math.cos(x) + math.sin(x) * 1j + + +class test_phase_modulator(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_fm_001(self): + pi = math.pi + sensitivity = pi/4 + src_data = (1.0/4, 1.0/2, 1.0/4, -1.0/4, -1.0/2, -1/4.0) + expected_result = tuple([sincos(sensitivity*x) for x in src_data]) + + src = gr.vector_source_f(src_data) + op = analog.phase_modulator_fc(sensitivity) + dst = gr.vector_sink_c() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_phase_modulator, "test_phase_modulator.xml") + diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 4c35f9b07..665da9686 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -43,6 +43,7 @@ #include "analog/noise_source_i.h" #include "analog/noise_source_f.h" #include "analog/noise_source_c.h" +#include "analog/phase_modulator_fc.h" #include "analog/squelch_base_cc.h" #include "analog/squelch_base_ff.h" %} @@ -63,6 +64,7 @@ %include "analog/noise_source_i.h" %include "analog/noise_source_f.h" %include "analog/noise_source_c.h" +%include "analog/phase_modulator_fc.h" %include "analog/squelch_base_cc.h" %include "analog/squelch_base_ff.h" @@ -80,3 +82,4 @@ GR_SWIG_BLOCK_MAGIC2(analog, noise_source_s); GR_SWIG_BLOCK_MAGIC2(analog, noise_source_i); GR_SWIG_BLOCK_MAGIC2(analog, noise_source_f); GR_SWIG_BLOCK_MAGIC2(analog, noise_source_c); +GR_SWIG_BLOCK_MAGIC2(analog, phase_modulator_fc); -- cgit From 440739593a0648f40ddaf4e6d4cd898495a9c856 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 30 Oct 2012 11:44:01 -0400 Subject: analog: fixing noise source in GRC. --- gr-analog/grc/analog_block_tree.xml | 4 ++++ gr-analog/grc/analog_noise_source_x.xml | 16 ++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/gr-analog/grc/analog_block_tree.xml b/gr-analog/grc/analog_block_tree.xml index 7927c1086..54142e623 100644 --- a/gr-analog/grc/analog_block_tree.xml +++ b/gr-analog/grc/analog_block_tree.xml @@ -42,4 +42,8 @@ analog_frequency_modulator_fc analog_phase_modulator_fc + + Sources + analog_noise_source_x + diff --git a/gr-analog/grc/analog_noise_source_x.xml b/gr-analog/grc/analog_noise_source_x.xml index 72daaaa20..5404e7896 100644 --- a/gr-analog/grc/analog_noise_source_x.xml +++ b/gr-analog/grc/analog_noise_source_x.xml @@ -6,9 +6,9 @@ --> Noise Source - gr_noise_source_x - from gnuradio import gr - gr.noise_source_$(type.fcn)($noise_type, $amp, $seed) + analog_noise_source_x + from gnuradio import analog + analog.noise_source_$(type.fcn)($noise_type, $amp, $seed) set_type($noise_type) set_amplitude($amp) @@ -39,23 +39,23 @@ Noise Type noise_type - gr.GR_GAUSSIAN + analog.GR_GAUSSIAN int -- cgit From 11cd6d2dc3e6b3b40474a5a4495d814a7688fe0a Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 30 Oct 2012 13:30:01 -0400 Subject: analog: added PLL blocks to gr-analog with QA and GRC. --- gnuradio-core/src/lib/general/gri_control_loop.cc | 23 +++ gnuradio-core/src/lib/general/gri_control_loop.h | 39 +++- gr-analog/grc/analog_block_tree.xml | 6 + gr-analog/grc/analog_pll_carriertracking_cc.xml | 38 ++++ gr-analog/grc/analog_pll_freqdet_cf.xml | 38 ++++ gr-analog/grc/analog_pll_refout_cc.xml | 38 ++++ gr-analog/include/analog/CMakeLists.txt | 3 + gr-analog/include/analog/pll_carriertracking_cc.h | 88 +++++++++ gr-analog/include/analog/pll_freqdet_cf.h | 83 ++++++++ gr-analog/include/analog/pll_refout_cc.h | 66 +++++++ gr-analog/lib/CMakeLists.txt | 3 + gr-analog/lib/pll_carriertracking_cc_impl.cc | 228 ++++++++++++++++++++++ gr-analog/lib/pll_carriertracking_cc_impl.h | 76 ++++++++ gr-analog/lib/pll_freqdet_cf_impl.cc | 198 +++++++++++++++++++ gr-analog/lib/pll_freqdet_cf_impl.h | 70 +++++++ gr-analog/lib/pll_refout_cc_impl.cc | 201 +++++++++++++++++++ gr-analog/lib/pll_refout_cc_impl.h | 69 +++++++ gr-analog/python/qa_pll_carriertracking.py | 157 +++++++++++++++ gr-analog/python/qa_pll_freqdet.py | 161 +++++++++++++++ gr-analog/python/qa_pll_refout.py | 157 +++++++++++++++ gr-analog/swig/analog_swig.i | 9 + 21 files changed, 1745 insertions(+), 6 deletions(-) create mode 100644 gr-analog/grc/analog_pll_carriertracking_cc.xml create mode 100644 gr-analog/grc/analog_pll_freqdet_cf.xml create mode 100644 gr-analog/grc/analog_pll_refout_cc.xml create mode 100644 gr-analog/include/analog/pll_carriertracking_cc.h create mode 100644 gr-analog/include/analog/pll_freqdet_cf.h create mode 100644 gr-analog/include/analog/pll_refout_cc.h create mode 100644 gr-analog/lib/pll_carriertracking_cc_impl.cc create mode 100644 gr-analog/lib/pll_carriertracking_cc_impl.h create mode 100644 gr-analog/lib/pll_freqdet_cf_impl.cc create mode 100644 gr-analog/lib/pll_freqdet_cf_impl.h create mode 100644 gr-analog/lib/pll_refout_cc_impl.cc create mode 100644 gr-analog/lib/pll_refout_cc_impl.h create mode 100755 gr-analog/python/qa_pll_carriertracking.py create mode 100755 gr-analog/python/qa_pll_freqdet.py create mode 100755 gr-analog/python/qa_pll_refout.py diff --git a/gnuradio-core/src/lib/general/gri_control_loop.cc b/gnuradio-core/src/lib/general/gri_control_loop.cc index 5a93737f9..bb3c4a326 100644 --- a/gnuradio-core/src/lib/general/gri_control_loop.cc +++ b/gnuradio-core/src/lib/general/gri_control_loop.cc @@ -144,6 +144,17 @@ gri_control_loop::set_phase(float phase) d_phase += M_TWOPI; } +void +gri_control_loop::set_max_freq(float freq) +{ + d_max_freq = freq; +} + +void +gri_control_loop::set_min_freq(float freq) +{ + d_min_freq = freq; +} /******************************************************************* GET FUNCTIONS @@ -185,3 +196,15 @@ gri_control_loop::get_phase() const { return d_phase; } + +float +gri_control_loop::get_max_freq() const +{ + return d_max_freq; +} + +float +gri_control_loop::get_min_freq() const +{ + return d_min_freq; +} diff --git a/gnuradio-core/src/lib/general/gri_control_loop.h b/gnuradio-core/src/lib/general/gri_control_loop.h index df260d2cf..304857ac7 100644 --- a/gnuradio-core/src/lib/general/gri_control_loop.h +++ b/gnuradio-core/src/lib/general/gri_control_loop.h @@ -141,9 +141,9 @@ class GR_CORE_API gri_control_loop void set_beta(float beta); /*! - * \brief Set the Costas loop's frequency. + * \brief Set the control loop's frequency. * - * Set's the Costas Loop's frequency. While this is normally updated by the + * Set's the control loop's frequency. While this is normally updated by the * inner loop of the algorithm, it could be useful to manually initialize, * set, or reset this under certain circumstances. * @@ -153,9 +153,9 @@ class GR_CORE_API gri_control_loop void set_frequency(float freq); /*! - * \brief Set the Costas loop's phase. + * \brief Set the control loop's phase. * - * Set's the Costas Loop's phase. While this is normally updated by the + * Set's the control loop's phase. While this is normally updated by the * inner loop of the algorithm, it could be useful to manually initialize, * set, or reset this under certain circumstances. * @@ -164,6 +164,23 @@ class GR_CORE_API gri_control_loop */ void set_phase(float phase); + /*! + * \brief Set the control loop's maximum frequency. + * + * Set the maximum frequency the control loop can track. + * + * \param freq (float) new max frequency + */ + void set_max_freq(float freq); + + /*! + * \brief Set the control loop's minimum frequency. + * + * Set the minimum frequency the control loop can track. + * + * \param freq (float) new min frequency + */ + void set_min_freq(float freq); /******************************************************************* GET FUNCTIONS @@ -190,14 +207,24 @@ class GR_CORE_API gri_control_loop float get_beta() const; /*! - * \brief Get the Costas loop's frequency estimate + * \brief Get the control loop's frequency estimate */ float get_frequency() const; /*! - * \brief Get the Costas loop's phase estimate + * \brief Get the control loop's phase estimate */ float get_phase() const; + + /*! + * \brief Get the control loop's maximum frequency. + */ + float get_max_freq() const; + + /*! + * \brief Get the control loop's minimum frequency. + */ + float get_min_freq() const; }; #endif /* GRI_CONTROL_LOOP */ diff --git a/gr-analog/grc/analog_block_tree.xml b/gr-analog/grc/analog_block_tree.xml index 54142e623..7283d9f5a 100644 --- a/gr-analog/grc/analog_block_tree.xml +++ b/gr-analog/grc/analog_block_tree.xml @@ -46,4 +46,10 @@ Sources analog_noise_source_x + + Synchronizers + analog_pll_carriertracking_cc + analog_pll_freqdet_cf + analog_pll_refout_cc + diff --git a/gr-analog/grc/analog_pll_carriertracking_cc.xml b/gr-analog/grc/analog_pll_carriertracking_cc.xml new file mode 100644 index 000000000..95ec4b415 --- /dev/null +++ b/gr-analog/grc/analog_pll_carriertracking_cc.xml @@ -0,0 +1,38 @@ + + + + PLL Carrier Tracking + analog_pll_carriertracking_cc + from gnuradio import analog + analog.pll_carriertracking_cc($w, $max_freq, $min_freq) + set_loop_bandwidth($w) + set_max_freq($max_freq) + set_min_freq($min_freq) + + Loop Bandwidth + w + real + + + Max Freq + max_freq + real + + + Min Freq + min_freq + real + + + in + complex + + + out + complex + + diff --git a/gr-analog/grc/analog_pll_freqdet_cf.xml b/gr-analog/grc/analog_pll_freqdet_cf.xml new file mode 100644 index 000000000..0d44c160b --- /dev/null +++ b/gr-analog/grc/analog_pll_freqdet_cf.xml @@ -0,0 +1,38 @@ + + + + PLL Freq Det + analog_pll_freqdet_cf + from gnuradio import analog + analog.pll_freqdet_cf($w, $max_freq, $min_freq) + set_loop_bandwidth($w) + set_max_freq($max_freq) + set_min_freq($min_freq) + + Loop Bandwidth + w + real + + + Max Freq + max_freq + real + + + Min Freq + min_freq + real + + + in + complex + + + out + float + + diff --git a/gr-analog/grc/analog_pll_refout_cc.xml b/gr-analog/grc/analog_pll_refout_cc.xml new file mode 100644 index 000000000..eb2d752b2 --- /dev/null +++ b/gr-analog/grc/analog_pll_refout_cc.xml @@ -0,0 +1,38 @@ + + + + PLL Ref Out + analog_pll_refout_cc + from gnuradio import analog + analog.pll_refout_cc($w, $max_freq, $min_freq) + set_loop_bandwidth($w) + set_max_freq($max_freq) + set_min_freq($min_freq) + + Loop Bandwidth + w + real + + + Max Freq + max_freq + real + + + Min Freq + min_freq + real + + + in + complex + + + out + complex + + diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index fded7501a..ac1d65932 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -91,6 +91,9 @@ install(FILES fmdet_cf.h frequency_modulator_fc.h phase_modulator_fc.h + pll_carriertracking_cc.h + pll_freqdet_cf.h + pll_refout_cc.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog COMPONENT "analog_devel" ) diff --git a/gr-analog/include/analog/pll_carriertracking_cc.h b/gr-analog/include/analog/pll_carriertracking_cc.h new file mode 100644 index 000000000..3596429d4 --- /dev/null +++ b/gr-analog/include/analog/pll_carriertracking_cc.h @@ -0,0 +1,88 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2011,2012 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_ANALOG_PLL_CARRIERTRACKING_CC_H +#define INCLUDED_ANALOG_PLL_CARRIERTRACKING_CC_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief Implements a PLL which locks to the input frequency and outputs the + * input signal mixed with that carrier. + * \ingroup sync_blk + * + * Input stream 0: complex + * Output stream 0: complex + * + * This PLL locks onto a [possibly noisy] reference carrier on the + * input and outputs that signal, downconverted to DC + * + * All settings max_freq and min_freq are in terms of radians per + * sample, NOT HERTZ. The loop bandwidth determins the lock range + * and should be set around pi/200 -- 2pi/100. \sa + * pll_freqdet_cf, pll_carriertracking_cc + */ + class ANALOG_API pll_carriertracking_cc : virtual public gr_sync_block + { + public: + // gr::analog::pll_carriertracking_cc::sptr + typedef boost::shared_ptr sptr; + + /* \brief Make a carrier tracking PLL block. + * + * \param loop_bw: control loop's bandwidth parameter. + * \param max_freq: maximum (normalized) frequency PLL will lock to. + * \param min_freq: minimum (normalized) frequency PLL will lock to. + */ + static sptr make(float loop_bw, float max_freq, float min_freq); + + virtual bool lock_detector(void) = 0; + virtual bool squelch_enable(bool) = 0; + virtual float set_lock_threshold(float) = 0; + + virtual void set_loop_bandwidth(float bw) = 0; + virtual void set_damping_factor(float df) = 0; + virtual void set_alpha(float alpha) = 0; + virtual void set_beta(float beta) = 0; + virtual void set_frequency(float freq) = 0; + virtual void set_phase(float phase) = 0; + virtual void set_min_freq(float freq) = 0; + virtual void set_max_freq(float freq) = 0; + + virtual float get_loop_bandwidth() const = 0; + virtual float get_damping_factor() const = 0; + virtual float get_alpha() const = 0; + virtual float get_beta() const = 0; + virtual float get_frequency() const = 0; + virtual float get_phase() const = 0; + virtual float get_min_freq() const = 0; + virtual float get_max_freq() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PLL_CARRIERTRACKING_CC_H */ diff --git a/gr-analog/include/analog/pll_freqdet_cf.h b/gr-analog/include/analog/pll_freqdet_cf.h new file mode 100644 index 000000000..613e85263 --- /dev/null +++ b/gr-analog/include/analog/pll_freqdet_cf.h @@ -0,0 +1,83 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2011 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_ANALOG_PLL_FREQDET_CF_H +#define INCLUDED_ANALOG_PLL_FREQDET_CF_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief Implements a PLL which locks to the input frequency and outputs + * an estimate of that frequency. Useful for FM Demod. + * \ingroup sync_blk + * + * Input stream 0: complex + * Output stream 0: float + * + * This PLL locks onto a [possibly noisy] reference carrier on + * the input and outputs an estimate of that frequency in radians per sample. + * All settings max_freq and min_freq are in terms of radians per sample, + * NOT HERTZ. The loop bandwidth determins the lock range and should be set + * around pi/200 -- 2pi/100. + * \sa pll_refout_cc, pll_carriertracking_cc + */ + class ANALOG_API pll_freqdet_cf : virtual public gr_sync_block + { + public: + // gr::analog::pll_freqdet_cf::sptr + typedef boost::shared_ptr sptr; + + /* \brief Make PLL block that outputs the tracked signal's frequency. + * + * \param loop_bw: control loop's bandwidth parameter. + * \param max_freq: maximum (normalized) frequency PLL will lock to. + * \param min_freq: minimum (normalized) frequency PLL will lock to. + */ + static sptr make(float loop_bw, float max_freq, float min_freq); + + virtual void set_loop_bandwidth(float bw) = 0; + virtual void set_damping_factor(float df) = 0; + virtual void set_alpha(float alpha) = 0; + virtual void set_beta(float beta) = 0; + virtual void set_frequency(float freq) = 0; + virtual void set_phase(float phase) = 0; + virtual void set_min_freq(float freq) = 0; + virtual void set_max_freq(float freq) = 0; + + virtual float get_loop_bandwidth() const = 0; + virtual float get_damping_factor() const = 0; + virtual float get_alpha() const = 0; + virtual float get_beta() const = 0; + virtual float get_frequency() const = 0; + virtual float get_phase() const = 0; + virtual float get_min_freq() const = 0; + virtual float get_max_freq() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PLL_FREQDET_CF_H */ diff --git a/gr-analog/include/analog/pll_refout_cc.h b/gr-analog/include/analog/pll_refout_cc.h new file mode 100644 index 000000000..a18d177e6 --- /dev/null +++ b/gr-analog/include/analog/pll_refout_cc.h @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2011,2012 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_ANALOG_PLL_REFOUT_CC_H +#define INCLUDED_ANALOG_PLL_REFOUT_CC_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief Implements a PLL which locks to the input frequency and outputs a carrier + * \ingroup sync_blk + * + * Input stream 0: complex + * Output stream 0: complex + * + * This PLL locks onto a [possibly noisy] reference carrier on the + * input and outputs a clean version which is phase and frequency + * aligned to it. + * + * All settings max_freq and min_freq are in terms of radians per + * sample, NOT HERTZ. The loop bandwidth determins the lock range + * and should be set around pi/200 -- 2pi/100. \sa + * pll_freqdet_cf, pll_carriertracking_cc + */ + class ANALOG_API pll_refout_cc : virtual public gr_sync_block + { + public: + // gr::analog::pll_refout_cc::sptr + typedef boost::shared_ptr sptr; + + /* \brief Make PLL block that outputs the tracked carrier signal. + * + * \param loop_bw: control loop's bandwidth parameter. + * \param max_freq: maximum (normalized) frequency PLL will lock to. + * \param min_freq: minimum (normalized) frequency PLL will lock to. + */ + static sptr make(float loop_bw, float max_freq, float min_freq); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PLL_REFOUT_CC_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index a151fbf76..20a86621e 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -117,6 +117,9 @@ list(APPEND analog_sources fmdet_cf_impl.cc frequency_modulator_fc_impl.cc phase_modulator_fc_impl.cc + pll_carriertracking_cc_impl.cc + pll_freqdet_cf_impl.cc + pll_refout_cc_impl.cc ) list(APPEND analog_libs diff --git a/gr-analog/lib/pll_carriertracking_cc_impl.cc b/gr-analog/lib/pll_carriertracking_cc_impl.cc new file mode 100644 index 000000000..c53e0f433 --- /dev/null +++ b/gr-analog/lib/pll_carriertracking_cc_impl.cc @@ -0,0 +1,228 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2010-2012 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 "pll_carriertracking_cc_impl.h" +#include +#include +#include +#include + +namespace gr { + namespace analog { + +#ifndef M_TWOPI +#define M_TWOPI (2.0f*M_PI) +#endif + + pll_carriertracking_cc::sptr + pll_carriertracking_cc::make(float loop_bw, float max_freq, float min_freq) + { + return gnuradio::get_initial_sptr + (new pll_carriertracking_cc_impl(loop_bw, max_freq, min_freq)); + } + + pll_carriertracking_cc_impl::pll_carriertracking_cc_impl(float loop_bw, + float max_freq, + float min_freq) + : gr_sync_block("pll_carriertracking_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + gri_control_loop(loop_bw, max_freq, min_freq), + d_locksig(0), d_lock_threshold(0), d_squelch_enable(false) + { + } + + pll_carriertracking_cc_impl::~pll_carriertracking_cc_impl() + { + } + + float + pll_carriertracking_cc_impl::mod_2pi(float in) + { + if(in>M_PI) + return in-M_TWOPI; + else if(in<-M_PI) + return in+M_TWOPI; + else + return in; + } + + float + pll_carriertracking_cc_impl::phase_detector(gr_complex sample, float ref_phase) + { + float sample_phase; + // sample_phase = atan2(sample.imag(),sample.real()); + sample_phase = gr_fast_atan2f(sample.imag(),sample.real()); + return mod_2pi(sample_phase-ref_phase); + } + + bool + pll_carriertracking_cc_impl::lock_detector(void) + { + return (fabsf(d_locksig) > d_lock_threshold); + } + + bool + pll_carriertracking_cc_impl::squelch_enable(bool set_squelch) + { + return d_squelch_enable = set_squelch; + } + + float + pll_carriertracking_cc_impl::set_lock_threshold(float threshold) + { + return d_lock_threshold = threshold; + } + + int + pll_carriertracking_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *iptr = (gr_complex*)input_items[0]; + gr_complex *optr = (gr_complex*)output_items[0]; + + float error; + float t_imag, t_real; + + for(int i = 0; i < noutput_items; i++) { + gr_sincosf(d_phase, &t_imag, &t_real); + optr[i] = iptr[i] * gr_complex(t_real, -t_imag); + + error = phase_detector(iptr[i], d_phase); + + advance_loop(error); + phase_wrap(); + frequency_limit(); + + d_locksig = d_locksig * (1.0 - d_alpha) + \ + d_alpha*(iptr[i].real() * t_real + iptr[i].imag() * t_imag); + + if((d_squelch_enable) && !lock_detector()) + optr[i] = 0; + } + return noutput_items; + } + + void + pll_carriertracking_cc_impl::set_loop_bandwidth(float bw) + { + gri_control_loop::set_loop_bandwidth(bw); + } + + void + pll_carriertracking_cc_impl::set_damping_factor(float df) + { + gri_control_loop::set_damping_factor(df); + } + + void + pll_carriertracking_cc_impl::set_alpha(float alpha) + { + gri_control_loop::set_alpha(alpha); + } + + void + pll_carriertracking_cc_impl::set_beta(float beta) + { + gri_control_loop::set_beta(beta); + } + + void + pll_carriertracking_cc_impl::set_frequency(float freq) + { + gri_control_loop::set_frequency(freq); + } + + void + pll_carriertracking_cc_impl::set_phase(float phase) + { + gri_control_loop::set_phase(phase); + } + + void + pll_carriertracking_cc_impl::set_min_freq(float freq) + { + gri_control_loop::set_min_freq(freq); + } + + void + pll_carriertracking_cc_impl::set_max_freq(float freq) + { + gri_control_loop::set_max_freq(freq); + } + + + float + pll_carriertracking_cc_impl::get_loop_bandwidth() const + { + return gri_control_loop::get_loop_bandwidth(); + } + + float + pll_carriertracking_cc_impl::get_damping_factor() const + { + return gri_control_loop::get_damping_factor(); + } + + float + pll_carriertracking_cc_impl::get_alpha() const + { + return gri_control_loop::get_alpha(); + } + + float + pll_carriertracking_cc_impl::get_beta() const + { + return gri_control_loop::get_beta(); + } + + float + pll_carriertracking_cc_impl::get_frequency() const + { + return gri_control_loop::get_frequency(); + } + + float + pll_carriertracking_cc_impl::get_phase() const + { + return gri_control_loop::get_phase(); + } + + float + pll_carriertracking_cc_impl::get_min_freq() const + { + return gri_control_loop::get_min_freq(); + } + + float + pll_carriertracking_cc_impl::get_max_freq() const + { + return gri_control_loop::get_max_freq(); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/pll_carriertracking_cc_impl.h b/gr-analog/lib/pll_carriertracking_cc_impl.h new file mode 100644 index 000000000..d67223db8 --- /dev/null +++ b/gr-analog/lib/pll_carriertracking_cc_impl.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2011,2012 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_ANALOG_PLL_CARRIERTRACKING_CC_IMPL_H +#define INCLUDED_ANALOG_PLL_CARRIERTRACKING_CC_IMPL_H + +#include +#include + +namespace gr { + namespace analog { + + class pll_carriertracking_cc_impl + : public pll_carriertracking_cc, public gri_control_loop + { + private: + float d_locksig,d_lock_threshold; + bool d_squelch_enable; + + float mod_2pi(float in); + float phase_detector(gr_complex sample,float ref_phase); + + public: + pll_carriertracking_cc_impl(float loop_bw, float max_freq, float min_freq); + ~pll_carriertracking_cc_impl(); + + bool lock_detector(void); + bool squelch_enable(bool); + float set_lock_threshold(float); + + void set_loop_bandwidth(float bw); + void set_damping_factor(float df); + void set_alpha(float alpha); + void set_beta(float beta); + void set_frequency(float freq); + void set_phase(float phase); + void set_min_freq(float freq); + void set_max_freq(float freq); + + float get_loop_bandwidth() const; + float get_damping_factor() const; + float get_alpha() const; + float get_beta() const; + float get_frequency() const; + float get_phase() const; + float get_min_freq() const; + float get_max_freq() const; + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PLL_CARRIERTRACKING_CC_IMPL_H */ diff --git a/gr-analog/lib/pll_freqdet_cf_impl.cc b/gr-analog/lib/pll_freqdet_cf_impl.cc new file mode 100644 index 000000000..27e8d02aa --- /dev/null +++ b/gr-analog/lib/pll_freqdet_cf_impl.cc @@ -0,0 +1,198 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2011 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 "pll_freqdet_cf_impl.h" +#include +#include +#include + +namespace gr { + namespace analog { + +#ifndef M_TWOPI +#define M_TWOPI (2.0f*M_PI) +#endif + + pll_freqdet_cf::sptr + pll_freqdet_cf::make(float loop_bw, float max_freq, float min_freq) + { + return gnuradio::get_initial_sptr + (new pll_freqdet_cf_impl(loop_bw, max_freq, min_freq)); + } + + pll_freqdet_cf_impl::pll_freqdet_cf_impl(float loop_bw, float max_freq, float min_freq) + : gr_sync_block("pll_freqdet_cf", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(float))), + gri_control_loop(loop_bw, max_freq, min_freq) + { + } + + pll_freqdet_cf_impl::~pll_freqdet_cf_impl() + { + } + + float + pll_freqdet_cf_impl::mod_2pi(float in) + { + if(in > M_PI) + return in - M_TWOPI; + else if(in < -M_PI) + return in + M_TWOPI; + else + return in; + } + + float + pll_freqdet_cf_impl::phase_detector(gr_complex sample, float ref_phase) + { + float sample_phase; + sample_phase = gr_fast_atan2f(sample.imag(), sample.real()); + return mod_2pi(sample_phase - ref_phase); + } + + int + pll_freqdet_cf_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *iptr = (gr_complex*)input_items[0]; + float *optr = (float*)output_items[0]; + + float error; + int size = noutput_items; + + while(size-- > 0) { + *optr++ = d_freq; + + error = phase_detector(*iptr++, d_phase); + + advance_loop(error); + phase_wrap(); + frequency_limit(); + } + return noutput_items; + } + + void + pll_freqdet_cf_impl::set_loop_bandwidth(float bw) + { + gri_control_loop::set_loop_bandwidth(bw); + } + + void + pll_freqdet_cf_impl::set_damping_factor(float df) + { + gri_control_loop::set_damping_factor(df); + } + + void + pll_freqdet_cf_impl::set_alpha(float alpha) + { + gri_control_loop::set_alpha(alpha); + } + + void + pll_freqdet_cf_impl::set_beta(float beta) + { + gri_control_loop::set_beta(beta); + } + + void + pll_freqdet_cf_impl::set_frequency(float freq) + { + gri_control_loop::set_frequency(freq); + } + + void + pll_freqdet_cf_impl::set_phase(float phase) + { + gri_control_loop::set_phase(phase); + } + + void + pll_freqdet_cf_impl::set_min_freq(float freq) + { + gri_control_loop::set_min_freq(freq); + } + + void + pll_freqdet_cf_impl::set_max_freq(float freq) + { + gri_control_loop::set_max_freq(freq); + } + + + float + pll_freqdet_cf_impl::get_loop_bandwidth() const + { + return gri_control_loop::get_loop_bandwidth(); + } + + float + pll_freqdet_cf_impl::get_damping_factor() const + { + return gri_control_loop::get_damping_factor(); + } + + float + pll_freqdet_cf_impl::get_alpha() const + { + return gri_control_loop::get_alpha(); + } + + float + pll_freqdet_cf_impl::get_beta() const + { + return gri_control_loop::get_beta(); + } + + float + pll_freqdet_cf_impl::get_frequency() const + { + return gri_control_loop::get_frequency(); + } + + float + pll_freqdet_cf_impl::get_phase() const + { + return gri_control_loop::get_phase(); + } + + float + pll_freqdet_cf_impl::get_min_freq() const + { + return gri_control_loop::get_min_freq(); + } + + float + pll_freqdet_cf_impl::get_max_freq() const + { + return gri_control_loop::get_max_freq(); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/pll_freqdet_cf_impl.h b/gr-analog/lib/pll_freqdet_cf_impl.h new file mode 100644 index 000000000..7acf53ebb --- /dev/null +++ b/gr-analog/lib/pll_freqdet_cf_impl.h @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2011,2012 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_ANALOG_PLL_FREQDET_CF_IMPL_H +#define INCLUDED_ANALOG_PLL_FREQDET_CF_IMPL_H + +#include +#include + +namespace gr { + namespace analog { + + class pll_freqdet_cf_impl : + public pll_freqdet_cf, public gri_control_loop + { + private: + float phase_detector(gr_complex sample,float ref_phase); + + public: + pll_freqdet_cf_impl(float loop_bw, float max_freq, float min_freq); + ~pll_freqdet_cf_impl(); + + float mod_2pi(float in); + + void set_loop_bandwidth(float bw); + void set_damping_factor(float df); + void set_alpha(float alpha); + void set_beta(float beta); + void set_frequency(float freq); + void set_phase(float phase); + void set_min_freq(float freq); + void set_max_freq(float freq); + + float get_loop_bandwidth() const; + float get_damping_factor() const; + float get_alpha() const; + float get_beta() const; + float get_frequency() const; + float get_phase() const; + float get_min_freq() const; + float get_max_freq() const; + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PLL_FREQDET_CF_IMPL_H */ diff --git a/gr-analog/lib/pll_refout_cc_impl.cc b/gr-analog/lib/pll_refout_cc_impl.cc new file mode 100644 index 000000000..b94e3660a --- /dev/null +++ b/gr-analog/lib/pll_refout_cc_impl.cc @@ -0,0 +1,201 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010-2012 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 "pll_refout_cc_impl.h" +#include +#include +#include +#include + +namespace gr { + namespace analog { + +#ifndef M_TWOPI +#define M_TWOPI (2.0f*M_PI) +#endif + + pll_refout_cc::sptr + pll_refout_cc::make(float loop_bw, float max_freq, float min_freq) + { + return gnuradio::get_initial_sptr + (new pll_refout_cc_impl(loop_bw, max_freq, min_freq)); + } + + pll_refout_cc_impl::pll_refout_cc_impl(float loop_bw, float max_freq, float min_freq) + : gr_sync_block("pll_refout_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + gri_control_loop(loop_bw, max_freq, min_freq) + { + } + + pll_refout_cc_impl::~pll_refout_cc_impl() + { + } + + float + pll_refout_cc_impl::mod_2pi(float in) + { + if(in > M_PI) + return in - M_TWOPI; + else if(in < -M_PI) + return in+ M_TWOPI; + else + return in; + } + + float + pll_refout_cc_impl::phase_detector(gr_complex sample,float ref_phase) + { + float sample_phase; + sample_phase = gr_fast_atan2f(sample.imag(),sample.real()); + return mod_2pi(sample_phase-ref_phase); + } + + int + pll_refout_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *iptr = (gr_complex*)input_items[0]; + gr_complex *optr = (gr_complex*)output_items[0]; + + float error; + float t_imag, t_real; + int size = noutput_items; + + while(size-- > 0) { + gr_sincosf(d_phase,&t_imag,&t_real); + *optr++ = gr_complex(t_real,t_imag); + + error = phase_detector(*iptr++,d_phase); + + advance_loop(error); + phase_wrap(); + frequency_limit(); + } + return noutput_items; + } + + void + pll_refout_cc_impl::set_loop_bandwidth(float bw) + { + gri_control_loop::set_loop_bandwidth(bw); + } + + void + pll_refout_cc_impl::set_damping_factor(float df) + { + gri_control_loop::set_damping_factor(df); + } + + void + pll_refout_cc_impl::set_alpha(float alpha) + { + gri_control_loop::set_alpha(alpha); + } + + void + pll_refout_cc_impl::set_beta(float beta) + { + gri_control_loop::set_beta(beta); + } + + void + pll_refout_cc_impl::set_frequency(float freq) + { + gri_control_loop::set_frequency(freq); + } + + void + pll_refout_cc_impl::set_phase(float phase) + { + gri_control_loop::set_phase(phase); + } + + void + pll_refout_cc_impl::set_min_freq(float freq) + { + gri_control_loop::set_min_freq(freq); + } + + void + pll_refout_cc_impl::set_max_freq(float freq) + { + gri_control_loop::set_max_freq(freq); + } + + + float + pll_refout_cc_impl::get_loop_bandwidth() const + { + return gri_control_loop::get_loop_bandwidth(); + } + + float + pll_refout_cc_impl::get_damping_factor() const + { + return gri_control_loop::get_damping_factor(); + } + + float + pll_refout_cc_impl::get_alpha() const + { + return gri_control_loop::get_alpha(); + } + + float + pll_refout_cc_impl::get_beta() const + { + return gri_control_loop::get_beta(); + } + + float + pll_refout_cc_impl::get_frequency() const + { + return gri_control_loop::get_frequency(); + } + + float + pll_refout_cc_impl::get_phase() const + { + return gri_control_loop::get_phase(); + } + + float + pll_refout_cc_impl::get_min_freq() const + { + return gri_control_loop::get_min_freq(); + } + + float + pll_refout_cc_impl::get_max_freq() const + { + return gri_control_loop::get_max_freq(); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/pll_refout_cc_impl.h b/gr-analog/lib/pll_refout_cc_impl.h new file mode 100644 index 000000000..9e8ae286b --- /dev/null +++ b/gr-analog/lib/pll_refout_cc_impl.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2011,2012 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_ANALOG_PLL_REFOUT_CC_IMPL_H +#define INCLUDED_ANALOG_PLL_REFOUT_CC_IMPL_H + +#include +#include + +namespace gr { + namespace analog { + + class pll_refout_cc_impl + : public pll_refout_cc, public gri_control_loop + { + private: + float mod_2pi (float in); + float phase_detector(gr_complex sample, float ref_phase); + + public: + pll_refout_cc_impl(float loop_bw, float max_freq, float min_freq); + ~pll_refout_cc_impl(); + + void set_loop_bandwidth(float bw); + void set_damping_factor(float df); + void set_alpha(float alpha); + void set_beta(float beta); + void set_frequency(float freq); + void set_phase(float phase); + void set_min_freq(float freq); + void set_max_freq(float freq); + + float get_loop_bandwidth() const; + float get_damping_factor() const; + float get_alpha() const; + float get_beta() const; + float get_frequency() const; + float get_phase() const; + float get_min_freq() const; + float get_max_freq() const; + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PLL_REFOUT_CC_IMPL_H */ diff --git a/gr-analog/python/qa_pll_carriertracking.py b/gr-analog/python/qa_pll_carriertracking.py new file mode 100755 index 000000000..a292059d1 --- /dev/null +++ b/gr-analog/python/qa_pll_carriertracking.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010-2012 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, gr_unittest +import analog_swig as analog +import math + +class test_pll_carriertracking(gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block() + + def tearDown (self): + self.tb = None + + def test_pll_carriertracking(self): + expected_result = ((1.00000238419+7.21919457547e-09j), + (0.998025715351+0.062790453434j), + (0.992777824402+0.119947694242j), + (0.985192835331+0.171441286802j), + (0.976061582565+0.217501848936j), + (0.966034710407+0.258409559727j), + (0.95565611124+0.294477283955j), + (0.945357382298+0.326030552387j), + (0.935475051403+0.353395611048j), + (0.926258146763+0.376889169216j), + (0.917895197868+0.39681750536j), + (0.910515546799+0.413470208645j), + (0.904196679592+0.427117019892j), + (0.898972511292+0.438006043434j), + (0.894769787788+0.446523308754j), + (0.891652584076+0.452715367079j), + (0.8895829916+0.456773489714j), + (0.888502895832+0.458873122931j), + (0.888343691826+0.459175437689j), + (0.889035582542+0.457833081484j), + (0.890497922897+0.454985737801j), + (0.892645597458+0.450762689114j), + (0.895388305187+0.445282936096j), + (0.898648142815+0.438664674759j), + (0.902342617512+0.431016951799j), + (0.906392872334+0.422441422939j), + (0.910642921925+0.413191765547j), + (0.915039420128+0.403358519077j), + (0.919594764709+0.392864197493j), + (0.92425006628+0.381792247295j), + (0.928944349289+0.370217680931j), + (0.933634519577+0.358220815659j), + (0.938279032707+0.345874190331j), + (0.942840516567+0.333247303963j), + (0.947280526161+0.32040438056j), + (0.951574921608+0.307409763336j), + (0.955703914165+0.294323593378j), + (0.959648966789+0.281201630831j), + (0.963392794132+0.268095195293j), + (0.966880619526+0.255221515894j), + (0.970162451267+0.242447137833j), + (0.973235487938+0.229809194803j), + (0.97609680891+0.217341512442j), + (0.978744983673+0.20507311821j), + (0.981189727783+0.193033605814j), + (0.983436584473+0.181248426437j), + (0.985490739346+0.169738590717j), + (0.987353682518+0.158523857594j), + (0.989041447639+0.147622272372j), + (0.990563035011+0.137049794197j), + (0.991928339005+0.126818582416j), + (0.993117690086+0.117111675441j), + (0.994156062603+0.107930034399j), + (0.995076179504+0.0990980416536j), + (0.995887458324+0.0906178802252j), + (0.996591091156+0.0824909061193j), + (0.997202515602+0.0747182965279j), + (0.997730851173+0.0672992765903j), + (0.998185396194+0.0602316558361j), + (0.99856698513+0.0535135567188j), + (0.998885989189+0.0471420884132j), + (0.99915266037+0.0411129891872j), + (0.999372899532+0.0354214012623j), + (0.999548316002+0.0300626158714j), + (0.999680638313+0.0252036750317j), + (0.999784469604+0.020652115345j), + (0.999865531921+0.0163950324059j), + (0.999923825264+0.0124222636223j), + (0.999960243702+0.00872156023979j), + (0.999983668327+0.00528120994568j), + (0.999997138977+0.00209015607834j), + (1.00000119209-0.00086285173893j), + (0.999992132187-0.00358882546425j), + (0.999979138374-0.00609711557627j), + (0.999963641167-0.00839691981673j), + (0.999947249889-0.0104993218556j), + (0.999924004078-0.0122378543019j), + (0.999904811382-0.0136305987835j), + (0.999888062477-0.0148707330227j), + (0.9998742342-0.0159679055214j), + (0.999856114388-0.0169314742088j), + (0.999839782715-0.0177700817585j), + (0.999826967716-0.0184917747974j), + (0.999818325043-0.0191045701504j), + (0.999807476997-0.0196143388748j), + (0.999797284603-0.0200265944004j), + (0.999791204929-0.0203481912613j), + (0.99978852272-0.0205836892128j), + (0.99978530407-0.0207380950451j), + (0.999785065651-0.0206423997879j), + (0.999787807465-0.0204866230488j), + (0.999794304371-0.0202808082104j), + (0.999800384045-0.0200312435627j), + (0.999803245068-0.0197458267212j), + (0.9998087883-0.0194311738014j), + (0.999816894531-0.0190933048725j), + (0.999825954437-0.0187371373177j), + (0.999829888344-0.0183679759502j), + (0.999835848808-0.017987690866j), + (0.999844014645-0.0176006518304j)) + + sampling_freq = 10e3 + freq = sampling_freq / 100 + + loop_bw = math.pi/100.0 + maxf = 1 + minf = -1 + + src = gr.sig_source_c(sampling_freq, gr.GR_COS_WAVE, freq, 1.0) + pll = analog.pll_carriertracking_cc(loop_bw, maxf, minf) + head = gr.head(gr.sizeof_gr_complex, int (freq)) + dst = gr.vector_sink_c() + + self.tb.connect(src, pll, head) + self.tb.connect(head, dst) + + self.tb.run() + dst_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_pll_carriertracking, "test_pll_carriertracking.xml") diff --git a/gr-analog/python/qa_pll_freqdet.py b/gr-analog/python/qa_pll_freqdet.py new file mode 100755 index 000000000..1f808afa6 --- /dev/null +++ b/gr-analog/python/qa_pll_freqdet.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010-2012 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, gr_unittest +import analog_swig as analog +import math + +class test_pll_freqdet(gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block() + + def tearDown (self): + self.tb = None + + def test_pll_freqdet(self): + expected_result = (0.0, + 4.33888922882e-08, + 0.367369994515, + 1.08135249597, + 2.10983253908, + 3.42221529438, + 4.98940390402, + 6.78379190842, + 8.77923286024, + 10.9510106794, + 13.2758363182, + 15.7317829127, + 18.2982902299, + 20.9561068599, + 23.6755271122, + 26.452952094, + 29.2731265301, + 32.1219053479, + 34.9862418188, + 37.8540971414, + 40.7144315483, + 43.5571390869, + 46.3730179743, + 49.1537231663, + 51.8917218889, + 54.58026103, + 57.2015358514, + 59.7513664199, + 62.2380533124, + 64.657612252, + 67.006640002, + 69.2822432184, + 71.4820384499, + 73.6041047056, + 75.6469478817, + 77.6094829742, + 79.4909866472, + 81.2911031615, + 83.0097850853, + 84.6355598352, + 86.1820937186, + 87.6504420946, + 89.0418441206, + 90.3577286819, + 91.5996432431, + 92.7692775646, + 93.8684162704, + 94.8989269904, + 95.8627662892, + 96.7619381633, + 97.598505899, + 98.362769679, + 99.0579904444, + 99.6992633875, + 100.288805948, + 100.828805921, + 101.321421457, + 101.76878699, + 102.17300138, + 102.536116055, + 102.860158727, + 103.147085962, + 103.398830608, + 103.617254366, + 103.792467691, + 103.939387906, + 104.060030865, + 104.15631756, + 104.230085975, + 104.283067372, + 104.316933727, + 104.333238432, + 104.333440018, + 104.318914008, + 104.290941063, + 104.250742554, + 104.187634452, + 104.103822339, + 104.013227468, + 103.916810336, + 103.815448432, + 103.709936239, + 103.600997093, + 103.489283183, + 103.375351833, + 103.259712936, + 103.142828952, + 103.025091195, + 102.90686726, + 102.776726069, + 102.648078982, + 102.521459607, + 102.397294831, + 102.275999684, + 102.157882471, + 102.043215927, + 101.93218978, + 101.824958181, + 101.72159228, + 101.622151366) + + sampling_freq = 10e3 + freq = sampling_freq / 100 + + loop_bw = math.pi/100.0 + maxf = 1 + minf = -1 + + src = gr.sig_source_c(sampling_freq, gr.GR_COS_WAVE, freq, 1.0) + pll = analog.pll_freqdet_cf(loop_bw, maxf, minf) + head = gr.head(gr.sizeof_float, int (freq)) + dst = gr.vector_sink_f() + + self.tb.connect(src, pll, head) + self.tb.connect(head, dst) + + self.tb.run() + dst_data = dst.data() + + # convert it from normalized frequency to absolute frequency (Hz) + dst_data = [i*(sampling_freq/(2*math.pi)) for i in dst_data] + + self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 3) + +if __name__ == '__main__': + gr_unittest.run(test_pll_freqdet, "test_pll_freqdet.xml") diff --git a/gr-analog/python/qa_pll_refout.py b/gr-analog/python/qa_pll_refout.py new file mode 100755 index 000000000..2831b2909 --- /dev/null +++ b/gr-analog/python/qa_pll_refout.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +# +# Copyright 2004,2010,2012 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, gr_unittest +import analog_swig as analog +import math + +class test_pll_refout(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_pll_refout(self): + expected_result = ((1+0j), + (1+6.4087357643e-10j), + (0.999985277653+0.00542619498447j), + (0.999868750572+0.0162021834403j), + (0.99948567152+0.0320679470897j), + (0.99860727787+0.0527590736747j), + (0.996953129768+0.0780025869608j), + (0.994203746319+0.107512556016j), + (0.990011692047+0.140985429287j), + (0.984013140202+0.178095817566j), + (0.975838363171+0.218493551016j), + (0.965121984482+0.261800557375j), + (0.95151245594+0.307610183954j), + (0.934681296349+0.355486690998j), + (0.914401650429+0.404808044434j), + (0.890356600285+0.455263823271j), + (0.862329125404+0.506348133087j), + (0.830152392387+0.557536482811j), + (0.793714106083+0.608290970325j), + (0.752960026264+0.658066213131j), + (0.707896590233+0.706316053867j), + (0.658591926098+0.752500295639j), + (0.605175673962+0.796091973782j), + (0.547837555408+0.836584687233j), + (0.48682525754+0.873499393463j), + (0.42244040966+0.906390726566j), + (0.355197101831+0.934791445732j), + (0.285494059324+0.958380460739j), + (0.213591173291+0.976923108101j), + (0.139945343137+0.990159213543j), + (0.065038472414+0.997882783413j), + (-0.0106285437942+0.999943494797j), + (-0.0865436866879+0.996248066425j), + (-0.162189796567+0.986759603024j), + (-0.23705175519+0.971496999264j), + (-0.310622543097+0.950533330441j), + (-0.38240903616+0.923993110657j), + (-0.451937526464+0.89204955101j), + (-0.518758952618+0.854920566082j), + (-0.582311093807+0.812966048717j), + (-0.642372369766+0.76639264822j), + (-0.698591887951+0.715520322323j), + (-0.750654160976+0.660695314407j), + (-0.798280358315+0.602286040783j), + (-0.841228663921+0.540679454803j), + (-0.87929558754+0.476276367903j), + (-0.912315964699+0.409486919641j), + (-0.940161883831+0.340728074312j), + (-0.962742805481+0.270418733358j), + (-0.980004072189+0.198977485299j), + (-0.991925954819+0.126818284392j), + (-0.99851256609+0.0545223206282j), + (-0.999846458435-0.0175215266645j), + (-0.996021270752-0.0891158208251j), + (-0.987133920193-0.159895718098j), + (-0.973306238651-0.2295101583j), + (-0.954683184624-0.297624111176j), + (-0.931430280209-0.363919824362j), + (-0.903732538223-0.428097635508j), + (-0.871792256832-0.489875763655j), + (-0.835827112198-0.548992812634j), + (-0.796068251133-0.605206847191j), + (-0.752758979797-0.658296227455j), + (-0.706152498722-0.70805978775j), + (-0.656641483307-0.754202902317j), + (-0.604367733002-0.79670548439j), + (-0.549597978592-0.835429251194j), + (-0.492602348328-0.870254516602j), + (-0.433654457331-0.901079237461j), + (-0.373029649258-0.927819430828j), + (-0.31100410223-0.950408577919j), + (-0.247853919864-0.968797445297j), + (-0.183855071664-0.982953369617j), + (-0.119282215834-0.992860376835j), + (-0.0544078871608-0.998518764973j), + (0.0104992967099-0.999944865704j), + (0.0749994292855-0.997183561325j), + (0.138844624162-0.990314185619j), + (0.201967850327-0.979392170906j), + (0.264124274254-0.964488625526j), + (0.325075358152-0.945688128471j), + (0.3845885396-0.92308807373j), + (0.442438393831-0.89679890871j), + (0.498407125473-0.866943061352j), + (0.552284479141-0.833655714989j), + (0.603869199753-0.797083437443j), + (0.652970373631-0.757383465767j), + (0.69940674305-0.714723825455j), + (0.743007957935-0.66928255558j), + (0.78350687027-0.62138313055j), + (0.820889055729-0.571087777615j), + (0.855021059513-0.51859331131j), + (0.885780930519-0.46410369873j), + (0.913058102131-0.407829582691j), + (0.936754107475-0.349988251925j), + (0.956783294678-0.290801793337j), + (0.973072886467-0.230497643352j), + (0.985563337803-0.169307261705j), + (0.9942086339-0.1074674353j), + (0.9989772439-0.0452152714133j)) + + sampling_freq = 10e3 + freq = sampling_freq / 100 + + loop_bw = math.pi/100.0 + maxf = 1 + minf = -1 + + src = gr.sig_source_c(sampling_freq, gr.GR_COS_WAVE, freq, 1.0) + pll = analog.pll_refout_cc(loop_bw, maxf, minf) + head = gr.head(gr.sizeof_gr_complex, int (freq)) + dst = gr.vector_sink_c() + + self.tb.connect(src, pll, head) + self.tb.connect(head, dst) + + self.tb.run() + dst_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_pll_refout, "test_pll_refout.xml") diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 665da9686..b1bc61d5d 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -44,6 +44,9 @@ #include "analog/noise_source_f.h" #include "analog/noise_source_c.h" #include "analog/phase_modulator_fc.h" +#include "analog/pll_carriertracking_cc.h" +#include "analog/pll_freqdet_cf.h" +#include "analog/pll_refout_cc.h" #include "analog/squelch_base_cc.h" #include "analog/squelch_base_ff.h" %} @@ -65,6 +68,9 @@ %include "analog/noise_source_f.h" %include "analog/noise_source_c.h" %include "analog/phase_modulator_fc.h" +%include "analog/pll_carriertracking_cc.h" +%include "analog/pll_freqdet_cf.h" +%include "analog/pll_refout_cc.h" %include "analog/squelch_base_cc.h" %include "analog/squelch_base_ff.h" @@ -83,3 +89,6 @@ GR_SWIG_BLOCK_MAGIC2(analog, noise_source_i); GR_SWIG_BLOCK_MAGIC2(analog, noise_source_f); GR_SWIG_BLOCK_MAGIC2(analog, noise_source_c); GR_SWIG_BLOCK_MAGIC2(analog, phase_modulator_fc); +GR_SWIG_BLOCK_MAGIC2(analog, pll_carriertracking_cc); +GR_SWIG_BLOCK_MAGIC2(analog, pll_freqdet_cf); +GR_SWIG_BLOCK_MAGIC2(analog, pll_refout_cc); -- cgit From 1eb6dd37acdfb81f7a8602897ac5cb1685c532e8 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 30 Oct 2012 14:46:29 -0400 Subject: analog: adding probe_avg_mag_sqrd blocks to gr-analog with QA and GRC. --- gr-analog/include/analog/CMakeLists.txt | 3 + gr-analog/include/analog/probe_avg_mag_sqrd_c.h | 67 ++++++++++++++++ gr-analog/include/analog/probe_avg_mag_sqrd_cf.h | 69 +++++++++++++++++ gr-analog/include/analog/probe_avg_mag_sqrd_f.h | 69 +++++++++++++++++ gr-analog/lib/CMakeLists.txt | 3 + gr-analog/lib/probe_avg_mag_sqrd_c_impl.cc | 91 ++++++++++++++++++++++ gr-analog/lib/probe_avg_mag_sqrd_c_impl.h | 60 +++++++++++++++ gr-analog/lib/probe_avg_mag_sqrd_cf_impl.cc | 93 ++++++++++++++++++++++ gr-analog/lib/probe_avg_mag_sqrd_cf_impl.h | 60 +++++++++++++++ gr-analog/lib/probe_avg_mag_sqrd_f_impl.cc | 92 ++++++++++++++++++++++ gr-analog/lib/probe_avg_mag_sqrd_f_impl.h | 60 +++++++++++++++ gr-analog/python/qa_probe_avg_mag_sqrd.py | 98 ++++++++++++++++++++++++ gr-analog/swig/analog_swig.i | 9 +++ 13 files changed, 774 insertions(+) create mode 100644 gr-analog/include/analog/probe_avg_mag_sqrd_c.h create mode 100644 gr-analog/include/analog/probe_avg_mag_sqrd_cf.h create mode 100644 gr-analog/include/analog/probe_avg_mag_sqrd_f.h create mode 100644 gr-analog/lib/probe_avg_mag_sqrd_c_impl.cc create mode 100644 gr-analog/lib/probe_avg_mag_sqrd_c_impl.h create mode 100644 gr-analog/lib/probe_avg_mag_sqrd_cf_impl.cc create mode 100644 gr-analog/lib/probe_avg_mag_sqrd_cf_impl.h create mode 100644 gr-analog/lib/probe_avg_mag_sqrd_f_impl.cc create mode 100644 gr-analog/lib/probe_avg_mag_sqrd_f_impl.h create mode 100644 gr-analog/python/qa_probe_avg_mag_sqrd.py diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index ac1d65932..f2c0f6d6f 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -94,6 +94,9 @@ install(FILES pll_carriertracking_cc.h pll_freqdet_cf.h pll_refout_cc.h + probe_avg_mag_sqrd_c.h + probe_avg_mag_sqrd_cf.h + probe_avg_mag_sqrd_f.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog COMPONENT "analog_devel" ) diff --git a/gr-analog/include/analog/probe_avg_mag_sqrd_c.h b/gr-analog/include/analog/probe_avg_mag_sqrd_c.h new file mode 100644 index 000000000..9e62732a3 --- /dev/null +++ b/gr-analog/include/analog/probe_avg_mag_sqrd_c.h @@ -0,0 +1,67 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 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_ANALOG_PROBE_AVG_MAG_SQRD_C_H +#define INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_C_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief compute avg magnitude squared. + * \ingroup sink_blk + * + * Input stream 0: complex + * + * Compute a running average of the magnitude squared of the the + * input. The level and indication as to whether the level exceeds + * threshold can be retrieved with the level and unmuted + * accessors. + */ + class ANALOG_API probe_avg_mag_sqrd_c : virtual public gr_sync_block + { + public: + // gr::analog::probe_avg_mag_sqrd_c::sptr + typedef boost::shared_ptr sptr; + + /*! + * \brief Make a complex sink that computes avg magnitude squared. + * + * \param threshold_db Threshold for muting. + * \param alpha Gain parameter for the running average filter. + */ + static sptr make(double threshold_db, double alpha = 0.0001); + + virtual bool unmuted() const = 0; + virtual double level() const = 0; + virtual double threshold() const = 0; + + virtual void set_alpha(double alpha) = 0; + virtual void set_threshold(double decibels) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_C_H */ diff --git a/gr-analog/include/analog/probe_avg_mag_sqrd_cf.h b/gr-analog/include/analog/probe_avg_mag_sqrd_cf.h new file mode 100644 index 000000000..b18916ae9 --- /dev/null +++ b/gr-analog/include/analog/probe_avg_mag_sqrd_cf.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 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_ANALOG_PROBE_AVG_MAG_SQRD_CF_H +#define INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_CF_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief compute avg magnitude squared. + * \ingroup sink_blk + * + * Input stream 0: complex + * Output stream 0: float + * + * Compute a running average of the magnitude squared of the the + * input. The level and indication as to whether the level exceeds + * threshold can be retrieved with the level and unmuted + * accessors. + */ + class ANALOG_API probe_avg_mag_sqrd_cf : virtual public gr_sync_block + { + public: + // gr::analog::probe_avg_mag_sqrd_cf::sptr + typedef boost::shared_ptr sptr; + + /*! + * \brief Make a block that computes avg magnitude squared. + * + * \param threshold_db Threshold for muting. + * \param alpha Gain parameter for the running average filter. + */ + static sptr make(double threshold_db, double alpha = 0.0001); + + virtual bool unmuted() const = 0; + virtual double level() const = 0; + virtual double threshold() const = 0; + + virtual void set_alpha(double alpha) = 0; + virtual void set_threshold(double decibels) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_CF_H */ diff --git a/gr-analog/include/analog/probe_avg_mag_sqrd_f.h b/gr-analog/include/analog/probe_avg_mag_sqrd_f.h new file mode 100644 index 000000000..fe9d27793 --- /dev/null +++ b/gr-analog/include/analog/probe_avg_mag_sqrd_f.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 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_ANALOG_PROBE_AVG_MAG_SQRD_F_H +#define INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_F_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief compute avg magnitude squared. + * \ingroup sink_blk + * + * input stream 0: float + * + * Compute a running average of the magnitude squared of the the + * input. The level and indication as to whether the level exceeds + * threshold can be retrieved with the level and unmuted + * accessors. + */ + class ANALOG_API probe_avg_mag_sqrd_f : virtual public gr_sync_block + { + public: + // gr::analog::probe_avg_mag_sqrd_f::sptr + typedef boost::shared_ptr sptr; + + /*! + * \brief Make a float sink that computes avg magnitude squared. + * + * \param threshold_db Threshold for muting. + * \param alpha Gain parameter for the running average filter. + */ + static sptr make(double threshold_db, double alpha = 0.0001); + + virtual bool unmuted() const = 0; + virtual double level() const = 0; + + virtual double threshold() const = 0; + + virtual void set_alpha (double alpha) = 0; + virtual void set_threshold (double decibels) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_F_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index 20a86621e..93ab5e83e 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -120,6 +120,9 @@ list(APPEND analog_sources pll_carriertracking_cc_impl.cc pll_freqdet_cf_impl.cc pll_refout_cc_impl.cc + probe_avg_mag_sqrd_c_impl.cc + probe_avg_mag_sqrd_cf_impl.cc + probe_avg_mag_sqrd_f_impl.cc ) list(APPEND analog_libs diff --git a/gr-analog/lib/probe_avg_mag_sqrd_c_impl.cc b/gr-analog/lib/probe_avg_mag_sqrd_c_impl.cc new file mode 100644 index 000000000..291809bb2 --- /dev/null +++ b/gr-analog/lib/probe_avg_mag_sqrd_c_impl.cc @@ -0,0 +1,91 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2010,2012 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 "probe_avg_mag_sqrd_c_impl.h" +#include +#include + +namespace gr { + namespace analog { + + probe_avg_mag_sqrd_c::sptr + probe_avg_mag_sqrd_c::make(double threshold_db, double alpha) + { + return gnuradio::get_initial_sptr + (new probe_avg_mag_sqrd_c_impl(threshold_db, alpha)); + } + + probe_avg_mag_sqrd_c_impl::probe_avg_mag_sqrd_c_impl(double threshold_db, double alpha) + : gr_sync_block("probe_avg_mag_sqrd_c", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(0, 0, 0)), + d_unmuted(false), d_level(0), d_iir(alpha) + { + set_threshold(threshold_db); + } + + probe_avg_mag_sqrd_c_impl::~probe_avg_mag_sqrd_c_impl() + { + } + + int + probe_avg_mag_sqrd_c_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + + for(int i = 0; i < noutput_items; i++) { + double mag_sqrd = in[i].real()*in[i].real() + in[i].imag()*in[i].imag(); + d_iir.filter(mag_sqrd); // computed for side effect: prev_output() + } + + d_unmuted = d_iir.prev_output() >= d_threshold; + d_level = d_iir.prev_output(); + return noutput_items; + } + + double + probe_avg_mag_sqrd_c_impl::threshold() const + { + return 10 * std::log10(d_threshold); + } + + void + probe_avg_mag_sqrd_c_impl::set_threshold(double decibels) + { + // convert to absolute threshold (mag squared) + d_threshold = std::pow(10.0, decibels/10); + } + + void + probe_avg_mag_sqrd_c_impl::set_alpha(double alpha) + { + d_iir.set_taps(alpha); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/probe_avg_mag_sqrd_c_impl.h b/gr-analog/lib/probe_avg_mag_sqrd_c_impl.h new file mode 100644 index 000000000..0a2685357 --- /dev/null +++ b/gr-analog/lib/probe_avg_mag_sqrd_c_impl.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 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_ANALOG_PROBE_AVG_MAG_SQRD_C_IMPL_H +#define INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_C_IMPL_H + +#include +#include + +namespace gr { + namespace analog { + + class probe_avg_mag_sqrd_c_impl : public probe_avg_mag_sqrd_c + { + private: + double d_threshold; + bool d_unmuted; + double d_level; + filter::single_pole_iir d_iir; + + public: + probe_avg_mag_sqrd_c_impl(double threshold_db, double alpha = 0.0001); + ~probe_avg_mag_sqrd_c_impl(); + + bool unmuted() const { return d_unmuted; } + double level() const { return d_level; } + + double threshold() const; + + void set_alpha(double alpha); + void set_threshold(double decibels); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_C_IMPL_H */ diff --git a/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.cc b/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.cc new file mode 100644 index 000000000..ceaf5dbf0 --- /dev/null +++ b/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.cc @@ -0,0 +1,93 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2007,2010,2012 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 "probe_avg_mag_sqrd_cf_impl.h" +#include +#include + +namespace gr { + namespace analog { + + probe_avg_mag_sqrd_cf::sptr + probe_avg_mag_sqrd_cf::make(double threshold_db, double alpha) + { + return gnuradio::get_initial_sptr + (new probe_avg_mag_sqrd_cf_impl(threshold_db, alpha)); + } + + probe_avg_mag_sqrd_cf_impl::probe_avg_mag_sqrd_cf_impl(double threshold_db, double alpha) + : gr_sync_block("probe_avg_mag_sqrd_cf", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(float))), + d_unmuted(false), d_level(0), d_iir(alpha) + { + set_threshold(threshold_db); + } + + probe_avg_mag_sqrd_cf_impl::~probe_avg_mag_sqrd_cf_impl() + { + } + + int + probe_avg_mag_sqrd_cf_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + float *out = (float*)output_items[0]; + + for(int i = 0; i < noutput_items; i++) { + out[i] = d_iir.prev_output(); + double mag_sqrd = in[i].real()*in[i].real() + in[i].imag()*in[i].imag(); + d_iir.filter(mag_sqrd); // computed for side effect: prev_output() + } + + d_unmuted = d_iir.prev_output() >= d_threshold; + d_level = d_iir.prev_output(); + return noutput_items; + } + + double + probe_avg_mag_sqrd_cf_impl::threshold() const + { + return 10 * std::log10(d_threshold); + } + + void + probe_avg_mag_sqrd_cf_impl::set_threshold(double decibels) + { + // convert to absolute threshold (mag squared) + d_threshold = std::pow(10.0, decibels/10); + } + + void + probe_avg_mag_sqrd_cf_impl::set_alpha(double alpha) + { + d_iir.set_taps(alpha); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.h b/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.h new file mode 100644 index 000000000..9cd8f8d4c --- /dev/null +++ b/gr-analog/lib/probe_avg_mag_sqrd_cf_impl.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,2012 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_ANALOG_PROBE_AVG_MAG_SQRD_CF_IMPL_H +#define INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_CF_IMPL_H + +#include +#include + +namespace gr { + namespace analog { + + class probe_avg_mag_sqrd_cf_impl : public probe_avg_mag_sqrd_cf + { + private: + double d_threshold; + bool d_unmuted; + double d_level; + filter::single_pole_iir d_iir; + + public: + probe_avg_mag_sqrd_cf_impl(double threshold_db, double alpha); + ~probe_avg_mag_sqrd_cf_impl(); + + bool unmuted() const { return d_unmuted; } + double level() const { return d_level; } + + double threshold() const; + + void set_alpha(double alpha); + void set_threshold(double decibels); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_CF_IMPL_H */ diff --git a/gr-analog/lib/probe_avg_mag_sqrd_f_impl.cc b/gr-analog/lib/probe_avg_mag_sqrd_f_impl.cc new file mode 100644 index 000000000..4ac7ef06b --- /dev/null +++ b/gr-analog/lib/probe_avg_mag_sqrd_f_impl.cc @@ -0,0 +1,92 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2010,2012 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 "probe_avg_mag_sqrd_f_impl.h" +#include +#include + +namespace gr { + namespace analog { + + probe_avg_mag_sqrd_f::sptr + probe_avg_mag_sqrd_f::make(double threshold_db, double alpha) + { + return gnuradio::get_initial_sptr + (new probe_avg_mag_sqrd_f_impl(threshold_db, alpha)); + } + + probe_avg_mag_sqrd_f_impl::probe_avg_mag_sqrd_f_impl(double threshold_db, double alpha) + : gr_sync_block("probe_avg_mag_sqrd_f", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(0, 0, 0)), + d_unmuted(false), d_level(0), d_iir(alpha) + { + set_threshold(threshold_db); + } + + probe_avg_mag_sqrd_f_impl::~probe_avg_mag_sqrd_f_impl() + { + } + + int + probe_avg_mag_sqrd_f_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + + for(int i = 0; i < noutput_items; i++) { + double mag_sqrd = in[i]*in[i]; + d_iir.filter(mag_sqrd); // computed for side effect: prev_output() + } + + d_unmuted = d_iir.prev_output() >= d_threshold; + d_level = d_iir.prev_output(); + return noutput_items; + } + + double + probe_avg_mag_sqrd_f_impl::threshold() const + { + return 10 * std::log10(d_threshold); + } + + void + probe_avg_mag_sqrd_f_impl::set_threshold(double decibels) + { + // convert to absolute threshold (mag sqrd) + d_threshold = std::pow(10.0, decibels/10); + } + + void + probe_avg_mag_sqrd_f_impl::set_alpha(double alpha) + { + d_iir.set_taps(alpha); + } + + } /* namespace analog */ +} /* namespace gr */ + diff --git a/gr-analog/lib/probe_avg_mag_sqrd_f_impl.h b/gr-analog/lib/probe_avg_mag_sqrd_f_impl.h new file mode 100644 index 000000000..ba879763c --- /dev/null +++ b/gr-analog/lib/probe_avg_mag_sqrd_f_impl.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 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_ANALOG_PROBE_AVG_MAG_SQRD_F_IMPL_H +#define INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_F_IMPL_H + +#include +#include + +namespace gr { + namespace analog { + + class probe_avg_mag_sqrd_f_impl : public probe_avg_mag_sqrd_f + { + private: + double d_threshold; + bool d_unmuted; + double d_level; + filter::single_pole_iir d_iir; + + public: + probe_avg_mag_sqrd_f_impl(double threshold_db, double alpha); + ~probe_avg_mag_sqrd_f_impl(); + + bool unmuted() const { return d_unmuted; } + double level() const { return d_level; } + + double threshold() const; + + void set_alpha(double alpha); + void set_threshold(double decibels); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PROBE_AVG_MAG_SQRD_F_IMPL_H */ diff --git a/gr-analog/python/qa_probe_avg_mag_sqrd.py b/gr-analog/python/qa_probe_avg_mag_sqrd.py new file mode 100644 index 000000000..5c6c97e45 --- /dev/null +++ b/gr-analog/python/qa_probe_avg_mag_sqrd.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# +# Copyright 2012 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, gr_unittest +import analog_swig as analog +import math + +def avg_mag_sqrd_c(x, alpha): + y = [0,] + for xi in x: + tmp = alpha*(xi.real*xi.real + xi.imag*xi.imag) + (1-alpha)*y[-1] + y.append(tmp) + return y + +def avg_mag_sqrd_f(x, alpha): + y = [0,] + for xi in x: + tmp = alpha*(xi*xi) + (1-alpha)*y[-1] + y.append(tmp) + return y + +class test_probe_avg_mag_sqrd(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_c_001(self): + alpha = 0.0001 + src_data = [1.0+1.0j, 2.0+2.0j, 3.0+3.0j, 4.0+4.0j, 5.0+5.0j, + 6.0+6.0j, 7.0+7.0j, 8.0+8.0j, 9.0+9.0j, 10.0+10.0j] + expected_result = avg_mag_sqrd_c(src_data, alpha)[-1] + + src = gr.vector_source_c(src_data) + op = analog.probe_avg_mag_sqrd_c(0, alpha) + + self.tb.connect(src, op) + self.tb.run() + + result_data = op.level() + self.assertAlmostEqual(expected_result, result_data, 5) + + def test_cf_002(self): + alpha = 0.0001 + src_data = [1.0+1.0j, 2.0+2.0j, 3.0+3.0j, 4.0+4.0j, 5.0+5.0j, + 6.0+6.0j, 7.0+7.0j, 8.0+8.0j, 9.0+9.0j, 10.0+10.0j] + expected_result = avg_mag_sqrd_c(src_data, alpha)[0:-1] + + src = gr.vector_source_c(src_data) + op = analog.probe_avg_mag_sqrd_cf(0, alpha) + dst = gr.vector_sink_f() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 5) + + def test_f_003(self): + alpha = 0.0001 + src_data = [1.0, 2.0, 3.0, 4.0, 5.0, + 6.0, 7.0, 8.0, 9.0, 10.0] + expected_result = avg_mag_sqrd_f(src_data, alpha)[-1] + + src = gr.vector_source_f(src_data) + op = analog.probe_avg_mag_sqrd_f(0, alpha) + + self.tb.connect(src, op) + self.tb.run() + + result_data = op.level() + self.assertAlmostEqual(expected_result, result_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_probe_avg_mag_sqrd, "test_probe_avg_mag_sqrd.xml") + diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index b1bc61d5d..16f32ede7 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -47,6 +47,9 @@ #include "analog/pll_carriertracking_cc.h" #include "analog/pll_freqdet_cf.h" #include "analog/pll_refout_cc.h" +#include "analog/probe_avg_mag_sqrd_c.h" +#include "analog/probe_avg_mag_sqrd_cf.h" +#include "analog/probe_avg_mag_sqrd_f.h" #include "analog/squelch_base_cc.h" #include "analog/squelch_base_ff.h" %} @@ -71,6 +74,9 @@ %include "analog/pll_carriertracking_cc.h" %include "analog/pll_freqdet_cf.h" %include "analog/pll_refout_cc.h" +%include "analog/probe_avg_mag_sqrd_c.h" +%include "analog/probe_avg_mag_sqrd_cf.h" +%include "analog/probe_avg_mag_sqrd_f.h" %include "analog/squelch_base_cc.h" %include "analog/squelch_base_ff.h" @@ -92,3 +98,6 @@ GR_SWIG_BLOCK_MAGIC2(analog, phase_modulator_fc); GR_SWIG_BLOCK_MAGIC2(analog, pll_carriertracking_cc); GR_SWIG_BLOCK_MAGIC2(analog, pll_freqdet_cf); GR_SWIG_BLOCK_MAGIC2(analog, pll_refout_cc); +GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_c); +GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_cf); +GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_f); -- cgit From 43e13c6c0877930562a3d23e75bdb4db5698c466 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 30 Oct 2012 14:55:26 -0400 Subject: analog: moving LFSR code into gr-analog. --- gr-analog/include/analog/lfsr.h | 162 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 gr-analog/include/analog/lfsr.h diff --git a/gr-analog/include/analog/lfsr.h b/gr-analog/include/analog/lfsr.h new file mode 100644 index 000000000..9612a9d43 --- /dev/null +++ b/gr-analog/include/analog/lfsr.h @@ -0,0 +1,162 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2010,2012 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_ANALOG_LFSR_H +#define INCLUDED_ANALOG_LFSR_H + +#include +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief Fibonacci Linear Feedback Shift Register using specified + * polynomial mask + * \ingroup misc + * + * Generates a maximal length pseudo-random sequence of length + * 2^degree-1 + * + * Constructor: analog::lfsr(int mask, int seed, int reg_len); + * + * \param mask - polynomial coefficients representing the + * locations of feedback taps from a shift register + * which are xor'ed together to form the new high + * order bit. + * + * Some common masks might be: + * x^4 + x^3 + x^0 = 0x19 + * x^5 + x^3 + x^0 = 0x29 + * x^6 + x^5 + x^0 = 0x61 + * + * \param seed - the initialization vector placed into the + * register durring initialization. Low order bit + * corresponds to x^0 coefficient -- the first to be + * shifted as output. + * + * \param reg_len - specifies the length of the feedback shift + * register to be used. Durring each iteration, the + * register is rightshifted one and the new bit is + * placed in bit reg_len. reg_len should generally be + * at least order(mask) + 1 + * + * + * see http://en.wikipedia.org/wiki/Linear_feedback_shift_register + * for more explanation. + * + * next_bit() - Standard LFSR operation + * + * Perform one cycle of the LFSR. The output bit is taken from + * the shift register LSB. The shift register MSB is assigned from + * the modulo 2 sum of the masked shift register. + * + * next_bit_scramble(unsigned char input) - Scramble an input stream + * + * Perform one cycle of the LFSR. The output bit is taken from + * the shift register LSB. The shift register MSB is assigned from + * the modulo 2 sum of the masked shift register and the input LSB. + * + * next_bit_descramble(unsigned char input) - Descramble an input stream + * + * Perform one cycle of the LFSR. The output bit is taken from + * the modulo 2 sum of the masked shift register and the input LSB. + * The shift register MSB is assigned from the LSB of the input. + * + * See http://en.wikipedia.org/wiki/Scrambler for operation of these + * last two functions (see multiplicative scrambler.) + */ + class ANALOG_API lfsr + { + private: + uint32_t d_shift_register; + uint32_t d_mask; + uint32_t d_seed; + uint32_t d_shift_register_length; // less than 32 + + static uint32_t + popCount(uint32_t x) + { + uint32_t r = x - ((x >> 1) & 033333333333) + - ((x >> 2) & 011111111111); + return ((r + (r >> 3)) & 030707070707) % 63; + } + + public: + lfsr(uint32_t mask, uint32_t seed, uint32_t reg_len) + : d_shift_register(seed), + d_mask(mask), + d_seed(seed), + d_shift_register_length(reg_len) + { + if(reg_len > 31) + throw std::invalid_argument("reg_len must be <= 31"); + } + + unsigned char next_bit() + { + unsigned char output = d_shift_register & 1; + unsigned char newbit = popCount( d_shift_register & d_mask )%2; + d_shift_register = ((d_shift_register>>1) | (newbit<>1) | (newbit<>1) | (newbit< gr_complex; typedef std::complex gr_complexd; typedef unsigned long long uint64_t; typedef long long int64_t; +typedef unsigned long uint32_t; +typedef long int32_t; // instantiate the required template specializations -- cgit From e0f8e5e72ac119c980bc33f2fad9a7b83f44ab1b Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 30 Oct 2012 15:27:34 -0400 Subject: analog: export lfsr class to Python and adding QA code for it. --- gr-analog/python/qa_lfsr.py | 49 ++++++++++++++++++++++++++++++++++++++++++++ gr-analog/swig/analog_swig.i | 2 ++ 2 files changed, 51 insertions(+) create mode 100755 gr-analog/python/qa_lfsr.py diff --git a/gr-analog/python/qa_lfsr.py b/gr-analog/python/qa_lfsr.py new file mode 100755 index 000000000..2a8167a57 --- /dev/null +++ b/gr-analog/python/qa_lfsr.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# +# Copyright 2012 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, gr_unittest +import analog_swig as analog +import math + + +class test_lfsr(gr_unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_lfsr_001(self): + reglen = 8 + l = analog.lfsr(1, 1, reglen) + + result_data = [] + for i in xrange(4*(reglen+1)): + result_data.append(l.next_bit()) + + expected_result = 4*([1,] + reglen*[0,]) + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_lfsr, "test_lfsr.xml") + diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 16f32ede7..e1461e462 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -39,6 +39,7 @@ #include "analog/feedforward_agc_cc.h" #include "analog/fmdet_cf.h" #include "analog/frequency_modulator_fc.h" +#include "analog/lfsr.h" #include "analog/noise_source_s.h" #include "analog/noise_source_i.h" #include "analog/noise_source_f.h" @@ -66,6 +67,7 @@ %include "analog/feedforward_agc_cc.h" %include "analog/fmdet_cf.h" %include "analog/frequency_modulator_fc.h" +%include "analog/lfsr.h" %include "analog/noise_source_s.h" %include "analog/noise_source_i.h" %include "analog/noise_source_f.h" -- cgit From 4c155b6caad4166c9dae2c49bd25215e8cba1e51 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 30 Oct 2012 15:28:04 -0400 Subject: analog: executable flag for python QA codes. --- gr-analog/python/qa_cpfsk.py | 0 gr-analog/python/qa_ctcss_squelch.py | 0 gr-analog/python/qa_dpll.py | 0 gr-analog/python/qa_fmdet.py | 0 gr-analog/python/qa_phase_modulator.py | 0 gr-analog/python/qa_probe_avg_mag_sqrd.py | 0 6 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 gr-analog/python/qa_cpfsk.py mode change 100644 => 100755 gr-analog/python/qa_ctcss_squelch.py mode change 100644 => 100755 gr-analog/python/qa_dpll.py mode change 100644 => 100755 gr-analog/python/qa_fmdet.py mode change 100644 => 100755 gr-analog/python/qa_phase_modulator.py mode change 100644 => 100755 gr-analog/python/qa_probe_avg_mag_sqrd.py diff --git a/gr-analog/python/qa_cpfsk.py b/gr-analog/python/qa_cpfsk.py old mode 100644 new mode 100755 diff --git a/gr-analog/python/qa_ctcss_squelch.py b/gr-analog/python/qa_ctcss_squelch.py old mode 100644 new mode 100755 diff --git a/gr-analog/python/qa_dpll.py b/gr-analog/python/qa_dpll.py old mode 100644 new mode 100755 diff --git a/gr-analog/python/qa_fmdet.py b/gr-analog/python/qa_fmdet.py old mode 100644 new mode 100755 diff --git a/gr-analog/python/qa_phase_modulator.py b/gr-analog/python/qa_phase_modulator.py old mode 100644 new mode 100755 diff --git a/gr-analog/python/qa_probe_avg_mag_sqrd.py b/gr-analog/python/qa_probe_avg_mag_sqrd.py old mode 100644 new mode 100755 -- cgit From bffff0329827a3c89ab50e6561ae0573c46c1dac Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 30 Oct 2012 15:28:18 -0400 Subject: digital: switched digital components over to using LFSR class now in gr-analog. --- gr-digital/CMakeLists.txt | 1 + gr-digital/include/digital_additive_scrambler_bb.h | 4 ++-- gr-digital/include/digital_descrambler_bb.h | 4 ++-- gr-digital/include/digital_scrambler_bb.h | 4 ++-- gr-digital/lib/CMakeLists.txt | 3 ++- gr-digital/swig/CMakeLists.txt | 1 + 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/gr-digital/CMakeLists.txt b/gr-digital/CMakeLists.txt index eb7ed67e1..864cd673a 100644 --- a/gr-digital/CMakeLists.txt +++ b/gr-digital/CMakeLists.txt @@ -29,6 +29,7 @@ include(GrComponent) GR_REGISTER_COMPONENT("gr-digital" ENABLE_GR_DIGITAL Boost_FOUND ENABLE_GR_CORE + ENABLE_GR_ANALOG ) GR_SET_GLOBAL(GR_DIGITAL_INCLUDE_DIRS diff --git a/gr-digital/include/digital_additive_scrambler_bb.h b/gr-digital/include/digital_additive_scrambler_bb.h index d4bd7d4ae..f1d0113e9 100644 --- a/gr-digital/include/digital_additive_scrambler_bb.h +++ b/gr-digital/include/digital_additive_scrambler_bb.h @@ -24,7 +24,7 @@ #include #include -#include +#include class digital_additive_scrambler_bb; typedef boost::shared_ptr digital_additive_scrambler_bb_sptr; @@ -57,7 +57,7 @@ class DIGITAL_API digital_additive_scrambler_bb : public gr_sync_block digital_make_additive_scrambler_bb(int mask, int seed, int len, int count); - gri_lfsr d_lfsr; + gr::analog::lfsr d_lfsr; int d_count; int d_bits; diff --git a/gr-digital/include/digital_descrambler_bb.h b/gr-digital/include/digital_descrambler_bb.h index b719803f3..d503102a9 100644 --- a/gr-digital/include/digital_descrambler_bb.h +++ b/gr-digital/include/digital_descrambler_bb.h @@ -24,7 +24,7 @@ #include #include -#include "gri_lfsr.h" +#include class digital_descrambler_bb; typedef boost::shared_ptr digital_descrambler_bb_sptr; @@ -49,7 +49,7 @@ class DIGITAL_API digital_descrambler_bb : public gr_sync_block friend DIGITAL_API digital_descrambler_bb_sptr digital_make_descrambler_bb(int mask, int seed, int len); - gri_lfsr d_lfsr; + gr::analog::lfsr d_lfsr; digital_descrambler_bb(int mask, int seed, int len); diff --git a/gr-digital/include/digital_scrambler_bb.h b/gr-digital/include/digital_scrambler_bb.h index d6f08dcc8..cafb0e5f2 100644 --- a/gr-digital/include/digital_scrambler_bb.h +++ b/gr-digital/include/digital_scrambler_bb.h @@ -24,7 +24,7 @@ #include #include -#include "gri_lfsr.h" +#include class digital_scrambler_bb; typedef boost::shared_ptr digital_scrambler_bb_sptr; @@ -49,7 +49,7 @@ class DIGITAL_API digital_scrambler_bb : public gr_sync_block friend DIGITAL_API digital_scrambler_bb_sptr digital_make_scrambler_bb(int mask, int seed, int len); - gri_lfsr d_lfsr; + gr::analog::lfsr d_lfsr; digital_scrambler_bb(int mask, int seed, int len); diff --git a/gr-digital/lib/CMakeLists.txt b/gr-digital/lib/CMakeLists.txt index bd4f1a500..155a10098 100644 --- a/gr-digital/lib/CMakeLists.txt +++ b/gr-digital/lib/CMakeLists.txt @@ -22,6 +22,7 @@ ######################################################################## include_directories( ${GNURADIO_CORE_INCLUDE_DIRS} + ${GR_ANALOG_INCLUDE_DIRS} ${GR_DIGITAL_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}/../include ) @@ -146,4 +147,4 @@ add_library(gnuradio-digital SHARED ${gr_digital_sources}) target_link_libraries(gnuradio-digital ${digital_libs}) GR_LIBRARY_FOO(gnuradio-digital RUNTIME_COMPONENT "digital_runtime" DEVEL_COMPONENT "digital_devel") -add_dependencies(gnuradio-digital digital_generated_includes digital_generated_swigs) +add_dependencies(gnuradio-digital digital_generated_includes digital_generated_swigs gnuradio-analog) diff --git a/gr-digital/swig/CMakeLists.txt b/gr-digital/swig/CMakeLists.txt index df5f04148..42bc8baa6 100644 --- a/gr-digital/swig/CMakeLists.txt +++ b/gr-digital/swig/CMakeLists.txt @@ -105,6 +105,7 @@ execute_process( ) set(GR_SWIG_INCLUDE_DIRS + ${GR_ANALOG_INCLUDE_DIRS} ${GR_DIGITAL_INCLUDE_DIRS} ${GNURADIO_CORE_SWIG_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} -- cgit From acde17371a4bec6afb07e9c83db001aa02a618eb Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 30 Oct 2012 16:12:37 -0400 Subject: Revert "core: adding int32_t and uint32_t types to swig." This reverts commit 4c2330d08927e6436652c1cd3f651633b6b9e2d1. --- gnuradio-core/src/lib/swig/gnuradio.i | 2 -- 1 file changed, 2 deletions(-) diff --git a/gnuradio-core/src/lib/swig/gnuradio.i b/gnuradio-core/src/lib/swig/gnuradio.i index 458982017..3a421ad5d 100644 --- a/gnuradio-core/src/lib/swig/gnuradio.i +++ b/gnuradio-core/src/lib/swig/gnuradio.i @@ -53,8 +53,6 @@ typedef std::complex gr_complex; typedef std::complex gr_complexd; typedef unsigned long long uint64_t; typedef long long int64_t; -typedef unsigned long uint32_t; -typedef long int32_t; // instantiate the required template specializations -- cgit From a2cbbdd98e262b29d96109be7df2d888e4fe9c28 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 30 Oct 2012 16:13:28 -0400 Subject: Revert "core: adding int32_t and uint32_t types to swig." This reverts commit 4c2330d08927e6436652c1cd3f651633b6b9e2d1. Instead, using stdint.i in analog_swig.i for the data type. --- gr-analog/swig/analog_swig.i | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index e1461e462..83b61c32d 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -22,6 +22,7 @@ #define ANALOG_API %include "gnuradio.i" +%include "stdint.i" //load generated python docstrings %include "analog_swig_doc.i" @@ -51,6 +52,7 @@ #include "analog/probe_avg_mag_sqrd_c.h" #include "analog/probe_avg_mag_sqrd_cf.h" #include "analog/probe_avg_mag_sqrd_f.h" +#include "analog/sincos.h" #include "analog/squelch_base_cc.h" #include "analog/squelch_base_ff.h" %} @@ -79,6 +81,7 @@ %include "analog/probe_avg_mag_sqrd_c.h" %include "analog/probe_avg_mag_sqrd_cf.h" %include "analog/probe_avg_mag_sqrd_f.h" +%include "analog/sincos.h" %include "analog/squelch_base_cc.h" %include "analog/squelch_base_ff.h" -- cgit From 1c5accf1a195616f241f0a31f07e5a1847a3941d Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 30 Oct 2012 17:19:55 -0400 Subject: analog: adding sincos functions to gr-analog. Adds QA test in C++ for sincos and the structure for running CppUnit tests in gr-analog. --- gr-analog/include/analog/sincos.h | 46 +++++++++++++++++++++ gr-analog/lib/CMakeLists.txt | 31 ++++++++++++++ gr-analog/lib/qa_analog.cc | 39 ++++++++++++++++++ gr-analog/lib/qa_analog.h | 38 +++++++++++++++++ gr-analog/lib/qa_sincos.cc | 75 ++++++++++++++++++++++++++++++++++ gr-analog/lib/qa_sincos.h | 47 +++++++++++++++++++++ gr-analog/lib/sincos.c | 86 +++++++++++++++++++++++++++++++++++++++ gr-analog/lib/test_gr_analog.cc | 43 ++++++++++++++++++++ 8 files changed, 405 insertions(+) create mode 100644 gr-analog/include/analog/sincos.h create mode 100644 gr-analog/lib/qa_analog.cc create mode 100644 gr-analog/lib/qa_analog.h create mode 100644 gr-analog/lib/qa_sincos.cc create mode 100644 gr-analog/lib/qa_sincos.h create mode 100644 gr-analog/lib/sincos.c create mode 100644 gr-analog/lib/test_gr_analog.cc diff --git a/gr-analog/include/analog/sincos.h b/gr-analog/include/analog/sincos.h new file mode 100644 index 000000000..c262434f0 --- /dev/null +++ b/gr-analog/include/analog/sincos.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2004,2012 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_ANALOG_SINCOS_H +#define INCLUDED_ANALOG_SINCOS_H + +#include + +namespace gr { + namespace analog { + +#ifdef __cplusplus +extern "C" { +#endif + + // compute sine and cosine at the same time + ANALOG_API void sincos(double x, double *sin, double *cos); + ANALOG_API void sincosf(float x, float *sin, float *cos); + +#ifdef __cplusplus +}; +#endif + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SINCOS_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index 93ab5e83e..e0e621d13 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -27,6 +27,8 @@ include_directories( ${GR_FFT_INCLUDE_DIRS} ${GR_FILTER_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}/../include + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} ) include_directories(${Boost_INCLUDE_DIRS}) @@ -136,3 +138,32 @@ add_library(gnuradio-analog SHARED ${analog_sources}) target_link_libraries(gnuradio-analog ${analog_libs}) GR_LIBRARY_FOO(gnuradio-analog RUNTIME_COMPONENT "analog_runtime" DEVEL_COMPONENT "analog_devel") add_dependencies(gnuradio-analog analog_generated_includes analog_generated_swigs gnuradio-filter) + + +######################################################################## +# QA C++ Code for gr-filter +######################################################################## +if(ENABLE_TESTING) + include(GrTest) + + include_directories(${CPPUNIT_INCLUDE_DIRS}) + link_directories(${CPPUNIT_LIBRARY_DIRS}) + + list(APPEND test_gr_analog_sources + ${CMAKE_CURRENT_SOURCE_DIR}/test_gr_analog.cc + ${CMAKE_CURRENT_SOURCE_DIR}/qa_analog.cc + ${CMAKE_CURRENT_SOURCE_DIR}/qa_sincos.cc + ) + + add_executable(test-gr-analog ${test_gr_analog_sources}) + + target_link_libraries( + test-gr-analog + gnuradio-core + gnuradio-analog + ${Boost_LIBRARIES} + ${CPPUNIT_LIBRARIES} + ) + + GR_ADD_TEST(test_gr_analog test-gr-analog) +endif(ENABLE_TESTING) diff --git a/gr-analog/lib/qa_analog.cc b/gr-analog/lib/qa_analog.cc new file mode 100644 index 000000000..ceecb096d --- /dev/null +++ b/gr-analog/lib/qa_analog.cc @@ -0,0 +1,39 @@ +/* + * Copyright 2012 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. + */ + +/* + * This class gathers together all the test cases for the gr-analog + * directory into a single test suite. As you create new test cases, + * add them here. + */ + +#include +#include + +CppUnit::TestSuite * +qa_gr_analog::suite() +{ + CppUnit::TestSuite *s = new CppUnit::TestSuite("gr-analog"); + + s->addTest(gr::analog::qa_sincos::suite()); + + return s; +} diff --git a/gr-analog/lib/qa_analog.h b/gr-analog/lib/qa_analog.h new file mode 100644 index 000000000..458861cc9 --- /dev/null +++ b/gr-analog/lib/qa_analog.h @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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 _QA_GR_ANALOG_H_ +#define _QA_GR_ANALOG_H_ + +#include +#include + +//! collect all the tests for the gr-analog directory + +class __GR_ATTR_EXPORT qa_gr_analog { + public: + //! return suite of tests for all of gr-analog directory + static CppUnit::TestSuite *suite(); +}; + + +#endif /* _QA_GR_ANALOG_H_ */ diff --git a/gr-analog/lib/qa_sincos.cc b/gr-analog/lib/qa_sincos.cc new file mode 100644 index 000000000..62642c117 --- /dev/null +++ b/gr-analog/lib/qa_sincos.cc @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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 +#endif + +#include +#include +#include +#include +#include + +namespace gr { + namespace analog { + + void + qa_sincos::t1() + { + static const unsigned int N = 1000; + double c_sin, c_cos; + double gr_sin, gr_cos; + + for(unsigned i = 0; i < N; i++) { + double x = i/100.0; + c_sin = sin(x); + c_cos = cos(x); + + analog::sincos(x, &gr_sin, &gr_cos); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(c_sin, gr_sin, 0.0001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(c_cos, gr_cos, 0.0001); + } + } + + void + qa_sincos::t2() + { + static const unsigned int N = 1000; + float c_sin, c_cos; + float gr_sin, gr_cos; + + for(unsigned i = 0; i < N; i++) { + float x = i/100.0; + c_sin = sinf(x); + c_cos = cosf(x); + + analog::sincosf(x, &gr_sin, &gr_cos); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(c_sin, gr_sin, 0.0001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(c_cos, gr_cos, 0.0001); + } + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/qa_sincos.h b/gr-analog/lib/qa_sincos.h new file mode 100644 index 000000000..f18e879dd --- /dev/null +++ b/gr-analog/lib/qa_sincos.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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 _QA_ANALOG_SINCOS_H_ +#define _QA_ANALOG_SINCOS_H_ + +#include +#include + +namespace gr { + namespace analog { + + class qa_sincos : public CppUnit::TestCase + { + CPPUNIT_TEST_SUITE(qa_sincos); + CPPUNIT_TEST(t1); + CPPUNIT_TEST(t2); + CPPUNIT_TEST_SUITE_END(); + + private: + void t1(); + void t2(); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* _QA_ANALOG_SINCOS_H_ */ diff --git a/gr-analog/lib/sincos.c b/gr-analog/lib/sincos.c new file mode 100644 index 000000000..aa72b1cd4 --- /dev/null +++ b/gr-analog/lib/sincos.c @@ -0,0 +1,86 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012 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 + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE // ask for GNU extensions if available +#endif + +#include +#include + +namespace gr { + namespace analog { + +// ---------------------------------------------------------------- + +#if defined (HAVE_SINCOS) + + void + sincos(double x, double *sinx, double *cosx) + { + sincos(x, sinx, cosx); + } + +#else + + void + sincos(double x, double *sinx, double *cosx) + { + *sinx = sin(x); + *cosx = cos(x); + } + +#endif + +// ---------------------------------------------------------------- + +#if defined (HAVE_SINCOSF) + + void + sincosf(float x, float *sinx, float *cosx) + { + sincosf(x, sinx, cosx); + } + +#elif defined (HAVE_SINF) && defined (HAVE_COSF) + + void + sincosf(float x, float *sinx, float *cosx) + { + *sinx = sinf(x); + *cosx = cosf(x); + } + +#else + + void + sincosf(float x, float *sinx, float *cosx) + { + *sinx = sin(x); + *cosx = cos(x); + } + +#endif diff --git a/gr-analog/lib/test_gr_analog.cc b/gr-analog/lib/test_gr_analog.cc new file mode 100644 index 000000000..00d624269 --- /dev/null +++ b/gr-analog/lib/test_gr_analog.cc @@ -0,0 +1,43 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +#include +#include + +#include +#include "qa_analog.h" +#include + +int +main (int argc, char **argv) +{ + CppUnit::TextTestRunner runner; + std::ofstream xmlfile(get_unittest_path("gr_analog.xml").c_str()); + CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile); + + runner.addTest(qa_gr_analog::suite()); + runner.setOutputter(xmlout); + + bool was_successful = runner.run("", false); + + return was_successful ? 0 : 1; +} -- cgit From c8b0062aeb430e9e8655014a430e5a8899278881 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Tue, 30 Oct 2012 22:16:54 -0400 Subject: analog: adding rotator to gr-analog with QA. --- gr-analog/include/analog/CMakeLists.txt | 1 + gr-analog/include/analog/rotator.h | 63 +++++++++++++++++++++++++ gr-analog/lib/CMakeLists.txt | 1 + gr-analog/lib/qa_analog.cc | 2 + gr-analog/lib/qa_rotator.cc | 81 +++++++++++++++++++++++++++++++++ gr-analog/lib/qa_rotator.h | 45 ++++++++++++++++++ 6 files changed, 193 insertions(+) create mode 100644 gr-analog/include/analog/rotator.h create mode 100644 gr-analog/lib/qa_rotator.cc create mode 100644 gr-analog/lib/qa_rotator.h diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index f2c0f6d6f..83a6ccd98 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -97,6 +97,7 @@ install(FILES probe_avg_mag_sqrd_c.h probe_avg_mag_sqrd_cf.h probe_avg_mag_sqrd_f.h + rotator.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog COMPONENT "analog_devel" ) diff --git a/gr-analog/include/analog/rotator.h b/gr-analog/include/analog/rotator.h new file mode 100644 index 000000000..7f7bae222 --- /dev/null +++ b/gr-analog/include/analog/rotator.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003,2008,2012 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 _ANALOG_ROTATOR_H_ +#define _ANALOG_ROTATOR_H_ + +#include +#include + +namespace gr { + namespace analog { + + class ANALOG_API rotator + { + private: + gr_complex d_phase; + gr_complex d_phase_incr; + unsigned int d_counter; + + public: + rotator() : d_phase (1), d_phase_incr (1), d_counter(0) + { } + + void set_phase(gr_complex phase) { d_phase = phase / abs(phase); } + void set_phase_incr(gr_complex incr) { d_phase_incr = incr / abs(incr); } + + gr_complex rotate (gr_complex in) + { + d_counter++; + + gr_complex z = in * d_phase; // rotate in by phase + d_phase *= d_phase_incr; // incr our phase (complex mult == add phases) + + if((d_counter % 512) == 0) + d_phase /= abs(d_phase); // Normalize to ensure multiplication is rotation + + return z; + } + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* _ANALOG_ROTATOR_H_ */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index e0e621d13..c93c220cc 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -153,6 +153,7 @@ if(ENABLE_TESTING) ${CMAKE_CURRENT_SOURCE_DIR}/test_gr_analog.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_analog.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_sincos.cc + ${CMAKE_CURRENT_SOURCE_DIR}/qa_rotator.cc ) add_executable(test-gr-analog ${test_gr_analog_sources}) diff --git a/gr-analog/lib/qa_analog.cc b/gr-analog/lib/qa_analog.cc index ceecb096d..c3d51863b 100644 --- a/gr-analog/lib/qa_analog.cc +++ b/gr-analog/lib/qa_analog.cc @@ -27,6 +27,7 @@ #include #include +#include CppUnit::TestSuite * qa_gr_analog::suite() @@ -34,6 +35,7 @@ qa_gr_analog::suite() CppUnit::TestSuite *s = new CppUnit::TestSuite("gr-analog"); s->addTest(gr::analog::qa_sincos::suite()); + s->addTest(gr::analog::qa_rotator::suite()); return s; } diff --git a/gr-analog/lib/qa_rotator.cc b/gr-analog/lib/qa_rotator.cc new file mode 100644 index 000000000..b722f32c4 --- /dev/null +++ b/gr-analog/lib/qa_rotator.cc @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2012 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 +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace gr { + namespace analog { + + // error vector magnitude + __GR_ATTR_UNUSED static float + error_vector_mag(gr_complex a, gr_complex b) + { + return abs(a-b); + } + + void + qa_rotator::t1() + { + static const unsigned int N = 100000; + + rotator r; + + double phase_incr = 2*M_PI / 1003; + double phase = 0; + + // Old code: We increment then return the rotated value, thus we + // need to start one tick back + // r.set_phase(gr_complex(1,0) * conj(gr_expj(phase_incr))); + + r.set_phase(gr_complex(1,0)); + r.set_phase_incr(gr_expj(phase_incr)); + + for(unsigned i = 0; i < N; i++) { + gr_complex expected = gr_expj(phase); + gr_complex actual = r.rotate(gr_complex(1, 0)); + +#if 0 + float evm = error_vector_mag(expected, actual); + printf("[%6d] expected: (%8.6f, %8.6f) actual: (%8.6f, %8.6f) evm: %8.6f\n", + i, expected.real(), expected.imag(), actual.real(), actual.imag(), evm); +#endif + + CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected, actual, 0.0001); + + phase += phase_incr; + if(phase >= 2*M_PI) + phase -= 2*M_PI; + } + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/qa_rotator.h b/gr-analog/lib/qa_rotator.h new file mode 100644 index 000000000..a22e41ec2 --- /dev/null +++ b/gr-analog/lib/qa_rotator.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2012 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 _QA_ANALOG_ROTATOR_H_ +#define _QA_ANALOG_ROTATOR_H_ + +#include +#include + +namespace gr { + namespace analog { + + class qa_rotator : public CppUnit::TestCase + { + CPPUNIT_TEST_SUITE(qa_rotator); + CPPUNIT_TEST(t1); + CPPUNIT_TEST_SUITE_END(); + + private: + void t1(); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* _QA_ANALOG_ROTATOR_H_ */ -- cgit From 0353e0b56734c62884c7fd6d3634a28bafbae74f Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Wed, 31 Oct 2012 11:04:49 -0400 Subject: analog: adding sig_source to gr-analog with QA and GRC. --- gr-analog/grc/analog_block_tree.xml | 1 + gr-analog/grc/analog_sig_source_x.xml | 104 ++++++++++ gr-analog/include/analog/CMakeLists.txt | 2 + gr-analog/include/analog/sig_source_X.h.t | 75 ++++++++ gr-analog/include/analog/sig_source_waveform.h | 41 ++++ gr-analog/lib/CMakeLists.txt | 1 + gr-analog/lib/sig_source_X_impl.cc.t | 253 +++++++++++++++++++++++++ gr-analog/lib/sig_source_X_impl.h.t | 70 +++++++ gr-analog/python/qa_sig_source.py | 160 ++++++++++++++++ gr-analog/swig/analog_swig.i | 14 ++ 10 files changed, 721 insertions(+) create mode 100644 gr-analog/grc/analog_sig_source_x.xml create mode 100644 gr-analog/include/analog/sig_source_X.h.t create mode 100644 gr-analog/include/analog/sig_source_waveform.h create mode 100644 gr-analog/lib/sig_source_X_impl.cc.t create mode 100644 gr-analog/lib/sig_source_X_impl.h.t create mode 100755 gr-analog/python/qa_sig_source.py diff --git a/gr-analog/grc/analog_block_tree.xml b/gr-analog/grc/analog_block_tree.xml index 7283d9f5a..5043e9562 100644 --- a/gr-analog/grc/analog_block_tree.xml +++ b/gr-analog/grc/analog_block_tree.xml @@ -44,6 +44,7 @@ Sources + analog_sig_source_x analog_noise_source_x diff --git a/gr-analog/grc/analog_sig_source_x.xml b/gr-analog/grc/analog_sig_source_x.xml new file mode 100644 index 000000000..b2cd8ad43 --- /dev/null +++ b/gr-analog/grc/analog_sig_source_x.xml @@ -0,0 +1,104 @@ + + + + Signal Source + analog_sig_source_x + from gnuradio import analog + analog.sig_source_$(type.fcn)($samp_rate, $waveform, $freq, $amp, $offset) + set_sampling_freq($samp_rate) + set_waveform($waveform) + set_frequency($freq) + set_amplitude($amp) + set_offset($offset) + + Output Type + type + enum + + + + + + + Sample Rate + samp_rate + samp_rate + real + + + Waveform + waveform + analog.GR_COS_WAVE + int + + + + + + + + + Frequency + freq + 1000 + real + + + Amplitude + amp + 1 + real + + + Offset + offset + 0 + $type.offset_type + + + out + $type + + diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index 83a6ccd98..99839449b 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -65,6 +65,7 @@ endmacro(expand_h) # Invoke macro to generate various sources ####################################################################### expand_h(noise_source_X s i f c) +expand_h(sig_source_X s i f c) add_custom_target(analog_generated_includes DEPENDS ${generated_includes} @@ -98,6 +99,7 @@ install(FILES probe_avg_mag_sqrd_cf.h probe_avg_mag_sqrd_f.h rotator.h + sig_source_waveform.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog COMPONENT "analog_devel" ) diff --git a/gr-analog/include/analog/sig_source_X.h.t b/gr-analog/include/analog/sig_source_X.h.t new file mode 100644 index 000000000..2915c2abe --- /dev/null +++ b/gr-analog/include/analog/sig_source_X.h.t @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 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. + */ + +/* @WARNING@ */ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief signal generator with @TYPE@ output. + * \ingroup source_blk + */ + class ANALOG_API @BASE_NAME@ : virtual public gr_sync_block + { + public: + // gr::analog::@BASE_NAME@::sptr + typedef boost::shared_ptr<@BASE_NAME@> sptr; + + /*! + * \brief Make a signal source block. + * + * \param sampling_freq Sampling rate of signal. + * \param waveform wavetform type. + * \param wave_freq Frequency of waveform (relative to sampling_freq). + * \param ampl Signal amplitude. + * \param offset offset of signal. + */ + static sptr make(double sampling_freq, + gr::analog::gr_waveform_t waveform, + double wave_freq, + double ampl, @TYPE@ offset = 0); + + virtual double sampling_freq() const = 0; + virtual gr::analog::gr_waveform_t waveform() const = 0; + virtual double frequency() const = 0; + virtual double amplitude() const = 0; + virtual @TYPE@ offset() const = 0; + + virtual void set_sampling_freq(double sampling_freq) = 0; + virtual void set_waveform(gr::analog::gr_waveform_t waveform) = 0; + virtual void set_frequency(double frequency) = 0; + virtual void set_amplitude(double ampl) = 0; + virtual void set_offset(@TYPE@ offset) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-analog/include/analog/sig_source_waveform.h b/gr-analog/include/analog/sig_source_waveform.h new file mode 100644 index 000000000..3a9edb8f3 --- /dev/null +++ b/gr-analog/include/analog/sig_source_waveform.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 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_ANALOG_SIG_SOURCE_WAVEFORM_H +#define INCLUDED_ANALOG_SIG_SOURCE_WAVEFORM_H + +namespace gr { + namespace analog { + + typedef enum { + GR_CONST_WAVE = 100, + GR_SIN_WAVE, + GR_COS_WAVE, + GR_SQR_WAVE, + GR_TRI_WAVE, + GR_SAW_WAVE + } gr_waveform_t; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SIG_SOURCE_WAVEFORM_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index c93c220cc..6b64c019d 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -99,6 +99,7 @@ endmacro(expand_cc) # Invoke macro to generate various sources ######################################################################## expand_cc(noise_source_X_impl s i f c) +expand_cc(sig_source_X_impl s i f c) ######################################################################## # Setup library diff --git a/gr-analog/lib/sig_source_X_impl.cc.t b/gr-analog/lib/sig_source_X_impl.cc.t new file mode 100644 index 000000000..60653dc1b --- /dev/null +++ b/gr-analog/lib/sig_source_X_impl.cc.t @@ -0,0 +1,253 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012 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. + */ + +/* @WARNING@ */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "@IMPL_NAME@.h" +#include +#include +#include +#include +#include + +namespace gr { + namespace analog { + + @BASE_NAME@::sptr + @BASE_NAME@::make(double sampling_freq, gr_waveform_t waveform, + double frequency, double ampl, @TYPE@ offset) + { + return gnuradio::get_initial_sptr + (new @IMPL_NAME@(sampling_freq, waveform, frequency, ampl, offset)); + } + + @IMPL_NAME@::@IMPL_NAME@(double sampling_freq, gr_waveform_t waveform, + double frequency, double ampl, @TYPE@ offset) + : gr_sync_block("@BASE_NAME@", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, sizeof(@TYPE@))), + d_sampling_freq(sampling_freq), d_waveform(waveform), + d_frequency(frequency), d_ampl(ampl), d_offset(offset) + { + d_nco.set_freq(2 * M_PI * d_frequency / d_sampling_freq); + } + + @IMPL_NAME@::~@IMPL_NAME@() + { + } + + int + @IMPL_NAME@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + @TYPE@ *optr = (@TYPE@*)output_items[0]; + @TYPE@ t; + + switch(d_waveform) { + +#if @IS_COMPLEX@ // complex? + + case GR_CONST_WAVE: + t = (gr_complex) d_ampl + d_offset; + std::fill_n(optr, noutput_items, t); + break; + + case GR_SIN_WAVE: + case GR_COS_WAVE: + d_nco.sincos(optr, noutput_items, d_ampl); + if(d_offset == gr_complex(0,0)) + break; + + for(int i = 0; i < noutput_items; i++) { + optr[i] += d_offset; + } + break; + + /* Implements a real square wave high from -PI to 0. + * The imaginary square wave leads by 90 deg. + */ + case GR_SQR_WAVE: + for(int i = 0; i < noutput_items; i++) { + if(d_nco.get_phase() < -1*M_PI/2) + optr[i] = gr_complex(d_ampl, 0) + d_offset; + else if(d_nco.get_phase() < 0) + optr[i] = gr_complex(d_ampl, d_ampl) + d_offset; + else if(d_nco.get_phase() < M_PI/2) + optr[i] = gr_complex(0, d_ampl) + d_offset; + else + optr[i] = d_offset; + d_nco.step(); + } + break; + + /* Implements a real triangle wave rising from -PI to 0 and + * falling from 0 to PI. The imaginary triangle wave leads by + * 90 deg. + */ + case GR_TRI_WAVE: + for(int i = 0; i < noutput_items; i++) { + if(d_nco.get_phase() < -1*M_PI/2){ + optr[i] = gr_complex(d_ampl*d_nco.get_phase()/M_PI + d_ampl, + -1*d_ampl*d_nco.get_phase()/M_PI - d_ampl/2) + d_offset; + } + else if(d_nco.get_phase() < 0) { + optr[i] = gr_complex(d_ampl*d_nco.get_phase()/M_PI + d_ampl, + d_ampl*d_nco.get_phase()/M_PI + d_ampl/2) + d_offset; + } + else if(d_nco.get_phase() < M_PI/2) { + optr[i] = gr_complex(-1*d_ampl*d_nco.get_phase()/M_PI + d_ampl, + d_ampl*d_nco.get_phase()/M_PI + d_ampl/2) + d_offset; + } + else { + optr[i] = gr_complex(-1*d_ampl*d_nco.get_phase()/M_PI + d_ampl, + -1*d_ampl*d_nco.get_phase()/M_PI + 3*d_ampl/2) + d_offset; + } + d_nco.step(); + } + break; + + /* Implements a real saw tooth wave rising from -PI to PI. + * The imaginary saw tooth wave leads by 90 deg. + */ + case GR_SAW_WAVE: + for(int i = 0; i < noutput_items; i++) { + if(d_nco.get_phase() < -1*M_PI/2) { + optr[i] = gr_complex(d_ampl*d_nco.get_phase()/(2*M_PI) + d_ampl/2, + d_ampl*d_nco.get_phase()/(2*M_PI) + 5*d_ampl/4) + d_offset; + } + else { + optr[i] = gr_complex(d_ampl*d_nco.get_phase()/(2*M_PI) + d_ampl/2, + d_ampl*d_nco.get_phase()/(2*M_PI) + d_ampl/4) + d_offset; + } + d_nco.step(); + } + break; + +#else // nope... + + case GR_CONST_WAVE: + t = (@TYPE@)d_ampl + d_offset; + std::fill_n(optr, noutput_items, t); + break; + + case GR_SIN_WAVE: + d_nco.sin(optr, noutput_items, d_ampl); + if(d_offset == 0) + break; + + for(int i = 0; i < noutput_items; i++) { + optr[i] += d_offset; + } + break; + + case GR_COS_WAVE: + d_nco.cos(optr, noutput_items, d_ampl); + if(d_offset == 0) + break; + + for(int i = 0; i < noutput_items; i++) { + optr[i] += d_offset; + } + break; + + /* The square wave is high from -PI to 0. */ + case GR_SQR_WAVE: + t = (@TYPE@)d_ampl + d_offset; + for(int i = 0; i < noutput_items; i++) { + if(d_nco.get_phase() < 0) + optr[i] = t; + else + optr[i] = d_offset; + d_nco.step(); + } + break; + + /* The triangle wave rises from -PI to 0 and falls from 0 to PI. */ + case GR_TRI_WAVE: + for(int i = 0; i < noutput_items; i++) { + double t = d_ampl*d_nco.get_phase()/M_PI; + if (d_nco.get_phase() < 0) + optr[i] = static_cast<@TYPE@>(t + d_ampl + d_offset); + else + optr[i] = static_cast<@TYPE@>(-1*t + d_ampl + d_offset); + d_nco.step(); + } + break; + + /* The saw tooth wave rises from -PI to PI. */ + case GR_SAW_WAVE: + for(int i = 0; i < noutput_items; i++) { + t = static_cast<@TYPE@>(d_ampl*d_nco.get_phase()/(2*M_PI) + + d_ampl/2 + d_offset); + optr[i] = t; + d_nco.step(); + } + break; + +#endif + + default: + throw std::runtime_error("gr_sig_source: invalid waveform"); + } + + return noutput_items; + } + + void + @NAME@::set_sampling_freq(double sampling_freq) + { + d_sampling_freq = sampling_freq; + d_nco.set_freq (2 * M_PI * d_frequency / d_sampling_freq); + } + + void + @NAME@::set_waveform(gr_waveform_t waveform) + { + d_waveform = waveform; + } + + void + @NAME@::set_frequency(double frequency) + { + d_frequency = frequency; + d_nco.set_freq(2 * M_PI * d_frequency / d_sampling_freq); + } + + void + @NAME@::set_amplitude(double ampl) + { + d_ampl = ampl; + } + + void + @NAME@::set_offset(@TYPE@ offset) + { + d_offset = offset; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/sig_source_X_impl.h.t b/gr-analog/lib/sig_source_X_impl.h.t new file mode 100644 index 000000000..50f179127 --- /dev/null +++ b/gr-analog/lib/sig_source_X_impl.h.t @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 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. + */ + +/* @WARNING@ */ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include +#include +#include + +namespace gr { + namespace analog { + + class @IMPL_NAME@ : public @BASE_NAME@ + { + private: + double d_sampling_freq; + gr_waveform_t d_waveform; + double d_frequency; + double d_ampl; + @TYPE@ d_offset; + gr_fxpt_nco d_nco; + + public: + @IMPL_NAME@(double sampling_freq, gr_waveform_t waveform, + double wave_freq, double ampl, @TYPE@ offset = 0); + ~@IMPL_NAME@(); + + virtual int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + double sampling_freq() const { return d_sampling_freq; } + gr_waveform_t waveform() const { return d_waveform; } + double frequency() const { return d_frequency; } + double amplitude() const { return d_ampl; } + @TYPE@ offset() const { return d_offset; } + + void set_sampling_freq(double sampling_freq); + void set_waveform(gr_waveform_t waveform); + void set_frequency(double frequency); + void set_amplitude(double ampl); + void set_offset(@TYPE@ offset); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-analog/python/qa_sig_source.py b/gr-analog/python/qa_sig_source.py new file mode 100755 index 000000000..bc48333ed --- /dev/null +++ b/gr-analog/python/qa_sig_source.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python +# +# Copyright 2004,2007,2010,2012 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, gr_unittest +import analog_swig as analog +import math + +class test_sig_source(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_const_f(self): + tb = self.tb + expected_result = (1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5) + src1 = analog.sig_source_f(1e6, analog.GR_CONST_WAVE, 0, 1.5) + op = gr.head(gr.sizeof_float, 10) + dst1 = gr.vector_sink_f() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + def test_const_i(self): + tb = self.tb + expected_result = (1, 1, 1, 1) + src1 = analog.sig_source_i(1e6, analog.GR_CONST_WAVE, 0, 1) + op = gr.head(gr.sizeof_int, 4) + dst1 = gr.vector_sink_i() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + def test_sine_f(self): + tb = self.tb + sqrt2 = math.sqrt(2) / 2 + expected_result = (0, sqrt2, 1, sqrt2, 0, -sqrt2, -1, -sqrt2, 0) + src1 = analog.sig_source_f(8, analog.GR_SIN_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_float, 9) + dst1 = gr.vector_sink_f() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5) + + def test_cosine_f(self): + tb = self.tb + sqrt2 = math.sqrt(2) / 2 + expected_result = (1, sqrt2, 0, -sqrt2, -1, -sqrt2, 0, sqrt2, 1) + src1 = analog.sig_source_f(8, analog.GR_COS_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_float, 9) + dst1 = gr.vector_sink_f() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5) + + def test_sqr_c(self): + tb = self.tb #arg6 is a bit before -PI/2 + expected_result = (1j, 1j, 0, 0, 1, 1, 1+0j, 1+1j, 1j) + src1 = analog.sig_source_c(8, analog.GR_SQR_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_gr_complex, 9) + dst1 = gr.vector_sink_c() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + def test_tri_c(self): + tb = self.tb + expected_result = (1+.5j, .75+.75j, .5+1j, .25+.75j, 0+.5j, + .25+.25j, .5+0j, .75+.25j, 1+.5j) + src1 = analog.sig_source_c(8, analog.GR_TRI_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_gr_complex, 9) + dst1 = gr.vector_sink_c() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 5) + + def test_saw_c(self): + tb = self.tb + expected_result = (.5+.25j, .625+.375j, .75+.5j, .875+.625j, + 0+.75j, .125+.875j, .25+1j, .375+.125j, .5+.25j) + src1 = analog.sig_source_c(8, analog.GR_SAW_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_gr_complex, 9) + dst1 = gr.vector_sink_c() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 5) + + def test_sqr_f(self): + tb = self.tb + expected_result = (0, 0, 0, 0, 1, 1, 1, 1, 0) + src1 = analog.sig_source_f(8, analog.GR_SQR_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_float, 9) + dst1 = gr.vector_sink_f() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertEqual(expected_result, dst_data) + + def test_tri_f(self): + tb = self.tb + expected_result = (1, .75, .5, .25, 0, .25, .5, .75, 1) + src1 = analog.sig_source_f(8, analog.GR_TRI_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_float, 9) + dst1 = gr.vector_sink_f() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5) + + def test_saw_f(self): + tb = self.tb + expected_result = (.5, .625, .75, .875, 0, .125, .25, .375, .5) + src1 = analog.sig_source_f(8, analog.GR_SAW_WAVE, 1.0, 1.0) + op = gr.head(gr.sizeof_float, 9) + dst1 = gr.vector_sink_f() + tb.connect(src1, op) + tb.connect(op, dst1) + tb.run() + dst_data = dst1.data() + self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_sig_source, "test_sig_source.xml") diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 83b61c32d..f23fa6d00 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -53,6 +53,11 @@ #include "analog/probe_avg_mag_sqrd_cf.h" #include "analog/probe_avg_mag_sqrd_f.h" #include "analog/sincos.h" +#include "analog/sig_source_s.h" +#include "analog/sig_source_i.h" +#include "analog/sig_source_f.h" +#include "analog/sig_source_c.h" +#include "analog/sig_source_waveform.h" #include "analog/squelch_base_cc.h" #include "analog/squelch_base_ff.h" %} @@ -82,6 +87,11 @@ %include "analog/probe_avg_mag_sqrd_cf.h" %include "analog/probe_avg_mag_sqrd_f.h" %include "analog/sincos.h" +%include "analog/sig_source_s.h" +%include "analog/sig_source_i.h" +%include "analog/sig_source_f.h" +%include "analog/sig_source_c.h" +%include "analog/sig_source_waveform.h" %include "analog/squelch_base_cc.h" %include "analog/squelch_base_ff.h" @@ -106,3 +116,7 @@ GR_SWIG_BLOCK_MAGIC2(analog, pll_refout_cc); GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_c); GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_cf); GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_f); +GR_SWIG_BLOCK_MAGIC2(analog, sig_source_s); +GR_SWIG_BLOCK_MAGIC2(analog, sig_source_i); +GR_SWIG_BLOCK_MAGIC2(analog, sig_source_f); +GR_SWIG_BLOCK_MAGIC2(analog, sig_source_c); -- cgit From 54e947e394dcd2bbff2b49968adf7b0861f0851b Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Wed, 31 Oct 2012 11:42:07 -0400 Subject: analog: adding simple_squelch block to gr-analog with QA and GRC. --- gr-analog/grc/analog_block_tree.xml | 1 + gr-analog/grc/analog_simple_squelch_cc.xml | 32 ++++++++ gr-analog/include/analog/CMakeLists.txt | 1 + gr-analog/include/analog/simple_squelch_cc.h | 62 ++++++++++++++++ gr-analog/lib/CMakeLists.txt | 1 + gr-analog/lib/simple_squelch_cc_impl.cc | 106 +++++++++++++++++++++++++++ gr-analog/lib/simple_squelch_cc_impl.h | 59 +++++++++++++++ gr-analog/python/qa_simple_squelch.py | 70 ++++++++++++++++++ gr-analog/swig/analog_swig.i | 3 + 9 files changed, 335 insertions(+) create mode 100644 gr-analog/grc/analog_simple_squelch_cc.xml create mode 100644 gr-analog/include/analog/simple_squelch_cc.h create mode 100644 gr-analog/lib/simple_squelch_cc_impl.cc create mode 100644 gr-analog/lib/simple_squelch_cc_impl.h create mode 100755 gr-analog/python/qa_simple_squelch.py diff --git a/gr-analog/grc/analog_block_tree.xml b/gr-analog/grc/analog_block_tree.xml index 5043e9562..4cfcb9bc9 100644 --- a/gr-analog/grc/analog_block_tree.xml +++ b/gr-analog/grc/analog_block_tree.xml @@ -34,6 +34,7 @@ analog_agc2_xx analog_feedforward_agc_cc analog_ctcss_squelch_ff + analog_simple_squelch_cc analog_dpll_bb diff --git a/gr-analog/grc/analog_simple_squelch_cc.xml b/gr-analog/grc/analog_simple_squelch_cc.xml new file mode 100644 index 000000000..648921a14 --- /dev/null +++ b/gr-analog/grc/analog_simple_squelch_cc.xml @@ -0,0 +1,32 @@ + + + + Simple Squelch + analog_simple_squelch_cc + from gnuradio import analog + analog.simple_squelch_cc($threshold, $alpha) + set_threshold($threshold) + set_alpha($alpha) + + Threshold (dB) + threshold + real + + + Alpha + alpha + real + + + in + complex + + + out + complex + + diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index 99839449b..0d2944c3b 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -100,6 +100,7 @@ install(FILES probe_avg_mag_sqrd_f.h rotator.h sig_source_waveform.h + simple_squelch_cc.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog COMPONENT "analog_devel" ) diff --git a/gr-analog/include/analog/simple_squelch_cc.h b/gr-analog/include/analog/simple_squelch_cc.h new file mode 100644 index 000000000..1e12646e4 --- /dev/null +++ b/gr-analog/include/analog/simple_squelch_cc.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 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_ANALOG_SIMPLE_SQUELCH_CC_H +#define INCLUDED_ANALOG_SIMPLE_SQUELCH_CC_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief simple squelch block based on average signal power and threshold in dB. + * \ingroup level_blk + */ + class ANALOG_API simple_squelch_cc : virtual public gr_sync_block + { + public: + // gr::analog::simple_squelch_cc::sptr + typedef boost::shared_ptr sptr; + + /*! + * \brief Make a simple squelch block. + * + * \param threshold_db Threshold for muting. + * \param alpha Gain parameter for the running average filter. + */ + static sptr make(double threshold_db, double alpha); + + virtual bool unmuted() const = 0; + + virtual void set_alpha(double alpha) = 0; + virtual void set_threshold(double decibels) = 0; + + virtual double threshold() const = 0; + virtual std::vector squelch_range() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SIMPLE_SQUELCH_CC_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index 6b64c019d..0aed18405 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -126,6 +126,7 @@ list(APPEND analog_sources probe_avg_mag_sqrd_c_impl.cc probe_avg_mag_sqrd_cf_impl.cc probe_avg_mag_sqrd_f_impl.cc + simple_squelch_cc_impl.cc ) list(APPEND analog_libs diff --git a/gr-analog/lib/simple_squelch_cc_impl.cc b/gr-analog/lib/simple_squelch_cc_impl.cc new file mode 100644 index 000000000..02ccc535d --- /dev/null +++ b/gr-analog/lib/simple_squelch_cc_impl.cc @@ -0,0 +1,106 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2010,2012 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 "simple_squelch_cc_impl.h" +#include +#include + +namespace gr { + namespace analog { + + simple_squelch_cc::sptr + simple_squelch_cc::make(double threshold_db, double alpha) + { + return gnuradio::get_initial_sptr + (new simple_squelch_cc_impl(threshold_db, alpha)); + } + + simple_squelch_cc_impl::simple_squelch_cc_impl(double threshold_db, double alpha) + : gr_sync_block("simple_squelch_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + d_unmuted(false), d_iir(alpha) + { + set_threshold(threshold_db); + } + + simple_squelch_cc_impl::~simple_squelch_cc_impl() + { + } + + void + simple_squelch_cc_impl::set_threshold(double decibels) + { + // convert to absolute threshold (mag squared) + d_threshold = std::pow(10.0, decibels/10); + } + + double + simple_squelch_cc_impl::threshold() const + { + return 10 * log10(d_threshold); + } + + void + simple_squelch_cc_impl::set_alpha(double alpha) + { + d_iir.set_taps(alpha); + } + + std::vector + simple_squelch_cc_impl::squelch_range() const + { + std::vector r(3); + r[0] = -50.0; // min FIXME + r[1] = +50.0; // max FIXME + r[2] = (r[1] - r[0]) / 100; // step size + + return r; + } + + int + simple_squelch_cc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + for(int i = 0; i < noutput_items; i++) { + double mag_sqrd = in[i].real()*in[i].real() + in[i].imag()*in[i].imag(); + double f = d_iir.filter(mag_sqrd); + if(f >= d_threshold) + out[i] = in[i]; + else + out[i] = 0; + } + + d_unmuted = d_iir.prev_output() >= d_threshold; + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/simple_squelch_cc_impl.h b/gr-analog/lib/simple_squelch_cc_impl.h new file mode 100644 index 000000000..ba11de91e --- /dev/null +++ b/gr-analog/lib/simple_squelch_cc_impl.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2012 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_ANALOG_SIMPLE_SQUELCH_CC_IMPL_H +#define INCLUDED_ANALOG_SIMPLE_SQUELCH_CC_IMPL_H + +#include +#include + +namespace gr { + namespace analog { + + class simple_squelch_cc_impl : public simple_squelch_cc + { + private: + double d_threshold; + bool d_unmuted; + filter::single_pole_iir d_iir; + + public: + simple_squelch_cc_impl(double threshold_db, double alpha); + ~simple_squelch_cc_impl(); + + bool unmuted() const { return d_unmuted; } + + void set_alpha(double alpha); + void set_threshold(double decibels); + + double threshold() const; + std::vector squelch_range() const; + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_SIMPLE_SQUELCH_CC_IMPL_H */ diff --git a/gr-analog/python/qa_simple_squelch.py b/gr-analog/python/qa_simple_squelch.py new file mode 100755 index 000000000..97deee06c --- /dev/null +++ b/gr-analog/python/qa_simple_squelch.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# Copyright 2012 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, gr_unittest +import analog_swig as analog + +class test_simple_squelch(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_simple_squelch_001(self): + # Test set/gets + + alpha = 0.0001 + + thr1 = 10 + thr2 = 20 + + op = analog.simple_squelch_cc(thr1, alpha) + + op.set_threshold(thr2) + t = op.threshold() + self.assertEqual(thr2, t) + + def test_simple_squelch_002(self): + # Test runtime, gate=True + alpha = 0.0001 + thr = -25 + + src_data = map(lambda x: float(x)/10.0, range(1, 40)) + src = gr.vector_source_c(src_data) + op = analog.simple_squelch_cc(thr, alpha) + dst = gr.vector_sink_c() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + expected_result = src_data + expected_result[0:20] = 20*[0,] + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_simple_squelch, "test_simple_squelch.xml") + diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index f23fa6d00..2e36e4e71 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -58,6 +58,7 @@ #include "analog/sig_source_f.h" #include "analog/sig_source_c.h" #include "analog/sig_source_waveform.h" +#include "analog/simple_squelch_cc.h" #include "analog/squelch_base_cc.h" #include "analog/squelch_base_ff.h" %} @@ -92,6 +93,7 @@ %include "analog/sig_source_f.h" %include "analog/sig_source_c.h" %include "analog/sig_source_waveform.h" +%include "analog/simple_squelch_cc.h" %include "analog/squelch_base_cc.h" %include "analog/squelch_base_ff.h" @@ -120,3 +122,4 @@ GR_SWIG_BLOCK_MAGIC2(analog, sig_source_s); GR_SWIG_BLOCK_MAGIC2(analog, sig_source_i); GR_SWIG_BLOCK_MAGIC2(analog, sig_source_f); GR_SWIG_BLOCK_MAGIC2(analog, sig_source_c); +GR_SWIG_BLOCK_MAGIC2(analog, simple_squelch_cc); -- cgit From 300f7b5313ff79d9f3d9c19e109e71ee608bea86 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Wed, 31 Oct 2012 13:15:25 -0400 Subject: analog: adding pwr_squelch blocks to gr-analog with QA and GRC. --- gr-analog/grc/analog_block_tree.xml | 3 +- gr-analog/grc/analog_pwr_squelch_xx.xml | 65 +++++++++++++++ gr-analog/include/analog/CMakeLists.txt | 2 + gr-analog/include/analog/pwr_squelch_cc.h | 75 +++++++++++++++++ gr-analog/include/analog/pwr_squelch_ff.h | 75 +++++++++++++++++ gr-analog/include/analog/squelch_base_cc.h | 2 +- gr-analog/lib/CMakeLists.txt | 2 + gr-analog/lib/pwr_squelch_cc_impl.cc | 73 ++++++++++++++++ gr-analog/lib/pwr_squelch_cc_impl.h | 78 ++++++++++++++++++ gr-analog/lib/pwr_squelch_ff_impl.cc | 73 ++++++++++++++++ gr-analog/lib/pwr_squelch_ff_impl.h | 78 ++++++++++++++++++ gr-analog/python/qa_ctcss_squelch.py | 2 +- gr-analog/python/qa_pwr_squelch.py | 128 +++++++++++++++++++++++++++++ gr-analog/python/qa_simple_squelch.py | 3 +- gr-analog/swig/analog_swig.i | 6 ++ 15 files changed, 660 insertions(+), 5 deletions(-) create mode 100644 gr-analog/grc/analog_pwr_squelch_xx.xml create mode 100644 gr-analog/include/analog/pwr_squelch_cc.h create mode 100644 gr-analog/include/analog/pwr_squelch_ff.h create mode 100644 gr-analog/lib/pwr_squelch_cc_impl.cc create mode 100644 gr-analog/lib/pwr_squelch_cc_impl.h create mode 100644 gr-analog/lib/pwr_squelch_ff_impl.cc create mode 100644 gr-analog/lib/pwr_squelch_ff_impl.h create mode 100755 gr-analog/python/qa_pwr_squelch.py diff --git a/gr-analog/grc/analog_block_tree.xml b/gr-analog/grc/analog_block_tree.xml index 4cfcb9bc9..5c5680744 100644 --- a/gr-analog/grc/analog_block_tree.xml +++ b/gr-analog/grc/analog_block_tree.xml @@ -32,10 +32,11 @@ Level Controls analog_agc_xx analog_agc2_xx + analog_dpll_bb analog_feedforward_agc_cc analog_ctcss_squelch_ff + analog_pwr_squelch_xx analog_simple_squelch_cc - analog_dpll_bb Modulators diff --git a/gr-analog/grc/analog_pwr_squelch_xx.xml b/gr-analog/grc/analog_pwr_squelch_xx.xml new file mode 100644 index 000000000..32d9c0e94 --- /dev/null +++ b/gr-analog/grc/analog_pwr_squelch_xx.xml @@ -0,0 +1,65 @@ + + + + Power Squelch + analog_pwr_squelch_xx + from gnuradio import analog + analog.pwr_squelch_$(type.fcn)($threshold, $alpha, $ramp, $gate) + set_threshold($threshold) + set_alpha($alpha) + + Type + type + enum + + + + + Threshold (dB) + threshold + real + + + Alpha + alpha + real + + + Ramp + ramp + int + + + Gate + gate + enum + + + + + in + $type + + + out + $type + + diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index 0d2944c3b..25ce50dd8 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -98,6 +98,8 @@ install(FILES probe_avg_mag_sqrd_c.h probe_avg_mag_sqrd_cf.h probe_avg_mag_sqrd_f.h + pwr_squelch_cc.h + pwr_squelch_ff.h rotator.h sig_source_waveform.h simple_squelch_cc.h diff --git a/gr-analog/include/analog/pwr_squelch_cc.h b/gr-analog/include/analog/pwr_squelch_cc.h new file mode 100644 index 000000000..79364a86b --- /dev/null +++ b/gr-analog/include/analog/pwr_squelch_cc.h @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_PWR_SQUELCH_CC_H +#define INCLUDED_ANALOG_PWR_SQUELCH_CC_H + +#include +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief gate or zero output when input power below threshold + * \ingroup level_blk + */ + class ANALOG_API pwr_squelch_cc : + public squelch_base_cc, virtual public gr_block + { + protected: + virtual void update_state(const gr_complex &in) = 0; + virtual bool mute() const = 0; + + public: + // gr::analog::pwr_squelch_cc::sptr + typedef boost::shared_ptr sptr; + + /*! + * \brief Make power-based squelch block. + * + * \param db threshold (in dB) for power squelch + * \param alpha Gain of averaging filter + * \param ramp + * \param gate + */ + static sptr make(double db, double alpha=0.0001, + int ramp=0, bool gate=false); + + virtual std::vector squelch_range() const = 0; + + virtual double threshold() const = 0; + virtual void set_threshold(double db) = 0; + virtual void set_alpha(double alpha) = 0; + + virtual int ramp() const = 0; + virtual void set_ramp(int ramp) = 0; + virtual bool gate() const = 0; + virtual void set_gate(bool gate) = 0; + virtual bool unmuted() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PWR_SQUELCH_CC_H */ diff --git a/gr-analog/include/analog/pwr_squelch_ff.h b/gr-analog/include/analog/pwr_squelch_ff.h new file mode 100644 index 000000000..6fdebec74 --- /dev/null +++ b/gr-analog/include/analog/pwr_squelch_ff.h @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_PWR_SQUELCH_FF_H +#define INCLUDED_ANALOG_PWR_SQUELCH_FF_H + +#include +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief gate or zero output when input power below threshold + * \ingroup level_blk + */ + class ANALOG_API pwr_squelch_ff : + public squelch_base_ff, virtual public gr_block + { + protected: + virtual void update_state(const float &in) = 0; + virtual bool mute() const = 0; + + public: + // gr::analog::pwr_squelch_ff::sptr + typedef boost::shared_ptr sptr; + + /*! + * \brief Make power-based squelch block. + * + * \param db threshold (in dB) for power squelch + * \param alpha Gain of averaging filter + * \param ramp + * \param gate + */ + static sptr make(double db, double alpha=0.0001, + int ramp=0, bool gate=false); + + virtual std::vector squelch_range() const = 0; + + virtual double threshold() const = 0; + virtual void set_threshold(double db) = 0; + virtual void set_alpha(double alpha) = 0; + + virtual int ramp() const = 0; + virtual void set_ramp(int ramp) = 0; + virtual bool gate() const = 0; + virtual void set_gate(bool gate) = 0; + virtual bool unmuted() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PWR_SQUELCH_FF_H */ diff --git a/gr-analog/include/analog/squelch_base_cc.h b/gr-analog/include/analog/squelch_base_cc.h index 4c2a7b352..11476e7e8 100644 --- a/gr-analog/include/analog/squelch_base_cc.h +++ b/gr-analog/include/analog/squelch_base_cc.h @@ -36,7 +36,7 @@ namespace gr { class ANALOG_API squelch_base_cc : virtual public gr_block { protected: - virtual void update_state(const float &sample) = 0; + virtual void update_state(const gr_complex &sample) = 0; virtual bool mute() const = 0; public: diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index 0aed18405..9a620133a 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -126,6 +126,8 @@ list(APPEND analog_sources probe_avg_mag_sqrd_c_impl.cc probe_avg_mag_sqrd_cf_impl.cc probe_avg_mag_sqrd_f_impl.cc + pwr_squelch_cc_impl.cc + pwr_squelch_ff_impl.cc simple_squelch_cc_impl.cc ) diff --git a/gr-analog/lib/pwr_squelch_cc_impl.cc b/gr-analog/lib/pwr_squelch_cc_impl.cc new file mode 100644 index 000000000..1bfba6846 --- /dev/null +++ b/gr-analog/lib/pwr_squelch_cc_impl.cc @@ -0,0 +1,73 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2010,2012 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 "pwr_squelch_cc_impl.h" + +namespace gr { + namespace analog { + + pwr_squelch_cc::sptr + pwr_squelch_cc::make(double threshold, double alpha, + int ramp, bool gate) + { + return gnuradio::get_initial_sptr + (new pwr_squelch_cc_impl(threshold, alpha, ramp, gate)); + } + + pwr_squelch_cc_impl::pwr_squelch_cc_impl(double threshold, double alpha, + int ramp, bool gate) + : gr_block("pwr_squelch_cc", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex))), + squelch_base_cc_impl("pwr_squelch_cc", ramp, gate), + d_iir(alpha) + { + set_threshold(threshold); + } + + pwr_squelch_cc_impl::~pwr_squelch_cc_impl() + { + } + + std::vector + pwr_squelch_cc_impl::squelch_range() const + { + std::vector r(3); + r[0] = -50.0; // min FIXME + r[1] = +50.0; // max FIXME + r[2] = (r[1] - r[0]) / 100; // step size + + return r; + } + + void + pwr_squelch_cc_impl::update_state(const gr_complex &in) + { + d_pwr = d_iir.filter(in.real()*in.real()+in.imag()*in.imag()); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/pwr_squelch_cc_impl.h b/gr-analog/lib/pwr_squelch_cc_impl.h new file mode 100644 index 000000000..72df0f3d2 --- /dev/null +++ b/gr-analog/lib/pwr_squelch_cc_impl.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_PWR_SQUELCH_CC_IMPL_H +#define INCLUDED_ANALOG_PWR_SQUELCH_CC_IMPL_H + +#include +#include "squelch_base_cc_impl.h" +#include +#include + +namespace gr { + namespace analog { + + class ANALOG_API pwr_squelch_cc_impl : + public pwr_squelch_cc, squelch_base_cc_impl + { + private: + double d_threshold; + double d_pwr; + filter::single_pole_iir d_iir; + + protected: + virtual void update_state(const gr_complex &in); + virtual bool mute() const { return d_pwr < d_threshold; } + + public: + pwr_squelch_cc_impl(double db, double alpha=0.0001, + int ramp=0, bool gate=false); + ~pwr_squelch_cc_impl(); + + std::vector squelch_range() const; + + double threshold() const { return 10*log10(d_threshold); } + void set_threshold(double db) { d_threshold = std::pow(10.0, db/10); } + void set_alpha(double alpha) { d_iir.set_taps(alpha); } + + int ramp() const { return squelch_base_cc_impl::ramp(); } + void set_ramp(int ramp) { squelch_base_cc_impl::set_ramp(ramp); } + bool gate() const { return squelch_base_cc_impl::gate(); } + void set_gate(bool gate) { squelch_base_cc_impl::set_gate(gate); } + bool unmuted() const { return squelch_base_cc_impl::unmuted(); } + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + return squelch_base_cc_impl::general_work(noutput_items, + ninput_items, + input_items, + output_items); + } + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PWR_SQUELCH_CC_IMPL_H */ diff --git a/gr-analog/lib/pwr_squelch_ff_impl.cc b/gr-analog/lib/pwr_squelch_ff_impl.cc new file mode 100644 index 000000000..c6bb6af90 --- /dev/null +++ b/gr-analog/lib/pwr_squelch_ff_impl.cc @@ -0,0 +1,73 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2010,2012 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 "pwr_squelch_ff_impl.h" + +namespace gr { + namespace analog { + + pwr_squelch_ff::sptr + pwr_squelch_ff::make(double threshold, double alpha, + int ramp, bool gate) + { + return gnuradio::get_initial_sptr + (new pwr_squelch_ff_impl(threshold, alpha, ramp, gate)); + } + + pwr_squelch_ff_impl::pwr_squelch_ff_impl(double threshold, double alpha, + int ramp, bool gate) + : gr_block("pwr_squelch_ff", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))), + squelch_base_ff_impl("pwr_squelch_ff", ramp, gate), + d_iir(alpha) + { + set_threshold(threshold); + } + + pwr_squelch_ff_impl::~pwr_squelch_ff_impl() + { + } + + std::vector + pwr_squelch_ff_impl::squelch_range() const + { + std::vector r(3); + r[0] = -50.0; // min FIXME + r[1] = +50.0; // max FIXME + r[2] = (r[1] - r[0]) / 100; // step size + + return r; + } + + void + pwr_squelch_ff_impl::update_state(const float &in) + { + d_pwr = d_iir.filter(in*in); + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/pwr_squelch_ff_impl.h b/gr-analog/lib/pwr_squelch_ff_impl.h new file mode 100644 index 000000000..96d959b4d --- /dev/null +++ b/gr-analog/lib/pwr_squelch_ff_impl.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2012 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_ANALOG_PWR_SQUELCH_FF_IMPL_H +#define INCLUDED_ANALOG_PWR_SQUELCH_FF_IMPL_H + +#include +#include "squelch_base_ff_impl.h" +#include +#include + +namespace gr { + namespace analog { + + class ANALOG_API pwr_squelch_ff_impl : + public pwr_squelch_ff, squelch_base_ff_impl + { + private: + double d_threshold; + double d_pwr; + filter::single_pole_iir d_iir; + + protected: + virtual void update_state(const float &in); + virtual bool mute() const { return d_pwr < d_threshold; } + + public: + pwr_squelch_ff_impl(double db, double alpha=0.0001, + int ramp=0, bool gate=false); + ~pwr_squelch_ff_impl(); + + std::vector squelch_range() const; + + double threshold() const { return 10*log10(d_threshold); } + void set_threshold(double db) { d_threshold = std::pow(10.0, db/10); } + void set_alpha(double alpha) { d_iir.set_taps(alpha); } + + int ramp() const { return squelch_base_ff_impl::ramp(); } + void set_ramp(int ramp) { squelch_base_ff_impl::set_ramp(ramp); } + bool gate() const { return squelch_base_ff_impl::gate(); } + void set_gate(bool gate) { squelch_base_ff_impl::set_gate(gate); } + bool unmuted() const { return squelch_base_ff_impl::unmuted(); } + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + return squelch_base_ff_impl::general_work(noutput_items, + ninput_items, + input_items, + output_items); + } + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_PWR_SQUELCH_FF_IMPL_H */ diff --git a/gr-analog/python/qa_ctcss_squelch.py b/gr-analog/python/qa_ctcss_squelch.py index 4d4fc3077..08d3dbfef 100755 --- a/gr-analog/python/qa_ctcss_squelch.py +++ b/gr-analog/python/qa_ctcss_squelch.py @@ -49,7 +49,7 @@ class test_ctcss_squelch(gr_unittest.TestCase): op.set_ramp(ramp2) r = op.ramp() - self.assertEqual(rate2, r) + self.assertEqual(ramp2, r) op.set_gate(gate2) g = op.gate() diff --git a/gr-analog/python/qa_pwr_squelch.py b/gr-analog/python/qa_pwr_squelch.py new file mode 100755 index 000000000..dd42c7fb9 --- /dev/null +++ b/gr-analog/python/qa_pwr_squelch.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# +# Copyright 2012 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, gr_unittest +import analog_swig as analog + +class test_pwr_squelch(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_pwr_squelch_001(self): + # Test set/gets + + alpha = 0.0001 + + thr1 = 10 + thr2 = 20 + ramp = 1 + ramp2 = 2 + gate = True + gate2 = False + + op = analog.pwr_squelch_cc(thr1, alpha, ramp, gate) + + op.set_threshold(thr2) + t = op.threshold() + self.assertEqual(thr2, t) + + op.set_ramp(ramp2) + r = op.ramp() + self.assertEqual(ramp2, r) + + op.set_gate(gate2) + g = op.gate() + self.assertEqual(gate2, g) + + def test_pwr_squelch_002(self): + # Test runtime, gate=True + alpha = 0.0001 + thr = -25 + + src_data = map(lambda x: float(x)/10.0, range(1, 40)) + src = gr.vector_source_c(src_data) + op = analog.pwr_squelch_cc(thr, alpha) + dst = gr.vector_sink_c() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + expected_result = src_data + expected_result[0:20] = 20*[0,] + + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 4) + + def test_pwr_squelch_003(self): + # Test set/gets + + alpha = 0.0001 + + thr1 = 10 + thr2 = 20 + ramp = 1 + ramp2 = 2 + gate = True + gate2 = False + + op = analog.pwr_squelch_ff(thr1, alpha, ramp, gate) + + op.set_threshold(thr2) + t = op.threshold() + self.assertEqual(thr2, t) + + op.set_ramp(ramp2) + r = op.ramp() + self.assertEqual(ramp2, r) + + op.set_gate(gate2) + g = op.gate() + self.assertEqual(gate2, g) + + + def test_pwr_squelch_004(self): + alpha = 0.0001 + thr = -25 + + src_data = map(lambda x: float(x)/10.0, range(1, 40)) + src = gr.vector_source_f(src_data) + op = analog.pwr_squelch_ff(thr, alpha) + dst = gr.vector_sink_f() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + expected_result = src_data + expected_result[0:20] = 20*[0,] + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_pwr_squelch, "test_pwr_squelch.xml") + diff --git a/gr-analog/python/qa_simple_squelch.py b/gr-analog/python/qa_simple_squelch.py index 97deee06c..9fa112864 100755 --- a/gr-analog/python/qa_simple_squelch.py +++ b/gr-analog/python/qa_simple_squelch.py @@ -46,7 +46,6 @@ class test_simple_squelch(gr_unittest.TestCase): self.assertEqual(thr2, t) def test_simple_squelch_002(self): - # Test runtime, gate=True alpha = 0.0001 thr = -25 @@ -63,7 +62,7 @@ class test_simple_squelch(gr_unittest.TestCase): expected_result[0:20] = 20*[0,] result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data, 4) + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 4) if __name__ == '__main__': gr_unittest.run(test_simple_squelch, "test_simple_squelch.xml") diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 2e36e4e71..38063c132 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -52,6 +52,8 @@ #include "analog/probe_avg_mag_sqrd_c.h" #include "analog/probe_avg_mag_sqrd_cf.h" #include "analog/probe_avg_mag_sqrd_f.h" +#include "analog/pwr_squelch_cc.h" +#include "analog/pwr_squelch_ff.h" #include "analog/sincos.h" #include "analog/sig_source_s.h" #include "analog/sig_source_i.h" @@ -87,6 +89,8 @@ %include "analog/probe_avg_mag_sqrd_c.h" %include "analog/probe_avg_mag_sqrd_cf.h" %include "analog/probe_avg_mag_sqrd_f.h" +%include "analog/pwr_squelch_cc.h" +%include "analog/pwr_squelch_ff.h" %include "analog/sincos.h" %include "analog/sig_source_s.h" %include "analog/sig_source_i.h" @@ -118,6 +122,8 @@ GR_SWIG_BLOCK_MAGIC2(analog, pll_refout_cc); GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_c); GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_cf); GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_f); +GR_SWIG_BLOCK_MAGIC2(analog, pwr_squelch_cc); +GR_SWIG_BLOCK_MAGIC2(analog, pwr_squelch_ff); GR_SWIG_BLOCK_MAGIC2(analog, sig_source_s); GR_SWIG_BLOCK_MAGIC2(analog, sig_source_i); GR_SWIG_BLOCK_MAGIC2(analog, sig_source_f); -- cgit From 9dbc8b75787e4a6d493251826c0436f9af167a6d Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Wed, 31 Oct 2012 15:06:23 -0400 Subject: analog: adding rail_ff block to gr-analog with QA and GRC. --- gr-analog/grc/analog_block_tree.xml | 1 + gr-analog/grc/analog_rail_ff.xml | 54 +++++++++++++++++++ gr-analog/include/analog/CMakeLists.txt | 1 + gr-analog/include/analog/rail_ff.h | 54 +++++++++++++++++++ gr-analog/lib/CMakeLists.txt | 1 + gr-analog/lib/rail_ff_impl.cc | 91 +++++++++++++++++++++++++++++++++ gr-analog/lib/rail_ff_impl.h | 57 +++++++++++++++++++++ gr-analog/python/qa_rail_ff.py | 79 ++++++++++++++++++++++++++++ gr-analog/swig/analog_swig.i | 3 ++ 9 files changed, 341 insertions(+) create mode 100644 gr-analog/grc/analog_rail_ff.xml create mode 100644 gr-analog/include/analog/rail_ff.h create mode 100644 gr-analog/lib/rail_ff_impl.cc create mode 100644 gr-analog/lib/rail_ff_impl.h create mode 100755 gr-analog/python/qa_rail_ff.py diff --git a/gr-analog/grc/analog_block_tree.xml b/gr-analog/grc/analog_block_tree.xml index 5c5680744..a25123f4a 100644 --- a/gr-analog/grc/analog_block_tree.xml +++ b/gr-analog/grc/analog_block_tree.xml @@ -37,6 +37,7 @@ analog_ctcss_squelch_ff analog_pwr_squelch_xx analog_simple_squelch_cc + analog_rail_ff Modulators diff --git a/gr-analog/grc/analog_rail_ff.xml b/gr-analog/grc/analog_rail_ff.xml new file mode 100644 index 000000000..87dff0977 --- /dev/null +++ b/gr-analog/grc/analog_rail_ff.xml @@ -0,0 +1,54 @@ + + + + + + Rail + analog_rail_ff + from gnuradio import analog + analog.rail_ff($lo, $hi) + set_lo($lo) + set_hi($hi) + + Low clipping + lo + real + + + Hi clipping + hi + real + + + in + float + + + out + float + + diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index 25ce50dd8..4623fb2dd 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -100,6 +100,7 @@ install(FILES probe_avg_mag_sqrd_f.h pwr_squelch_cc.h pwr_squelch_ff.h + rail_ff.h rotator.h sig_source_waveform.h simple_squelch_cc.h diff --git a/gr-analog/include/analog/rail_ff.h b/gr-analog/include/analog/rail_ff.h new file mode 100644 index 000000000..e51b2fc93 --- /dev/null +++ b/gr-analog/include/analog/rail_ff.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 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_ANALOG_RAIL_FF_H +#define INCLUDED_ANALOG_RAIL_FF_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief clips input values to min, max + * \ingroup misc + */ + class ANALOG_API rail_ff : virtual public gr_sync_block + { + public: + // gr::analog::rail_ff::sptr + typedef boost::shared_ptr sptr; + + static sptr make(float lo, float hi); + + virtual float lo() const = 0; + virtual float hi() const = 0; + + virtual void set_lo(float lo) = 0; + virtual void set_hi(float hi) = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_RAIL_FF_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index 9a620133a..f912649d9 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -128,6 +128,7 @@ list(APPEND analog_sources probe_avg_mag_sqrd_f_impl.cc pwr_squelch_cc_impl.cc pwr_squelch_ff_impl.cc + rail_ff_impl.cc simple_squelch_cc_impl.cc ) diff --git a/gr-analog/lib/rail_ff_impl.cc b/gr-analog/lib/rail_ff_impl.cc new file mode 100644 index 000000000..106c6353a --- /dev/null +++ b/gr-analog/lib/rail_ff_impl.cc @@ -0,0 +1,91 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012 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 "rail_ff_impl.h" +#include +#include + +namespace gr { + namespace analog { + + rail_ff::sptr + rail_ff::make(float lo, float hi) + { + return gnuradio::get_initial_sptr + (new rail_ff_impl(lo, hi)); + } + + rail_ff_impl::rail_ff_impl(float lo, float hi) + : gr_sync_block("rail_ff", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))), + d_lo(lo), d_hi(hi) + { + set_clipping(); + } + + rail_ff_impl::~rail_ff_impl() + { + } + + void + rail_ff_impl::set_lo(float lo) + { + d_lo = lo; + set_clipping(); + } + + void + rail_ff_impl::set_hi(float hi) + { + d_hi = hi; + set_clipping(); + } + + void + rail_ff_impl::set_clipping() + { + d_mid = (d_lo + d_hi)/2; + d_clip = d_hi - d_mid; + } + + int + rail_ff_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + float *out = (float*)output_items[0]; + + for(int i = 0; i < noutput_items; i++) { + out[i] = d_mid + gr_branchless_clip(in[i] - d_mid, d_clip); + } + + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/rail_ff_impl.h b/gr-analog/lib/rail_ff_impl.h new file mode 100644 index 000000000..436b10b41 --- /dev/null +++ b/gr-analog/lib/rail_ff_impl.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 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_ANALOG_RAIL_FF_IMPL_H +#define INCLUDED_ANALOG_RAIL_FF_IMPL_H + +#include + +namespace gr { + namespace analog { + + class rail_ff_impl : public rail_ff + { + private: + float d_lo, d_hi; + float d_mid, d_clip; + + void set_clipping(); + + public: + rail_ff_impl(float lo, float hi); + ~rail_ff_impl(); + + float lo() const { return d_lo; } + float hi() const { return d_hi; } + + void set_lo(float lo); + void set_hi(float hi); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_RAIL_FF_IMPL_H */ diff --git a/gr-analog/python/qa_rail_ff.py b/gr-analog/python/qa_rail_ff.py new file mode 100755 index 000000000..5bcf01c6b --- /dev/null +++ b/gr-analog/python/qa_rail_ff.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# +# Copyright 2012 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, gr_unittest +import analog_swig as analog + +def clip(x, lo, hi): + if(x < lo): + return lo + elif(x > hi): + return hi + else: + return x + +class test_rail(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_rail_001(self): + # Test set/gets + + hi1 = 1 + hi2 = 2 + lo1 = -1 + lo2 = -2 + + op = analog.rail_ff(lo1, hi1) + + op.set_hi(hi2) + h = op.hi() + self.assertEqual(hi2, h) + + op.set_lo(lo2) + l = op.lo() + self.assertEqual(lo2, l) + + def test_rail_002(self): + lo = -0.75 + hi = 0.90 + src_data = [-2, -1, -0.5, -0.25, 0, 0.25, 0.5, 1, 2] + expected_result = map(lambda x: clip(x, lo, hi), src_data) + + src = gr.vector_source_f(src_data) + op = analog.rail_ff(lo, hi) + dst = gr.vector_sink_f() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 4) + +if __name__ == '__main__': + gr_unittest.run(test_rail, "test_rail.xml") + diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 38063c132..9632b363c 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -54,6 +54,7 @@ #include "analog/probe_avg_mag_sqrd_f.h" #include "analog/pwr_squelch_cc.h" #include "analog/pwr_squelch_ff.h" +#include "analog/rail_ff.h" #include "analog/sincos.h" #include "analog/sig_source_s.h" #include "analog/sig_source_i.h" @@ -91,6 +92,7 @@ %include "analog/probe_avg_mag_sqrd_f.h" %include "analog/pwr_squelch_cc.h" %include "analog/pwr_squelch_ff.h" +%include "analog/rail_ff.h" %include "analog/sincos.h" %include "analog/sig_source_s.h" %include "analog/sig_source_i.h" @@ -124,6 +126,7 @@ GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_cf); GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_f); GR_SWIG_BLOCK_MAGIC2(analog, pwr_squelch_cc); GR_SWIG_BLOCK_MAGIC2(analog, pwr_squelch_ff); +GR_SWIG_BLOCK_MAGIC2(analog, rail_ff); GR_SWIG_BLOCK_MAGIC2(analog, sig_source_s); GR_SWIG_BLOCK_MAGIC2(analog, sig_source_i); GR_SWIG_BLOCK_MAGIC2(analog, sig_source_f); -- cgit From 21beb2a5dc1e589873b49836190c3caf354c86f7 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Wed, 31 Oct 2012 15:55:13 -0400 Subject: analog: adding quadrature_demod_cf to gr-analog with QA and GRC. --- gr-analog/grc/analog_block_tree.xml | 1 + gr-analog/grc/analog_quadrature_demod_cf.xml | 26 ++++++++++ gr-analog/include/analog/CMakeLists.txt | 1 + gr-analog/include/analog/quadrature_demod_cf.h | 54 +++++++++++++++++++ gr-analog/lib/CMakeLists.txt | 1 + gr-analog/lib/quadrature_demod_cf_impl.cc | 72 ++++++++++++++++++++++++++ gr-analog/lib/quadrature_demod_cf_impl.h | 51 ++++++++++++++++++ gr-analog/python/qa_quadrature_demod.py | 63 ++++++++++++++++++++++ gr-analog/swig/analog_swig.i | 3 ++ 9 files changed, 272 insertions(+) create mode 100644 gr-analog/grc/analog_quadrature_demod_cf.xml create mode 100644 gr-analog/include/analog/quadrature_demod_cf.h create mode 100644 gr-analog/lib/quadrature_demod_cf_impl.cc create mode 100644 gr-analog/lib/quadrature_demod_cf_impl.h create mode 100755 gr-analog/python/qa_quadrature_demod.py diff --git a/gr-analog/grc/analog_block_tree.xml b/gr-analog/grc/analog_block_tree.xml index a25123f4a..99255d759 100644 --- a/gr-analog/grc/analog_block_tree.xml +++ b/gr-analog/grc/analog_block_tree.xml @@ -44,6 +44,7 @@ analog_cpfsk_bc analog_frequency_modulator_fc analog_phase_modulator_fc + analog_quadrature_demod_cf Sources diff --git a/gr-analog/grc/analog_quadrature_demod_cf.xml b/gr-analog/grc/analog_quadrature_demod_cf.xml new file mode 100644 index 000000000..a60653135 --- /dev/null +++ b/gr-analog/grc/analog_quadrature_demod_cf.xml @@ -0,0 +1,26 @@ + + + + Quadrature Demod + analog_quadrature_demod_cf + from gnuradio import analog + analog.quadrature_demod_cf($gain) + set_gain($gain) + + Gain + gain + real + + + in + complex + + + out + float + + diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index 4623fb2dd..4de94a88b 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -100,6 +100,7 @@ install(FILES probe_avg_mag_sqrd_f.h pwr_squelch_cc.h pwr_squelch_ff.h + quadrature_demod_cf.h rail_ff.h rotator.h sig_source_waveform.h diff --git a/gr-analog/include/analog/quadrature_demod_cf.h b/gr-analog/include/analog/quadrature_demod_cf.h new file mode 100644 index 000000000..916d8b2ec --- /dev/null +++ b/gr-analog/include/analog/quadrature_demod_cf.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 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_ANALOG_QUADRATURE_DEMOD_CF_H +#define INCLUDED_ANALOG_QUADRATURE_DEMOD_CF_H + +#include +#include + +namespace gr { + namespace analog { + + /*! + * \brief quadrature demodulator: complex in, float out + * \ingroup demodulation_blk + * + * This can be used to demod FM, FSK, GMSK, etc. + * The input is complex baseband. + */ + class ANALOG_API quadrature_demod_cf : virtual public gr_sync_block + { + public: + // gr::analog::quadrature_demod_cf::sptr + typedef boost::shared_ptr sptr; + + static sptr make(float gain); + + virtual void set_gain(float gain) = 0; + virtual float gain() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_QUADRATURE_DEMOD_CF_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index f912649d9..5e7d131b0 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -128,6 +128,7 @@ list(APPEND analog_sources probe_avg_mag_sqrd_f_impl.cc pwr_squelch_cc_impl.cc pwr_squelch_ff_impl.cc + quadrature_demod_cf_impl.cc rail_ff_impl.cc simple_squelch_cc_impl.cc ) diff --git a/gr-analog/lib/quadrature_demod_cf_impl.cc b/gr-analog/lib/quadrature_demod_cf_impl.cc new file mode 100644 index 000000000..9490ba6be --- /dev/null +++ b/gr-analog/lib/quadrature_demod_cf_impl.cc @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2005,2010,2012 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 "quadrature_demod_cf_impl.h" +#include +#include + +namespace gr { + namespace analog { + + quadrature_demod_cf::sptr + quadrature_demod_cf::make(float gain) + { + return gnuradio::get_initial_sptr + (new quadrature_demod_cf_impl(gain)); + } + + quadrature_demod_cf_impl::quadrature_demod_cf_impl(float gain) + : gr_sync_block("quadrature_demod_cf", + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(float))), + d_gain(gain) + { + set_history(2); // we need to look at the previous value + } + + quadrature_demod_cf_impl::~quadrature_demod_cf_impl() + { + } + + int + quadrature_demod_cf_impl::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]; + float *out = (float*)output_items[0]; + in++; // ensure that in[-1] is valid + + for(int i = 0; i < noutput_items; i++) { + gr_complex product = in[i] * conj(in[i-1]); + out[i] = d_gain * gr_fast_atan2f(imag(product), real(product)); + } + + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ diff --git a/gr-analog/lib/quadrature_demod_cf_impl.h b/gr-analog/lib/quadrature_demod_cf_impl.h new file mode 100644 index 000000000..72beb2331 --- /dev/null +++ b/gr-analog/lib/quadrature_demod_cf_impl.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012 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_ANALOG_QUADRATURE_DEMOD_CF_IMPL_H +#define INCLUDED_ANALOG_QUADRATURE_DEMOD_CF_IMPL_H + +#include + +namespace gr { + namespace analog { + + class quadrature_demod_cf_impl : public quadrature_demod_cf + { + private: + float d_gain; + + public: + quadrature_demod_cf_impl(float gain); + ~quadrature_demod_cf_impl(); + + void set_gain(float gain) { d_gain = gain; } + float gain() const { return d_gain; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace analog */ +} /* namespace gr */ + +#endif /* INCLUDED_ANALOG_QUADRATURE_DEMOD_CF_IMPL_H */ diff --git a/gr-analog/python/qa_quadrature_demod.py b/gr-analog/python/qa_quadrature_demod.py new file mode 100755 index 000000000..e38ea72a7 --- /dev/null +++ b/gr-analog/python/qa_quadrature_demod.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# +# Copyright 2012 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, gr_unittest +import analog_swig as analog +import cmath + +class test_quadrature_demod(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_quad_demod_001(self): + f = 1000.0 + fs = 8000.0 + + src_data = [] + for i in xrange(200): + ti = i/fs + src_data.append(cmath.exp(2j*cmath.pi*f*ti)) + + # f/fs is a quarter turn per sample. + # Set the gain based on this to get 1 out. + gain = 1.0/(cmath.pi/4) + + expected_result = [0,] + 199*[1.0] + + src = gr.vector_source_c(src_data) + op = analog.quadrature_demod_cf(gain) + dst = gr.vector_sink_f() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 5) + +if __name__ == '__main__': + gr_unittest.run(test_quadrature_demod, "test_quadrature_demod.xml") + diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 9632b363c..016537c94 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -54,6 +54,7 @@ #include "analog/probe_avg_mag_sqrd_f.h" #include "analog/pwr_squelch_cc.h" #include "analog/pwr_squelch_ff.h" +#include "analog/quadrature_demod_cf.h" #include "analog/rail_ff.h" #include "analog/sincos.h" #include "analog/sig_source_s.h" @@ -92,6 +93,7 @@ %include "analog/probe_avg_mag_sqrd_f.h" %include "analog/pwr_squelch_cc.h" %include "analog/pwr_squelch_ff.h" +%include "analog/quadrature_demod_cf.h" %include "analog/rail_ff.h" %include "analog/sincos.h" %include "analog/sig_source_s.h" @@ -126,6 +128,7 @@ GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_cf); GR_SWIG_BLOCK_MAGIC2(analog, probe_avg_mag_sqrd_f); GR_SWIG_BLOCK_MAGIC2(analog, pwr_squelch_cc); GR_SWIG_BLOCK_MAGIC2(analog, pwr_squelch_ff); +GR_SWIG_BLOCK_MAGIC2(analog, quadrature_demod_cf); GR_SWIG_BLOCK_MAGIC2(analog, rail_ff); GR_SWIG_BLOCK_MAGIC2(analog, sig_source_s); GR_SWIG_BLOCK_MAGIC2(analog, sig_source_i); -- cgit