diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8caa947..c618cdd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -95,7 +95,7 @@ set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks)
########################################################################
# Find gnuradio build dependencies
########################################################################
-set(GR_REQUIRED_COMPONENTS RUNTIME PMT BLOCKS)
+set(GR_REQUIRED_COMPONENTS RUNTIME PMT BLOCKS FILTER ANALOG)
find_package(Gnuradio)
find_package(CppUnit)
diff --git a/grc/foo_channel_model.xml b/grc/foo_channel_model.xml
new file mode 100644
index 0000000..61fe93f
--- /dev/null
+++ b/grc/foo_channel_model.xml
@@ -0,0 +1,74 @@
+
+
+ Channel Model
+ foo_channel_model
+ [Foo]
+ import foo
+ foo.channel_model(
+ noise_voltage=$noise_voltage,
+ frequency_offset=$freq_offset,
+ epsilon=$epsilon,
+ taps=$taps,
+ noise_seed=$seed,
+ block_tags=$block_tags
+)
+ set_noise_voltage($noise_voltage)
+ set_frequency_offset($freq_offset)
+ set_taps($taps)
+ set_timing_offset($epsilon)
+
+ Noise Voltage
+ noise_voltage
+ 0.0
+ real
+
+
+ Frequency Offset
+ freq_offset
+ 0.0
+ real
+
+
+ Epsilon
+ epsilon
+ 1.0
+ real
+
+
+ Taps
+ taps
+ 1.0 + 1.0j
+ complex_vector
+
+
+ Seed
+ seed
+ 0
+ int
+
+
+ Block Tag Propagation
+ block_tags
+ False
+ enum
+ $block_tags.hide_block
+
+
+
+
+ in
+ complex
+
+
+ out
+ complex
+
+
diff --git a/include/foo/CMakeLists.txt b/include/foo/CMakeLists.txt
index de9b3ca..f4e5316 100644
--- a/include/foo/CMakeLists.txt
+++ b/include/foo/CMakeLists.txt
@@ -23,6 +23,7 @@
install(FILES
api.h
burst_tagger.h
+ channel_model.h
packet_dropper.h
packet_pad.h
packet_pad2.h
diff --git a/include/foo/channel_model.h b/include/foo/channel_model.h
new file mode 100644
index 0000000..a90f0ed
--- /dev/null
+++ b/include/foo/channel_model.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 Bastian Bloessl
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#ifndef INCLUDED_FOO_CHANNEL_MODEL_H
+#define INCLUDED_FOO_CHANNEL_MODEL_H
+
+#include
+#include
+#include
+
+namespace gr {
+namespace foo {
+
+class FOO_API channel_model : virtual public hier_block2
+{
+public:
+ typedef boost::shared_ptr sptr;
+
+ static sptr make(double noise_voltage = 0.0, double frequency_offset = 0.0,
+ double epsilon = 1.0,
+ const std::vector &taps = std::vector(1, 1),
+ double noise_seed = 0, bool block_tags = false);
+
+ virtual void set_noise_voltage(double noise_voltage) = 0;
+ virtual void set_frequency_offset(double frequency_offset) = 0;
+ virtual void set_taps(const std::vector &taps) = 0;
+ virtual void set_timing_offset(double epsilon) = 0;
+
+ virtual double noise_voltage() const = 0;
+ virtual double frequency_offset() const = 0;
+ virtual std::vector taps() const = 0;
+ virtual double timing_offset() const = 0;
+};
+
+} // namespace foo
+} // namespace gr
+
+#endif /* INCLUDED_FOO_CHANNEL_MODEL_H */
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 5d67eae..191f685 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -33,6 +33,7 @@ link_directories(
list(APPEND foo_sources
burst_tagger_impl.cc
+ channel_model_impl.cc
packet_dropper_impl.cc
packet_pad2.cc
packet_pad_impl.cc
diff --git a/lib/channel_model_impl.cc b/lib/channel_model_impl.cc
new file mode 100644
index 0000000..667c638
--- /dev/null
+++ b/lib/channel_model_impl.cc
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2017 Bastian Bloessl
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "channel_model_impl.h"
+#include
+#include
+
+namespace gr {
+namespace foo {
+
+channel_model::sptr
+channel_model::make(double noise_voltage,
+ double frequency_offset,
+ double epsilon,
+ const std::vector &taps,
+ double noise_seed,
+ bool block_tags)
+{
+ return gnuradio::get_initial_sptr
+ (new channel_model_impl(noise_voltage,
+ frequency_offset,
+ epsilon,
+ taps,
+ noise_seed,
+ block_tags));
+}
+
+// Hierarchical block constructor
+channel_model_impl::channel_model_impl(double noise_voltage,
+ double frequency_offset,
+ double epsilon,
+ const std::vector &taps,
+ double noise_seed,
+ bool block_tags
+ )
+ : hier_block2("channel_model",
+ io_signature::make(1, 1, sizeof(gr_complex)),
+ io_signature::make(1, 1, sizeof(gr_complex)))
+{
+ d_taps = taps;
+ while(d_taps.size() < 2) {
+ d_taps.push_back(0);
+ }
+
+ d_timing_offset = filter::fractional_resampler_cc::make(0, epsilon);
+
+ d_multipath = filter::fir_filter_ccc::make(1, d_taps);
+
+ d_noise_adder = blocks::add_cc::make();
+ d_noise = analog::noise_source_c::make(analog::GR_GAUSSIAN,
+ noise_voltage, noise_seed);
+ d_freq_offset = analog::sig_source_c::make(1, analog::GR_SIN_WAVE,
+ frequency_offset, 1.0, 0.0);
+ d_mixer_offset = blocks::multiply_cc::make();
+
+ connect(self(), 0, d_timing_offset, 0);
+ connect(d_timing_offset, 0, d_multipath, 0);
+ connect(d_multipath, 0, d_mixer_offset, 0);
+ connect(d_freq_offset, 0, d_mixer_offset, 1);
+ connect(d_mixer_offset, 0, d_noise_adder, 1);
+ connect(d_noise, 0, d_noise_adder, 0);
+ connect(d_noise_adder, 0, self(), 0);
+
+ if (block_tags) {
+ d_timing_offset->set_tag_propagation_policy(gr::block::TPP_DONT);
+ }
+}
+
+channel_model_impl::~channel_model_impl()
+{
+}
+
+void
+channel_model_impl::set_noise_voltage(double noise_voltage)
+{
+ d_noise->set_amplitude(noise_voltage);
+}
+
+void
+channel_model_impl::set_frequency_offset(double frequency_offset)
+{
+ d_freq_offset->set_frequency(frequency_offset);
+}
+
+void
+channel_model_impl::set_taps(const std::vector &taps)
+{
+ d_taps = taps;
+ while(d_taps.size() < 2) {
+ d_taps.push_back(0);
+ }
+ d_multipath->set_taps(d_taps);
+}
+
+void
+channel_model_impl::set_timing_offset(double epsilon)
+{
+ d_timing_offset->set_resamp_ratio(epsilon);
+}
+
+double
+channel_model_impl::noise_voltage() const
+{
+ return d_noise->amplitude();
+}
+
+double
+channel_model_impl::frequency_offset() const
+{
+ return d_freq_offset->frequency();
+}
+
+std::vector
+channel_model_impl::taps() const
+{
+ return d_multipath->taps();
+}
+
+double
+channel_model_impl::timing_offset() const
+{
+ return d_timing_offset->resamp_ratio();
+}
+
+} /* namespace channels */
+} /* namespace gr */
diff --git a/lib/channel_model_impl.h b/lib/channel_model_impl.h
new file mode 100644
index 0000000..0da3f0b
--- /dev/null
+++ b/lib/channel_model_impl.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 Bastian Bloessl
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#ifndef INCLUDED_FOO_CHANNEL_MODEL_IMPL_H
+#define INCLUDED_FOO_CHANNEL_MODEL_IMPL_H
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace gr {
+namespace foo {
+
+class FOO_API channel_model_impl : public foo::channel_model
+{
+private:
+ blocks::add_cc::sptr d_noise_adder;
+ blocks::multiply_cc::sptr d_mixer_offset;
+
+ analog::sig_source_c::sptr d_freq_offset;
+ analog::noise_source_c::sptr d_noise;
+
+ filter::fractional_resampler_cc::sptr d_timing_offset;
+ filter::fir_filter_ccc::sptr d_multipath;
+
+ std::vector d_taps;
+
+public:
+ channel_model_impl(double noise_voltage,
+ double frequency_offset,
+ double epsilon,
+ const std::vector &taps,
+ double noise_seed,
+ bool block_tags);
+
+ ~channel_model_impl();
+
+ void set_noise_voltage(double noise_voltage);
+ void set_frequency_offset(double frequency_offset);
+ void set_taps(const std::vector &taps);
+ void set_timing_offset(double epsilon);
+
+ double noise_voltage() const;
+ double frequency_offset() const;
+ std::vector taps() const;
+ double timing_offset() const;
+};
+
+} // namespace foo
+} // namespace gr
+
+#endif /* INCLUDED_FOO_CHANNEL_MODEL_IMPL_H */
diff --git a/swig/foo_swig.i b/swig/foo_swig.i
index 6919196..faeaab4 100644
--- a/swig/foo_swig.i
+++ b/swig/foo_swig.i
@@ -7,6 +7,7 @@
%{
#include "foo/burst_tagger.h"
+#include "foo/channel_model.h"
#include "foo/packet_dropper.h"
#include "foo/packet_pad.h"
#include "foo/packet_pad2.h"
@@ -18,6 +19,7 @@
%include "foo/burst_tagger.h"
+%include "foo/channel_model.h"
%include "foo/packet_dropper.h"
%include "foo/packet_pad.h"
%include "foo/packet_pad2.h"
@@ -27,6 +29,7 @@
%include "foo/wireshark_connector.h"
GR_SWIG_BLOCK_MAGIC2(foo, burst_tagger);
+GR_SWIG_BLOCK_MAGIC2(foo, channel_model);
GR_SWIG_BLOCK_MAGIC2(foo, packet_dropper);
GR_SWIG_BLOCK_MAGIC2(foo, packet_pad);
GR_SWIG_BLOCK_MAGIC2(foo, packet_pad2);