From d17d683b2d3c674fba0ec1a3b78897b16295014b Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Thu, 19 May 2022 16:53:29 +0200 Subject: [PATCH] M17 code cleanup pass: reorganised data type definitions and constants --- openrtx/include/protocols/M17/M17Constants.h | 47 +++++++++++++++++++ openrtx/include/protocols/M17/M17Datatypes.h | 5 +- .../include/protocols/M17/M17Demodulator.h | 11 ++--- openrtx/include/protocols/M17/M17Modulator.h | 29 ++---------- openrtx/include/protocols/M17/M17Utils.h | 43 +++++++++++++---- openrtx/src/protocols/M17/M17Demodulator.cpp | 10 ++-- openrtx/src/protocols/M17/M17FrameDecoder.cpp | 1 + openrtx/src/protocols/M17/M17FrameEncoder.cpp | 1 + openrtx/src/protocols/M17/M17Modulator.cpp | 15 +++--- 9 files changed, 105 insertions(+), 57 deletions(-) create mode 100644 openrtx/include/protocols/M17/M17Constants.h diff --git a/openrtx/include/protocols/M17/M17Constants.h b/openrtx/include/protocols/M17/M17Constants.h new file mode 100644 index 00000000..abbc0c70 --- /dev/null +++ b/openrtx/include/protocols/M17/M17Constants.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2022 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#ifndef M17_CONSTANTS_H +#define M17_CONSTANTS_H + +#include +#include +#include + +#ifndef __cplusplus +#error This header is C++ only! +#endif + +namespace M17 +{ + +static constexpr size_t M17_SYMBOL_RATE = 4800; +static constexpr size_t M17_FRAME_SYMBOLS = 192; +static constexpr size_t M17_SYNCWORD_SYMBOLS = 8; +static constexpr size_t M17_FRAME_BYTES = M17_FRAME_SYMBOLS / 4; + +static constexpr syncw_t LSF_SYNC_WORD = {0x55, 0xF7}; // LSF sync word +static constexpr syncw_t BERT_SYNC_WORD = {0xDF, 0x55}; // BERT data sync word +static constexpr syncw_t STREAM_SYNC_WORD = {0xFF, 0x5D}; // Stream data sync word +static constexpr syncw_t PACKET_SYNC_WORD = {0x75, 0xFF}; // Packet data sync word + +} // namespace M17 + +#endif // M17_CONSTANTS_H diff --git a/openrtx/include/protocols/M17/M17Datatypes.h b/openrtx/include/protocols/M17/M17Datatypes.h index 1165b306..d56c06f3 100644 --- a/openrtx/include/protocols/M17/M17Datatypes.h +++ b/openrtx/include/protocols/M17/M17Datatypes.h @@ -36,10 +36,7 @@ using meta_t = std::array< uint8_t, 14 >; // Data type for LSF metadata fie using payload_t = std::array< uint8_t, 16 >; // Data type for frame payload field using lich_t = std::array< uint8_t, 12 >; // Data type for Golay(24,12) encoded LICH data using frame_t = std::array< uint8_t, 48 >; // Data type for a full M17 data frame, including sync word - -static constexpr std::array LSF_SYNC_WORD = {0x55, 0xF7}; // LSF sync word -static constexpr std::array STREAM_SYNC_WORD = {0xFF, 0x5D}; // Stream data sync word -static constexpr std::array PACKET_SYNC_WORD = {0x75, 0xFF}; // Packet data sync word +using syncw_t = std::array< uint8_t, 2 >; // Data type for a sync word /** * This structure provides bit field definitions for the "TYPE" field diff --git a/openrtx/include/protocols/M17/M17Demodulator.h b/openrtx/include/protocols/M17/M17Demodulator.h index 2e6f53d6..18d0a009 100644 --- a/openrtx/include/protocols/M17/M17Demodulator.h +++ b/openrtx/include/protocols/M17/M17Demodulator.h @@ -35,7 +35,8 @@ #include #include #include -#include "M17Datatypes.h" +#include +#include namespace M17 { @@ -110,16 +111,12 @@ public: private: /** - * M17 baseband signal sampled at 48kHz, half of an M17 frame is processed + * M17 baseband signal sampled at 24kHz, half of an M17 frame is processed * at each update of the demodulator. */ - static constexpr size_t M17_SYMBOL_RATE = 4800; - static constexpr size_t M17_FRAME_SYMBOLS = 192; - static constexpr size_t M17_SYNCWORD_SYMBOLS = 8; static constexpr size_t M17_RX_SAMPLE_RATE = 24000; static constexpr size_t M17_SAMPLES_PER_SYMBOL = M17_RX_SAMPLE_RATE / M17_SYMBOL_RATE; - static constexpr size_t M17_FRAME_BYTES = M17_FRAME_SYMBOLS / 4; static constexpr size_t M17_FRAME_SAMPLES = M17_FRAME_SYMBOLS * M17_SAMPLES_PER_SYMBOL; static constexpr size_t M17_SAMPLE_BUF_SIZE = M17_FRAME_SAMPLES / 2; static constexpr size_t M17_SYNCWORD_SAMPLES = M17_SAMPLES_PER_SYMBOL * M17_SYNCWORD_SYMBOLS; @@ -134,8 +131,6 @@ private: */ int8_t lsf_syncword[M17_SYNCWORD_SYMBOLS] = { +3, +3, +3, +3, -3, -3, +3, -3 }; int8_t stream_syncword[M17_SYNCWORD_SYMBOLS] = { -3, -3, -3, -3, +3, +3, -3, +3 }; - uint8_t lsf_syncword_bytes[2] = {0x55, 0xf7}; - uint8_t stream_syncword_bytes[2] = {0xff, 0x5d}; /* * Buffers diff --git a/openrtx/include/protocols/M17/M17Modulator.h b/openrtx/include/protocols/M17/M17Modulator.h index 072f4c2b..640b02f9 100644 --- a/openrtx/include/protocols/M17/M17Modulator.h +++ b/openrtx/include/protocols/M17/M17Modulator.h @@ -26,6 +26,7 @@ #endif #include +#include #include #include #include @@ -86,32 +87,10 @@ private: */ void emitBaseband(); - /** - * Utility function to encode a given byte of data into 4FSK symbols. Each - * byte is encoded in four symbols. - * - * @param value: value to be encoded in 4FSK symbols. - * @return std::array containing the four symbols obtained by 4FSK encoding. - */ - inline std::array< int8_t, 4 > byteToSymbols(uint8_t value) - { - static constexpr int8_t LUT[] = { +1, +3, -1, -3}; - std::array< int8_t, 4 > symbols; + static constexpr size_t M17_TX_SAMPLE_RATE = 48000; + static constexpr size_t M17_SAMPLES_PER_SYMBOL = M17_TX_SAMPLE_RATE / M17_SYMBOL_RATE; + static constexpr size_t M17_FRAME_SAMPLES = M17_FRAME_SYMBOLS * M17_SAMPLES_PER_SYMBOL; - symbols[3] = LUT[value & 0x03]; - value >>= 2; - symbols[2] = LUT[value & 0x03]; - value >>= 2; - symbols[1] = LUT[value & 0x03]; - value >>= 2; - symbols[0] = LUT[value & 0x03]; - - return symbols; - } - - static constexpr size_t M17_TX_SAMPLE_RATE = 48000; - static constexpr size_t M17_FRAME_SAMPLES_48K = 1920; - static constexpr size_t M17_FRAME_SYMBOLS = 192; #ifdef PLATFORM_MOD17 static constexpr float M17_RRC_GAIN = 15000.0f; static constexpr float M17_RRC_OFFSET = 11500.0f; diff --git a/openrtx/include/protocols/M17/M17Utils.h b/openrtx/include/protocols/M17/M17Utils.h index 448452ba..fd33d950 100644 --- a/openrtx/include/protocols/M17/M17Utils.h +++ b/openrtx/include/protocols/M17/M17Utils.h @@ -72,6 +72,20 @@ inline void setBit(std::array< uint8_t, N >& array, const size_t pos, (bit ? mask : 0x00); } + +/** + * Compute the hamming distance between two bytes. + * + * @param x: first byte. + * @param y: second byte. + * @return hamming distance between x and y. + */ +static inline uint8_t hammingDistance(const uint8_t x, const uint8_t y) +{ + return __builtin_popcount(x ^ y); +} + + /** * Utility function allowing to set the value of a symbol on an array * of bytes. Symbols are packed putting the most significant bit first, @@ -84,9 +98,10 @@ inline void setBit(std::array< uint8_t, N >& array, const size_t pos, */ template < size_t N > inline void setSymbol(std::array< uint8_t, N >& array, const size_t pos, - const int8_t symbol) + const int8_t symbol) { - switch(symbol) { + switch(symbol) + { case +3: setBit (array, 2 * pos , 0); setBit (array, 2 * pos + 1, 1); @@ -108,16 +123,28 @@ inline void setSymbol(std::array< uint8_t, N >& array, const size_t pos, } } + /** - * Compute the hamming distance between two bytes. + * Utility function to encode a given byte of data into 4FSK symbols. Each + * byte is encoded in four symbols. * - * @param x: first byte. - * @param y: second byte. - * @return hamming distance between x and y. + * @param value: value to be encoded in 4FSK symbols. + * @return std::array containing the four symbols obtained by 4FSK encoding. */ -static inline uint8_t hammingDistance(const uint8_t x, const uint8_t y) +inline std::array< int8_t, 4 > byteToSymbols(uint8_t value) { - return __builtin_popcount(x ^ y); + static constexpr int8_t LUT[] = { +1, +3, -1, -3}; + std::array< int8_t, 4 > symbols; + + symbols[3] = LUT[value & 0x03]; + value >>= 2; + symbols[2] = LUT[value & 0x03]; + value >>= 2; + symbols[1] = LUT[value & 0x03]; + value >>= 2; + symbols[0] = LUT[value & 0x03]; + + return symbols; } } // namespace M17 diff --git a/openrtx/src/protocols/M17/M17Demodulator.cpp b/openrtx/src/protocols/M17/M17Demodulator.cpp index 72b199ae..15c37ea3 100644 --- a/openrtx/src/protocols/M17/M17Demodulator.cpp +++ b/openrtx/src/protocols/M17/M17Demodulator.cpp @@ -334,7 +334,7 @@ int32_t M17Demodulator::syncwordSweep(int32_t offset) bool M17Demodulator::update() { - M17::sync_t syncword = { 0, false }; + sync_t syncword = { 0, false }; int32_t offset = syncDetected ? 0 : -(int32_t) M17_BRIDGE_SIZE; uint16_t decoded_syms = 0; @@ -427,14 +427,14 @@ bool M17Demodulator::update() { // If syncword is not valid, lock is lost, accept 2 bit errors uint8_t hammingSync = hammingDistance((*activeFrame)[0], - stream_syncword_bytes[0]) + STREAM_SYNC_WORD[0]) + hammingDistance((*activeFrame)[1], - stream_syncword_bytes[1]); + STREAM_SYNC_WORD[1]); uint8_t hammingLsf = hammingDistance((*activeFrame)[0], - lsf_syncword_bytes[0]) + LSF_SYNC_WORD[0]) + hammingDistance((*activeFrame)[1], - lsf_syncword_bytes[1]); + LSF_SYNC_WORD[1]); // Too many errors in the syncword, lock is lost if ((hammingSync > 2) && (hammingLsf > 2)) diff --git a/openrtx/src/protocols/M17/M17FrameDecoder.cpp b/openrtx/src/protocols/M17/M17FrameDecoder.cpp index e66cce96..234e5ffc 100644 --- a/openrtx/src/protocols/M17/M17FrameDecoder.cpp +++ b/openrtx/src/protocols/M17/M17FrameDecoder.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/openrtx/src/protocols/M17/M17FrameEncoder.cpp b/openrtx/src/protocols/M17/M17FrameEncoder.cpp index f12afb49..6f51386d 100644 --- a/openrtx/src/protocols/M17/M17FrameEncoder.cpp +++ b/openrtx/src/protocols/M17/M17FrameEncoder.cpp @@ -22,6 +22,7 @@ #include #include #include +#include using namespace M17; diff --git a/openrtx/src/protocols/M17/M17Modulator.cpp b/openrtx/src/protocols/M17/M17Modulator.cpp index 765f6700..8c03c79e 100644 --- a/openrtx/src/protocols/M17/M17Modulator.cpp +++ b/openrtx/src/protocols/M17/M17Modulator.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #if defined(PLATFORM_LINUX) @@ -51,7 +52,7 @@ void M17Modulator::init() * placement new. */ - baseband_buffer = new int16_t[2 * M17_FRAME_SAMPLES_48K]; + baseband_buffer = new int16_t[2 * M17_FRAME_SAMPLES]; idleBuffer = baseband_buffer; txRunning = false; #if defined(PLATFORM_MD3x0) || defined(PLATFORM_MDUV3x0) @@ -90,14 +91,14 @@ void M17Modulator::send(const std::array< uint8_t, 2 >& sync, void M17Modulator::generateBaseband() { - memset(idleBuffer, 0x00, M17_FRAME_SAMPLES_48K * sizeof(stream_sample_t)); + memset(idleBuffer, 0x00, M17_FRAME_SAMPLES * sizeof(stream_sample_t)); for(size_t i = 0; i < symbols.size(); i++) { idleBuffer[i * 10] = symbols[i]; } - for(size_t i = 0; i < M17_FRAME_SAMPLES_48K; i++) + for(size_t i = 0; i < M17_FRAME_SAMPLES; i++) { float elem = static_cast< float >(idleBuffer[i]); elem = M17::rrc_48k(elem * M17_RRC_GAIN) - M17_RRC_OFFSET; @@ -109,8 +110,8 @@ void M17Modulator::generateBaseband() void M17Modulator::emitBaseband() { #if defined(PLATFORM_MD3x0) || defined(PLATFORM_MDUV3x0) - dsp_pwmCompensate(&pwmFilterState, idleBuffer, M17_FRAME_SAMPLES_48K); - dsp_invertPhase(idleBuffer, M17_FRAME_SAMPLES_48K); + dsp_pwmCompensate(&pwmFilterState, idleBuffer, M17_FRAME_SAMPLES); + dsp_invertPhase(idleBuffer, M17_FRAME_SAMPLES); #endif if(txRunning == false) @@ -119,7 +120,7 @@ void M17Modulator::emitBaseband() outStream = outputStream_start(SINK_RTX, PRIO_TX, baseband_buffer, - 2*M17_FRAME_SAMPLES_48K, + 2*M17_FRAME_SAMPLES, BUF_CIRC_DOUBLE, M17_TX_SAMPLE_RATE); txRunning = true; @@ -152,7 +153,7 @@ void M17Modulator::emitBaseband() { FILE *outfile = fopen("/tmp/m17_output.raw", "ab"); - for(size_t i = 0; i < M17_FRAME_SAMPLES_48K; i++) + for(size_t i = 0; i < M17_FRAME_SAMPLES; i++) { auto s = idleBuffer[i]; fwrite(&s, sizeof(s), 1, outfile);