2019-06-23 02:53:34 +00:00
|
|
|
// Copyright 2015-2019 Mobilinkd LLC <rob@mobilinkd.com>
|
2018-07-30 02:34:53 +00:00
|
|
|
// All rights reserved.
|
|
|
|
|
|
|
|
#ifndef MOBILINKD__AFSK_DEMODULATOR_HPP_
|
|
|
|
#define MOBILINKD__AFSK_DEMODULATOR_HPP_
|
|
|
|
|
|
|
|
#include <arm_math.h>
|
|
|
|
#include "DelayLine.hpp"
|
|
|
|
#include "AudioInput.hpp"
|
|
|
|
#include "DigitalPLL.hpp"
|
|
|
|
#include "HdlcDecoder.hpp"
|
|
|
|
#include "Hysteresis.hpp"
|
|
|
|
#include "FirFilter.hpp"
|
|
|
|
#include "NRZI.hpp"
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
namespace mobilinkd { namespace tnc { namespace afsk1200 {
|
|
|
|
|
2019-06-23 02:53:34 +00:00
|
|
|
const size_t LPF_FILTER_LEN = 96;
|
|
|
|
|
|
|
|
const q15_t lpf_coeffs[] = {
|
|
|
|
0, 1, 3, 5, 8, 11, 14, 17, 19, 20, 18, 14,
|
|
|
|
7, -2, -16, -33, -53, -76, -101, -126, -151, -174, -194, -208,
|
|
|
|
-215, -212, -199, -173, -133, -79, -10, 74, 173, 287, 413, 549,
|
|
|
|
693, 842, 993, 1142, 1287, 1423, 1547, 1656, 1747, 1817, 1865, 1889,
|
|
|
|
1889, 1865, 1817, 1747, 1656, 1547, 1423, 1287, 1142, 993, 842, 693,
|
|
|
|
549, 413, 287, 173, 74, -10, -79, -133, -173, -199, -212, -215,
|
|
|
|
-208, -194, -174, -151, -126, -101, -76, -53, -33, -16, -2, 7,
|
|
|
|
14, 18, 20, 19, 17, 14, 11, 8, 5, 3, 1, 0,
|
2018-07-30 02:34:53 +00:00
|
|
|
};
|
|
|
|
|
2021-01-03 03:59:59 +00:00
|
|
|
static constexpr uint32_t ADC_BUFFER_SIZE = 88;
|
|
|
|
typedef FirFilter<ADC_BUFFER_SIZE, 9> emphasis_filter_type;
|
2018-07-30 02:34:53 +00:00
|
|
|
|
|
|
|
struct Demodulator {
|
|
|
|
|
|
|
|
typedef float float_type;
|
|
|
|
|
|
|
|
typedef std::function<float_type(float_type)> filter_function_type;
|
|
|
|
|
|
|
|
static const size_t SYMBOL_RATE = 1200;
|
|
|
|
|
|
|
|
typedef BaseDigitalPLL<float_type> DPLL;
|
|
|
|
|
|
|
|
size_t sample_rate_;
|
|
|
|
emphasis_filter_type& audio_filter_;
|
2021-07-01 01:16:15 +00:00
|
|
|
float audio_filter_input_buffer[ADC_BUFFER_SIZE];
|
2018-07-30 02:34:53 +00:00
|
|
|
libafsk::FixedDelayLine<40> delay_line_;
|
|
|
|
DPLL pll_;
|
2021-01-03 03:59:59 +00:00
|
|
|
Q15FirFilter<ADC_BUFFER_SIZE, LPF_FILTER_LEN> lpf_filter_;
|
2018-07-30 02:34:53 +00:00
|
|
|
libafsk::NRZI nrzi_;
|
2019-06-23 02:53:34 +00:00
|
|
|
hdlc::NewDecoder hdlc_decoder_;
|
2018-07-30 02:34:53 +00:00
|
|
|
bool locked_;
|
2021-01-03 03:59:59 +00:00
|
|
|
q15_t buffer_[ADC_BUFFER_SIZE];
|
2018-07-30 02:34:53 +00:00
|
|
|
|
|
|
|
Demodulator(size_t sample_rate, emphasis_filter_type& c)
|
|
|
|
: sample_rate_(sample_rate)
|
|
|
|
, audio_filter_(c)
|
|
|
|
, delay_line_(sample_rate, 0.000448)
|
|
|
|
, pll_(sample_rate, SYMBOL_RATE)
|
|
|
|
, nrzi_(), hdlc_decoder_(false), locked_(false)
|
2019-06-23 02:53:34 +00:00
|
|
|
{
|
|
|
|
lpf_filter_.init(lpf_coeffs);
|
|
|
|
}
|
2018-07-30 02:34:53 +00:00
|
|
|
|
2019-06-23 02:53:34 +00:00
|
|
|
hdlc::IoFrame* operator()(q15_t* samples, size_t len);
|
2018-07-30 02:34:53 +00:00
|
|
|
|
|
|
|
bool locked() const {return locked_;}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
}}} // mobilinkd::tnc::afsk1200
|
|
|
|
|
|
|
|
|
|
|
|
#endif // MOBILINKD__AFSK_DEMODULATOR_HPP_
|