M17 code cleanup pass: reorganised data type definitions and constants

This commit is contained in:
Silvano Seva 2022-05-19 16:53:29 +02:00
parent 5b27e6b692
commit d17d683b2d
9 changed files with 105 additions and 57 deletions

View File

@ -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 <http://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef M17_CONSTANTS_H
#define M17_CONSTANTS_H
#include <M17/M17Datatypes.h>
#include <cstdint>
#include <array>
#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

View File

@ -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<uint8_t, 2> LSF_SYNC_WORD = {0x55, 0xF7}; // LSF sync word
static constexpr std::array<uint8_t, 2> STREAM_SYNC_WORD = {0xFF, 0x5D}; // Stream data sync word
static constexpr std::array<uint8_t, 2> 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

View File

@ -35,7 +35,8 @@
#include <dsp.h>
#include <deque>
#include <stdio.h>
#include "M17Datatypes.h"
#include <M17/M17Datatypes.h>
#include <M17/M17Constants.h>
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

View File

@ -26,6 +26,7 @@
#endif
#include <interfaces/audio_stream.h>
#include <M17/M17Constants.h>
#include <cstdint>
#include <array>
#include <dsp.h>
@ -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;

View File

@ -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<N> (array, 2 * pos , 0);
setBit<N> (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

View File

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

View File

@ -23,6 +23,7 @@
#include <M17/M17Interleaver.h>
#include <M17/M17Decorrelator.h>
#include <M17/M17CodePuncturing.h>
#include <M17/M17Constants.h>
#include <M17/M17Utils.h>
#include <algorithm>

View File

@ -22,6 +22,7 @@
#include <M17/M17Decorrelator.h>
#include <M17/M17Interleaver.h>
#include <M17/M17FrameEncoder.h>
#include <M17/M17Constants.h>
using namespace M17;

View File

@ -23,6 +23,7 @@
#include <cstring>
#include <experimental/array>
#include <M17/M17Modulator.h>
#include <M17/M17Utils.h>
#include <M17/M17DSP.h>
#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);