diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 0000000..f104652 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1 @@ +*.py diff --git a/examples/README b/examples/README deleted file mode 100644 index c012bdf..0000000 --- a/examples/README +++ /dev/null @@ -1,4 +0,0 @@ -It is considered good practice to add examples in here to demonstrate the -functionality of your OOT module. Python scripts, GRC flow graphs or other -code can go here. - diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..1f67438 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,13 @@ +# Examples +This directory contains a set of useful examples and flowgraphs +for testing and demonstrating the performance of the different components of this +OOT module + +## Files +* `morse_ref.wav `: This is a reference file containing the `HELLO WORLD` message. +The file is sampled at 8 KHz and the audio frequency is 700 Hz. The Morse code +Words per Minute (WPM) is about 20. + +## Flowgraphs +* `test_matched_filter.grc`: Demonstrates the performance of the implemented + matched filter for CW decoding. \ No newline at end of file diff --git a/examples/morse_ref.wav b/examples/morse_ref.wav new file mode 100644 index 0000000..2aaff68 Binary files /dev/null and b/examples/morse_ref.wav differ diff --git a/examples/test_matched_filter.grc b/examples/test_matched_filter.grc new file mode 100644 index 0000000..8356457 --- /dev/null +++ b/examples/test_matched_filter.grc @@ -0,0 +1,822 @@ + + + + Sun Jan 17 23:03:00 2016 + + options + + author + + + + window_size + + + + category + Custom + + + comment + + + + description + + + + _enabled + True + + + _coordinate + (8, 8) + + + _rotation + 0 + + + generate_options + qt_gui + + + id + test_matched_filter + + + max_nouts + 0 + + + realtime_scheduling + + + + run_options + prompt + + + run + True + + + thread_safe_setters + + + + title + + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (8, 160) + + + _rotation + 0 + + + id + samp_rate + + + value + 8000 + + + + analog_agc2_xx + + attack_rate + 6.25e-4 + + + alias + + + + comment + + + + affinity + + + + decay_rate + 2e-6 + + + _enabled + 1 + + + _coordinate + (752, 320) + + + _rotation + 0 + + + gain + 0.0 + + + id + analog_agc2_xx_0 + + + max_gain + 65536 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + reference + 0.3 + + + type + float + + + + analog_fastnoise_source_x + + amp + 0.6 + + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (112, 455) + + + _rotation + 0 + + + id + analog_fastnoise_source_x_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + noise_type + analog.GR_GAUSSIAN + + + type + float + + + seed + 0 + + + samples + 8192 + + + + audio_sink + + alias + + + + comment + + + + affinity + + + + device_name + + + + _enabled + 1 + + + _coordinate + (1032, 348) + + + _rotation + 0 + + + id + audio_sink_0 + + + num_inputs + 1 + + + ok_to_block + True + + + samp_rate + samp_rate + + + + blocks_add_xx + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (416, 440) + + + _rotation + 0 + + + id + blocks_add_xx_0 + + + type + float + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + num_inputs + 2 + + + vlen + 1 + + + + blocks_wavfile_source + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + file + /home/surligas/workspace/gr-satnogs/examples/morse_ref.wav + + + _coordinate + (96, 237) + + + _rotation + 0 + + + id + blocks_wavfile_source_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + nchan + 1 + + + repeat + True + + + + qtgui_time_sink_x + + autoscale + False + + + alias + + + + comment + + + + ctrlpanel + True + + + affinity + + + + entags + True + + + _enabled + True + + + _coordinate + (952, 166) + + + gui_hint + + + + _rotation + 0 + + + grid + False + + + id + qtgui_time_sink_x_0 + + + legend + True + + + alpha1 + 1.0 + + + color1 + "blue" + + + label1 + With AGC + + + marker1 + -1 + + + style1 + 1 + + + width1 + 1 + + + alpha10 + 1.0 + + + color10 + "blue" + + + label10 + + + + marker10 + -1 + + + style10 + 1 + + + width10 + 1 + + + alpha2 + 1.0 + + + color2 + "red" + + + label2 + Without AGC + + + marker2 + -1 + + + style2 + 1 + + + width2 + 1 + + + alpha3 + 1.0 + + + color3 + "green" + + + label3 + + + + marker3 + -1 + + + style3 + 1 + + + width3 + 1 + + + alpha4 + 1.0 + + + color4 + "black" + + + label4 + + + + marker4 + -1 + + + style4 + 1 + + + width4 + 1 + + + alpha5 + 1.0 + + + color5 + "cyan" + + + label5 + + + + marker5 + -1 + + + style5 + 1 + + + width5 + 1 + + + alpha6 + 1.0 + + + color6 + "magenta" + + + label6 + + + + marker6 + -1 + + + style6 + 1 + + + width6 + 1 + + + alpha7 + 1.0 + + + color7 + "yellow" + + + label7 + + + + marker7 + -1 + + + style7 + 1 + + + width7 + 1 + + + alpha8 + 1.0 + + + color8 + "dark red" + + + label8 + + + + marker8 + -1 + + + style8 + 1 + + + width8 + 1 + + + alpha9 + 1.0 + + + color9 + "dark green" + + + label9 + + + + marker9 + -1 + + + style9 + 1 + + + width9 + 1 + + + name + "" + + + nconnections + 2 + + + size + 1024 + + + srate + samp_rate + + + tr_chan + 0 + + + tr_delay + 0 + + + tr_level + 0.0 + + + tr_mode + qtgui.TRIG_MODE_NORM + + + tr_slope + qtgui.TRIG_SLOPE_POS + + + tr_tag + "" + + + type + float + + + update_time + 0.10 + + + ylabel + Amplitude + + + yunit + "" + + + ymax + 1 + + + ymin + -1 + + + + satnogs_cw_matched_filter_ff + + carrier_freq + 700 + + + alias + + + + comment + + + + affinity + + + + _enabled + 1 + + + _coordinate + (536, 222) + + + _rotation + 0 + + + id + satnogs_cw_matched_filter_ff_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + sampling_rate + samp_rate + + + wpm + 20 + + + + analog_agc2_xx_0 + audio_sink_0 + 0 + 0 + + + analog_agc2_xx_0 + qtgui_time_sink_x_0 + 0 + 0 + + + analog_fastnoise_source_x_0 + blocks_add_xx_0 + 0 + 1 + + + blocks_add_xx_0 + satnogs_cw_matched_filter_ff_0 + 0 + 0 + + + blocks_wavfile_source_0 + blocks_add_xx_0 + 0 + 0 + + + satnogs_cw_matched_filter_ff_0 + analog_agc2_xx_0 + 0 + 0 + + + satnogs_cw_matched_filter_ff_0 + qtgui_time_sink_x_0 + 0 + 1 + + diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index d776de7..7ac2b19 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -16,7 +16,6 @@ # 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. - install(FILES - DESTINATION share/gnuradio/grc/blocks + satnogs_cw_matched_filter_ff.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/satnogs_cw_matched_filter_ff.xml b/grc/satnogs_cw_matched_filter_ff.xml new file mode 100644 index 0000000..6143b75 --- /dev/null +++ b/grc/satnogs_cw_matched_filter_ff.xml @@ -0,0 +1,37 @@ + + + CW Matched Filter + satnogs_cw_matched_filter_ff + satnogs + import satnogs + satnogs.cw_matched_filter_ff($sampling_rate, $carrier_freq, $wpm) + + + Sampling Rate + sampling_rate + real + + + + Audio Frequency (Hz) + carrier_freq + real + + + + Words per Minute + wpm + 20 + int + + + + in + float + + + + out + float + + diff --git a/include/satnogs/CMakeLists.txt b/include/satnogs/CMakeLists.txt index 70bfe41..796dad1 100644 --- a/include/satnogs/CMakeLists.txt +++ b/include/satnogs/CMakeLists.txt @@ -22,5 +22,5 @@ ######################################################################## install(FILES api.h - DESTINATION include/satnogs + cw_matched_filter_ff.h DESTINATION include/satnogs ) diff --git a/include/satnogs/cw_matched_filter_ff.h b/include/satnogs/cw_matched_filter_ff.h new file mode 100644 index 0000000..dafdf35 --- /dev/null +++ b/include/satnogs/cw_matched_filter_ff.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * 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_SATNOGS_CW_MATCHED_FILTER_FF_H +#define INCLUDED_SATNOGS_CW_MATCHED_FILTER_FF_H + +#include +#include + +namespace gr { + namespace satnogs { + + /*! + * \brief This block implements a matched filter to reduce the noise + * level of the received CW signal. + * + * \ingroup satnogs + * + */ + class SATNOGS_API cw_matched_filter_ff : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr sptr; + + /*! + * \brief Matched filter for CW noise reduction + * + * @param sampling_rate the sampling rate of the signal + * @param carrier_freq the audio frequency of the CW signal + * @param wpm Morse code Words per Minute + */ + static sptr make(double sampling_rate, double carrier_freq = 500, + size_t wpm = 20); + }; + + } // namespace satnogs +} // namespace gr + +#endif /* INCLUDED_SATNOGS_CW_MATCHED_FILTER_FF_H */ + diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index f644763..04b3daf 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -24,9 +24,8 @@ include(GrPlatform) #define LIB_SUFFIX include_directories(${Boost_INCLUDE_DIR}) link_directories(${Boost_LIBRARY_DIRS}) - list(APPEND satnogs_sources -) + cw_matched_filter_ff_impl.cc ) set(satnogs_sources "${satnogs_sources}" PARENT_SCOPE) if(NOT satnogs_sources) @@ -58,21 +57,21 @@ install(TARGETS gnuradio-satnogs ######################################################################## include(GrTest) -include_directories(${CPPUNIT_INCLUDE_DIRS}) +#include_directories(${CPPUNIT_INCLUDE_DIRS}) -list(APPEND test_satnogs_sources - ${CMAKE_CURRENT_SOURCE_DIR}/test_satnogs.cc - ${CMAKE_CURRENT_SOURCE_DIR}/qa_satnogs.cc -) +#list(APPEND test_satnogs_sources +# ${CMAKE_CURRENT_SOURCE_DIR}/test_satnogs.cc +# ${CMAKE_CURRENT_SOURCE_DIR}/qa_satnogs.cc +#) -add_executable(test-satnogs ${test_satnogs_sources}) +#add_executable(test-satnogs ${test_satnogs_sources}) -target_link_libraries( - test-satnogs - ${GNURADIO_RUNTIME_LIBRARIES} - ${Boost_LIBRARIES} - ${CPPUNIT_LIBRARIES} - gnuradio-satnogs -) +#target_link_libraries( +# test-satnogs +# ${GNURADIO_RUNTIME_LIBRARIES} +# ${Boost_LIBRARIES} +# ${CPPUNIT_LIBRARIES} +# gnuradio-satnogs +#) -GR_ADD_TEST(test_satnogs test-satnogs) +#GR_ADD_TEST(test_satnogs test-satnogs) diff --git a/lib/cw_matched_filter_ff_impl.cc b/lib/cw_matched_filter_ff_impl.cc new file mode 100644 index 0000000..1917635 --- /dev/null +++ b/lib/cw_matched_filter_ff_impl.cc @@ -0,0 +1,92 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * 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 . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "cw_matched_filter_ff_impl.h" + +#include +#include + +namespace gr { + namespace satnogs { + + cw_matched_filter_ff::sptr + cw_matched_filter_ff::make(double sampling_rate, double carrier_freq, size_t wpm) + { + return gnuradio::get_initial_sptr + (new cw_matched_filter_ff_impl(sampling_rate, carrier_freq, wpm)); + } + + /* + * The private constructor + */ + cw_matched_filter_ff_impl::cw_matched_filter_ff_impl (double sampling_rate, + double carrier_freq, + size_t wpm) : + gr::sync_block ("cw_matched_filter_ff", + gr::io_signature::make (1, 1, sizeof(float)), + gr::io_signature::make (1, 1, sizeof(float))), + d_dot_duration(1.2/wpm), + d_dot_samples(d_dot_duration / (1.0 / sampling_rate)) + { + set_history(d_dot_samples); + + d_sin_wave = (float *)volk_malloc(d_dot_samples * sizeof(float), 32); + if(!d_sin_wave){ + throw std::runtime_error("Could not allocate sine wave buffer"); + } + + /* Now fill the buffer with the appropriate sine wave */ + gr::fxpt_nco nco; + nco.set_freq(2 * M_PI * carrier_freq / sampling_rate); + nco.sin(d_sin_wave, d_dot_samples, 1.0); + } + + /* + * Our virtual destructor. + */ + cw_matched_filter_ff_impl::~cw_matched_filter_ff_impl() + { + volk_free(d_sin_wave); + } + + int + cw_matched_filter_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++ ){ + volk_32f_x2_dot_prod_32f_a(out + i, in + i, d_sin_wave, + d_dot_samples); + } + + return noutput_items; + } + + } /* namespace satnogs */ +} /* namespace gr */ + diff --git a/lib/cw_matched_filter_ff_impl.h b/lib/cw_matched_filter_ff_impl.h new file mode 100644 index 0000000..d3b6787 --- /dev/null +++ b/lib/cw_matched_filter_ff_impl.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * 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_SATNOGS_CW_MATCHED_FILTER_FF_IMPL_H +#define INCLUDED_SATNOGS_CW_MATCHED_FILTER_FF_IMPL_H + +#include + + +namespace gr { + namespace satnogs { + + class cw_matched_filter_ff_impl : public cw_matched_filter_ff + { + private: + /** + * The duration of the dot in seconds + */ + const double d_dot_duration; + /** + * The duration of the dot in number of samples + */ + const size_t d_dot_samples; + + float *d_sin_wave; + + public: + cw_matched_filter_ff_impl(double sampling_rate, double carrier_freq, + size_t wpm); + ~cw_matched_filter_ff_impl(); + + // Where all the action really happens + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace satnogs +} // namespace gr + +#endif /* INCLUDED_SATNOGS_CW_MATCHED_FILTER_FF_IMPL_H */ + diff --git a/lib/qa_satnogs.cc b/lib/qa_satnogs.cc deleted file mode 100644 index 5e5332f..0000000 --- a/lib/qa_satnogs.cc +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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-filter - * directory into a single test suite. As you create new test cases, - * add them here. - */ - -#include "qa_satnogs.h" - -CppUnit::TestSuite * -qa_satnogs::suite() -{ - CppUnit::TestSuite *s = new CppUnit::TestSuite("satnogs"); - - return s; -} diff --git a/lib/qa_satnogs.h b/lib/qa_satnogs.h deleted file mode 100644 index 7858970..0000000 --- a/lib/qa_satnogs.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- 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_SATNOGS_H_ -#define _QA_SATNOGS_H_ - -#include -#include - -//! collect all the tests for the gr-filter directory - -class __GR_ATTR_EXPORT qa_satnogs -{ - public: - //! return suite of tests for all of gr-filter directory - static CppUnit::TestSuite *suite(); -}; - -#endif /* _QA_SATNOGS_H_ */ diff --git a/lib/test_satnogs.cc b/lib/test_satnogs.cc deleted file mode 100644 index 7b43f2d..0000000 --- a/lib/test_satnogs.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- 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 "config.h" -#endif - -#include -#include - -#include -#include "qa_satnogs.h" -#include -#include - -int -main (int argc, char **argv) -{ - CppUnit::TextTestRunner runner; - std::ofstream xmlfile(get_unittest_path("satnogs.xml").c_str()); - CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile); - - runner.addTest(qa_satnogs::suite()); - runner.setOutputter(xmlout); - - bool was_successful = runner.run("", false); - - return was_successful ? 0 : 1; -} diff --git a/swig/satnogs_swig.i b/swig/satnogs_swig.i index 92fdc7d..6e3fb37 100644 --- a/swig/satnogs_swig.i +++ b/swig/satnogs_swig.i @@ -8,6 +8,8 @@ %include "satnogs_swig_doc.i" %{ +#include "satnogs/cw_matched_filter_ff.h" %} - +%include "satnogs/cw_matched_filter_ff.h" +GR_SWIG_BLOCK_MAGIC2(satnogs, cw_matched_filter_ff);