M17: try to fix MSVC errors

This commit is contained in:
f4exb 2022-08-02 05:56:40 +02:00
parent 7ca7dec872
commit 75148f9659
4 changed files with 78 additions and 60 deletions

View File

@ -44,7 +44,6 @@ struct M17FrameDecoder
M17Randomizer derandomize_; M17Randomizer derandomize_;
PolynomialInterleaver<45, 92, 368> interleaver_; PolynomialInterleaver<45, 92, 368> interleaver_;
Trellis<4,2> trellis_{makeTrellis<4, 2>({031,027})}; Trellis<4,2> trellis_{makeTrellis<4, 2>({031,027})};
Viterbi<decltype(trellis_), 4> viterbi_{trellis_};
CRC16 crc_; CRC16 crc_;
enum class State { LSF, STREAM, BASIC_PACKET, FULL_PACKET, BERT }; enum class State { LSF, STREAM, BASIC_PACKET, FULL_PACKET, BERT };
@ -154,8 +153,10 @@ struct M17FrameDecoder
DecodeResult decode_lsf(input_buffer_t& buffer, int& viterbi_cost) DecodeResult decode_lsf(input_buffer_t& buffer, int& viterbi_cost)
{ {
depunctured_buffer_t depuncture_buffer; depunctured_buffer_t depuncture_buffer;
depuncture<368, 488, 61>(buffer, depuncture_buffer.lsf, P1); PunctureOps<368, 488, 61> punct;
viterbi_cost = viterbi_.decode(depuncture_buffer.lsf, decode_buffer.lsf); punct.depuncture(buffer, depuncture_buffer.lsf, P1);
Viterbi<decltype(trellis_), 4, 488, 240> viterbi_lsf{trellis_};
viterbi_cost = viterbi_lsf.decode(depuncture_buffer.lsf, decode_buffer.lsf);
to_byte_array(decode_buffer.lsf, output_buffer.lsf); to_byte_array(decode_buffer.lsf, output_buffer.lsf);
// qDebug() << "modemm17::M17FrameDecoder::decode_lsf: vierbi:" << viterbi_cost <<dump(output_buffer.lsf); // qDebug() << "modemm17::M17FrameDecoder::decode_lsf: vierbi:" << viterbi_cost <<dump(output_buffer.lsf);
@ -268,8 +269,10 @@ struct M17FrameDecoder
DecodeResult decode_bert(input_buffer_t& buffer, int& viterbi_cost) DecodeResult decode_bert(input_buffer_t& buffer, int& viterbi_cost)
{ {
depunctured_buffer_t depuncture_buffer; depunctured_buffer_t depuncture_buffer;
depuncture<368, 402, 12>(buffer, depuncture_buffer.bert, P2); PunctureOps<368, 402, 12> punct;
viterbi_cost = viterbi_.decode(depuncture_buffer.bert, decode_buffer.bert); punct.depuncture(buffer, depuncture_buffer.bert, P2);
Viterbi<decltype(trellis_), 4, 402, 197> viterbi_bert{trellis_};
viterbi_cost = viterbi_bert.decode(depuncture_buffer.bert, decode_buffer.bert);
to_byte_array(decode_buffer.bert, output_buffer.bert); to_byte_array(decode_buffer.bert, output_buffer.bert);
output_buffer.type = FrameType::BERT; output_buffer.type = FrameType::BERT;
@ -284,8 +287,10 @@ struct M17FrameDecoder
std::copy(buffer.begin() + 96, buffer.end(), tmp.begin()); std::copy(buffer.begin() + 96, buffer.end(), tmp.begin());
depunctured_buffer_t depuncture_buffer; depunctured_buffer_t depuncture_buffer;
depuncture<272, 296, 12>(tmp, depuncture_buffer.stream, P2); PunctureOps<272, 296, 12> punct;
viterbi_cost = viterbi_.decode(depuncture_buffer.stream, decode_buffer.stream); punct.depuncture(tmp, depuncture_buffer.stream, P2);
Viterbi<decltype(trellis_), 4, 296, 144> viterbi_stream{trellis_};
viterbi_cost = viterbi_stream.decode(depuncture_buffer.stream, decode_buffer.stream);
to_byte_array(decode_buffer.stream, output_buffer.stream); to_byte_array(decode_buffer.stream, output_buffer.stream);
if ((viterbi_cost < 60) && (output_buffer.stream[0] & 0x80)) if ((viterbi_cost < 60) && (output_buffer.stream[0] & 0x80))
@ -311,8 +316,10 @@ struct M17FrameDecoder
DecodeResult decode_packet(input_buffer_t& buffer, int& viterbi_cost, FrameType type) DecodeResult decode_packet(input_buffer_t& buffer, int& viterbi_cost, FrameType type)
{ {
depunctured_buffer_t depuncture_buffer; depunctured_buffer_t depuncture_buffer;
depuncture<368, 420, 8>(buffer, depuncture_buffer.packet, P3); PunctureOps<368, 420, 8> punct;
viterbi_cost = viterbi_.decode(depuncture_buffer.packet, decode_buffer.packet); punct.depuncture(buffer, depuncture_buffer.packet, P3);
Viterbi<decltype(trellis_), 4, 420, 206> viterbi_packet{trellis_};
viterbi_cost = viterbi_packet.decode(depuncture_buffer.packet, decode_buffer.packet);
to_byte_array(decode_buffer.packet, output_buffer.packet); to_byte_array(decode_buffer.packet, output_buffer.packet);
output_buffer.type = type; output_buffer.type = type;

View File

@ -175,7 +175,8 @@ public:
} }
std::array<int8_t, 368> punctured; std::array<int8_t, 368> punctured;
auto size = puncture<488, 368, 61>(encoded, punctured, P1); PunctureOps<488, 368, 61> punct;
auto size = punct.puncture(encoded, punctured, P1);
if (size != 368) { if (size != 368) {
qWarning() << "modemm17::M17Modulator::make_lsf: incorrect size (not 368)" << size; qWarning() << "modemm17::M17Modulator::make_lsf: incorrect size (not 368)" << size;
@ -275,7 +276,8 @@ public:
} }
std::array<int8_t, 272> punctured; std::array<int8_t, 272> punctured;
auto size = modemm17::puncture<296, 272, 12>(encoded, punctured, modemm17::P2); modemm17::PunctureOps<296, 272, 12> punct;
auto size = punct.puncture(encoded, punctured, modemm17::P2);
if (size != 272) { if (size != 272) {
qWarning() << "modemm17::M17Modulator::make_stream_data_frame: incorrect size (not 272)" << size; qWarning() << "modemm17::M17Modulator::make_stream_data_frame: incorrect size (not 272)" << size;
@ -356,7 +358,8 @@ public:
} }
std::array<int8_t, 368> punctured; std::array<int8_t, 368> punctured;
auto size = puncture<420, 368, 8>(encoded, punctured, P3); PunctureOps<420, 368, 8> punct;
auto size = punct.puncture(encoded, punctured, P3);
if (size != 368) { if (size != 368) {
qWarning() << "modemm17::M17Modulator::make_packet_frame: incorrect size (not 368)" << size; qWarning() << "modemm17::M17Modulator::make_packet_frame: incorrect size (not 368)" << size;
@ -437,7 +440,8 @@ public:
} }
std::array<int8_t, 368> punctured; std::array<int8_t, 368> punctured;
auto size = puncture<402, 368, 12>(encoded, punctured, P2); PunctureOps<402, 368, 12> punct;
auto size = punct.puncture(encoded, punctured, P2);
if (size != 368) { if (size != 368) {
qWarning() << "modemm17::M17Modulator::make_bert_frame: incorrect size (not 368)" << size; qWarning() << "modemm17::M17Modulator::make_bert_frame: incorrect size (not 368)" << size;

View File

@ -171,56 +171,62 @@ std::array<U, M> depunctured(
} }
template <size_t IN, size_t OUT, size_t P> template <size_t IN, size_t OUT, size_t P>
size_t depuncture( // FIXME: MSVC struct PunctureOps
const std::array<int8_t, IN>& in,
std::array<int8_t, OUT>& out,
const std::array<int8_t, P>& p
)
{ {
size_t index = 0; static constexpr size_t IN_ = IN;
size_t pindex = 0; static constexpr size_t OUT_ = OUT;
size_t bit_count = 0; static constexpr size_t P_ = P;
for (size_t i = 0; i != OUT && index < IN; ++i)
size_t depuncture( // FIXME: MSVC
const std::array<int8_t, IN_>& in,
std::array<int8_t, OUT_>& out,
const std::array<int8_t, P_>& p
)
{ {
if (!p[pindex++]) size_t index = 0;
size_t pindex = 0;
size_t bit_count = 0;
for (size_t i = 0; i != OUT && index < IN; ++i)
{ {
out[i] = 0; if (!p[pindex++])
bit_count++; {
} out[i] = 0;
else bit_count++;
{ }
out[i] = in[index++]; else
} {
if (pindex == P) { out[i] = in[index++];
pindex = 0; }
if (pindex == P) {
pindex = 0;
}
} }
return bit_count;
} }
return bit_count;
}
size_t puncture( // FIXME: MSVC
template <size_t IN, size_t OUT, size_t P> const std::array<uint8_t, IN_>& in,
size_t puncture( // FIXME: MSVC std::array<int8_t, OUT_>& out,
const std::array<uint8_t, IN>& in, const std::array<int8_t, P_>& p
std::array<int8_t, OUT>& out, )
const std::array<int8_t, P>& p
)
{
size_t index = 0;
size_t pindex = 0;
size_t bit_count = 0;
for (size_t i = 0; i != IN && index != OUT; ++i)
{ {
if (p[pindex++]) size_t index = 0;
size_t pindex = 0;
size_t bit_count = 0;
for (size_t i = 0; i != IN && index != OUT; ++i)
{ {
out[index++] = in[i]; if (p[pindex++])
bit_count++; {
} out[index++] = in[i];
bit_count++;
}
if (pindex == P) pindex = 0; if (pindex == P) pindex = 0;
}
return bit_count;
} }
return bit_count; };
}
template <size_t N> template <size_t N>
constexpr bool get_bit_index( constexpr bool get_bit_index(

View File

@ -91,11 +91,13 @@ constexpr auto makeCost(Trellis_ trellis)
* Soft decision Viterbi algorithm based on the trellis and LLR size. * Soft decision Viterbi algorithm based on the trellis and LLR size.
* *
*/ */
template <typename Trellis_, size_t LLR_ = 2> template <typename Trellis_, size_t LLR_, size_t IN, size_t OUT>
struct Viterbi struct Viterbi
{ {
static_assert(LLR_ < 7, "Need to be < 7 to avoid overflow errors"); static_assert(LLR_ < 7, "Need to be < 7 to avoid overflow errors");
static constexpr size_t IN_ = IN;
static constexpr size_t OUT_ = OUT;
static constexpr size_t K = Trellis_::K; static constexpr size_t K = Trellis_::K;
static constexpr size_t k = Trellis_::k; static constexpr size_t k = Trellis_::k;
static constexpr size_t n = Trellis_::n; static constexpr size_t n = Trellis_::n;
@ -119,10 +121,10 @@ struct Viterbi
// because of a static assertion in the decode() function. // because of a static assertion in the decode() function.
std::array<std::bitset<NumStates>, 244> history_; std::array<std::bitset<NumStates>, 244> history_;
Viterbi(Trellis_ trellis) Viterbi(Trellis_ trellis) :
: cost_(makeCost<Trellis_, LLR_>(trellis)) cost_(makeCost<Trellis_, LLR_>(trellis)),
, nextState_(makeNextState(trellis)) nextState_(makeNextState(trellis)),
, prevState_(makePrevState(trellis)) prevState_(makePrevState(trellis))
{} {}
void calculate_path_metric( void calculate_path_metric(
@ -159,8 +161,7 @@ struct Viterbi
* *
* @return path metric for estimating BER. * @return path metric for estimating BER.
*/ */
template <size_t IN, size_t OUT> size_t decode(const std::array<int8_t, IN_>& in, std::array<uint8_t, OUT_>& out)
size_t decode(const std::array<int8_t, IN>& in, std::array<uint8_t, OUT>& out)
{ {
static_assert(sizeof(history_) >= IN / 2, "Invalid size"); static_assert(sizeof(history_) >= IN / 2, "Invalid size");