You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
3.1 KiB
121 lines
3.1 KiB
/*
|
|
* Copyright (C) 2009,2010,2013,2014,2015 by Jonathan Naylor, G4KLX
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; version 2 of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include "DStarGMSKDemodulator.h"
|
|
|
|
// Generated by gaussfir(0.5, 4, 10)
|
|
const float COEFFS_TABLE[] = {
|
|
0.000000000000003F, 0.000000000000065F, 0.000000000001037F, 0.000000000014448F, 0.000000000174579F,
|
|
0.000000001829471F, 0.000000016627294F, 0.000000131062698F, 0.000000895979719F, 0.000005312253663F, 0.000027316243802F,
|
|
0.000121821714020F, 0.000471183399421F, 0.001580581180127F, 0.004598383433830F, 0.011602594308899F, 0.025390226926262F,
|
|
0.048188078330624F, 0.079318443411643F, 0.113232294527059F, 0.140193533802410F, 0.150538369557851F, 0.140193533802410F,
|
|
0.113232294527059F, 0.079318443411643F, 0.048188078330623F, 0.025390226926262F, 0.011602594308899F, 0.004598383433830F,
|
|
0.001580581180127F, 0.000471183399421F, 0.000121821714020F, 0.000027316243802F, 0.000005312253663F, 0.000000895979719F,
|
|
0.000000131062698F, 0.000000016627294F, 0.000000001829471F, 0.000000000174579F, 0.000000000014448F, 0.000000000001037F,
|
|
0.000000000000065F, 0.000000000000003F};
|
|
|
|
const unsigned int COEFFS_LENGTH = 43U;
|
|
|
|
const unsigned int DCOFFSET_COUNT = 4800U; // 5 seconds
|
|
|
|
const unsigned int PLLMAX = 0x10000U;
|
|
const unsigned int PLLINC = PLLMAX / DSTAR_RADIO_BIT_LENGTH;
|
|
const unsigned int INC_LOCK = PLLINC / 64U;
|
|
const unsigned int INC_UNLOCK = PLLINC / 32U;
|
|
|
|
CDStarGMSKDemodulator::CDStarGMSKDemodulator() :
|
|
m_filter(COEFFS_TABLE, COEFFS_LENGTH),
|
|
m_invert(false),
|
|
m_pll(0U),
|
|
m_prev(false),
|
|
m_inc(INC_UNLOCK),
|
|
m_locked(false),
|
|
m_offset(0.0F),
|
|
m_accum(0.0F),
|
|
m_count(0U)
|
|
{
|
|
}
|
|
|
|
CDStarGMSKDemodulator::~CDStarGMSKDemodulator()
|
|
{
|
|
}
|
|
|
|
TRISTATE CDStarGMSKDemodulator::decode(float val)
|
|
{
|
|
TRISTATE state = STATE_UNKNOWN;
|
|
|
|
// Calculate the DC offset when we are locked
|
|
if (m_locked) {
|
|
m_accum += val;
|
|
m_count++;
|
|
|
|
if (m_count >= DCOFFSET_COUNT) {
|
|
m_accum /= float(DCOFFSET_COUNT);
|
|
|
|
m_offset = m_offset * 0.9F + m_accum * 0.1F;
|
|
|
|
m_accum = 0.0F;
|
|
m_count = 0U;
|
|
}
|
|
}
|
|
|
|
float out = m_filter.process(val - m_offset);
|
|
|
|
bool bit = out > 0.0F;
|
|
|
|
if (bit != m_prev) {
|
|
if (m_pll < (PLLMAX / 2U))
|
|
m_pll += m_inc;
|
|
else
|
|
m_pll -= m_inc;
|
|
}
|
|
|
|
m_prev = bit;
|
|
|
|
m_pll += PLLINC;
|
|
|
|
if (m_pll >= PLLMAX) {
|
|
if (m_invert)
|
|
state = bit ? STATE_TRUE : STATE_FALSE;
|
|
else
|
|
state = bit ? STATE_FALSE : STATE_TRUE;
|
|
|
|
m_pll -= PLLMAX;
|
|
}
|
|
|
|
return state;
|
|
}
|
|
|
|
void CDStarGMSKDemodulator::reset()
|
|
{
|
|
m_pll = 0U;
|
|
m_prev = false;
|
|
m_inc = INC_UNLOCK;
|
|
m_locked = false;
|
|
}
|
|
|
|
void CDStarGMSKDemodulator::setInvert(bool set)
|
|
{
|
|
m_invert = set;
|
|
}
|
|
|
|
void CDStarGMSKDemodulator::lock(bool on)
|
|
{
|
|
// Debugging only XXX
|
|
// (wxLogMessage removed - was: "Current DC offset: %f", m_offset)
|
|
|
|
m_locked = on;
|
|
|
|
m_inc = on ? INC_LOCK : INC_UNLOCK;
|
|
}
|