diff --git a/cmake/Modules/FindLog4cpp.cmake b/cmake/Modules/FindLog4cpp.cmake new file mode 100644 index 0000000..fc314c6 --- /dev/null +++ b/cmake/Modules/FindLog4cpp.cmake @@ -0,0 +1,53 @@ +# - Find Log4cpp +# Find the native LOG4CPP includes and library +# +# LOG4CPP_INCLUDE_DIR - where to find LOG4CPP.h, etc. +# LOG4CPP_LIBRARIES - List of libraries when using LOG4CPP. +# LOG4CPP_FOUND - True if LOG4CPP found. + + +if (LOG4CPP_INCLUDE_DIR) + # Already in cache, be silent + set(LOG4CPP_FIND_QUIETLY TRUE) +endif () + +find_path(LOG4CPP_INCLUDE_DIR log4cpp/Category.hh + /opt/local/include + /usr/local/include + /usr/include +) + +set(LOG4CPP_NAMES log4cpp) +find_library(LOG4CPP_LIBRARY + NAMES ${LOG4CPP_NAMES} + PATHS /usr/lib /usr/local/lib /opt/local/lib +) + + +if (LOG4CPP_INCLUDE_DIR AND LOG4CPP_LIBRARY) + set(LOG4CPP_FOUND TRUE) + set(LOG4CPP_LIBRARIES ${LOG4CPP_LIBRARY} CACHE INTERNAL "" FORCE) + set(LOG4CPP_INCLUDE_DIRS ${LOG4CPP_INCLUDE_DIR} CACHE INTERNAL "" FORCE) +else () + set(LOG4CPP_FOUND FALSE CACHE INTERNAL "" FORCE) + set(LOG4CPP_LIBRARY "" CACHE INTERNAL "" FORCE) + set(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE) + set(LOG4CPP_INCLUDE_DIR "" CACHE INTERNAL "" FORCE) + set(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE) +endif () + +if (LOG4CPP_FOUND) + if (NOT LOG4CPP_FIND_QUIETLY) + message(STATUS "Found LOG4CPP: ${LOG4CPP_LIBRARIES}") + endif () +else () + if (LOG4CPP_FIND_REQUIRED) + message(STATUS "Looked for LOG4CPP libraries named ${LOG4CPPS_NAMES}.") + message(FATAL_ERROR "Could NOT find LOG4CPP library") + endif () +endif () + +mark_as_advanced( + LOG4CPP_LIBRARIES + LOG4CPP_INCLUDE_DIRS +) diff --git a/include/digitalhf/CMakeLists.txt b/include/digitalhf/CMakeLists.txt index 90dc3cb..64f9c7c 100644 --- a/include/digitalhf/CMakeLists.txt +++ b/include/digitalhf/CMakeLists.txt @@ -24,5 +24,10 @@ install(FILES api.h adaptive_dfe.h - doppler_correction_cc.h DESTINATION include/digitalhf + doppler_correction_cc.h + viterbi27.h + viterbi29.h + viterbi39.h + viterbi48.h + DESTINATION include/digitalhf ) diff --git a/include/digitalhf/viterbi27.h b/include/digitalhf/viterbi27.h new file mode 100644 index 0000000..4809ea3 --- /dev/null +++ b/include/digitalhf/viterbi27.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 hcab14@mail.com. + * + * This 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. + * + * This software 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_DIGITALHF_VITERBI27_H +#define INCLUDED_DIGITALHF_VITERBI27_H + +#include +#include + +namespace gr { +namespace digitalhf { + +/*! + * \brief <+description of block+> + * \ingroup digitalhf + * + */ +class DIGITALHF_API viterbi27 +{ + public: + typedef boost::shared_ptr sptr; + + virtual ~viterbi27() {} + /*! + * \brief Return a shared_ptr to a new instance of digitalhf::viterbi27. + * + * To avoid accidental use of raw pointers, digitalhf::viterbi27's + * constructor is in a private implementation + * class. digitalhf::viterbi27::make is the public interface for + * creating new instances. + */ + static sptr make(std::uint32_t pol0=0x6D, + std::uint32_t pol1=0x4F); + + virtual void reset() = 0; + virtual const std::vector& udpate(const std::vector& soft_dec) = 0; + virtual float quality() = 0; +} ; + +} // namespace digitalhf +} // namespace gr + +#endif /* INCLUDED_DIGITALHF_VITERBI27_H */ diff --git a/include/digitalhf/viterbi29.h b/include/digitalhf/viterbi29.h new file mode 100644 index 0000000..9b01d0d --- /dev/null +++ b/include/digitalhf/viterbi29.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 hcab14@mail.com. + * + * This 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. + * + * This software 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_DIGITALHF_VITERBI29_H +#define INCLUDED_DIGITALHF_VITERBI29_H + +#include +#include + +namespace gr { +namespace digitalhf { + +/*! + * \brief <+description of block+> + * \ingroup digitalhf + * + */ +class DIGITALHF_API viterbi29 +{ + public: + typedef boost::shared_ptr sptr; + + virtual ~viterbi29() {} + /*! + * \brief Return a shared_ptr to a new instance of digitalhf::viterbi29. + * + * To avoid accidental use of raw pointers, digitalhf::viterbi29's + * constructor is in a private implementation + * class. digitalhf::viterbi29::make is the public interface for + * creating new instances. + */ + static sptr make(std::uint32_t pol0=0x11D, + std::uint32_t pol1=0x1AF); + + virtual void reset() = 0; + virtual const std::vector& udpate(const std::vector& soft_dec) = 0; + virtual float quality() = 0; +} ; + +} // namespace digitalhf +} // namespace gr + +#endif /* INCLUDED_DIGITALHF_VITERBI29_H */ diff --git a/include/digitalhf/viterbi39.h b/include/digitalhf/viterbi39.h new file mode 100644 index 0000000..fd75eb2 --- /dev/null +++ b/include/digitalhf/viterbi39.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 hcab14@mail.com. + * + * This 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. + * + * This software 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_DIGITALHF_VITERBI39_H +#define INCLUDED_DIGITALHF_VITERBI39_H + +#include +#include + +namespace gr { +namespace digitalhf { + +/*! + * \brief <+description of block+> + * \ingroup digitalhf + * + */ +class DIGITALHF_API viterbi39 +{ + public: + typedef boost::shared_ptr sptr; + + virtual ~viterbi39() {} + /*! + * \brief Return a shared_ptr to a new instance of digitalhf::viterbi39. + * + * To avoid accidental use of raw pointers, digitalhf::viterbi39's + * constructor is in a private implementation + * class. digitalhf::viterbi39::make is the public interface for + * creating new instances. + */ + static sptr make(std::uint32_t pol0=0x127, + std::uint32_t pol1=0x19B, + std::uint32_t pol2=0x1ED); + + virtual void reset() = 0; + virtual const std::vector& udpate(const std::vector& soft_dec) = 0; + virtual float quality() = 0; +} ; + +} // namespace digitalhf +} // namespace gr + +#endif /* INCLUDED_DIGITALHF_VITERBI39_H */ diff --git a/include/digitalhf/viterbi48.h b/include/digitalhf/viterbi48.h new file mode 100644 index 0000000..c0a6e30 --- /dev/null +++ b/include/digitalhf/viterbi48.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 hcab14@mail.com. + * + * This 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. + * + * This software 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_DIGITALHF_VITERBI48_H +#define INCLUDED_DIGITALHF_VITERBI48_H + +#include +#include + +namespace gr { +namespace digitalhf { + +/*! + * \brief <+description of block+> + * \ingroup digitalhf + * + */ +class DIGITALHF_API viterbi48 +{ + public: + typedef boost::shared_ptr sptr; + + virtual ~viterbi48() {} + /*! + * \brief Return a shared_ptr to a new instance of digitalhf::viterbi48. + * + * To avoid accidental use of raw pointers, digitalhf::viterbi48's + * constructor is in a private implementation + * class. digitalhf::viterbi48::make is the public interface for + * creating new instances. + */ + static sptr make(std::uint32_t pol0=0xB9, + std::uint32_t pol1=0x9D, + std::uint32_t pol2=0xD3, + std::uint32_t pol3=0xF7); + + virtual void reset() = 0; + virtual const std::vector& udpate(const std::vector& soft_dec) = 0; + virtual float quality() = 0; +} ; + +} // namespace digitalhf +} // namespace gr + +#endif /* INCLUDED_DIGITALHF_VITERBI48_H */ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 87626f4..c32e57d 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -27,7 +27,11 @@ include_directories(${Boost_INCLUDE_DIR}) link_directories(${Boost_LIBRARY_DIRS}) list(APPEND digitalhf_sources adaptive_dfe_impl.cc - doppler_correction_cc_impl.cc ) + doppler_correction_cc_impl.cc + viterbi27_impl.cc + viterbi29_impl.cc + viterbi39_impl.cc + viterbi48_impl.cc) set(digitalhf_sources "${digitalhf_sources}" PARENT_SCOPE) if(NOT digitalhf_sources) diff --git a/lib/llr_to_prob.h b/lib/llr_to_prob.h new file mode 100644 index 0000000..5076c9d --- /dev/null +++ b/lib/llr_to_prob.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 hcab14@mail.com. + * + * This 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. + * + * This software 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +namespace gr { +namespace digitalhf { + +#include +#include +#include + +template +class llr_to_prob { +public: + llr_to_prob() + : _table() { + for (int i=0; i probability(1) + float const x = -7.0f + 14.0f*float(i)/float(N-1); + _table[i] = std::uint8_t(0.5f + 255.0f/(1.0f + std::exp(x))); + } + } + virtual ~llr_to_prob() {} + + std::uint8_t table_lookup(float llr) const { + float const x = (7.0f + std::max(-7.0f, std::min(+7.0f, llr)))/14.0f; // \in [0,1] + return _table[int(0.5 + (N-1)*x)]; + } +protected: +private: + std::array _table; +} ; + +} // namespace digitalhf +} // namespace gr diff --git a/lib/viterbi.h b/lib/viterbi.h new file mode 100644 index 0000000..5b440dd --- /dev/null +++ b/lib/viterbi.h @@ -0,0 +1,124 @@ +// -*- C++ -*- + +#ifndef _VITERBI_HPP_ +#define _VITERBI_HPP_ + +#include +#include +#include +#include +#include + +// soft-decision viterbi decoder +// based on Phil Karn's libfec +template +class viterbi { +public: + + enum { M = 1<<(K-1) }; + typedef std::vector vec_type; + typedef std::array arr_type; + + viterbi(std::array const& polys) // ={0x6d,0x4f} + : _decisions() // len<<(K-1)) + , _metric() + , _bits() + , _prev() + , _last_max_metric(0) { + make_tables(polys); + } + + void reset() { + std::fill_n(_metric.begin(), _metric.size(), 0); + _last_max_metric = 0; + } + + void resize(size_t len) { + _decisions.resize(len<<(K-1)); + } + + void update(int j, std::arrayconst& sym) { + int s[N]; + for (int l=0; l (1<<15)) { + _last_max_metric -= imin; + for (int i=0; i& v) { + return chainback(v.begin(), v.end()); + } + + float chainback(std::vector::iterator begin, + std::vector::iterator end) { + assert(std::distance(begin, end) == ssize_t((_decisions.size()>>(K-1)))); + + auto const imax = std::max_element(_metric.begin(), _metric.end()); + int idx_max = std::distance(_metric.begin(), imax); + for (int k=_decisions.size()>>(K-1); k!=0; --k) { + begin[k-1] = idx_max&1; + //idx_max = _prev[idx_max][decision(k-1)[idx_max]]; + idx_max = (idx_max>>1) + (decision(k-1)[idx_max] != 0)*M/2; + } + int const max_metric = *imax; + float const quality = float(max_metric - _last_max_metric)/255.0; + _last_max_metric = max_metric; + return quality; + } + +protected: + vec_type::iterator decision(int i) { + return _decisions.begin() + (i<<(K-1)); + } + void make_tables(std::array const& polys) { + for (int i=0, n=1< const b(polys[l]&i); + _bits[i>>1][i%2][l] = 255*(b.count()%2); + } + } + for (int i=0; i>1); + _prev[i][1] = _prev[i][0] + M/2; + } + } +private: + vec_type _decisions; + arr_type _metric; + int _bits[M][2][N]; + int _prev[M][2]; + int _last_max_metric; +} ; + +#endif // _VITERBI2_HPP_ diff --git a/lib/viterbi27_impl.cc b/lib/viterbi27_impl.cc new file mode 100644 index 0000000..dbf1cf6 --- /dev/null +++ b/lib/viterbi27_impl.cc @@ -0,0 +1,108 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 hcab14@mail.com. + * + * This 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. + * + * This software 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 software; 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 +#include + +#include + +#include "viterbi27_impl.h" + +namespace gr { +namespace digitalhf { + +viterbi27::sptr +viterbi27::make(std::uint32_t pol0, std::uint32_t pol1) +{ + return sptr(new viterbi27_impl(pol0, pol1)); +} + +viterbi27_impl::viterbi27_impl(std::uint32_t pol0, std::uint32_t pol1) + : _v({pol0, pol1}) + , _quality(0) + , _num_bits(0) + , _bits() +{ +} + +viterbi27_impl::~viterbi27_impl() +{ +} + +void viterbi27_impl::reset() { + _v.reset(); + _quality = 0; +} + + +const std::vector& viterbi27_impl::udpate(const std::vector& soft_dec) { + size_t symb_len = soft_dec.size(); + float const *sd = &soft_dec[0]; + + size_t const num_bits = symb_len/2; + _bits.resize(num_bits); + std::vector::iterator iterator_bits = _bits.begin(); + + size_t bits_per_frame = 5*7; // 5 times constraint length + _v.resize(bits_per_frame); + + size_t num_frames = num_bits/bits_per_frame; + + _quality = 0; + int i = 0; + for (; i const symb = { + table_lookup(sd[2*(i*bits_per_frame+j) ]), + table_lookup(sd[2*(i*bits_per_frame+j)+1]) + }; + _v.update(j, symb); + } + _quality += _v.chainback(iterator_bits, iterator_bits+bits_per_frame); + iterator_bits += bits_per_frame; + } + + size_t remaining_bits = num_bits - bits_per_frame*num_frames; + _v.resize(remaining_bits); + for (int j=0; j const symb = { + table_lookup(sd[2*(i*bits_per_frame+j) ]), + table_lookup(sd[2*(i*bits_per_frame+j)+1]) + }; + _v.update(j, symb); + } + _quality += _v.chainback(iterator_bits, iterator_bits+remaining_bits); + return _bits; +} + +float viterbi27_impl::quality() { + return _quality; +} + +} // namespace digitalhf +} // namespace gr diff --git a/lib/viterbi27_impl.h b/lib/viterbi27_impl.h new file mode 100644 index 0000000..27af2d1 --- /dev/null +++ b/lib/viterbi27_impl.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 hcab14@mail.com. + * + * This 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. + * + * This software 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITALHF_VITERBI27IMPL_H +#define INCLUDED_DIGITALHF_VITERBI27IMPL_H + +#include + +#include "viterbi.h" +#include "llr_to_prob.h" + +namespace gr { +namespace digitalhf { + +class viterbi27_impl : public viterbi27, public llr_to_prob<1024> { +private: + viterbi<2,7> _v; + float _quality; + size_t _num_bits; + std::vector _bits; + +public: + viterbi27_impl(std::uint32_t pol0, std::uint32_t pol1); + virtual ~viterbi27_impl(); + + virtual void reset(); + virtual const std::vector& udpate(const std::vector& soft_dec); + virtual float quality(); +} ; + +} // namespace digitalhf +} // namespace gr + +#endif /* INCLUDED_DIGITALHF_VITERBI27IMPL_H */ diff --git a/lib/viterbi29_impl.cc b/lib/viterbi29_impl.cc new file mode 100644 index 0000000..505f206 --- /dev/null +++ b/lib/viterbi29_impl.cc @@ -0,0 +1,108 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 hcab14@mail.com. + * + * This 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. + * + * This software 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 software; 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 +#include + +#include + +#include "viterbi29_impl.h" + +namespace gr { +namespace digitalhf { + +viterbi29::sptr +viterbi29::make(std::uint32_t pol0, std::uint32_t pol1) +{ + return sptr(new viterbi29_impl(pol0, pol1)); +} + +viterbi29_impl::viterbi29_impl(std::uint32_t pol0, std::uint32_t pol1) + : _v({pol0, pol1}) + , _quality(0) + , _num_bits(0) + , _bits() +{ +} + +viterbi29_impl::~viterbi29_impl() +{ +} + +void viterbi29_impl::reset() { + _v.reset(); + _quality = 0; +} + + +const std::vector& viterbi29_impl::udpate(const std::vector& soft_dec) { + size_t symb_len = soft_dec.size(); + float const *sd = &soft_dec[0]; + + size_t const num_bits = symb_len/2; + _bits.resize(num_bits); + std::vector::iterator iterator_bits = _bits.begin(); + + size_t bits_per_frame = 5*9; // 5 times constraint length + _v.resize(bits_per_frame); + + size_t num_frames = num_bits/bits_per_frame; + + _quality = 0; + int i = 0; + for (; i const symb = { + table_lookup(sd[2*(i*bits_per_frame+j) ]), + table_lookup(sd[2*(i*bits_per_frame+j)+1]) + }; + _v.update(j, symb); + } + _quality += _v.chainback(iterator_bits, iterator_bits+bits_per_frame); + iterator_bits += bits_per_frame; + } + + size_t remaining_bits = num_bits - bits_per_frame*num_frames; + _v.resize(remaining_bits); + for (int j=0; j const symb = { + table_lookup(sd[2*(i*bits_per_frame+j) ]), + table_lookup(sd[2*(i*bits_per_frame+j)+1]) + }; + _v.update(j, symb); + } + _quality += _v.chainback(iterator_bits, iterator_bits+remaining_bits); + return _bits; +} + +float viterbi29_impl::quality() { + return _quality; +} + +} // namespace digitalhf +} // namespace gr diff --git a/lib/viterbi29_impl.h b/lib/viterbi29_impl.h new file mode 100644 index 0000000..d9ef555 --- /dev/null +++ b/lib/viterbi29_impl.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 hcab14@mail.com. + * + * This 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. + * + * This software 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITALHF_VITERBI29IMPL_H +#define INCLUDED_DIGITALHF_VITERBI29IMPL_H + +#include + +#include "viterbi.h" +#include "llr_to_prob.h" + +namespace gr { +namespace digitalhf { + +class viterbi29_impl : public viterbi29, public llr_to_prob<1024> { +private: + viterbi<2,9> _v; + float _quality; + size_t _num_bits; + std::vector _bits; + +public: + viterbi29_impl(std::uint32_t pol0, std::uint32_t pol1); + virtual ~viterbi29_impl(); + + virtual void reset(); + virtual const std::vector& udpate(const std::vector& soft_dec); + virtual float quality(); +} ; + +} // namespace digitalhf +} // namespace gr + +#endif /* INCLUDED_DIGITALHF_VITERBI29IMPL_H */ diff --git a/lib/viterbi39_impl.cc b/lib/viterbi39_impl.cc new file mode 100644 index 0000000..6d5186e --- /dev/null +++ b/lib/viterbi39_impl.cc @@ -0,0 +1,114 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 hcab14@mail.com. + * + * This 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. + * + * This software 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 software; 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 +#include + +#include + +#include "viterbi39_impl.h" + +namespace gr { +namespace digitalhf { + +viterbi39::sptr +viterbi39::make(std::uint32_t pol0, + std::uint32_t pol1, + std::uint32_t pol2) +{ + return sptr(new viterbi39_impl(pol0, pol1, pol2)); +} + +viterbi39_impl::viterbi39_impl(std::uint32_t pol0, + std::uint32_t pol1, + std::uint32_t pol2) + : _v({pol0, pol1, pol2}) + , _quality(0) + , _num_bits(0) + , _bits() +{ +} + +viterbi39_impl::~viterbi39_impl() +{ +} + +void viterbi39_impl::reset() { + _v.reset(); + _quality = 0; +} + + +const std::vector& viterbi39_impl::udpate(const std::vector& soft_dec) { + size_t symb_len = soft_dec.size(); + float const *sd = &soft_dec[0]; + + size_t const num_bits = symb_len/3; + _bits.resize(num_bits); + std::vector::iterator iterator_bits = _bits.begin(); + + size_t bits_per_frame = 5*9; // 5 times constraint length + _v.resize(bits_per_frame); + + size_t num_frames = num_bits/bits_per_frame; + + _quality = 0; + int i = 0; + for (; i const symb = { + table_lookup(sd[3*(i*bits_per_frame+j) ]), + table_lookup(sd[3*(i*bits_per_frame+j)+1]), + table_lookup(sd[3*(i*bits_per_frame+j)+2]) + }; + _v.update(j, symb); + } + _quality += _v.chainback(iterator_bits, iterator_bits+bits_per_frame); + iterator_bits += bits_per_frame; + } + + size_t remaining_bits = num_bits - bits_per_frame*num_frames; + _v.resize(remaining_bits); + for (int j=0; j const symb = { + table_lookup(sd[3*(i*bits_per_frame+j) ]), + table_lookup(sd[3*(i*bits_per_frame+j)+1]), + table_lookup(sd[3*(i*bits_per_frame+j)+2]) + }; + _v.update(j, symb); + } + _quality += _v.chainback(iterator_bits, iterator_bits+remaining_bits); + return _bits; +} + +float viterbi39_impl::quality() { + return _quality; +} + +} // namespace digitalhf +} // namespace gr diff --git a/lib/viterbi39_impl.h b/lib/viterbi39_impl.h new file mode 100644 index 0000000..e955698 --- /dev/null +++ b/lib/viterbi39_impl.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 hcab14@mail.com. + * + * This 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. + * + * This software 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITALHF_VITERBI39IMPL_H +#define INCLUDED_DIGITALHF_VITERBI39IMPL_H + +#include + +#include "viterbi.h" +#include "llr_to_prob.h" + +namespace gr { +namespace digitalhf { + +class viterbi39_impl : public viterbi39, public llr_to_prob<1024> { +private: + viterbi<3,9> _v; + float _quality; + size_t _num_bits; + std::vector _bits; + +public: + viterbi39_impl(std::uint32_t pol0, + std::uint32_t pol1, + std::uint32_t pol2); + virtual ~viterbi39_impl(); + + virtual void reset(); + virtual const std::vector& udpate(const std::vector& soft_dec); + virtual float quality(); +} ; + +} // namespace digitalhf +} // namespace gr + +#endif /* INCLUDED_DIGITALHF_VITERBI39IMPL_H */ diff --git a/lib/viterbi48_impl.cc b/lib/viterbi48_impl.cc new file mode 100644 index 0000000..bfe0b81 --- /dev/null +++ b/lib/viterbi48_impl.cc @@ -0,0 +1,114 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 hcab14@mail.com. + * + * This 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. + * + * This software 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 software; 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 +#include + +#include + +#include "viterbi48_impl.h" + +namespace gr { +namespace digitalhf { + +viterbi48::sptr +viterbi48::make(std::uint32_t pol0, std::uint32_t pol1, + std::uint32_t pol2, std::uint32_t pol3) +{ + return sptr(new viterbi48_impl(pol0, pol1, pol2, pol3)); +} + +viterbi48_impl::viterbi48_impl(std::uint32_t pol0, std::uint32_t pol1, + std::uint32_t pol2, std::uint32_t pol3) + : _v({pol0, pol1, pol2, pol3}) + , _quality(0) + , _num_bits(0) + , _bits() +{ +} + +viterbi48_impl::~viterbi48_impl() +{ +} + +void viterbi48_impl::reset() { + _v.reset(); + _quality = 0; +} + + +const std::vector& viterbi48_impl::udpate(const std::vector& soft_dec) { + size_t symb_len = soft_dec.size(); + float const *sd = &soft_dec[0]; + + size_t const num_bits = symb_len/4; + _bits.resize(num_bits); + std::vector::iterator iterator_bits = _bits.begin(); + + size_t bits_per_frame = 5*8; // 5 times constraint length + _v.resize(bits_per_frame); + + size_t num_frames = num_bits/bits_per_frame; + + _quality = 0; + int i = 0; + for (; i const symb = { + table_lookup(sd[4*(i*bits_per_frame+j) ]), + table_lookup(sd[4*(i*bits_per_frame+j)+1]), + table_lookup(sd[4*(i*bits_per_frame+j)+2]), + table_lookup(sd[4*(i*bits_per_frame+j)+3]) + }; + _v.update(j, symb); + } + _quality += _v.chainback(iterator_bits, iterator_bits+bits_per_frame); + iterator_bits += bits_per_frame; + } + + size_t remaining_bits = num_bits - bits_per_frame*num_frames; + _v.resize(remaining_bits); + for (int j=0; j const symb = { + table_lookup(sd[4*(i*bits_per_frame+j) ]), + table_lookup(sd[4*(i*bits_per_frame+j)+1]), + table_lookup(sd[4*(i*bits_per_frame+j)+2]), + table_lookup(sd[4*(i*bits_per_frame+j)+3]) + }; + _v.update(j, symb); + } + _quality += _v.chainback(iterator_bits, iterator_bits+remaining_bits); + return _bits; +} + +float viterbi48_impl::quality() { + return _quality; +} + +} // namespace digitalhf +} // namespace gr diff --git a/lib/viterbi48_impl.h b/lib/viterbi48_impl.h new file mode 100644 index 0000000..e5a584a --- /dev/null +++ b/lib/viterbi48_impl.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 hcab14@mail.com. + * + * This 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. + * + * This software 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITALHF_VITERBI48IMPL_H +#define INCLUDED_DIGITALHF_VITERBI48IMPL_H + +#include + +#include "viterbi.h" +#include "llr_to_prob.h" + +namespace gr { +namespace digitalhf { + +class viterbi48_impl : public viterbi48, public llr_to_prob<1024> { +private: + viterbi<4,8> _v; + float _quality; + size_t _num_bits; + std::vector _bits; + +public: + viterbi48_impl(std::uint32_t pol0, std::uint32_t pol1, + std::uint32_t pol2, std::uint32_t pol3); + virtual ~viterbi48_impl(); + + virtual void reset(); + virtual const std::vector& udpate(const std::vector& soft_dec); + virtual float quality(); +} ; + +} // namespace digitalhf +} // namespace gr + +#endif /* INCLUDED_DIGITALHF_VITERBI48IMPL_H */ diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index ede36a1..cacf591 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -46,6 +46,11 @@ set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) GR_ADD_TEST(qa_adaptive_dfe ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_adaptive_dfe.py) add_subdirectory(physical_layer) -GR_ADD_TEST(qa_physical_layer_driver_driver ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_physical_layer_driver_driver.py) -GR_ADD_TEST(qa_doppler_correction_cc ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_doppler_correction_cc.py) -GR_ADD_TEST(qa_msg_proxy ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_msg_proxy.py) +## FIXME: +# GR_ADD_TEST(qa_physical_layer_driver_driver ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_physical_layer_driver_driver.py) +# GR_ADD_TEST(qa_doppler_correction_cc ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_doppler_correction_cc.py) +# GR_ADD_TEST(qa_msg_proxy ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_msg_proxy.py) +GR_ADD_TEST(qa_viterbi27 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_viterbi27.py) +GR_ADD_TEST(qa_viterbi29 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_viterbi29.py) +GR_ADD_TEST(qa_viterbi39 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_viterbi39.py) +GR_ADD_TEST(qa_viterbi48 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_viterbi48.py) diff --git a/python/physical_layer/MIL_STD_188_110D.py b/python/physical_layer/MIL_STD_188_110D.py index c058993..99bf2db 100644 --- a/python/physical_layer/MIL_STD_188_110D.py +++ b/python/physical_layer/MIL_STD_188_110D.py @@ -558,6 +558,42 @@ BW_INTL_INCR = { ## [BW][WID][INTL] -> interleaver increment {'US': 3401, 'S': 26449, 'M': 105209, 'L': 326729}] ## WID 12 } +BW_CODE_RATE = { # [BW][WID] -> code rate + '3 kHz': [ '1/2', '1/8' , '1/4', '1/3', '2/3', '3/4', '3/4', '3/4', '3/4', '3/4', '3/4', '8/9', '8/9', '9/16'], + '6 kHz': [ '1/2', '1/8' , '1/4', '1/3', '2/3', '3/4', '3/4', '3/4', '3/4', '3/4', '3/4', '8/9', '8/9' ], + '9 kHz': [ '2/3', '1/8' , '1/4', '1/2', '-', '3/4', '3/4', '3/4', '3/4', '3/4', '3/4', '8/9', '8/9' ], + '12 kHz': [ '1/2', '1/8' , '1/4', '1/3', '2/3', '3/4', '3/4', '3/4', '3/4', '3/4', '3/4', '8/9', '8/9' ], + '15 kHz': [ '2/5', '1/12', '1/6', '1/3', '2/3', '3/4', '3/4', '3/4', '3/4', '3/4', '3/4', '8/9', '8/9' ], + '18 kHz': [ '2/3', '1/8' , '1/4', '1/2', '-', '3/4', '3/4', '3/4', '3/4', '3/4', '3/4', '8/9', '5/6' ], + '21 kHz': [ '2/7', '1/16', '1/8', '1/4', '1/2', '2/3', '2/3', '2/3', '2/3', '2/3', '2/3', '4/5', '9/10'], + '24 kHz': [ '1/2', '1/8' , '1/4', '1/3', '2/3', '3/4', '3/4', '3/4', '3/4', '3/4', '3/4', '8/9', '5/6' ], + '30 kHz': [ '2/5', '1/12', '1/6', '1/3', '2/3', '3/4', '3/4', '3/4', '3/4', '3/4', '3/4', '8/9', '8/9' ], + '36 kHz': [ '2/3', '1/8' , '1/4', '1/2', '1/2', '3/4', '3/4', '3/4', '3/4', '3/4', '3/4', '8/9', '8/9' ], + '42 kHz': [ '4/7', '1/8' , '1/4', '1/2', '1/2', '2/3', '2/3', '2/3', '2/3', '2/3', '2/3', '5/6', '3/4' ], + '48 kHz': [ '1/2', '1/8' , '1/4', '1/2', '1/2', '3/4', '3/4', '3/4', '3/4', '3/4', '3/4', '8/9', '5/6' ] +} + +## Code Rate K=7 Puncture Pattern K=9 Puncture Pattern Number of Repeats +CODE_RATE_PUNCT = { # [code rate][K] -> punct pattern, [code rate]['Rep'] -> # repetitions + '9/10': { 'K=7': ['111101110','100010001'], 'K=9': ['111000101','100111010'], 'Rep': 1 }, + '8/9' : { 'K=7': [ '11110100', '10001011'], 'K=9': [ '11100000', '10011111'], 'Rep': 1 }, + '5/6' : { 'K=7': [ '11010', '10101'], 'K=9': [ '10110', '11001'], 'Rep': 1 }, + '4/5' : { 'K=7': [ '1111', '1000'], 'K=9': [ '1101', '1010'], 'Rep': 1 }, + '3/4' : { 'K=7': [ '110', '101'], 'K=9': [ '111', '100'], 'Rep': 1 }, + '2/3' : { 'K=7': [ '11', '10'], 'K=9': [ '11', '10'], 'Rep': 1 }, + '4/7' : { 'K=7': [ '1111', '0111'], 'K=9': [ '1111', '0111'], 'Rep': 1 }, + '9/16': { 'K=7': ['111101111','111111011'], 'K=9': ['111101111','111111011'], 'Rep': 1 }, + '1/2' : { 'K=7': [ '1', '1'], 'K=9': [ '1', '1'], 'Rep': 1 }, + '2/5' : { 'K=7': [ '1110', '1010'], 'K=9': [ '1110', '1010'], 'Rep': 2 }, + '1/3' : { 'K=7': [ '11', '10'], 'K=9': [ '11', '10'], 'Rep': 2 }, + '2/7' : { 'K=7': [ '1111', '0111'], 'K=9': [ '1111', '0111'], 'Rep': 2 }, + '1/4' : { 'K=7': [ '1', '1'], 'K=9': [ '1', '1'], 'Rep': 2 }, + '1/6' : { 'K=7': [ '1', '1'], 'K=9': [ '1', '1'], 'Rep': 3 }, + '1/8' : { 'K=7': [ '1', '1'], 'K=9': [ '1', '1'], 'Rep': 4 }, + '1/12': { 'K=7': [ '1', '1'], 'K=9': [ '1', '1'], 'Rep': 6 }, + '1/16': { 'K=7': [ '1', '1'], 'K=9': [ '1', '1'], 'Rep': 8 } +} + ## ---- Walsh-4 codes ---------------------------------------------------------- WALSH = np.array([[0,0,0,0], # 0 - 00 [0,1,0,1], # 1 - 01 @@ -778,8 +814,10 @@ class PhysicalLayer(object): self._mp = make_mp(self._known, mp_info['base_len'], 0) self._mp_shifted = make_mp(self._known, mp_info['base_len'], mp_info['base_shift']) self._intl_info = BW_INTL[self._bw][self._wid][self._intl_type] + self._intl_incr = BW_INTL_INCR[self._bw][self._wid][self._intl_type] self._intl_frames = self._intl_info[0] - print('b=', b, success, self._wid, self._intl_type, self._intl_frames, self._constraint_length, + self._intl_bits = self._intl_info[1] + print('b=', b, success, self._wid, self._intl_type, self._intl_frames, self._intl_incr, self._constraint_length, self._known, self._unknown) return success diff --git a/python/physical_layer_driver.py b/python/physical_layer_driver.py index 4180338..03b409d 100644 --- a/python/physical_layer_driver.py +++ b/python/physical_layer_driver.py @@ -26,7 +26,6 @@ from gnuradio import filter from gnuradio import gr import pmt import digitalhf -import digitalhf.physical_layer class physical_layer_driver(gr.hier_block2): """ diff --git a/python/qa_adaptive_dfe.py b/python/qa_adaptive_dfe.py index bd1e19c..2bf7fe3 100755 --- a/python/qa_adaptive_dfe.py +++ b/python/qa_adaptive_dfe.py @@ -1,23 +1,23 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# +# # Copyright 2018 hcab14@mail.com. -# +# # This 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. -# +# # This software 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 software; 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 from gnuradio import blocks @@ -31,6 +31,7 @@ class qa_adaptive_dfe(gr_unittest.TestCase): def tearDown(self): self.tb = None + def test_001_t(self): # set up fg self.tb.run() diff --git a/python/qa_msg_proxy.py b/python/qa_msg_proxy.py index b42c05b..33fad65 100755 --- a/python/qa_msg_proxy.py +++ b/python/qa_msg_proxy.py @@ -1,23 +1,23 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# +# # Copyright 2018 hcab14@gmail.com. -# +# # This 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. -# +# # This software 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 software; 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 from gnuradio import blocks diff --git a/python/qa_viterbi27.py b/python/qa_viterbi27.py new file mode 100644 index 0000000..edc9aba --- /dev/null +++ b/python/qa_viterbi27.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2018 hcab14@mail.com. +# +# This 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. +# +# This software 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 software; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import digitalhf.digitalhf_swig as digitalhf +import random +import pmt +def main(): + v = digitalhf.viterbi27(0x6d, 0x4f) + N = 35*500+5 + bits = [random.randint(0,1) for _ in range(N+7)] + a = [1,0,1,1,0,1,1] + b = [1,1,1,1,0,0,1] + llr_encoded_bits = [] + for i in range(N): + t1=t2=0 + for j in range(7): + t1 += a[j]*bits[i+7-j] + t2 += b[j]*bits[i+7-j] + llr_encoded_bits.extend([7*(1-2*(t1%2)), 7*(1-2*(t2%2))]) + v.reset() + decoded_bits = v.udpate(llr_encoded_bits) + print(bits[7:37]) + print(decoded_bits[0:30]) + print('quality:', v.quality()) + test = [all([decoded_bits[i] == bits[i+7] for i in range(N)]), abs(v.quality()-2*N)<1] + print('test:', test) + if not all(test): + raise Exception(test) + +if __name__ == '__main__': + main() diff --git a/python/qa_viterbi29.py b/python/qa_viterbi29.py new file mode 100644 index 0000000..f06599f --- /dev/null +++ b/python/qa_viterbi29.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2018 hcab14@mail.com. +# +# This 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. +# +# This software 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 software; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import digitalhf.digitalhf_swig as digitalhf +import random +import pmt +def main(): + v = digitalhf.viterbi29(0x11d, 0x1af) + N = 45*500+5 + bits = [random.randint(0,1) for _ in range(N+9)] + a = [1,0,1,1,1,0,0,0,1] + b = [1,1,1,1,0,1,0,1,1] + llr_encoded_bits = [] + for i in range(N): + t1=t2=0 + for j in range(9): + t1 += a[j]*bits[i+9-j] + t2 += b[j]*bits[i+9-j] + llr_encoded_bits.extend([7*(1-2*(t1%2)), 7*(1-2*(t2%2))]) + v.reset() + decoded_bits = v.udpate(llr_encoded_bits) + print(bits[9:39]) + print(decoded_bits[0:30]) + print('quality:', v.quality()) + test = [all([decoded_bits[i] == bits[i+9] for i in range(N)]), abs(v.quality()-2*N)<1] + print('test:', test) + if not all(test): + raise Exception(test) + +if __name__ == '__main__': + main() diff --git a/python/qa_viterbi39.py b/python/qa_viterbi39.py new file mode 100644 index 0000000..90c01c1 --- /dev/null +++ b/python/qa_viterbi39.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2018 hcab14@mail.com. +# +# This 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. +# +# This software 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 software; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import digitalhf.digitalhf_swig as digitalhf +import random +import pmt +def main(): + v = digitalhf.viterbi39(0x127, 0x19B, 0x1ED) + N = 45*500+5 + bits = [random.randint(0,1) for _ in range(N+9)] + a = [1,1,1,0,0,1,0,0,1] + b = [1,1,0,1,1,0,0,1,1] + c = [1,0,1,1,0,1,1,1,1] + llr_encoded_bits = [] + for i in range(N): + t1=t2=t3=0 + for j in range(9): + t1 += a[j]*bits[i+9-j] + t2 += b[j]*bits[i+9-j] + t3 += c[j]*bits[i+9-j] + llr_encoded_bits.extend([7*(1-2*(t1%2)), 7*(1-2*(t2%2)), 7*(1-2*(t3%2))]) + v.reset() + decoded_bits = v.udpate(llr_encoded_bits) + print(bits[9:39]) + print(decoded_bits[0:30]) + print('quality:', v.quality()) + test = [all([decoded_bits[i] == bits[i+9] for i in range(N)]), abs(v.quality()-3*N)<1] + print('test:', test) + if not all(test): + raise Exception(test) +if __name__ == '__main__': + main() diff --git a/python/qa_viterbi48.py b/python/qa_viterbi48.py new file mode 100644 index 0000000..6ed1ae9 --- /dev/null +++ b/python/qa_viterbi48.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2018 hcab14@mail.com. +# +# This 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. +# +# This software 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 software; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import digitalhf.digitalhf_swig as digitalhf +import random +import pmt +def main(): + v = digitalhf.viterbi48(0xB9, 0x9D, 0xD3, 0xF7) + N = 40*500+5 + bits = [random.randint(0,1) for _ in range(N+8)] + a = [1,0,0,1,1,1,0,1] + b = [1,0,1,1,1,0,0,1] + c = [1,1,0,0,1,0,1,1] + d = [1,1,1,0,1,1,1,1] + llr_encoded_bits = [] + for i in range(N): + t1=t2=t3=t4=0 + for j in range(8): + t1 += a[j]*bits[i+8-j] + t2 += b[j]*bits[i+8-j] + t3 += c[j]*bits[i+8-j] + t4 += d[j]*bits[i+8-j] + llr_encoded_bits.extend([7*(1-2*(t1%2)), 7*(1-2*(t2%2)), 7*(1-2*(t3%2)), 7*(1-2*(t4%2))]) + v.reset() + decoded_bits = v.udpate(llr_encoded_bits) + print(bits[8:38]) + print(decoded_bits[0:30]) + print('quality:', v.quality()) + test = [all([decoded_bits[i] == bits[i+8] for i in range(N)]), abs(v.quality()-4*N)<1] + print('test:', test) + if not all(test): + raise Exception(test) + +if __name__ == '__main__': + main() diff --git a/swig/digitalhf_swig.i b/swig/digitalhf_swig.i index cb5c2ad..95bd414 100644 --- a/swig/digitalhf_swig.i +++ b/swig/digitalhf_swig.i @@ -10,9 +10,24 @@ %{ #include "digitalhf/adaptive_dfe.h" #include "digitalhf/doppler_correction_cc.h" +#include "digitalhf/viterbi27.h" +#include "digitalhf/viterbi29.h" +#include "digitalhf/viterbi39.h" +#include "digitalhf/viterbi48.h" %} %include "digitalhf/adaptive_dfe.h" GR_SWIG_BLOCK_MAGIC2(digitalhf, adaptive_dfe); + %include "digitalhf/doppler_correction_cc.h" GR_SWIG_BLOCK_MAGIC2(digitalhf, doppler_correction_cc); + +/* FIXME */ +%include "digitalhf/viterbi27.h" +GR_SWIG_BLOCK_MAGIC2(digitalhf, viterbi27); +%include "digitalhf/viterbi29.h" +GR_SWIG_BLOCK_MAGIC2(digitalhf, viterbi29); +%include "digitalhf/viterbi39.h" +GR_SWIG_BLOCK_MAGIC2(digitalhf, viterbi39); +%include "digitalhf/viterbi48.h" +GR_SWIG_BLOCK_MAGIC2(digitalhf, viterbi48);