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:
parent
6786baabd3
commit
4e5d41573d
53
cmake/Modules/FindLog4cpp.cmake
Normal file
53
cmake/Modules/FindLog4cpp.cmake
Normal 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
|
||||||
|
)
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
61
include/digitalhf/viterbi27.h
Normal file
61
include/digitalhf/viterbi27.h
Normal 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 */
|
61
include/digitalhf/viterbi29.h
Normal file
61
include/digitalhf/viterbi29.h
Normal 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 */
|
62
include/digitalhf/viterbi39.h
Normal file
62
include/digitalhf/viterbi39.h
Normal 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 */
|
63
include/digitalhf/viterbi48.h
Normal file
63
include/digitalhf/viterbi48.h
Normal 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 */
|
|
@ -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
50
lib/llr_to_prob.h
Normal 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
124
lib/viterbi.h
Normal 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
108
lib/viterbi27_impl.cc
Normal 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
51
lib/viterbi27_impl.h
Normal 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
108
lib/viterbi29_impl.cc
Normal 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
51
lib/viterbi29_impl.h
Normal 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
114
lib/viterbi39_impl.cc
Normal 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
53
lib/viterbi39_impl.h
Normal 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
114
lib/viterbi48_impl.cc
Normal 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
52
lib/viterbi48_impl.h
Normal 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 */
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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
49
python/qa_viterbi27.py
Normal 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
49
python/qa_viterbi29.py
Normal 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
50
python/qa_viterbi39.py
Normal 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
53
python/qa_viterbi48.py
Normal 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()
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue