Improved detection of M17 frames to avoid spurious decodes

This commit is contained in:
AlexandreRouma 2023-02-18 16:08:57 +01:00
parent 93e985ab54
commit 1f97e9e10b
2 changed files with 59 additions and 0 deletions

View File

@ -27,6 +27,10 @@ extern "C" {
#define M17_RAW_FRAME_SIZE 384 #define M17_RAW_FRAME_SIZE 384
#define M17_CUT_FRAME_SIZE 368 #define M17_CUT_FRAME_SIZE 368
#define M17_MAX_FN 0x7FFF
#define M17_END_FN 0x8000
#define M17_STREAM_TIMEOUT 500
const uint8_t M17_LSF_SYNC[16] = { 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1 }; const uint8_t M17_LSF_SYNC[16] = { 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1 };
const uint8_t M17_STF_SYNC[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1 }; const uint8_t M17_STF_SYNC[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1 };
const uint8_t M17_PKF_SYNC[16] = { 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; const uint8_t M17_PKF_SYNC[16] = { 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
@ -438,6 +442,7 @@ namespace dsp {
void init(stream<uint8_t>* in) { void init(stream<uint8_t>* in) {
_in = in; _in = in;
lastConseqTime = std::chrono::high_resolution_clock::now();
codec = codec2_create(CODEC2_MODE_3200); codec = codec2_create(CODEC2_MODE_3200);
sampsPerC2Frame = codec2_samples_per_frame(codec); sampsPerC2Frame = codec2_samples_per_frame(codec);
@ -460,10 +465,46 @@ namespace dsp {
block::tempStart(); block::tempStart();
} }
bool isReceiving() {
std::lock_guard<std::recursive_mutex> lck(recvMtx);
return receiving && !timedOut();
}
bool timedOut() {
std::lock_guard<std::recursive_mutex> lck(recvMtx);
auto now = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(now - lastConseqTime).count() > M17_STREAM_TIMEOUT;
}
int run() { int run() {
int count = _in->read(); int count = _in->read();
if (count < 0) { return -1; } if (count < 0) { return -1; }
// Decode frame number
uint16_t fn = ((uint16_t)_in->readBuf[0] << 8) | _in->readBuf[1];
// Check if we need to start or stop receiving
bool consecutive = ((((int)fn - (int)lastFn + M17_END_FN) % M17_END_FN) == 1);
if (!receiving && consecutive) {
std::lock_guard<std::recursive_mutex> lck(recvMtx);
receiving = true;
}
else if (receiving && consecutive) {
std::lock_guard<std::recursive_mutex> lck(recvMtx);
lastConseqTime = std::chrono::high_resolution_clock::now();;
}
else if (receiving && !consecutive && timedOut()) {
std::lock_guard<std::recursive_mutex> lck(recvMtx);
receiving = false;
}
// Save FN and if we have to stop receiving and it's not the last frame, stop
lastFn = fn;
if (!receiving) {
_in->flush();
return count;
}
// Decode both parts using codec // Decode both parts using codec
codec2_decode(codec, int16Audio, &_in->readBuf[2]); codec2_decode(codec, int16Audio, &_in->readBuf[2]);
codec2_decode(codec, &int16Audio[sampsPerC2Frame], &_in->readBuf[2 + 8]); codec2_decode(codec, &int16Audio[sampsPerC2Frame], &_in->readBuf[2 + 8]);
@ -485,6 +526,11 @@ namespace dsp {
private: private:
stream<uint8_t>* _in; stream<uint8_t>* _in;
std::recursive_mutex recvMtx;
bool receiving = false;
uint16_t lastFn = 0;
std::chrono::high_resolution_clock::time_point lastConseqTime;
int16_t* int16Audio; int16_t* int16Audio;
float* floatAudio; float* floatAudio;
@ -637,6 +683,10 @@ namespace dsp {
demod.setInput(input); demod.setInput(input);
} }
bool isReceiving() {
return decodeAudio.isReceiving();
}
stream<float>* diagOut = NULL; stream<float>* diagOut = NULL;
stream<stereo_t>* out = NULL; stream<stereo_t>* out = NULL;

View File

@ -227,6 +227,15 @@ private:
config.release(true); config.release(true);
} }
ImGui::TextUnformatted("Status:");
ImGui::SameLine();
if (_this->decoder.isReceiving()) {
ImGui::TextColored(ImVec4(0.0, 1.0, 0.0, 1.0), "Receiving");
}
else {
ImGui::TextUnformatted("Idle");
}
if (!_this->enabled) { style::endDisabled(); } if (!_this->enabled) { style::endDisabled(); }
} }