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

/*
* 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;
}

Powered by TurnKey Linux.