Reorganised constants inside M17 demodulator class

This commit is contained in:
Silvano Seva 2022-04-05 11:39:53 +02:00
parent 77dfeef9e7
commit beca0d2acc
2 changed files with 37 additions and 28 deletions

View File

@ -100,36 +100,40 @@ public:
*/ */
bool update(); bool update();
/**
* @return true if a demodulator is locked on an M17 stream.
*/
bool isLocked();
private: private:
/* /**
* We are sampling @ 24KHz so an M17 frame has half the samples, * M17 baseband signal sampled at 48kHz, half of an M17 frame is processed
* our input buffer contains half M17 frame. * at each update of the demodulator.
*/ */
static constexpr size_t M17_SYMBOL_RATE = 4800; static constexpr size_t M17_SYMBOL_RATE = 4800;
static constexpr size_t M17_FRAME_SAMPLES_24K = 960;
static constexpr size_t M17_FRAME_SYMBOLS = 192; static constexpr size_t M17_FRAME_SYMBOLS = 192;
static constexpr size_t M17_SYNCWORD_SYMBOLS = 8; static constexpr size_t M17_SYNCWORD_SYMBOLS = 8;
static constexpr size_t M17_CONV_THRESHOLD = 50000;
static constexpr size_t M17_RX_SAMPLE_RATE = 48000; static constexpr size_t M17_RX_SAMPLE_RATE = 48000;
static constexpr size_t M17_SAMPLES_PER_SYMBOL = M17_RX_SAMPLE_RATE / M17_SYMBOL_RATE; static constexpr size_t M17_SAMPLES_PER_SYMBOL = M17_RX_SAMPLE_RATE / M17_SYMBOL_RATE;
static constexpr size_t M17_INPUT_BUF_SIZE = 2 * M17_FRAME_SAMPLES_24K;
static constexpr size_t M17_FRAME_BYTES = M17_FRAME_SYMBOLS / 4; static constexpr size_t M17_FRAME_BYTES = M17_FRAME_SYMBOLS / 4;
static constexpr float conv_stats_alpha = 0.001f; static constexpr size_t M17_FRAME_SAMPLES = M17_FRAME_SYMBOLS * M17_SAMPLES_PER_SYMBOL;
static constexpr float qnt_stats_alpha = 0.9f; static constexpr size_t M17_SAMPLE_BUF_SIZE = M17_FRAME_SAMPLES / 2;
static constexpr float conv_threshold_factor = 3.40; static constexpr size_t M17_BRIDGE_SIZE = M17_SAMPLES_PER_SYMBOL * M17_SYNCWORD_SYMBOLS;
static constexpr size_t M17_BRIDGE_SIZE = M17_SAMPLES_PER_SYMBOL *
M17_SYNCWORD_SYMBOLS; static constexpr size_t M17_CONV_THRESHOLD = 50000;
static constexpr float CONV_STATS_ALPHA = 0.001f;
static constexpr float QNT_STATS_ALPHA = 0.9f;
static constexpr float CONV_THRESHOLD_FACTOR = 3.40;
/** /**
* M17 syncwords; * M17 syncwords;
*/ */
int8_t lsf_syncword[M17_SYNCWORD_SYMBOLS] = { +3, +3, +3, +3, -3, -3, +3, -3 }; 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 }; 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 lsf_syncword_bytes[2] = {0x55, 0xf7};
uint8_t stream_syncword_bytes[2] = {0xff, 0x5d}; uint8_t stream_syncword_bytes[2] = {0xff, 0x5d};
using dataBuffer_t = std::array< int16_t, M17_FRAME_SAMPLES_24K >;
/* /*
* Buffers * Buffers

View File

@ -55,7 +55,7 @@ void M17Demodulator::init()
* placement new. * placement new.
*/ */
baseband_buffer = new int16_t[2 * M17_INPUT_BUF_SIZE]; baseband_buffer = new int16_t[2 * M17_SAMPLE_BUF_SIZE];
baseband = { nullptr, 0 }; baseband = { nullptr, 0 };
activeFrame = new frame_t; activeFrame = new frame_t;
rawFrame = new uint16_t[M17_FRAME_SYMBOLS]; rawFrame = new uint16_t[M17_FRAME_SYMBOLS];
@ -88,7 +88,7 @@ void M17Demodulator::startBasebandSampling()
{ {
basebandId = inputStream_start(SOURCE_RTX, PRIO_RX, basebandId = inputStream_start(SOURCE_RTX, PRIO_RX,
baseband_buffer, baseband_buffer,
M17_INPUT_BUF_SIZE, 2 * M17_SAMPLE_BUF_SIZE,
BUF_CIRC_DOUBLE, BUF_CIRC_DOUBLE,
M17_RX_SAMPLE_RATE); M17_RX_SAMPLE_RATE);
// Clean start of the demodulation statistics // Clean start of the demodulation statistics
@ -113,9 +113,9 @@ void M17Demodulator::resetCorrelationStats()
void M17Demodulator::updateCorrelationStats(int32_t value) void M17Demodulator::updateCorrelationStats(int32_t value)
{ {
float delta = (float) value - conv_ema; float delta = (float) value - conv_ema;
float incr = conv_stats_alpha * delta; float incr = CONV_STATS_ALPHA * delta;
conv_ema += incr; conv_ema += incr;
conv_emvar = (1.0f - conv_stats_alpha) * (conv_emvar + delta * incr); conv_emvar = (1.0f - CONV_STATS_ALPHA) * (conv_emvar + delta * incr);
} }
float M17Demodulator::getCorrelationStddev() float M17Demodulator::getCorrelationStddev()
@ -140,17 +140,17 @@ void M17Demodulator::updateQuantizationStats(int32_t offset)
sample = baseband.data[offset]; sample = baseband.data[offset];
// Compute symbols exponential moving average // Compute symbols exponential moving average
float delta = (float) sample - qnt_ema; float delta = (float) sample - qnt_ema;
qnt_ema += conv_stats_alpha * delta; qnt_ema += CONV_STATS_ALPHA * delta;
// Remove DC offset // Remove DC offset
int16_t s = sample - (int16_t) qnt_ema; int16_t s = sample - (int16_t) qnt_ema;
if (s > qnt_max) if (s > qnt_max)
qnt_max = s; qnt_max = s;
else else
qnt_max *= qnt_stats_alpha; qnt_max *= QNT_STATS_ALPHA;
if (s < qnt_min) if (s < qnt_min)
qnt_min = s; qnt_min = s;
else else
qnt_min *= qnt_stats_alpha; qnt_min *= QNT_STATS_ALPHA;
} }
int32_t M17Demodulator::convolution(int32_t offset, int32_t M17Demodulator::convolution(int32_t offset,
@ -202,20 +202,20 @@ sync_t M17Demodulator::nextFrameSync(int32_t offset)
fprintf(csv_log, "%" PRId16 ",%d,%f,%d\n", fprintf(csv_log, "%" PRId16 ",%d,%f,%d\n",
sample, sample,
conv - static_cast< int32_t >(conv_ema), conv - static_cast< int32_t >(conv_ema),
conv_threshold_factor * getCorrelationStddev(), CONV_THRESHOLD_FACTOR * getCorrelationStddev(),
i); i);
#endif #endif
// Positive correlation peak -> frame syncword // Positive correlation peak -> frame syncword
if ((conv - static_cast< int32_t >(conv_ema)) > if ((conv - static_cast< int32_t >(conv_ema)) >
(getCorrelationStddev() * conv_threshold_factor)) (getCorrelationStddev() * CONV_THRESHOLD_FACTOR))
{ {
syncword.lsf = false; syncword.lsf = false;
syncword.index = i; syncword.index = i;
} }
// Negative correlation peak -> LSF syncword // Negative correlation peak -> LSF syncword
else if ((conv - static_cast< int32_t >(conv_ema)) < else if ((conv - static_cast< int32_t >(conv_ema)) <
-(getCorrelationStddev() * conv_threshold_factor)) -(getCorrelationStddev() * CONV_THRESHOLD_FACTOR))
{ {
syncword.lsf = true; syncword.lsf = true;
syncword.index = i; syncword.index = i;
@ -259,6 +259,11 @@ bool M17Demodulator::isFrameLSF()
return isLSF; return isLSF;
} }
bool M17::M17Demodulator::isLocked()
{
return locked;
}
uint8_t M17Demodulator::hammingDistance(uint8_t x, uint8_t y) uint8_t M17Demodulator::hammingDistance(uint8_t x, uint8_t y)
{ {
return __builtin_popcount(x ^ y); return __builtin_popcount(x ^ y);
@ -373,7 +378,7 @@ bool M17Demodulator::update()
{ {
// Compute phase of next buffer // Compute phase of next buffer
phase = (offset % M17_SAMPLES_PER_SYMBOL) + phase = (offset % M17_SAMPLES_PER_SYMBOL) +
(M17_INPUT_BUF_SIZE % M17_SAMPLES_PER_SYMBOL); (baseband.len % M17_SAMPLES_PER_SYMBOL);
} }
else else
{ {