M17 code cleanup pass: reorganised data type definitions and constants
This commit is contained in:
parent
5b27e6b692
commit
d17d683b2d
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <M17/M17Decorrelator.h>
|
||||
#include <M17/M17Interleaver.h>
|
||||
#include <M17/M17FrameEncoder.h>
|
||||
#include <M17/M17Constants.h>
|
||||
|
||||
using namespace M17;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue