Commit b4dd0f1e authored by Manolis Surligas's avatar Manolis Surligas

Add matched filter implementation for CW noise reduction

* The matched filter makes use of VOLK
* The examples directory contains a simple flowgraph that demonstrates
the performance of the matched filter
parent 5e231a8a
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.
# 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
This diff is collapsed.
......@@ -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
)
<?xml version="1.0"?>
<block>
<name>CW Matched Filter</name>
<key>satnogs_cw_matched_filter_ff</key>
<category>satnogs</category>
<import>import satnogs</import>
<make>satnogs.cw_matched_filter_ff($sampling_rate, $carrier_freq, $wpm)</make>
<param>
<name>Sampling Rate</name>
<key>sampling_rate</key>
<type>real</type>
</param>
<param>
<name>Audio Frequency (Hz)</name>
<key>carrier_freq</key>
<type>real</type>
</param>
<param>
<name>Words per Minute</name>
<key>wpm</key>
<value>20</value>
<type>int</type>
</param>
<sink>
<name>in</name>
<type>float</type>
</sink>
<source>
<name>out</name>
<type>float</type>
</source>
</block>
......@@ -22,5 +22,5 @@
########################################################################
install(FILES
api.h
DESTINATION include/satnogs
cw_matched_filter_ff.h DESTINATION include/satnogs
)
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_SATNOGS_CW_MATCHED_FILTER_FF_H
#define INCLUDED_SATNOGS_CW_MATCHED_FILTER_FF_H
#include <satnogs/api.h>
#include <gnuradio/sync_block.h>
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<cw_matched_filter_ff> 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 */
......@@ -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)
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#include "cw_matched_filter_ff_impl.h"
#include <volk/volk.h>
#include <gnuradio/fxpt_nco.h>
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 */
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_SATNOGS_CW_MATCHED_FILTER_FF_IMPL_H
#define INCLUDED_SATNOGS_CW_MATCHED_FILTER_FF_IMPL_H
#include <satnogs/cw_matched_filter_ff.h>
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 */
/*
* 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;
}
/* -*- 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 <gnuradio/attributes.h>
#include <cppunit/TestSuite.h>
//! 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_ */
/* -*- 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 <cppunit/TextTestRunner.h>
#include <cppunit/XmlOutputter.h>
#include <gnuradio/unittests.h>
#include "qa_satnogs.h"
#include <iostream>
#include <fstream>
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;
}
......@@ -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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment