1
0
Fork 0
mirror of https://github.com/hb9fxq/gr-digitalhf synced 2024-12-22 15:10:00 +00:00

soft-decision Viterbit decoders added

This commit is contained in:
cmayer 2019-04-04 22:28:53 +02:00
parent 6786baabd3
commit 4e5d41573d
27 changed files with 1410 additions and 17 deletions

View file

@ -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
)

View file

@ -24,5 +24,10 @@
install(FILES install(FILES
api.h api.h
adaptive_dfe.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
) )

View file

@ -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 <digitalhf/api.h>
#include <pmt/pmt.h>
namespace gr {
namespace digitalhf {
/*!
* \brief <+description of block+>
* \ingroup digitalhf
*
*/
class DIGITALHF_API viterbi27
{
public:
typedef boost::shared_ptr<viterbi27> 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<std::uint8_t>& udpate(const std::vector<float>& soft_dec) = 0;
virtual float quality() = 0;
} ;
} // namespace digitalhf
} // namespace gr
#endif /* INCLUDED_DIGITALHF_VITERBI27_H */

View file

@ -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 <digitalhf/api.h>
#include <pmt/pmt.h>
namespace gr {
namespace digitalhf {
/*!
* \brief <+description of block+>
* \ingroup digitalhf
*
*/
class DIGITALHF_API viterbi29
{
public:
typedef boost::shared_ptr<viterbi29> 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<std::uint8_t>& udpate(const std::vector<float>& soft_dec) = 0;
virtual float quality() = 0;
} ;
} // namespace digitalhf
} // namespace gr
#endif /* INCLUDED_DIGITALHF_VITERBI29_H */

View file

@ -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 <digitalhf/api.h>
#include <pmt/pmt.h>
namespace gr {
namespace digitalhf {
/*!
* \brief <+description of block+>
* \ingroup digitalhf
*
*/
class DIGITALHF_API viterbi39
{
public:
typedef boost::shared_ptr<viterbi39> 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<std::uint8_t>& udpate(const std::vector<float>& soft_dec) = 0;
virtual float quality() = 0;
} ;
} // namespace digitalhf
} // namespace gr
#endif /* INCLUDED_DIGITALHF_VITERBI39_H */

View file

@ -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 <digitalhf/api.h>
#include <pmt/pmt.h>
namespace gr {
namespace digitalhf {
/*!
* \brief <+description of block+>
* \ingroup digitalhf
*
*/
class DIGITALHF_API viterbi48
{
public:
typedef boost::shared_ptr<viterbi48> 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<std::uint8_t>& udpate(const std::vector<float>& soft_dec) = 0;
virtual float quality() = 0;
} ;
} // namespace digitalhf
} // namespace gr
#endif /* INCLUDED_DIGITALHF_VITERBI48_H */

View file

@ -27,7 +27,11 @@ include_directories(${Boost_INCLUDE_DIR})
link_directories(${Boost_LIBRARY_DIRS}) link_directories(${Boost_LIBRARY_DIRS})
list(APPEND digitalhf_sources list(APPEND digitalhf_sources
adaptive_dfe_impl.cc 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) set(digitalhf_sources "${digitalhf_sources}" PARENT_SCOPE)
if(NOT digitalhf_sources) if(NOT digitalhf_sources)

50
lib/llr_to_prob.h Normal file
View file

@ -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 <array>
#include <cmath>
#include <cstdint>
template<size_t N>
class llr_to_prob {
public:
llr_to_prob()
: _table() {
for (int i=0; i<N; ++i) { // llr -> 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<std::uint8_t, N> _table;
} ;
} // namespace digitalhf
} // namespace gr

124
lib/viterbi.h Normal file
View file

@ -0,0 +1,124 @@
// -*- C++ -*-
#ifndef _VITERBI_HPP_
#define _VITERBI_HPP_
#include <cassert>
#include <algorithm>
#include <array>
#include <bitset>
#include <vector>
// soft-decision viterbi decoder
// based on Phil Karn's libfec
template<std::size_t N, std::size_t K>
class viterbi {
public:
enum { M = 1<<(K-1) };
typedef std::vector<int> vec_type;
typedef std::array<int, M> arr_type;
viterbi(std::array<std::uint32_t, N> 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::array<std::uint8_t,N>const& sym) {
int s[N];
for (int l=0; l<N; ++l)
s[l] = sym[l] ^ 255;
arr_type new_metric;
auto jdec = decision(j);
int mmin[2] = {65535, 65535};
for (int i=0; i<M; i+=2) {
int const p0 = _prev[i][0];
int const p1 = _prev[i][1];
int m0[2] = { _metric[p0], _metric[p1] };
int m1[2] = { _metric[p0], _metric[p1] };
for (int l=0; l<N; ++l) {
m0[0] += _bits[p0][0][l] ^ s[l];
m0[1] += _bits[p1][0][l] ^ s[l];
m1[0] += _bits[p0][1][l] ^ s[l];
m1[1] += _bits[p1][1][l] ^ s[l];
}
jdec[i ] = m0[0] < m0[1];
jdec[i+1] = m1[0] < m1[1];
new_metric[i ] = m0[jdec[i ]];
new_metric[i+1] = m1[jdec[i+1]];
mmin[0] = std::min(mmin[0], new_metric[i ]);
mmin[1] = std::min(mmin[1], new_metric[i+1]);
}
// avoid path metric overflow
int const imin = std::min(mmin[0], mmin[1]);
if (imin > (1<<15)) {
_last_max_metric -= imin;
for (int i=0; i<M; ++i)
_metric[i] = new_metric[i] - imin;
} else {
std::copy(new_metric.begin(), new_metric.end(), _metric.begin());
}
}
float chainback(std::vector<uint8_t>& v) {
return chainback(v.begin(), v.end());
}
float chainback(std::vector<uint8_t>::iterator begin,
std::vector<uint8_t>::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<std::uint32_t, N> const& polys) {
for (int i=0, n=1<<K; i<n; ++i) {
for (int l=0; l<N; ++l) {
std::bitset<K> const b(polys[l]&i);
_bits[i>>1][i%2][l] = 255*(b.count()%2);
}
}
for (int i=0; i<M; ++i) {
_prev[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_

108
lib/viterbi27_impl.cc Normal file
View file

@ -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 <boost/format.hpp>
#include <gnuradio/math.h>
#include <gnuradio/expj.h>
#include <gnuradio/io_signature.h>
#include <gnuradio/logger.h>
#include <volk/volk.h>
#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<std::uint8_t>& viterbi27_impl::udpate(const std::vector<float>& 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<uint8_t>::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<num_frames; ++i) {
for (int j=0; j<bits_per_frame; ++j) {
std::array<std::uint8_t, 2> 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<remaining_bits; ++j) {
std::array<std::uint8_t, 2> 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

51
lib/viterbi27_impl.h Normal file
View file

@ -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 <digitalhf/viterbi27.h>
#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<std::uint8_t> _bits;
public:
viterbi27_impl(std::uint32_t pol0, std::uint32_t pol1);
virtual ~viterbi27_impl();
virtual void reset();
virtual const std::vector<std::uint8_t>& udpate(const std::vector<float>& soft_dec);
virtual float quality();
} ;
} // namespace digitalhf
} // namespace gr
#endif /* INCLUDED_DIGITALHF_VITERBI27IMPL_H */

108
lib/viterbi29_impl.cc Normal file
View file

@ -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 <boost/format.hpp>
#include <gnuradio/math.h>
#include <gnuradio/expj.h>
#include <gnuradio/io_signature.h>
#include <gnuradio/logger.h>
#include <volk/volk.h>
#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<std::uint8_t>& viterbi29_impl::udpate(const std::vector<float>& 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<uint8_t>::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<num_frames; ++i) {
for (int j=0; j<bits_per_frame; ++j) {
std::array<std::uint8_t, 2> 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<remaining_bits; ++j) {
std::array<std::uint8_t, 2> 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

51
lib/viterbi29_impl.h Normal file
View file

@ -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 <digitalhf/viterbi29.h>
#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<std::uint8_t> _bits;
public:
viterbi29_impl(std::uint32_t pol0, std::uint32_t pol1);
virtual ~viterbi29_impl();
virtual void reset();
virtual const std::vector<std::uint8_t>& udpate(const std::vector<float>& soft_dec);
virtual float quality();
} ;
} // namespace digitalhf
} // namespace gr
#endif /* INCLUDED_DIGITALHF_VITERBI29IMPL_H */

114
lib/viterbi39_impl.cc Normal file
View file

@ -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 <boost/format.hpp>
#include <gnuradio/math.h>
#include <gnuradio/expj.h>
#include <gnuradio/io_signature.h>
#include <gnuradio/logger.h>
#include <volk/volk.h>
#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<std::uint8_t>& viterbi39_impl::udpate(const std::vector<float>& 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<uint8_t>::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<num_frames; ++i) {
for (int j=0; j<bits_per_frame; ++j) {
std::array<std::uint8_t, 3> 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<remaining_bits; ++j) {
std::array<std::uint8_t, 3> 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

53
lib/viterbi39_impl.h Normal file
View file

@ -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 <digitalhf/viterbi39.h>
#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<std::uint8_t> _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<std::uint8_t>& udpate(const std::vector<float>& soft_dec);
virtual float quality();
} ;
} // namespace digitalhf
} // namespace gr
#endif /* INCLUDED_DIGITALHF_VITERBI39IMPL_H */

114
lib/viterbi48_impl.cc Normal file
View file

@ -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 <boost/format.hpp>
#include <gnuradio/math.h>
#include <gnuradio/expj.h>
#include <gnuradio/io_signature.h>
#include <gnuradio/logger.h>
#include <volk/volk.h>
#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<std::uint8_t>& viterbi48_impl::udpate(const std::vector<float>& 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<uint8_t>::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<num_frames; ++i) {
for (int j=0; j<bits_per_frame; ++j) {
std::array<std::uint8_t, 4> 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<remaining_bits; ++j) {
std::array<std::uint8_t, 4> 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

52
lib/viterbi48_impl.h Normal file
View file

@ -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 <digitalhf/viterbi48.h>
#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<std::uint8_t> _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<std::uint8_t>& udpate(const std::vector<float>& soft_dec);
virtual float quality();
} ;
} // namespace digitalhf
} // namespace gr
#endif /* INCLUDED_DIGITALHF_VITERBI48IMPL_H */

View file

@ -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) GR_ADD_TEST(qa_adaptive_dfe ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_adaptive_dfe.py)
add_subdirectory(physical_layer) add_subdirectory(physical_layer)
GR_ADD_TEST(qa_physical_layer_driver_driver ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_physical_layer_driver_driver.py) ## FIXME:
GR_ADD_TEST(qa_doppler_correction_cc ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_doppler_correction_cc.py) # GR_ADD_TEST(qa_physical_layer_driver_driver ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_physical_layer_driver_driver.py)
GR_ADD_TEST(qa_msg_proxy ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_msg_proxy.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)

View file

@ -558,6 +558,42 @@ BW_INTL_INCR = { ## [BW][WID][INTL] -> interleaver increment
{'US': 3401, 'S': 26449, 'M': 105209, 'L': 326729}] ## WID 12 {'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-4 codes ----------------------------------------------------------
WALSH = np.array([[0,0,0,0], # 0 - 00 WALSH = np.array([[0,0,0,0], # 0 - 00
[0,1,0,1], # 1 - 01 [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 = 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._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_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] 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) self._known, self._unknown)
return success return success

View file

@ -26,7 +26,6 @@ from gnuradio import filter
from gnuradio import gr from gnuradio import gr
import pmt import pmt
import digitalhf import digitalhf
import digitalhf.physical_layer
class physical_layer_driver(gr.hier_block2): class physical_layer_driver(gr.hier_block2):
""" """

View file

@ -31,6 +31,7 @@ class qa_adaptive_dfe(gr_unittest.TestCase):
def tearDown(self): def tearDown(self):
self.tb = None self.tb = None
def test_001_t(self): def test_001_t(self):
# set up fg # set up fg
self.tb.run() self.tb.run()

49
python/qa_viterbi27.py Normal file
View file

@ -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()

49
python/qa_viterbi29.py Normal file
View file

@ -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()

50
python/qa_viterbi39.py Normal file
View file

@ -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()

53
python/qa_viterbi48.py Normal file
View file

@ -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()

View file

@ -10,9 +10,24 @@
%{ %{
#include "digitalhf/adaptive_dfe.h" #include "digitalhf/adaptive_dfe.h"
#include "digitalhf/doppler_correction_cc.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" %include "digitalhf/adaptive_dfe.h"
GR_SWIG_BLOCK_MAGIC2(digitalhf, adaptive_dfe); GR_SWIG_BLOCK_MAGIC2(digitalhf, adaptive_dfe);
%include "digitalhf/doppler_correction_cc.h" %include "digitalhf/doppler_correction_cc.h"
GR_SWIG_BLOCK_MAGIC2(digitalhf, doppler_correction_cc); 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);