diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index a55262c..d45a10c 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -22,5 +22,6 @@ install(FILES satnogs_morse_debug_source.xml satnogs_clear_text_msg_sink.xml satnogs_cw_to_symbol.xml - satnogs_afsk_decoder.xml DESTINATION share/gnuradio/grc/blocks + satnogs_afsk_decoder.xml + satnogs_sine_matched_filter_ff.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/satnogs_sine_matched_filter_ff.xml b/grc/satnogs_sine_matched_filter_ff.xml new file mode 100644 index 0000000..c178171 --- /dev/null +++ b/grc/satnogs_sine_matched_filter_ff.xml @@ -0,0 +1,56 @@ + + + Sine Matched filter + satnogs_sine_matched_filter_ff + satnogs + import satnogs + satnogs.sine_matched_filter_ff($sampling_rate, $sine_freq, $baud, $compute_energy) + + + Sampling Rate + sampling_rate + real + + + + Sine Frequency (Hz) + sine_freq + real + + + + Baudrate + baud + real + + + + Compute Energy + compute_energy + enum + + + + + + freq + message + 1 + + + + in + float + + + + out + float + + diff --git a/include/satnogs/CMakeLists.txt b/include/satnogs/CMakeLists.txt index 362547b..5404f81 100644 --- a/include/satnogs/CMakeLists.txt +++ b/include/satnogs/CMakeLists.txt @@ -31,5 +31,6 @@ install(FILES morse_debug_source.h clear_text_msg_sink.h cw_to_symbol.h - afsk_decoder.h DESTINATION include/satnogs + afsk_decoder.h + sine_matched_filter_ff.h DESTINATION include/satnogs ) diff --git a/include/satnogs/sine_matched_filter_ff.h b/include/satnogs/sine_matched_filter_ff.h new file mode 100644 index 0000000..ecfb5e4 --- /dev/null +++ b/include/satnogs/sine_matched_filter_ff.h @@ -0,0 +1,69 @@ +/* -*- 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_SINE_MATCHED_FILTER_FF_H +#define INCLUDED_SATNOGS_SINE_MATCHED_FILTER_FF_H + +#include +#include + +namespace gr +{ + namespace satnogs + { + + /*! + * \brief Matched filter for signals that use sinusoidal transmissions, + * like FSK, AFSK, e.t.c. + * + * \ingroup satnogs + * + */ + class SATNOGS_API sine_matched_filter_ff : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr sptr; + + /*! + * A matched filter that produces the filtered signal or its energy + * @param sampling_rate the sampling rate + * @param sine_freq the frequency of the sine wave + * @param baudrate the Baud-rate (aka symbols-per-second) of the + * telecommunication protocol + * @param compute_energy id set to true the filter computes the energy + * of the filtered signal. Otherwise, the filtered signal itself is + * produced + */ + static sptr + make (double sampling_rate, double sine_freq, double baudrate, + bool compute_energy = false); + + virtual void + set_new_freq (double freq) = 0; + + virtual void + set_new_freq_locked (double freq) = 0; + }; + + } // namespace satnogs +} // namespace gr + +#endif /* INCLUDED_SATNOGS_SINE_MATCHED_FILTER_FF_H */ + diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index e66f214..fa5d566 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -31,7 +31,8 @@ list(APPEND satnogs_sources morse_debug_source_impl.cc clear_text_msg_sink_impl.cc cw_to_symbol_impl.cc - afsk_decoder_impl.cc ) + afsk_decoder_impl.cc + sine_matched_filter_ff_impl.cc ) set(satnogs_sources "${satnogs_sources}" PARENT_SCOPE) if(NOT satnogs_sources) diff --git a/lib/sine_matched_filter_ff_impl.cc b/lib/sine_matched_filter_ff_impl.cc new file mode 100644 index 0000000..5b8dea1 --- /dev/null +++ b/lib/sine_matched_filter_ff_impl.cc @@ -0,0 +1,135 @@ +/* -*- 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 +#include + +#include "sine_matched_filter_ff_impl.h" + +namespace gr { + namespace satnogs { + + sine_matched_filter_ff::sptr + sine_matched_filter_ff::make(double sampling_rate, double sine_freq, + double baudrate, bool compute_energy) + { + return gnuradio::get_initial_sptr + (new sine_matched_filter_ff_impl(sampling_rate, sine_freq, + baudrate, compute_energy)); + } + + /* + * The private constructor + */ + sine_matched_filter_ff_impl::sine_matched_filter_ff_impl(double sampling_rate, + double sine_freq, + double baudrate, + bool compute_energy) + : gr::sync_block("sine_matched_filter_ff", + gr::io_signature::make(1, 1, sizeof(float)), + gr::io_signature::make(1, 1, sizeof(float))), + d_samp_rate(sampling_rate), + d_baud_rate(baudrate), + d_produce_enrg(compute_energy), + d_filter_taps(2 * std::ceil(sampling_rate / baudrate)) + { + const int alignment_multiple = volk_get_alignment() / sizeof(float); + set_alignment(std::max(1,alignment_multiple)); + set_history(d_filter_taps); + + /* + * TODO: Perhaps is better that now phase offset exists at the end + * of the buffer + */ + d_sin_wave = (float *)volk_malloc(d_filter_taps * sizeof(float), 32); + if(!d_sin_wave){ + throw std::runtime_error("Could not allocate sine wave buffer"); + } + + /* Register the input port for frequency change messages */ + message_port_register_in(pmt::mp("freq")); + set_msg_handler(pmt::mp("freq"), + boost::bind(&sine_matched_filter_ff_impl::new_freq_msg_handler, + this, _1)); + + /* Now fill the buffer with the appropriate sine wave */ + gr::fxpt_nco nco; + nco.set_freq(2 * M_PI * sine_freq / sampling_rate); + nco.sin(d_sin_wave, d_filter_taps, 1.0); + } + + void + sine_matched_filter_ff_impl::new_freq_msg_handler (pmt::pmt_t msg) + { + if (pmt::is_pair (msg)) { + set_new_freq (pmt::to_double (pmt::cdr (msg))); + } + } + + /* + * Our virtual destructor. + */ + sine_matched_filter_ff_impl::~sine_matched_filter_ff_impl() + { + volk_free(d_sin_wave); + } + + int + sine_matched_filter_ff_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + boost::mutex::scoped_lock lock (d_mutex); + 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 (out + i, in + i, d_sin_wave, d_filter_taps); + } + if (d_produce_enrg) { + volk_32f_s32f_power_32f (out, out, 2, noutput_items); + } + + return noutput_items; + } + + void + sine_matched_filter_ff_impl::set_new_freq (double freq) + { + gr::fxpt_nco nco; + nco.set_freq (2 * M_PI * freq / d_samp_rate); + nco.sin (d_sin_wave, d_filter_taps, 1.0); + } + + void + sine_matched_filter_ff_impl::set_new_freq_locked (double freq) + { + boost::mutex::scoped_lock lock(d_mutex); + set_new_freq(freq); + } + + } /* namespace satnogs */ +} /* namespace gr */ + diff --git a/lib/sine_matched_filter_ff_impl.h b/lib/sine_matched_filter_ff_impl.h new file mode 100644 index 0000000..198fc18 --- /dev/null +++ b/lib/sine_matched_filter_ff_impl.h @@ -0,0 +1,80 @@ +/* -*- 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_SINE_MATCHED_FILTER_FF_IMPL_H +#define INCLUDED_SATNOGS_SINE_MATCHED_FILTER_FF_IMPL_H + +#include + +namespace gr +{ + namespace satnogs + { + + class sine_matched_filter_ff_impl : public sine_matched_filter_ff + { + private: + /** + * The sampling rate of the signal + */ + const double d_samp_rate; + + /** + * The baudrate of the system + */ + const double d_baud_rate; + + /** + * If set to true, this block produces the energy of the filtered + * samples, rather the samples themselves + */ + const bool d_produce_enrg; + + const size_t d_filter_taps; + + float *d_sin_wave; + + boost::mutex d_mutex; + + void + new_freq_msg_handler (pmt::pmt_t msg); + + public: + sine_matched_filter_ff_impl (double sampling_rate, double sine_freq, + double baudrate, bool compute_energy); + ~sine_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); + + void + set_new_freq (double freq); + + void + set_new_freq_locked (double freq); + }; + + } // namespace satnogs +} // namespace gr + +#endif /* INCLUDED_SATNOGS_SINE_MATCHED_FILTER_FF_IMPL_H */ + diff --git a/swig/satnogs_swig.i b/swig/satnogs_swig.i index b9c590f..6b00b04 100644 --- a/swig/satnogs_swig.i +++ b/swig/satnogs_swig.i @@ -15,6 +15,7 @@ #include "satnogs/clear_text_msg_sink.h" #include "satnogs/cw_to_symbol.h" #include "satnogs/afsk_decoder.h" +#include "satnogs/sine_matched_filter_ff.h" %} %include "satnogs/cw_matched_filter_ff.h" @@ -30,3 +31,5 @@ GR_SWIG_BLOCK_MAGIC2(satnogs, clear_text_msg_sink); GR_SWIG_BLOCK_MAGIC2(satnogs, cw_to_symbol); %include "satnogs/afsk_decoder.h" GR_SWIG_BLOCK_MAGIC2(satnogs, afsk_decoder); +%include "satnogs/sine_matched_filter_ff.h" +GR_SWIG_BLOCK_MAGIC2(satnogs, sine_matched_filter_ff);