mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2024-12-25 18:38:30 +01:00
Improved detection of M17 frames to avoid spurious decodes
This commit is contained in:
parent
93e985ab54
commit
1f97e9e10b
@ -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;
|
||||||
|
|
||||||
|
@ -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(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user