1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-03 23:41:16 -05:00
sdrangel/plugins/channelrx/demodm17/m17/M17Demodulator.h

128 lines
2.9 KiB
C
Raw Normal View History

// Copyright 2020-2021 Rob Riggs <rob@mobilinkd.com>
// All rights reserved.
#pragma once
#include "ClockRecovery.h"
#include "Correlator.h"
#include "DataCarrierDetect.h"
#include "FirFilter.h"
#include "FreqDevEstimator.h"
#include "M17FrameDecoder.h"
#include "M17Framer.h"
#include "Util.h"
#include <algorithm>
#include <array>
#include <functional>
#include <optional>
#include <tuple>
namespace mobilinkd {
namespace detail
{
} // detail
struct M17Demodulator
{
static const uint16_t SAMPLE_RATE = 48000;
static const uint16_t SYMBOL_RATE = 4800;
static const uint16_t SAMPLES_PER_SYMBOL = SAMPLE_RATE / SYMBOL_RATE;
static const uint16_t BLOCK_SIZE = 192;
static constexpr float sample_rate = SAMPLE_RATE;
static constexpr float symbol_rate = SYMBOL_RATE;
static const uint8_t MAX_MISSING_SYNC = 8;
using collelator_t = Correlator;
using sync_word_t = SyncWord<collelator_t>;
using callback_t = M17FrameDecoder::callback_t;
using diagnostic_callback_t = std::function<void(bool, float, float, float, int, float, int, int, int, int)>;
enum class DemodState {
UNLOCKED,
LSF_SYNC,
STREAM_SYNC,
PACKET_SYNC,
BERT_SYNC,
FRAME
};
DataCarrierDetect<SAMPLE_RATE, 500> dcd{2500, 4000, 1.0, 4.0};
ClockRecovery<SAMPLE_RATE, SYMBOL_RATE> clock_recovery;
collelator_t correlator;
sync_word_t preamble_sync{{+3,-3,+3,-3,+3,-3,+3,-3}, 29.f};
sync_word_t lsf_sync{{+3,+3,+3,+3,-3,-3,+3,-3}, 32.f, -31.f}; // LSF or STREAM (inverted)
sync_word_t packet_sync{{3,-3,3,3,-3,-3,-3,-3}, 31.f, -31.f}; // PACKET or BERT (inverted)
FreqDevEstimator dev;
float idev;
size_t count_ = 0;
int8_t polarity = 1;
M17Framer<368> framer;
M17FrameDecoder decoder;
DemodState demodState = DemodState::UNLOCKED;
M17FrameDecoder::SyncWordType sync_word_type = M17FrameDecoder::SyncWordType::LSF;
uint8_t sample_index = 0;
bool dcd_ = false;
bool need_clock_reset_ = false;
bool need_clock_update_ = false;
bool passall_ = false;
int viterbi_cost = 0;
int sync_count = 0;
int missing_sync_count = 0;
uint8_t sync_sample_index = 0;
diagnostic_callback_t diagnostic_callback;
M17Demodulator(callback_t callback) :
decoder(callback)
{}
virtual ~M17Demodulator() {}
void dcd_on();
void dcd_off();
void initialize(const float input);
void update_dcd();
void do_unlocked();
void do_lsf_sync();
void do_packet_sync();
void do_stream_sync();
void do_bert_sync();
void do_frame(float filtered_sample);
bool locked() const
{
return dcd_;
}
void passall(bool enabled)
{
passall_ = enabled;
// decoder.passall(enabled);
}
void diagnostics(diagnostic_callback_t callback)
{
diagnostic_callback = callback;
}
void update_values(uint8_t index);
void operator()(const float input);
private:
static const std::array<float, 150> rrc_taps;
BaseFirFilter<rrc_taps.size()> demod_filter{rrc_taps};
};
} // mobilinkd