M17: Demodulator: improve symbol deviation estimation

Using the DevEstimator class to obtain a better estimation of the outer
symbol deviation: now values are estimated using a full frame instead of
just the outer symbols of a syncword.

Signed-off-by: Silvano Seva <silseva@fastwebnet.it>
This commit is contained in:
Silvano Seva 2025-10-28 21:44:13 +01:00
parent 2df90bb269
commit dc81639713
2 changed files with 10 additions and 4 deletions

View File

@ -40,6 +40,7 @@
#include "protocols/M17/M17Constants.hpp" #include "protocols/M17/M17Constants.hpp"
#include "protocols/M17/Correlator.hpp" #include "protocols/M17/Correlator.hpp"
#include "protocols/M17/Synchronizer.hpp" #include "protocols/M17/Synchronizer.hpp"
#include "protocols/M17/DevEstimator.hpp"
namespace M17 namespace M17
{ {
@ -183,13 +184,13 @@ private:
uint8_t missedSyncs; ///< Counter of missed synchronizations uint8_t missedSyncs; ///< Counter of missed synchronizations
uint32_t initCount; ///< Downcounter for initialization uint32_t initCount; ///< Downcounter for initialization
uint32_t syncCount; ///< Downcounter for resynchronization uint32_t syncCount; ///< Downcounter for resynchronization
std::pair < int32_t, int32_t > outerDeviation; ///< Deviation of outer symbols
float corrThreshold; ///< Correlation threshold float corrThreshold; ///< Correlation threshold
struct dcBlock dcBlock; ///< State of the DC removal filter struct dcBlock dcBlock; ///< State of the DC removal filter
Correlator < M17_SYNCWORD_SYMBOLS, SAMPLES_PER_SYMBOL > correlator; Correlator < M17_SYNCWORD_SYMBOLS, SAMPLES_PER_SYMBOL > correlator;
Synchronizer < M17_SYNCWORD_SYMBOLS, SAMPLES_PER_SYMBOL > streamSync{{ -3, -3, -3, -3, +3, +3, -3, +3 }}; Synchronizer < M17_SYNCWORD_SYMBOLS, SAMPLES_PER_SYMBOL > streamSync{{ -3, -3, -3, -3, +3, +3, -3, +3 }};
Iir < 3 > sampleFilter{sfNum, sfDen}; Iir < 3 > sampleFilter{sfNum, sfDen};
DevEstimator devEstimator;
}; };
} /* M17 */ } /* M17 */

View File

@ -290,6 +290,7 @@ bool M17Demodulator::update(const bool invertPhase)
void M17Demodulator::quantize(stream_sample_t sample) void M17Demodulator::quantize(stream_sample_t sample)
{ {
auto outerDeviation = devEstimator.outerDeviation();
int8_t symbol; int8_t symbol;
if(sample > (2 * outerDeviation.first)/3) if(sample > (2 * outerDeviation.first)/3)
@ -314,6 +315,7 @@ void M17Demodulator::quantize(stream_sample_t sample)
if(frameIndex >= M17_FRAME_SYMBOLS) if(frameIndex >= M17_FRAME_SYMBOLS)
{ {
devEstimator.update();
std::swap(readyFrame, demodFrame); std::swap(readyFrame, demodFrame);
frameIndex = 0; frameIndex = 0;
newFrame = true; newFrame = true;
@ -345,8 +347,9 @@ void M17Demodulator::syncedState()
{ {
// Set sampling point and deviation, zero frame symbol count // Set sampling point and deviation, zero frame symbol count
samplingPoint = streamSync.samplingIndex(); samplingPoint = streamSync.samplingIndex();
outerDeviation = correlator.maxDeviation(samplingPoint); auto deviation = correlator.maxDeviation(samplingPoint);
frameIndex = 0; frameIndex = 0;
devEstimator.init(deviation);
// Quantize the syncword taking data from the correlator // Quantize the syncword taking data from the correlator
// memory. // memory.
@ -375,6 +378,7 @@ void M17Demodulator::lockedState(int16_t sample)
// Quantize and update frame at each sampling point // Quantize and update frame at each sampling point
quantize(sample); quantize(sample);
devEstimator.sample(sample);
// When we have reached almost the end of a frame, switch // When we have reached almost the end of a frame, switch
// to syncpoint update. // to syncpoint update.
@ -387,8 +391,10 @@ void M17Demodulator::lockedState(int16_t sample)
void M17Demodulator::syncUpdateState(int16_t sample) void M17Demodulator::syncUpdateState(int16_t sample)
{ {
// Keep filling the ongoing frame! // Keep filling the ongoing frame!
if(sampleIndex == samplingPoint) if(sampleIndex == samplingPoint) {
quantize(sample); quantize(sample);
devEstimator.sample(sample);
}
// Find the new correlation peak // Find the new correlation peak
int32_t syncThresh = static_cast< int32_t >(corrThreshold * 33.0f); int32_t syncThresh = static_cast< int32_t >(corrThreshold * 33.0f);
@ -402,7 +408,6 @@ void M17Demodulator::syncUpdateState(int16_t sample)
// Valid sync found: update deviation and sample // Valid sync found: update deviation and sample
// point, then go back to locked state // point, then go back to locked state
if(hd <= 1) { if(hd <= 1) {
outerDeviation = correlator.maxDeviation(samplingPoint);
samplingPoint = streamSync.samplingIndex(); samplingPoint = streamSync.samplingIndex();
missedSyncs = 0; missedSyncs = 0;
demodState = DemodState::LOCKED; demodState = DemodState::LOCKED;