mirror of
https://github.com/n5ac/mmtty.git
synced 2025-12-06 04:12:03 +01:00
2621 lines
56 KiB
C++
2621 lines
56 KiB
C++
|
|
//Copyright+LGPL
|
|||
|
|
|
|||
|
|
//-----------------------------------------------------------------------------------------------------------------------------------------------
|
|||
|
|
// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba
|
|||
|
|
//-----------------------------------------------------------------------------------------------------------------------------------------------
|
|||
|
|
// This file is part of MMTTY.
|
|||
|
|
|
|||
|
|
// MMTTY is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
|
|||
|
|
// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|||
|
|
|
|||
|
|
// MMTTY 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 Lesser General Public License for more details.
|
|||
|
|
|
|||
|
|
// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see
|
|||
|
|
// <http://www.gnu.org/licenses/>.
|
|||
|
|
//-----------------------------------------------------------------------------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
#include <vcl.h>
|
|||
|
|
#pragma hdrstop
|
|||
|
|
|
|||
|
|
#include "Rtty.h"
|
|||
|
|
|
|||
|
|
#define LOGFFT FALSE
|
|||
|
|
|
|||
|
|
CSinTable g_SinTable;
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
// CSinTable<6C>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
// Added by JE3HHT on Aug.2010
|
|||
|
|
__fastcall CSinTable::CSinTable()
|
|||
|
|
{
|
|||
|
|
m_Size = 48000;
|
|||
|
|
m_tSin = new double[m_Size];
|
|||
|
|
double pi2t = 2 * PI / double(m_Size);
|
|||
|
|
for( int i = 0; i < m_Size; i++ ){
|
|||
|
|
m_tSin[i] = sin(double(i) * pi2t);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
__fastcall CSinTable::~CSinTable()
|
|||
|
|
{
|
|||
|
|
delete[] m_tSin;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
CTICK::CTICK()
|
|||
|
|
{
|
|||
|
|
ptbl[0] = new int[12500];
|
|||
|
|
ptbl[1] = new int[12500];
|
|||
|
|
memset(ptbl[0], 0, sizeof(int[12500]));
|
|||
|
|
memset(ptbl[1], 0, sizeof(int[12500]));
|
|||
|
|
}
|
|||
|
|
CTICK::~CTICK()
|
|||
|
|
{
|
|||
|
|
delete[] ptbl[0]; //JA7UDE 0428
|
|||
|
|
delete[] ptbl[1]; //JA7UDE 0428
|
|||
|
|
}
|
|||
|
|
void CTICK::Init(void)
|
|||
|
|
{
|
|||
|
|
m_wsel = 0;
|
|||
|
|
m_wp = ptbl[0];
|
|||
|
|
m_wcnt = 0;
|
|||
|
|
m_Trig = 0;
|
|||
|
|
}
|
|||
|
|
void CTICK::Write(double d)
|
|||
|
|
{
|
|||
|
|
*m_wp = int(d);
|
|||
|
|
m_wp++;
|
|||
|
|
m_wcnt++;
|
|||
|
|
if( m_wcnt >= m_Samp ){
|
|||
|
|
m_wcnt = 0;
|
|||
|
|
m_wsel++;
|
|||
|
|
m_wsel &= 1;
|
|||
|
|
m_wp = ptbl[m_wsel];
|
|||
|
|
m_Trig = 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
int *CTICK::GetData(void)
|
|||
|
|
{
|
|||
|
|
if( !m_Trig ) return NULL;
|
|||
|
|
m_Trig = 0;
|
|||
|
|
int sel = m_wsel + 1;
|
|||
|
|
sel &= 1;
|
|||
|
|
return ptbl[sel];
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
// VCO<43>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CVCO::CVCO()
|
|||
|
|
{
|
|||
|
|
m_vlock = 0;
|
|||
|
|
m_SampleFreq = SampFreq;
|
|||
|
|
m_FreeFreq = 1900.0;
|
|||
|
|
m_TableSize = int(SampFreq*2);
|
|||
|
|
pSinTbl = new double[m_TableSize];
|
|||
|
|
m_c1 = m_TableSize/16.0;
|
|||
|
|
m_c2 = int( double(m_TableSize) * m_FreeFreq / m_SampleFreq );
|
|||
|
|
m_z = 0;
|
|||
|
|
double pi2t = 2 * PI / double(m_TableSize);
|
|||
|
|
for( int i = 0; i < m_TableSize; i++ ){
|
|||
|
|
pSinTbl[i] = sin(double(i) * pi2t);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CVCO::~CVCO()
|
|||
|
|
{
|
|||
|
|
if( m_vlock ) ::VirtualUnlock(pSinTbl, sizeof(double)*m_TableSize);
|
|||
|
|
delete[] pSinTbl;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CVCO::SetGain(double gain)
|
|||
|
|
{
|
|||
|
|
m_c1 = double(m_TableSize) * gain / m_SampleFreq;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CVCO::VirtualLock(void)
|
|||
|
|
{
|
|||
|
|
if( !m_vlock ){
|
|||
|
|
::VirtualLock(pSinTbl, sizeof(double)*m_TableSize);
|
|||
|
|
m_vlock = 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CVCO::SetSampleFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_SampleFreq = f;
|
|||
|
|
int size = int(m_SampleFreq*2);
|
|||
|
|
if( m_TableSize != size ){
|
|||
|
|
if( pSinTbl != NULL ){
|
|||
|
|
if( m_vlock ) ::VirtualUnlock(pSinTbl, sizeof(double)*m_TableSize);
|
|||
|
|
delete[] pSinTbl;
|
|||
|
|
}
|
|||
|
|
m_TableSize = size;
|
|||
|
|
pSinTbl = new double[m_TableSize];
|
|||
|
|
if( m_vlock ) ::VirtualLock(pSinTbl, sizeof(double)*m_TableSize);
|
|||
|
|
double pi2t = 2 * PI / double(m_TableSize);
|
|||
|
|
for( int i = 0; i < m_TableSize; i++ ){
|
|||
|
|
pSinTbl[i] = sin(double(i) * pi2t);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
SetFreeFreq(m_FreeFreq);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CVCO::SetFreeFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_FreeFreq = f;
|
|||
|
|
m_c2 = double(m_TableSize) * m_FreeFreq / m_SampleFreq;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CVCO::InitPhase(void)
|
|||
|
|
{
|
|||
|
|
m_z = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double CVCO::Do(double d)
|
|||
|
|
{ // -1 to 1
|
|||
|
|
m_z += (d * m_c1 + m_c2) + 0.5;
|
|||
|
|
while( m_z >= m_TableSize ){
|
|||
|
|
m_z -= m_TableSize;
|
|||
|
|
}
|
|||
|
|
while( m_z < 0 ){
|
|||
|
|
m_z += m_TableSize;
|
|||
|
|
}
|
|||
|
|
return pSinTbl[int(m_z)];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
// VCOX<4F>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
__fastcall CVCOX::CVCOX()
|
|||
|
|
{
|
|||
|
|
m_SampleFreq = SampFreq;
|
|||
|
|
m_FreeFreq = 2000.0;
|
|||
|
|
m_TableSize = g_SinTable.m_Size;
|
|||
|
|
m_TableCOS = m_TableSize / 4;
|
|||
|
|
m_c1 = 0.0;
|
|||
|
|
m_c2 = double(m_TableSize) * m_FreeFreq / m_SampleFreq;
|
|||
|
|
m_z = 0.0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
__fastcall CVCOX::~CVCOX()
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall CVCOX::SetGain(double gain)
|
|||
|
|
{
|
|||
|
|
m_c1 = double(m_TableSize) * gain / m_SampleFreq;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall CVCOX::SetSampleFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_SampleFreq = f;
|
|||
|
|
SetFreeFreq(m_FreeFreq);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall CVCOX::SetFreeFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_FreeFreq = f;
|
|||
|
|
m_c2 = double(m_TableSize) * m_FreeFreq / m_SampleFreq;
|
|||
|
|
if( f < 1.0 ) m_z = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall CVCOX::InitPhase(void)
|
|||
|
|
{
|
|||
|
|
m_z = 0.0;
|
|||
|
|
}
|
|||
|
|
//------------------------------------------------------------------
|
|||
|
|
double __fastcall CVCOX::Do(void)
|
|||
|
|
{
|
|||
|
|
m_z += m_c2;
|
|||
|
|
if( m_z >= m_TableSize ){
|
|||
|
|
m_z -= m_TableSize;
|
|||
|
|
}
|
|||
|
|
if( m_z < 0 ){
|
|||
|
|
m_z += m_TableSize;
|
|||
|
|
}
|
|||
|
|
return g_SinTable.m_tSin[int(m_z)];
|
|||
|
|
}
|
|||
|
|
//------------------------------------------------------------------
|
|||
|
|
double __fastcall CVCOX::Do(double d)
|
|||
|
|
{
|
|||
|
|
// -1 to 1
|
|||
|
|
m_z += (d * m_c1 + m_c2);
|
|||
|
|
while( m_z >= m_TableSize ){
|
|||
|
|
m_z -= m_TableSize;
|
|||
|
|
}
|
|||
|
|
while( m_z < 0 ){
|
|||
|
|
m_z += m_TableSize;
|
|||
|
|
}
|
|||
|
|
return g_SinTable.m_tSin[int(m_z)];
|
|||
|
|
}
|
|||
|
|
//------------------------------------------------------------------
|
|||
|
|
double __fastcall CVCOX::DoCos(void)
|
|||
|
|
{
|
|||
|
|
double z = m_z + m_TableCOS;
|
|||
|
|
if(z >= m_TableSize ) z -= m_TableSize;
|
|||
|
|
return g_SinTable.m_tSin[int(z)];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
// CFSKMOD<4F>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CFSKMOD::CFSKMOD()
|
|||
|
|
{
|
|||
|
|
m_SampFreq = sys.m_SampFreq + sys.m_TxOffset;
|
|||
|
|
vco.SetSampleFreq(m_SampFreq);
|
|||
|
|
|
|||
|
|
memset(ZBPF, 0, sizeof(ZBPF));
|
|||
|
|
memset(HBPF, 0, sizeof(HBPF));
|
|||
|
|
m_bpftap = 48;
|
|||
|
|
|
|||
|
|
m_rp = 0;
|
|||
|
|
m_wp = 0;
|
|||
|
|
m_cnt = 0;
|
|||
|
|
|
|||
|
|
m_BitLen = 5;
|
|||
|
|
m_StopLen = 4; // 0-1bit, 1-1.5bit, 2-2bit, 3-1.5bit, 4-1.5bit
|
|||
|
|
m_Parity = 0;
|
|||
|
|
m_SumParity = 0;
|
|||
|
|
|
|||
|
|
m_Data = 0;
|
|||
|
|
m_DataCount = 0;
|
|||
|
|
m_mode = 0;
|
|||
|
|
m_inv = 0;
|
|||
|
|
m_diddle = 2;
|
|||
|
|
m_fig = 0;
|
|||
|
|
m_figout = 0;
|
|||
|
|
|
|||
|
|
SetBaudRate(45.45);
|
|||
|
|
SetOutputGain(24576.0);
|
|||
|
|
|
|||
|
|
m_MarkFreq = 2125;
|
|||
|
|
m_SpaceFreq = 2295;
|
|||
|
|
SetMarkFreq(2125);
|
|||
|
|
SetSpaceFreq(2295);
|
|||
|
|
|
|||
|
|
m_out = 1;
|
|||
|
|
m_bpf = 1;
|
|||
|
|
SetLPFFreq(100.0);
|
|||
|
|
m_lpf = 0;
|
|||
|
|
|
|||
|
|
m_CharWaitCount = 0;
|
|||
|
|
m_CharWait = 0;
|
|||
|
|
m_DiddleWait = 0;
|
|||
|
|
m_CharWaitDiddle = 0;
|
|||
|
|
|
|||
|
|
m_idle = 1;
|
|||
|
|
pDem = NULL;
|
|||
|
|
m_RandomDiddle = 0;
|
|||
|
|
m_WaitTimer = 0;
|
|||
|
|
m_WaitTimerCount = 0;
|
|||
|
|
|
|||
|
|
m_DisDiddle = 0;
|
|||
|
|
|
|||
|
|
m_AmpVal = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKMOD::CalcBPF(void)
|
|||
|
|
{
|
|||
|
|
MakeFilter(HBPF, m_bpftap, ffBPF, SampFreq, m_MarkFreq - 150, m_SpaceFreq + 150, 60, 1.0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKMOD::SetMarkFreq(double d)
|
|||
|
|
{
|
|||
|
|
m_MarkFreq = d;
|
|||
|
|
vco.SetFreeFreq(m_SpaceFreq);
|
|||
|
|
vco.SetGain(m_MarkFreq - m_SpaceFreq);
|
|||
|
|
CalcBPF();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKMOD::SetSpaceFreq(double d)
|
|||
|
|
{
|
|||
|
|
m_SpaceFreq = d;
|
|||
|
|
vco.SetFreeFreq(m_SpaceFreq);
|
|||
|
|
vco.SetGain(m_MarkFreq - m_SpaceFreq);
|
|||
|
|
CalcBPF();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKMOD::SetSampFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_SampFreq = sys.m_SampFreq + sys.m_TxOffset;
|
|||
|
|
vco.SetSampleFreq(m_SampFreq);
|
|||
|
|
SetBaudRate(m_BaudRate);
|
|||
|
|
SetLPFFreq(m_LPFFreq);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKMOD::SetBaudRate(double b)
|
|||
|
|
{
|
|||
|
|
if( b >= 1.0 ){
|
|||
|
|
m_BaudRate = b;
|
|||
|
|
m_Count = m_ReCount = int(m_SampFreq/b + 0.5);
|
|||
|
|
m_Amp.SetMax(m_Count);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKMOD::SetLPFFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_LPFFreq = f;
|
|||
|
|
avgLPF.SetCount(int(m_SampFreq/f + 0.5));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKMOD::PutData(int d)
|
|||
|
|
{
|
|||
|
|
if( m_cnt < MODBUFMAX ){
|
|||
|
|
m_idle = 0;
|
|||
|
|
m_Buff[m_wp] = BYTE(d);
|
|||
|
|
m_wp++;
|
|||
|
|
if( m_wp >= MODBUFMAX ) m_wp = 0;
|
|||
|
|
m_cnt++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKMOD::OutTone(int sw, int bsize)
|
|||
|
|
{
|
|||
|
|
if( sw ){
|
|||
|
|
m_out = 1;
|
|||
|
|
m_Count = m_ReCount/2;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_out = -1;
|
|||
|
|
m_Count = m_ReCount * (1 + ((220 * bsize)/(m_SampFreq)));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double CFSKMOD::Do(int echo){
|
|||
|
|
if( m_CharWaitDiddle && m_CharWaitCount ){
|
|||
|
|
m_CharWaitCount--;
|
|||
|
|
}
|
|||
|
|
if( m_DisDiddle > 0 ) m_DisDiddle--;
|
|||
|
|
if( sys.m_TxPort && m_FSKCount ) m_FSKCount--;
|
|||
|
|
if( !m_Count ){
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
switch(m_mode){
|
|||
|
|
case 0: // <20>X<EFBFBD>^<5E>[<5B>g<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD>o<EFBFBD><6F>
|
|||
|
|
if( sys.m_TxPort == txTXD ) FSKDeff = m_cnt - FSKCount;
|
|||
|
|
if( !m_CharWaitDiddle ){
|
|||
|
|
if( m_CharWaitCount ){
|
|||
|
|
m_CharWaitCount--;
|
|||
|
|
m_out = 1;
|
|||
|
|
m_Count = 1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
else if( m_CharWait && m_cnt ){
|
|||
|
|
m_CharWaitCount = m_CharWait * m_ReCount/3;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
_try:;
|
|||
|
|
if( m_cnt &&
|
|||
|
|
((!m_CharWaitDiddle) || (!m_CharWaitCount)) &&
|
|||
|
|
((sys.m_TxPort != txTXD) || (FSKCount <= m_cnt) || (m_FSKCount) || (m_Buff[m_rp]==0xff) || (m_Buff[m_rp]==0xfe) )
|
|||
|
|
){
|
|||
|
|
m_WaitTimerCount = 4;
|
|||
|
|
m_idle = 0;
|
|||
|
|
m_out = 0;
|
|||
|
|
if( m_figout && (m_fig == 0x1b) && (m_Buff[m_rp]!=0x1f) ){
|
|||
|
|
m_Data = 0x1b;
|
|||
|
|
if( !echo ){
|
|||
|
|
pDem->WriteData(m_Data);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( sys.m_TxPort == txTXDOnly ){ // FSK Only<6C><79><EFBFBD>̓<EFBFBD><CC93><EFBFBD>
|
|||
|
|
#if 0
|
|||
|
|
while( FSKCount1 == FSKCount2 ){
|
|||
|
|
::Sleep(10);
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
FSKCount2++;
|
|||
|
|
}
|
|||
|
|
m_Data = m_Buff[m_rp];
|
|||
|
|
if( m_Data == 0xff ){ // <20>}<7D>[<5B>N<EFBFBD>M<EFBFBD><4D><EFBFBD><EFBFBD><EFBFBD>M
|
|||
|
|
m_out = 1;
|
|||
|
|
m_Count = m_ReCount * 3;
|
|||
|
|
m_cnt--;
|
|||
|
|
m_rp++;
|
|||
|
|
if( m_rp >= MODBUFMAX ) m_rp = 0;
|
|||
|
|
m_CharWaitCount = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
else if( m_Data == 0xfe ){ // <20>L<EFBFBD><4C><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>ؒf
|
|||
|
|
m_out = -1;
|
|||
|
|
m_Count = m_ReCount * 3;
|
|||
|
|
m_cnt--;
|
|||
|
|
m_rp++;
|
|||
|
|
if( m_rp >= MODBUFMAX ) m_rp = 0;
|
|||
|
|
m_CharWaitCount = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
else if( m_Data == 0xfd ){ // Dis Diddle
|
|||
|
|
m_DisDiddle = -1;
|
|||
|
|
m_cnt--;
|
|||
|
|
m_rp++;
|
|||
|
|
if( m_rp >= MODBUFMAX ) m_rp = 0;
|
|||
|
|
goto _try;
|
|||
|
|
}
|
|||
|
|
else if( m_Data == 0xfc ){ // Enb Diddle
|
|||
|
|
m_DisDiddle = 0;
|
|||
|
|
m_cnt--;
|
|||
|
|
m_rp++;
|
|||
|
|
if( m_rp >= MODBUFMAX ) m_rp = 0;
|
|||
|
|
goto _try;
|
|||
|
|
}
|
|||
|
|
else if( (m_Data == 0x1b)||(m_Data == 0x1f) ){
|
|||
|
|
m_fig = m_Data;
|
|||
|
|
}
|
|||
|
|
m_cnt--;
|
|||
|
|
m_rp++;
|
|||
|
|
if( m_rp >= MODBUFMAX ) m_rp = 0;
|
|||
|
|
if( !echo ){
|
|||
|
|
pDem->WriteData(m_Data);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
m_figout = 0;
|
|||
|
|
m_DataCount = m_BitLen;
|
|||
|
|
m_SumParity = 0;
|
|||
|
|
m_mode++;
|
|||
|
|
}
|
|||
|
|
else if( m_Data == 0x00fe ){
|
|||
|
|
m_idle = 1;
|
|||
|
|
m_out = -1;
|
|||
|
|
m_Count = m_ReCount * 50;
|
|||
|
|
m_Data = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
else if( (m_BitLen < 6) && ((m_diddle && !m_DisDiddle) || ((sys.m_TxPort == txTXD)&& m_cnt)) ){
|
|||
|
|
// else if( m_diddle && (!m_DisDiddle || ((sys.m_TxPort == txTXD)&& m_cnt) ) ){
|
|||
|
|
// else if( m_diddle && !m_DisDiddle ){
|
|||
|
|
#if 0
|
|||
|
|
if( sys.m_TxPort == txTXDOnly ){
|
|||
|
|
::Sleep((m_ReCount * m_BitLen)*1000/m_SampFreq);
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
if( !m_cnt ) m_idle = 1;
|
|||
|
|
m_out = 0;
|
|||
|
|
switch(m_diddle){
|
|||
|
|
case 1: // BLK
|
|||
|
|
if( m_RandomDiddle && !(rand() & 3) ){
|
|||
|
|
m_Data = 0x1f;
|
|||
|
|
if( m_BitLen <= 6 ) m_figout = 1;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_Data = 0x00;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
default: // LTR
|
|||
|
|
if( m_RandomDiddle && !(rand() & 3) ){
|
|||
|
|
m_Data = 0x00;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_Data = 0x1f;
|
|||
|
|
if( m_BitLen <= 6 ) m_figout = 1;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
m_DataCount = m_BitLen;
|
|||
|
|
m_SumParity = 0;
|
|||
|
|
m_mode++;
|
|||
|
|
if( !m_CharWaitDiddle ){
|
|||
|
|
if( (sys.m_LWait == 2) || m_cnt ){
|
|||
|
|
m_CharWaitCount = m_CharWait * m_ReCount/3;
|
|||
|
|
}
|
|||
|
|
else if( m_DiddleWait ){
|
|||
|
|
m_CharWaitCount = m_DiddleWait * m_ReCount/3;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_CharWaitCount = 0;
|
|||
|
|
}
|
|||
|
|
if( sys.m_LWait != 2 ){
|
|||
|
|
if( m_WaitTimer ){
|
|||
|
|
if( !m_WaitTimerCount ){
|
|||
|
|
m_CharWaitCount = 0;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_WaitTimerCount--;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( !m_cnt ) m_idle = 1;
|
|||
|
|
m_out = 1;
|
|||
|
|
m_Count = 1;
|
|||
|
|
#if 0
|
|||
|
|
if( sys.m_TxPort == txTXDOnly ){
|
|||
|
|
::Sleep(11);
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
if( m_CharWaitDiddle && (!m_CharWaitCount) ){
|
|||
|
|
if( m_Data != 0x1b ){
|
|||
|
|
m_CharWaitCount = m_CharWait * m_ReCount/3;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 1: // <20><><EFBFBD><EFBFBD><EFBFBD>o<EFBFBD><6F>
|
|||
|
|
if( m_DataCount ){
|
|||
|
|
switch(m_BitLen){
|
|||
|
|
case 6:
|
|||
|
|
m_out = (m_Data & 0x20) ? 1 : 0;
|
|||
|
|
break;
|
|||
|
|
case 7:
|
|||
|
|
m_out = (m_Data & 0x40) ? 1 : 0;
|
|||
|
|
break;
|
|||
|
|
case 8:
|
|||
|
|
m_out = (m_Data & 0x80) ? 1 : 0;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
m_out = (m_Data & 0x10) ? 1 : 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
m_Data = BYTE(m_Data << 1);
|
|||
|
|
m_DataCount--;
|
|||
|
|
if( m_out ) m_SumParity++;
|
|||
|
|
}
|
|||
|
|
else { // <20>X<EFBFBD>g<EFBFBD>b<EFBFBD>v<EFBFBD>r<EFBFBD>b<EFBFBD>g
|
|||
|
|
if( m_Parity ){
|
|||
|
|
m_mode++;
|
|||
|
|
switch(m_Parity){
|
|||
|
|
case 1: // Even
|
|||
|
|
m_out = m_SumParity & 1 ? 0 : 1;
|
|||
|
|
break;
|
|||
|
|
case 2: // Odd
|
|||
|
|
m_out = m_SumParity & 1 ? 1 : 0;
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
m_out = 1;
|
|||
|
|
break;
|
|||
|
|
case 4:
|
|||
|
|
m_out = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_mode++;
|
|||
|
|
goto _nx;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
_nx:;
|
|||
|
|
m_out = 1;
|
|||
|
|
m_mode++;
|
|||
|
|
switch(m_StopLen){
|
|||
|
|
case 0: // 1bit
|
|||
|
|
m_Count = 1;
|
|||
|
|
break;
|
|||
|
|
case 1: // 1.5bit
|
|||
|
|
case 3:
|
|||
|
|
case 4:
|
|||
|
|
m_Count = (m_ReCount/2) - 1;
|
|||
|
|
break;
|
|||
|
|
case 2: // 2bit
|
|||
|
|
m_Count = m_ReCount - 1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 3: // <20>X<EFBFBD>g<EFBFBD>b<EFBFBD>v<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD>I<EFBFBD><49>
|
|||
|
|
m_mode = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
m_Count--;
|
|||
|
|
double d;
|
|||
|
|
if( m_lpf ){ // GMSK
|
|||
|
|
if( m_inv ){
|
|||
|
|
d = m_out ? 0 : 1;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
d = m_out;
|
|||
|
|
}
|
|||
|
|
d = avgLPF.Avg(d);
|
|||
|
|
d = vco.Do(d) * m_OutputGain;
|
|||
|
|
}
|
|||
|
|
else { // AFSK
|
|||
|
|
if( m_inv ){
|
|||
|
|
d = vco.Do(m_out ? 0 : 1) * m_OutputGain;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
d = vco.Do(m_out) * m_OutputGain;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( m_out < 0 ) d = 0;
|
|||
|
|
if( m_bpf ){
|
|||
|
|
d = DoFIR(HBPF, ZBPF, d, m_bpftap);
|
|||
|
|
}
|
|||
|
|
return d * m_Amp.Do(m_AmpVal);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
// CFSKDEM<45>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CFSKDEM::CFSKDEM()
|
|||
|
|
{
|
|||
|
|
m_OverFlow = 0;
|
|||
|
|
m_lpf = 0;
|
|||
|
|
m_lpfOrder = 5;
|
|||
|
|
SetLPFFreq(40.0);
|
|||
|
|
|
|||
|
|
m_pll.SetSampleFreq(DemSamp);
|
|||
|
|
m_Phase.SetSampleFreq(DemSamp);
|
|||
|
|
|
|||
|
|
memset(ZMark, 0, sizeof(ZMark));
|
|||
|
|
memset(ZSpace, 0, sizeof(ZSpace));
|
|||
|
|
memset(HMark, 0, sizeof(HMark));
|
|||
|
|
memset(HSpace, 0, sizeof(HSpace));
|
|||
|
|
i2 = 0;
|
|||
|
|
// o1 = o2 = 0;
|
|||
|
|
Count = 0;
|
|||
|
|
|
|||
|
|
SetSmoozFreq(70.0);
|
|||
|
|
avgMark.SetCount(m_Smooz);
|
|||
|
|
avgSpace.SetCount(m_Smooz);
|
|||
|
|
|
|||
|
|
m_BitLen = 5;
|
|||
|
|
m_StopLen = 4; // 0-1bit, 1-1.5bit, 2-2bit, 3-1bit, 4-1.42bit
|
|||
|
|
m_Parity = 0;
|
|||
|
|
m_SumParity = 0;
|
|||
|
|
|
|||
|
|
m_mode = 0;
|
|||
|
|
m_DataCount = 0;
|
|||
|
|
|
|||
|
|
m_inv = 0;
|
|||
|
|
m_sq = 0;
|
|||
|
|
m_SQLevel = 600.0;
|
|||
|
|
m_Tap = 72;
|
|||
|
|
m_FilWidth = GetFilWidth(m_Tap);
|
|||
|
|
|
|||
|
|
m_wp = 0;
|
|||
|
|
m_rp = 0;
|
|||
|
|
m_BufCount = 0;
|
|||
|
|
|
|||
|
|
SetBaudRate(45.45);
|
|||
|
|
|
|||
|
|
m_MarkFreq = 2125;
|
|||
|
|
m_SpaceFreq = 2295;
|
|||
|
|
SetMarkFreq(2125);
|
|||
|
|
SetSpaceFreq(2295);
|
|||
|
|
|
|||
|
|
m_dMark = 0;
|
|||
|
|
m_dSpace = 0;
|
|||
|
|
|
|||
|
|
m_Scope = 0;
|
|||
|
|
m_majority = 1;
|
|||
|
|
m_ignoreFream = 0;
|
|||
|
|
m_XYScope = 0;
|
|||
|
|
SetIIR(60.0);
|
|||
|
|
m_Limit = 1;
|
|||
|
|
m_LimitGain = 10.0;
|
|||
|
|
|
|||
|
|
m_deff = 0;
|
|||
|
|
m_avgdeff = 0;
|
|||
|
|
|
|||
|
|
m_sqcount = 0;
|
|||
|
|
// SmoozSQ.SetCount(4);
|
|||
|
|
SmoozSQ.SetCount(8);
|
|||
|
|
|
|||
|
|
m_LimitOverSampling = 0;
|
|||
|
|
|
|||
|
|
m_Tick = 0;
|
|||
|
|
m_atcPLL.m_Max = 12;
|
|||
|
|
|
|||
|
|
m_LimitAGC = 1;
|
|||
|
|
m_limitMax = 1;
|
|||
|
|
m_limitMin = -1;
|
|||
|
|
m_d = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKDEM::SetIIR(double bw)
|
|||
|
|
{
|
|||
|
|
m_iirfw = bw;
|
|||
|
|
m_iirm.SetFreq(m_AFCMarkFreq, DemSamp, m_iirfw);
|
|||
|
|
m_iirs.SetFreq(m_AFCSpaceFreq, DemSamp, m_iirfw);
|
|||
|
|
m_pll.SetFreeFreq(m_AFCMarkFreq, m_AFCSpaceFreq);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKDEM::SetBaudRate(double b)
|
|||
|
|
{
|
|||
|
|
if( b >= 1.0 ){
|
|||
|
|
m_BaudRate = b;
|
|||
|
|
m_Count = m_ReCount = int(DemSamp/b + 0.5);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKDEM::SetSmoozFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_SmoozFreq = f;
|
|||
|
|
m_Smooz = int(DemSamp / f + 0.5);
|
|||
|
|
|
|||
|
|
avgMark.SetCount(m_Smooz);
|
|||
|
|
avgSpace.SetCount(m_Smooz);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKDEM::SetLPFFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_lpffreq = f;
|
|||
|
|
LpfMark.MakeIIR(f, DemSamp, m_lpfOrder, 0, 1.0);
|
|||
|
|
LpfSpace.MakeIIR(f, DemSamp, m_lpfOrder, 0, 1.0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKDEM::SetMarkFreq(double d)
|
|||
|
|
{
|
|||
|
|
m_SetMarkFreq = m_AFCMarkFreq = m_MarkFreq = d;
|
|||
|
|
MakeFilter(HMark, m_Tap, ffBPF, DemSamp, m_MarkFreq-m_FilWidth, m_MarkFreq+m_FilWidth, 60, 1.0);
|
|||
|
|
SetIIR(m_iirfw);
|
|||
|
|
m_Phase.SetCarrierFreq(m_AFCMarkFreq);
|
|||
|
|
if( m_AFCSpaceFreq > m_AFCMarkFreq ) m_Phase.SetShift(m_AFCSpaceFreq - m_AFCMarkFreq);
|
|||
|
|
m_AA6YQ.SetMarkFreq(m_AFCMarkFreq);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKDEM::SetSpaceFreq(double d)
|
|||
|
|
{
|
|||
|
|
m_SetSpaceFreq = m_AFCSpaceFreq = m_SpaceFreq = d;
|
|||
|
|
MakeFilter(HSpace, m_Tap, ffBPF, DemSamp, m_SpaceFreq-m_FilWidth, m_SpaceFreq+m_FilWidth, 60, 1.0);
|
|||
|
|
SetIIR(m_iirfw);
|
|||
|
|
m_Phase.SetCarrierFreq(m_AFCMarkFreq);
|
|||
|
|
if( m_AFCSpaceFreq > m_AFCMarkFreq ) m_Phase.SetShift(m_AFCSpaceFreq - m_AFCMarkFreq);
|
|||
|
|
m_AA6YQ.SetSpaceFreq(m_AFCSpaceFreq);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKDEM::AFCMarkFreq(double d)
|
|||
|
|
{
|
|||
|
|
if( d != m_MarkFreq ){
|
|||
|
|
m_MarkFreq = d;
|
|||
|
|
if( fabs(d - m_AFCMarkFreq) >= (m_type ? 10.0 : 5.0) ){
|
|||
|
|
m_AFCMarkFreq = d;
|
|||
|
|
MakeFilter(HMark, m_Tap, ffBPF, DemSamp, m_MarkFreq-m_FilWidth, m_MarkFreq+m_FilWidth, 60, 1.0);
|
|||
|
|
SetIIR(m_iirfw);
|
|||
|
|
m_Phase.SetCarrierFreq(m_AFCMarkFreq);
|
|||
|
|
}
|
|||
|
|
m_AA6YQ.SetMarkFreqByAFC(d);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKDEM::AFCSpaceFreq(double d)
|
|||
|
|
{
|
|||
|
|
if( d != m_SpaceFreq ){
|
|||
|
|
m_SpaceFreq = d;
|
|||
|
|
if( fabs(d - m_AFCSpaceFreq) >= (m_type ? 10.0 : 5.0) ){
|
|||
|
|
m_AFCSpaceFreq = d;
|
|||
|
|
MakeFilter(HSpace, m_Tap, ffBPF, DemSamp, m_SpaceFreq-m_FilWidth, m_SpaceFreq+m_FilWidth, 60, 1.0);
|
|||
|
|
SetIIR(m_iirfw);
|
|||
|
|
}
|
|||
|
|
m_AA6YQ.SetSpaceFreqByAFC(d);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double CFSKDEM::GetFilWidth(int tap)
|
|||
|
|
{
|
|||
|
|
double Width;
|
|||
|
|
|
|||
|
|
if( tap >= 256 ){
|
|||
|
|
Width = 20;
|
|||
|
|
}
|
|||
|
|
else if( tap >= 192 ){
|
|||
|
|
Width = 30;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
Width = 40;
|
|||
|
|
}
|
|||
|
|
return Width;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKDEM::SetFilterTap(int tap)
|
|||
|
|
{
|
|||
|
|
if( tap != m_Tap ){
|
|||
|
|
m_Tap = tap;
|
|||
|
|
m_FilWidth = GetFilWidth(tap);
|
|||
|
|
MakeFilter(HSpace, m_Tap, ffBPF, DemSamp, m_SpaceFreq-m_FilWidth, m_SpaceFreq+m_FilWidth, 60, 1.0);
|
|||
|
|
MakeFilter(HMark, m_Tap, ffBPF, DemSamp, m_MarkFreq-m_FilWidth, m_MarkFreq+m_FilWidth, 60, 1.0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKDEM::WriteData(BYTE d)
|
|||
|
|
{
|
|||
|
|
if( m_BufCount < DEMBUFMAX ){
|
|||
|
|
m_Buff[m_wp] = d;
|
|||
|
|
m_wp++;
|
|||
|
|
m_BufCount++;
|
|||
|
|
if( m_wp >= DEMBUFMAX ) m_wp = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKDEM::DoFSK(void)
|
|||
|
|
{
|
|||
|
|
int b;
|
|||
|
|
|
|||
|
|
if( m_Tick ){
|
|||
|
|
Tick.Write(m_dMark);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if( m_dMark >= m_dSpace ){ // <20>}<7D>[<5B>N<EFBFBD>̎<EFBFBD>
|
|||
|
|
b = m_inv ? 0 : 1;
|
|||
|
|
}
|
|||
|
|
else { // <20>X<EFBFBD>y<EFBFBD>[<5B>X<EFBFBD>̎<EFBFBD>
|
|||
|
|
b = m_inv ? 1 : 0;
|
|||
|
|
}
|
|||
|
|
double deff = fabs(m_dMark - m_dSpace);
|
|||
|
|
|
|||
|
|
// Adjustment for the level meter, added by JE3HHT (Ver 1.68A)
|
|||
|
|
if( m_AA6YQ.m_fEnabled && (m_type != 3) ){
|
|||
|
|
deff *= 4;
|
|||
|
|
deff -= 30000;
|
|||
|
|
}
|
|||
|
|
// till end
|
|||
|
|
|
|||
|
|
if( m_deff < deff ) m_deff = deff;
|
|||
|
|
if( !m_sqcount ){
|
|||
|
|
m_avgdeff = SmoozSQ.Avg(m_deff);
|
|||
|
|
m_deff = 0;
|
|||
|
|
m_sqcount = DemSamp / 10;
|
|||
|
|
}
|
|||
|
|
m_sqcount--;
|
|||
|
|
|
|||
|
|
if( m_sq ){
|
|||
|
|
if( !m_mode ){
|
|||
|
|
if( m_Limit ){ // <20><><EFBFBD>M<EFBFBD><4D>
|
|||
|
|
if( (m_SQLevel * 10.0) > m_avgdeff ){
|
|||
|
|
b = 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else { // <20><><EFBFBD>M<EFBFBD><4D>
|
|||
|
|
if( m_SQLevel > m_avgdeff ){
|
|||
|
|
b = 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// m_Bit = b;
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeSync.WriteData(m_Count ? 0 : 8192.0);
|
|||
|
|
m_ScopeBit.WriteData(b ? 8192.0 : 0);
|
|||
|
|
}
|
|||
|
|
switch(m_mode){
|
|||
|
|
case 0: // <20>X<EFBFBD>^<5E>[<5B>g<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD><67><EFBFBD>o<EFBFBD>҂<EFBFBD>
|
|||
|
|
if( !b ){
|
|||
|
|
m_Count = m_ReCount/2;
|
|||
|
|
if( m_majority ){
|
|||
|
|
m_mark = m_space = 0;
|
|||
|
|
m_mode = 256; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>W<EFBFBD>b<EFBFBD>N
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_mode++;
|
|||
|
|
}
|
|||
|
|
#if BITDEBUG
|
|||
|
|
m_bitCountA = m_bitCount;
|
|||
|
|
m_bitCount = 0;
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
// <20>ʏ탍<CA8F>W<EFBFBD>b<EFBFBD>N<EFBFBD>ɂ<EFBFBD><C982>锻<EFBFBD><E994BB>
|
|||
|
|
case 1: // <20>X<EFBFBD>^<5E>[<5B>g<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD><67><EFBFBD>o<EFBFBD>҂<EFBFBD>(Half)
|
|||
|
|
if( b ){
|
|||
|
|
m_mode = 0;
|
|||
|
|
}
|
|||
|
|
else if( !m_Count ){
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeSync.UpdateData(-8192.0); // <20>X<EFBFBD>^<5E>[<5B>g<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD>ʒu
|
|||
|
|
}
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
m_Data = 0;
|
|||
|
|
m_DataCount = m_BitLen;
|
|||
|
|
m_SumParity = 0;
|
|||
|
|
m_mode++;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 2: // <20><><EFBFBD><EFBFBD><EFBFBD>L<EFBFBD>^<5E><>
|
|||
|
|
if( !m_Count ){
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
m_Data = BYTE(m_Data << 1);
|
|||
|
|
m_Data |= BYTE(b);
|
|||
|
|
m_DataCount--;
|
|||
|
|
if( !m_DataCount ){
|
|||
|
|
if( m_Parity ){
|
|||
|
|
m_mode++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_mode += 2;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( m_Parity ){
|
|||
|
|
m_SumParity += b;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 3: // <20>p<EFBFBD><70><EFBFBD>e<EFBFBD>B<EFBFBD>r<EFBFBD>b<EFBFBD>g
|
|||
|
|
if( !m_Count ){
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
m_mode++;
|
|||
|
|
switch(m_Parity){
|
|||
|
|
case 1: // Even
|
|||
|
|
if( (!(m_SumParity & 1) ^ b) & 1 ) m_mode = 0; // <20>p<EFBFBD><70><EFBFBD>e<EFBFBD>B<EFBFBD>G<EFBFBD><47><EFBFBD>[
|
|||
|
|
break;
|
|||
|
|
case 2: // Odd
|
|||
|
|
if( ((m_SumParity & 1) ^ b) & 1 ) m_mode = 0; // <20>p<EFBFBD><70><EFBFBD>e<EFBFBD>B<EFBFBD>G<EFBFBD><47><EFBFBD>[
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
if( !b ) m_mode = 0;
|
|||
|
|
break;
|
|||
|
|
case 4:
|
|||
|
|
if( b ) m_mode = 0;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if( !m_mode ){ // <20>p<EFBFBD><70><EFBFBD>e<EFBFBD>B<EFBFBD>G<EFBFBD><47><EFBFBD>[
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
m_mode = 7;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 4: // <20>X<EFBFBD>g<EFBFBD>b<EFBFBD>v<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD>̊m<CC8A>F
|
|||
|
|
if( !m_Count ){
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeSync.UpdateData(-4096.0); // Stopbit<69>ʒu
|
|||
|
|
}
|
|||
|
|
if( b || m_ignoreFream ){
|
|||
|
|
if( m_BufCount < DEMBUFMAX ){
|
|||
|
|
m_Buff[m_wp] = m_Data;
|
|||
|
|
m_wp++;
|
|||
|
|
m_BufCount++;
|
|||
|
|
if( m_wp >= DEMBUFMAX ) m_wp = 0;
|
|||
|
|
}
|
|||
|
|
switch(m_StopLen){
|
|||
|
|
case 2: // 2bit
|
|||
|
|
m_Count = (m_ReCount * 11/8); // 23/16bit<69><74><EFBFBD>Ԃ̃E<CC83>G<EFBFBD>C<EFBFBD>g
|
|||
|
|
break;
|
|||
|
|
case 1: // 1.5bit
|
|||
|
|
m_Count = (m_ReCount * 7/8); // 15/16bit<69><74><EFBFBD>Ԃ̃E<CC83>G<EFBFBD>C<EFBFBD>g
|
|||
|
|
break;
|
|||
|
|
case 4: // 1.42bit
|
|||
|
|
m_Count = (m_ReCount * 4/5); // 0.82bit<EFBFBD><EFBFBD><EFBFBD>Ԃ̃E<EFBFBD>G<EFBFBD>C<EFBFBD>g
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
default: // 1bit
|
|||
|
|
m_Count = (m_ReCount * 3/8); // 7/16bit<69><74><EFBFBD>Ԃ̃E<CC83>G<EFBFBD>C<EFBFBD>g
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
m_mode++;
|
|||
|
|
}
|
|||
|
|
if( !b ){ // <20>t<EFBFBD><74><EFBFBD>[<5B>~<7E><><EFBFBD>O<EFBFBD>G<EFBFBD><47><EFBFBD>[
|
|||
|
|
m_mode = 8;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 5: // <20>X<EFBFBD>g<EFBFBD>b<EFBFBD>v<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD>I<EFBFBD><49><EFBFBD>҂<EFBFBD><D282>^<5E>C<EFBFBD>}<7D>[
|
|||
|
|
if( !m_Count ){
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeSync.UpdateData(-4096.0); // Stopbits<74>I<EFBFBD><49><EFBFBD>ʒu
|
|||
|
|
}
|
|||
|
|
m_mode++;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 6: // <20>X<EFBFBD>g<EFBFBD>b<EFBFBD>v<EFBFBD>I<EFBFBD><49><EFBFBD>҂<EFBFBD>
|
|||
|
|
if( b ){
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
}
|
|||
|
|
else { // <20><><EFBFBD>̃X<CC83>^<5E>[<5B>g<EFBFBD>r<EFBFBD>b<EFBFBD>g
|
|||
|
|
m_Count = m_ReCount/2;
|
|||
|
|
m_mode = 0;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 7: // <20>p<EFBFBD><70><EFBFBD>e<EFBFBD>B<EFBFBD>G<EFBFBD><47><EFBFBD>[<5B><>
|
|||
|
|
if( !m_Count ){
|
|||
|
|
m_ScopeSync.UpdateData(-4096.0); // Stopbit<69>ʒu
|
|||
|
|
m_mode--;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 8: // <20>t<EFBFBD><74><EFBFBD>[<5B>~<7E><><EFBFBD>O<EFBFBD>G<EFBFBD><47><EFBFBD>[<5B><>
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
if( b ){
|
|||
|
|
m_mode = 0;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>W<EFBFBD>b<EFBFBD>N<EFBFBD>ɂ<EFBFBD><C982><EFBFBD><EFBFBD>f<EFBFBD>[<5B>^<5E><><EFBFBD>肱<EFBFBD><E882B1>
|
|||
|
|
case 256: // <20>X<EFBFBD>^<5E>[<5B>g<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD><67><EFBFBD>o<EFBFBD>҂<EFBFBD>(Half)
|
|||
|
|
if( b ){m_mark++;} else {m_space++;}
|
|||
|
|
if( !m_Count ){
|
|||
|
|
b = (m_mark >= m_space) ? 1 : 0;
|
|||
|
|
if( b ){
|
|||
|
|
m_mode = 0;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeSync.UpdateData(-8192.0); // <20>X<EFBFBD>^<5E>[<5B>g<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD>ʒu
|
|||
|
|
}
|
|||
|
|
m_Count = m_ReCount/2;
|
|||
|
|
m_mode++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 257: // <20>X<EFBFBD>^<5E>[<5B>g<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD>I<EFBFBD><49><EFBFBD>҂<EFBFBD>
|
|||
|
|
if( !m_Count ){
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeSync.UpdateData(-8192.0); // <20>X<EFBFBD>^<5E>[<5B>g<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD>ʒu
|
|||
|
|
}
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
m_mark = m_space = 0;
|
|||
|
|
m_Data = 0;
|
|||
|
|
m_DataCount = m_BitLen;
|
|||
|
|
m_SumParity = 0;
|
|||
|
|
m_mode++;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 258: // <20><><EFBFBD><EFBFBD><EFBFBD>L<EFBFBD>^<5E><>
|
|||
|
|
if( b ){m_mark++;} else {m_space++;}
|
|||
|
|
if( !m_Count ){
|
|||
|
|
b = (m_mark >= m_space) ? 1 : 0;
|
|||
|
|
m_mark = m_space = 0;
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
m_Data = BYTE(m_Data << 1);
|
|||
|
|
m_Data |= BYTE(b);
|
|||
|
|
m_DataCount--;
|
|||
|
|
if( !m_DataCount ){
|
|||
|
|
if( m_Parity ){
|
|||
|
|
m_mode++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
switch(m_StopLen){
|
|||
|
|
case 2: // 2bit
|
|||
|
|
case 1: // 1.5bit
|
|||
|
|
case 4: // 1.42bit
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
default: // 1bit
|
|||
|
|
m_Count = m_ReCount * 7 / 8;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
m_mode += 2;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( m_Parity ){
|
|||
|
|
m_SumParity += b;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 259: // <20>p<EFBFBD><70><EFBFBD>e<EFBFBD>B<EFBFBD>r<EFBFBD>b<EFBFBD>g
|
|||
|
|
if( b ){
|
|||
|
|
m_mark++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_space++;
|
|||
|
|
}
|
|||
|
|
if( !m_Count ){
|
|||
|
|
b = (m_mark >= m_space) ? 1 : 0;
|
|||
|
|
m_mark = m_space = 0;
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
m_mode++;
|
|||
|
|
switch(m_Parity){
|
|||
|
|
case 1: // Even
|
|||
|
|
if( (!(m_SumParity & 1) ^ b) & 1 ) m_mode = 0; // <20>p<EFBFBD><70><EFBFBD>e<EFBFBD>B<EFBFBD>G<EFBFBD><47><EFBFBD>[
|
|||
|
|
break;
|
|||
|
|
case 2: // Odd
|
|||
|
|
if( ((m_SumParity & 1) ^ b) & 1 ) m_mode = 0; // <20>p<EFBFBD><70><EFBFBD>e<EFBFBD>B<EFBFBD>G<EFBFBD><47><EFBFBD>[
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
if( !b ) m_mode = 0;
|
|||
|
|
break;
|
|||
|
|
case 4:
|
|||
|
|
if( b ) m_mode = 0;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if( !m_mode ){ // <20>p<EFBFBD><70><EFBFBD>e<EFBFBD>B<EFBFBD>G<EFBFBD><47><EFBFBD>[
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
m_mode = 7;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
switch(m_StopLen){
|
|||
|
|
case 2: // 2bit
|
|||
|
|
case 1: // 1.5bit
|
|||
|
|
case 4: // 1.42bit
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
default: // 1bit
|
|||
|
|
m_Count = m_ReCount * 7 / 8;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 260: // <20>X<EFBFBD>g<EFBFBD>b<EFBFBD>v<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD>̊m<CC8A>F
|
|||
|
|
if( b ){
|
|||
|
|
m_mark++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_space++;
|
|||
|
|
}
|
|||
|
|
if( !m_Count ){
|
|||
|
|
b = (m_mark >= m_space) ? 1 : 0;
|
|||
|
|
m_mark = m_space = 0;
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeSync.UpdateData(-4096.0); // Stopbit<69>ʒu
|
|||
|
|
}
|
|||
|
|
if( b || m_ignoreFream ){
|
|||
|
|
if( m_BufCount < DEMBUFMAX ){
|
|||
|
|
m_Buff[m_wp] = m_Data;
|
|||
|
|
m_wp++;
|
|||
|
|
m_BufCount++;
|
|||
|
|
if( m_wp >= DEMBUFMAX ) m_wp = 0;
|
|||
|
|
}
|
|||
|
|
switch(m_StopLen){
|
|||
|
|
case 2: // 2bit
|
|||
|
|
m_Count = (m_ReCount * 7/8);
|
|||
|
|
break;
|
|||
|
|
case 1: // 1.5bit
|
|||
|
|
m_Count = (m_ReCount * 3/8);
|
|||
|
|
break;
|
|||
|
|
case 4: // 1.42bit
|
|||
|
|
m_Count = (m_ReCount * 2/5);
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
default: // 1bit
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeSync.UpdateData(-4096.0); // Stopbits<74>I<EFBFBD><49><EFBFBD>ʒu
|
|||
|
|
}
|
|||
|
|
m_mode = -1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
m_mode++;
|
|||
|
|
}
|
|||
|
|
if( !b ){ // <20>t<EFBFBD><74><EFBFBD>[<5B>~<7E><><EFBFBD>O<EFBFBD>G<EFBFBD><47><EFBFBD>[
|
|||
|
|
m_mode = 8;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 261: // <20>X<EFBFBD>g<EFBFBD>b<EFBFBD>v<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD>I<EFBFBD><49><EFBFBD>҂<EFBFBD><D282>^<5E>C<EFBFBD>}<7D>[
|
|||
|
|
if( !m_Count ){
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeSync.UpdateData(-4096.0); // Stopbits<74>I<EFBFBD><49><EFBFBD>ʒu
|
|||
|
|
}
|
|||
|
|
m_mode++;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 262: // <20>X<EFBFBD>g<EFBFBD>b<EFBFBD>v<EFBFBD>I<EFBFBD><49><EFBFBD>҂<EFBFBD>
|
|||
|
|
if( b ){
|
|||
|
|
m_Count = m_ReCount;
|
|||
|
|
}
|
|||
|
|
else { // <20><><EFBFBD>̃X<CC83>^<5E>[<5B>g<EFBFBD>r<EFBFBD>b<EFBFBD>g
|
|||
|
|
m_Count = m_ReCount/2;
|
|||
|
|
m_mode = 0;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
};
|
|||
|
|
m_Count--;
|
|||
|
|
#if BITDEBUG
|
|||
|
|
m_bitCount++;
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFSKDEM::Do(double d)
|
|||
|
|
{
|
|||
|
|
if( m_AA6YQ.m_fEnabled ) d = m_AA6YQ.Do(d);
|
|||
|
|
double ds = d;
|
|||
|
|
|
|||
|
|
if( (d > 24578.0) || (d < -24578.0) ){
|
|||
|
|
m_OverFlow = 1;
|
|||
|
|
}
|
|||
|
|
if( m_Limit ){
|
|||
|
|
if( m_LimitAGC ){
|
|||
|
|
if( m_limitMax < d ) m_limitMax = d;
|
|||
|
|
if( m_limitMin > d ) m_limitMin = d;
|
|||
|
|
if( (d >= 0) && (m_d < 0) ){
|
|||
|
|
m_limitagc = (m_limitMax - m_limitMin);
|
|||
|
|
if( m_limitagc ){
|
|||
|
|
m_limitagc = (64.0 * 16384.0)/ m_limitagc;
|
|||
|
|
if( m_limitagc >= 4096.0 ) m_limitagc = 4096;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_limitagc = 200;
|
|||
|
|
}
|
|||
|
|
m_limitMax = 1;
|
|||
|
|
m_limitMin = -1;
|
|||
|
|
}
|
|||
|
|
m_d = d;
|
|||
|
|
if( m_LimitOverSampling ){
|
|||
|
|
d = OverLimit.Do(d, m_limitagc);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
d *= m_limitagc;
|
|||
|
|
if( d > 16384.0 ) d = 16384.0;
|
|||
|
|
if( d < -16384.0 ) d = -16384.0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( m_LimitOverSampling ){
|
|||
|
|
d = OverLimit.Do(d, m_LimitGain);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
d *= m_LimitGain;
|
|||
|
|
if( d > 16384.0 ) d = 16384.0;
|
|||
|
|
if( d < -16384.0 ) d = -16384.0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// if( m_AA6YQ.m_fEnabled ) d *= 0.3333; // Delete by JE3HHT (Ver1.68A)
|
|||
|
|
}
|
|||
|
|
if( (Count & 1) || (!DemOver) ){
|
|||
|
|
if( DemOver ) d = DECM2.Do(d, i2); // 1/2<>f<EFBFBD>V<EFBFBD><56><EFBFBD>[<5B>^
|
|||
|
|
|
|||
|
|
switch(m_type){
|
|||
|
|
case 2: // PLL
|
|||
|
|
{
|
|||
|
|
double dm = m_iirm.Do(d);
|
|||
|
|
double ds = m_iirs.Do(d);
|
|||
|
|
d = m_pll.Do(d);
|
|||
|
|
if( m_XYScope ){ // For XY-Scope
|
|||
|
|
m_XYScopeMark.WriteData(dm);
|
|||
|
|
m_XYScopeSpace.WriteData(ds);
|
|||
|
|
}
|
|||
|
|
if( m_Scope ){ // For Scope
|
|||
|
|
m_ScopeMark[0].WriteData(dm);
|
|||
|
|
m_ScopeSpace[0].WriteData(ds);
|
|||
|
|
}
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeMark[1].WriteData(m_pll.GetOut());
|
|||
|
|
m_ScopeSpace[1].WriteData(d);
|
|||
|
|
}
|
|||
|
|
d = m_atcPLL.Do(d + 8192.0) - 8192.0;
|
|||
|
|
if( d >= 0 ){
|
|||
|
|
m_dMark = d;
|
|||
|
|
m_dSpace = 0;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_dMark = 0;
|
|||
|
|
m_dSpace = -d;
|
|||
|
|
}
|
|||
|
|
// <20><><EFBFBD><EFBFBD>
|
|||
|
|
if( m_lpf ){
|
|||
|
|
m_dMark = LpfMark.Do(m_dMark);
|
|||
|
|
m_dSpace = LpfSpace.Do(m_dSpace);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_dMark = avgMark.Avg(m_dMark);
|
|||
|
|
m_dSpace = avgSpace.Avg(m_dSpace);
|
|||
|
|
}
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeMark[2].WriteData(m_dMark);
|
|||
|
|
m_ScopeSpace[2].WriteData(m_dSpace);
|
|||
|
|
}
|
|||
|
|
if( m_atc ){
|
|||
|
|
m_dMark = m_atcMark.Do(m_dMark);
|
|||
|
|
m_dSpace = m_atcSpace.Do(m_dSpace);
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeMark[3].WriteData(m_dMark);
|
|||
|
|
m_ScopeSpace[3].WriteData(m_dSpace);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
case 3: // FFT
|
|||
|
|
{
|
|||
|
|
m_Phase.DoFSK(ds);
|
|||
|
|
m_dMark = m_Phase.m_dm;
|
|||
|
|
m_dSpace = m_Phase.m_ds;
|
|||
|
|
|
|||
|
|
if( m_XYScope || m_Scope ){
|
|||
|
|
double dm = m_iirm.Do(d);
|
|||
|
|
double ds = m_iirs.Do(d);
|
|||
|
|
|
|||
|
|
if( m_XYScope ){ // For XY-Scope
|
|||
|
|
m_XYScopeMark.WriteData(dm);
|
|||
|
|
m_XYScopeSpace.WriteData(ds);
|
|||
|
|
}
|
|||
|
|
if( m_Scope ){ // For Scope
|
|||
|
|
m_ScopeMark[0].WriteData(dm);
|
|||
|
|
m_ScopeSpace[0].WriteData(ds);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// <20><><EFBFBD>g
|
|||
|
|
// m_dMark = fabs(m_dMark);
|
|||
|
|
// m_dSpace = fabs(m_dSpace);
|
|||
|
|
if( m_dMark < 0.0 ) m_dMark = -m_dMark;
|
|||
|
|
if( m_dSpace < 0.0 ) m_dSpace = -m_dSpace;
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeMark[1].WriteData(m_dMark);
|
|||
|
|
m_ScopeSpace[1].WriteData(m_dSpace);
|
|||
|
|
}
|
|||
|
|
// <20><><EFBFBD><EFBFBD>
|
|||
|
|
if( m_lpf ){
|
|||
|
|
m_dMark = LpfMark.Do(m_dMark);
|
|||
|
|
m_dSpace = LpfSpace.Do(m_dSpace);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_dMark = avgMark.Avg(m_dMark);
|
|||
|
|
m_dSpace = avgSpace.Avg(m_dSpace);
|
|||
|
|
}
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeMark[2].WriteData(m_dMark);
|
|||
|
|
m_ScopeSpace[2].WriteData(m_dSpace);
|
|||
|
|
}
|
|||
|
|
if( m_atc ){
|
|||
|
|
m_dMark = m_atcMark.Do(m_dMark);
|
|||
|
|
m_dSpace = m_atcSpace.Do(m_dSpace);
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeMark[3].WriteData(m_dMark);
|
|||
|
|
m_ScopeSpace[3].WriteData(m_dSpace);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
#if 1 // <20><><EFBFBD><EFBFBD><EFBFBD>v<EFBFBD>Z
|
|||
|
|
m_dMark /= (64*32768.0);
|
|||
|
|
m_dSpace /= (64*32768.0);
|
|||
|
|
#else
|
|||
|
|
m_dMark = m_dMark > 0.0 ? sqrt(m_dMark) : 0.0;
|
|||
|
|
m_dSpace = m_dSpace > 0.0 ? sqrt(m_dSpace) : 0.0;
|
|||
|
|
m_dMark *= (1.0/16.0);
|
|||
|
|
m_dSpace *= (1.0/16.0);
|
|||
|
|
#endif
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
default:
|
|||
|
|
{
|
|||
|
|
if( m_type ){ // FIR
|
|||
|
|
m_dMark = DoFIR(HMark, ZMark, d, m_Tap);
|
|||
|
|
m_dSpace = DoFIR(HSpace, ZSpace, d, m_Tap);
|
|||
|
|
}
|
|||
|
|
else { // IIR
|
|||
|
|
m_dMark = m_iirm.Do(d);
|
|||
|
|
m_dSpace = m_iirs.Do(d);
|
|||
|
|
}
|
|||
|
|
if( m_XYScope ){ // For XY-Scope
|
|||
|
|
m_XYScopeMark.WriteData(m_dMark);
|
|||
|
|
m_XYScopeSpace.WriteData(m_dSpace);
|
|||
|
|
}
|
|||
|
|
if( m_Scope ){ // For Scope
|
|||
|
|
m_ScopeMark[0].WriteData(m_dMark);
|
|||
|
|
m_ScopeSpace[0].WriteData(m_dSpace);
|
|||
|
|
}
|
|||
|
|
// <20><><EFBFBD>g
|
|||
|
|
// m_dMark = fabs(m_dMark);
|
|||
|
|
// m_dSpace = fabs(m_dSpace);
|
|||
|
|
if( m_dMark < 0 ) m_dMark = -m_dMark;
|
|||
|
|
if( m_dSpace < 0 ) m_dSpace = -m_dSpace;
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeMark[1].WriteData(m_dMark);
|
|||
|
|
m_ScopeSpace[1].WriteData(m_dSpace);
|
|||
|
|
}
|
|||
|
|
// <20><><EFBFBD><EFBFBD>
|
|||
|
|
if( m_lpf ){
|
|||
|
|
m_dMark = LpfMark.Do(m_dMark);
|
|||
|
|
m_dSpace = LpfSpace.Do(m_dSpace);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_dMark = avgMark.Avg(m_dMark);
|
|||
|
|
m_dSpace = avgSpace.Avg(m_dSpace);
|
|||
|
|
}
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeMark[2].WriteData(m_dMark);
|
|||
|
|
m_ScopeSpace[2].WriteData(m_dSpace);
|
|||
|
|
}
|
|||
|
|
if( m_atc ){
|
|||
|
|
m_dMark = m_atcMark.Do(m_dMark);
|
|||
|
|
m_dSpace = m_atcSpace.Do(m_dSpace);
|
|||
|
|
if( m_Scope ){
|
|||
|
|
m_ScopeMark[3].WriteData(m_dMark);
|
|||
|
|
m_ScopeSpace[3].WriteData(m_dSpace);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
DoFSK();
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
i2 = d;
|
|||
|
|
}
|
|||
|
|
Count++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CFSKDEM::GetData(void)
|
|||
|
|
{
|
|||
|
|
int r;
|
|||
|
|
if( m_BufCount ){
|
|||
|
|
r = m_Buff[m_rp];
|
|||
|
|
m_BufCount--;
|
|||
|
|
m_rp++;
|
|||
|
|
if( m_rp >= DEMBUFMAX ) m_rp = 0;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
r = -1;
|
|||
|
|
}
|
|||
|
|
return r;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
BCODETBL _TTY[]={ // S-BELL
|
|||
|
|
// 0x20 - 0x7f
|
|||
|
|
{0x04, 2}, {0x16, 1}, {0x11, 1}, {0x00, 2}, // !"#
|
|||
|
|
{0x12, 1}, {0x00, 2}, {0x0b, 1}, {0x1a, 1}, // $%&'
|
|||
|
|
{0x1e, 1}, {0x09, 1}, {0x00, 2}, {0x00, 2}, // ()*+
|
|||
|
|
{0x06, 1}, {0x18, 1}, {0x07, 1}, {0x17, 1}, // ,-./
|
|||
|
|
{0x0d, 1}, {0x1d, 1}, {0x19, 1}, {0x10, 1}, // 0123 30-33
|
|||
|
|
{0x0a, 1}, {0x01, 1}, {0x15, 1}, {0x1c, 1}, // 4567 34-37
|
|||
|
|
{0x0c, 1}, {0x03, 1}, {0x0e, 1}, {0x0f, 1}, // 89 38-3b
|
|||
|
|
{0x00, 2}, {0x00, 2}, {0x00, 2}, {0x13, 1}, // <=>? 3c-3f
|
|||
|
|
{0x00, 2}, {0x18, 0}, {0x13, 0}, {0x0e, 0}, // @ABC 40-43
|
|||
|
|
{0x12, 0}, {0x10, 0}, {0x16, 0}, {0x0b, 0}, // DEFG
|
|||
|
|
{0x05, 0}, {0x0c, 0}, {0x1a, 0}, {0x1e, 0}, // HIJK
|
|||
|
|
{0x09, 0}, {0x07, 0}, {0x06, 0}, {0x03, 0}, // LMNO
|
|||
|
|
{0x0d, 0}, {0x1d, 0}, {0x0a, 0}, {0x14, 0}, // PQRS
|
|||
|
|
{0x01, 0}, {0x1c, 0}, {0x0f, 0}, {0x19, 0}, // TUVW
|
|||
|
|
{0x17, 0}, {0x15, 0}, {0x11, 0}, {0x00, 2}, // XYZ[ 58-5b
|
|||
|
|
{0x00, 2}, {0x00, 2}, {0x00, 2}, {0x00, 2}, // \]^_
|
|||
|
|
{0x00, 2}, {0x18, 0}, {0x13, 0}, {0x0e, 0}, // @ABC 60-63
|
|||
|
|
{0x12, 0}, {0x10, 0}, {0x16, 0}, {0x0b, 0}, // DEFG
|
|||
|
|
{0x05, 0}, {0x0c, 0}, {0x1a, 0}, {0x1e, 0}, // HIJK
|
|||
|
|
{0x09, 0}, {0x07, 0}, {0x06, 0}, {0x03, 0}, // LMNO
|
|||
|
|
{0x0d, 0}, {0x1d, 0}, {0x0a, 0}, {0x14, 0}, // PQRS
|
|||
|
|
{0x01, 0}, {0x1c, 0}, {0x0f, 0}, {0x19, 0}, // TUVW
|
|||
|
|
{0x17, 0}, {0x15, 0}, {0x11, 0}, {0x00, 2}, // XYZ[ 78-7b
|
|||
|
|
{0x00, 2}, {0x00, 2}, {0x00, 2}, {0x00, 2}, // |{~
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const char _LTR[32]={
|
|||
|
|
0x00, 'T', 0x0d, 'O', ' ', 'H', 'N', 'M',
|
|||
|
|
0x0a, 'L', 'R', 'G', 'I', 'P', 'C', 'V',
|
|||
|
|
'E', 'Z', 'D', 'B', 'S', 'Y', 'F', 'X',
|
|||
|
|
'A', 'W', 'J', 0x00, 'U', 'Q', 'K', 0x00,
|
|||
|
|
};
|
|||
|
|
const char _FIG[32]={
|
|||
|
|
0x00, '5', 0x0d, '9', ' ', 'h', ',', '.',
|
|||
|
|
0x0a, ')', '4', '&', '8', '0', ':', ';',
|
|||
|
|
'3', '"', '$', '?', 's', '6', '!', '/',
|
|||
|
|
'-', '2', 0x27, 0x00, '7', '1', '(', 0x00,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
CRTTY::CRTTY()
|
|||
|
|
{
|
|||
|
|
m_outfig = 3;
|
|||
|
|
|
|||
|
|
m_fig = 0;
|
|||
|
|
m_uos = 0;
|
|||
|
|
|
|||
|
|
m_txuos = 1;
|
|||
|
|
SetCodeSet();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CRTTY::SetCodeSet(void)
|
|||
|
|
{
|
|||
|
|
memcpy(m_TBL, _TTY, sizeof(m_TBL));
|
|||
|
|
if( sys.m_CodeSet ){ // J-BELL
|
|||
|
|
m_TBL[7].Code = 0x14;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 11011 FIG
|
|||
|
|
// 11111 LTR
|
|||
|
|
char CRTTY::ConvAscii(int d)
|
|||
|
|
{
|
|||
|
|
char c = 0;
|
|||
|
|
d &= 0x1f;
|
|||
|
|
if( d == 0x1b ){ // FIG
|
|||
|
|
m_fig = 1;
|
|||
|
|
}
|
|||
|
|
else if( d == 0x1f ){ // LTR
|
|||
|
|
m_fig = 0;
|
|||
|
|
}
|
|||
|
|
else if( m_fig ){
|
|||
|
|
c = _FIG[d];
|
|||
|
|
if( sys.m_CodeSet ){
|
|||
|
|
switch(c){
|
|||
|
|
case 's':
|
|||
|
|
c = 0x27;
|
|||
|
|
break;
|
|||
|
|
case 0x27:
|
|||
|
|
c = 'j';
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( m_uos ){
|
|||
|
|
switch(c){
|
|||
|
|
case ' ':
|
|||
|
|
// case 0x0d:
|
|||
|
|
// case 0x0a:
|
|||
|
|
m_fig = 0;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
c = _LTR[d];
|
|||
|
|
}
|
|||
|
|
return c;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CRTTY::ConvRTTY(char d)
|
|||
|
|
{
|
|||
|
|
int fig = 2;
|
|||
|
|
int r = 0;
|
|||
|
|
switch(d){
|
|||
|
|
case '_':
|
|||
|
|
r = 0x00ff;
|
|||
|
|
break;
|
|||
|
|
case '~':
|
|||
|
|
r = 0x00fe;
|
|||
|
|
break;
|
|||
|
|
case '[':
|
|||
|
|
r = 0x00fd;
|
|||
|
|
break;
|
|||
|
|
case ']':
|
|||
|
|
r = 0x00fc;
|
|||
|
|
break;
|
|||
|
|
case 0x0a:
|
|||
|
|
r = 0x08;
|
|||
|
|
break;
|
|||
|
|
case 0x0d:
|
|||
|
|
r = 0x02;
|
|||
|
|
break;
|
|||
|
|
case 0x1b:
|
|||
|
|
r = 0x1b;
|
|||
|
|
fig = 1;
|
|||
|
|
break;
|
|||
|
|
case 0x1f:
|
|||
|
|
r = 0x1f;
|
|||
|
|
fig = 0;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
if( d >= 0x20 ){
|
|||
|
|
d -= char(0x20);
|
|||
|
|
r = m_TBL[d].Code;
|
|||
|
|
fig = m_TBL[d].Fig;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if( fig != 2 ){
|
|||
|
|
if( fig != m_outfig ){
|
|||
|
|
r |= (fig ? 0x1b00 : 0x1f00);
|
|||
|
|
m_outfig = fig;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if( r == 0x04 ){ // <20>X<EFBFBD>y<EFBFBD>[<5B>X<EFBFBD>̎<EFBFBD>
|
|||
|
|
if( sys.m_txuos && (m_outfig == 1) ) m_outfig = 2;
|
|||
|
|
}
|
|||
|
|
return r;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CRTTY::ConvRTTY(BYTE *t, LPCSTR p)
|
|||
|
|
{
|
|||
|
|
int n;
|
|||
|
|
int d;
|
|||
|
|
for( n = 0;*p; p++ ){
|
|||
|
|
d = ConvRTTY(*p);
|
|||
|
|
if( d & 0x0000ff00 ){
|
|||
|
|
*t++ = BYTE(d >> 8);
|
|||
|
|
n++;
|
|||
|
|
if( sys.m_dblsft ){
|
|||
|
|
*t++ = BYTE(d >> 8);
|
|||
|
|
n++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
*t++ = BYTE(d);
|
|||
|
|
n++;
|
|||
|
|
}
|
|||
|
|
return n;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CRTTY::GetShift(char d)
|
|||
|
|
{
|
|||
|
|
int fig = 2;
|
|||
|
|
switch(d){
|
|||
|
|
default:
|
|||
|
|
if( d >= 0x20 ){
|
|||
|
|
d -= char(0x20);
|
|||
|
|
fig = m_TBL[d].Fig;
|
|||
|
|
if( !m_TBL[d].Code ){
|
|||
|
|
fig = 2;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
return fig;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
char CRTTY::InvShift(char c)
|
|||
|
|
{
|
|||
|
|
int fs = GetShift(c);
|
|||
|
|
if( (c == 'h') || (c == 's') || (c == 'j') ) fs = 1;
|
|||
|
|
int d = ConvRTTY(c) & 0x001f;
|
|||
|
|
switch(fs){
|
|||
|
|
case 0:
|
|||
|
|
if( _FIG[d] ){
|
|||
|
|
c = _FIG[d];
|
|||
|
|
if( sys.m_CodeSet ){
|
|||
|
|
switch(c){
|
|||
|
|
case 's':
|
|||
|
|
c = 0x27;
|
|||
|
|
break;
|
|||
|
|
case 0x27:
|
|||
|
|
c = 'j';
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return c;
|
|||
|
|
case 1:
|
|||
|
|
return _LTR[d] ? _LTR[d] : c;
|
|||
|
|
default:
|
|||
|
|
return c;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// CScope<70>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CScope::CScope()
|
|||
|
|
{
|
|||
|
|
m_ScopeSize = SCOPESIZE;
|
|||
|
|
m_DataFlag = 0;
|
|||
|
|
|
|||
|
|
pScopeData = new double[m_ScopeSize];
|
|||
|
|
memset(pScopeData, 0, sizeof(double)*m_ScopeSize);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CScope::~CScope()
|
|||
|
|
{
|
|||
|
|
delete[] pScopeData;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CScope::WriteData(double d)
|
|||
|
|
{
|
|||
|
|
if( !m_DataFlag ){
|
|||
|
|
if( m_wp < m_ScopeSize ){
|
|||
|
|
pScopeData[m_wp] = d;
|
|||
|
|
m_wp++;
|
|||
|
|
if( m_wp >= m_ScopeSize ){
|
|||
|
|
m_DataFlag = 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CScope::UpdateData(double d)
|
|||
|
|
{
|
|||
|
|
if( !m_DataFlag ){
|
|||
|
|
if( m_wp ){
|
|||
|
|
pScopeData[m_wp-1] = d;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CScope::Collect(int size)
|
|||
|
|
{
|
|||
|
|
m_DataFlag = 1;
|
|||
|
|
m_ScopeSize = size;
|
|||
|
|
m_wp = 0;
|
|||
|
|
m_DataFlag = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// CNoise<73>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CNoise::CNoise()
|
|||
|
|
{
|
|||
|
|
reg = 0x12345;
|
|||
|
|
|
|||
|
|
memset(Z, 0, sizeof(Z));
|
|||
|
|
MakeFilter(H, NOISEBPFTAP, ffLPF, SampFreq, 3000.0, 3000.0, 60, 1.0);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
double CNoise::GetNoise(void)
|
|||
|
|
{
|
|||
|
|
DWORD r = reg >> 1;
|
|||
|
|
if( (reg ^ r) & 1 ){
|
|||
|
|
r |= 0xffe00000;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
r &= 0x001fffff;
|
|||
|
|
}
|
|||
|
|
reg = r;
|
|||
|
|
double d = double(reg) / 500000.0;
|
|||
|
|
// return d;
|
|||
|
|
return DoFIR(H, Z, d, NOISEBPFTAP); // <20>ш搧<D188><E690A7>
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// CSamplePeak<61>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CSamplePeak::CSamplePeak()
|
|||
|
|
{
|
|||
|
|
memset(Strage, 0, sizeof(Strage));
|
|||
|
|
m_CurPeak = 0.0;
|
|||
|
|
m_Peak = 0.0;
|
|||
|
|
m_Strage = 8 - 1;
|
|||
|
|
SetBaudRate(45.45);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSamplePeak::SetBaudRate(double b)
|
|||
|
|
{
|
|||
|
|
if( b >= 1.0 ){
|
|||
|
|
m_ReCount = m_Count = int(DemSamp/b + 0.5);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSamplePeak::Sync(int Delay)
|
|||
|
|
{
|
|||
|
|
m_Count = m_ReCount - Delay;
|
|||
|
|
while( m_Count < 0 ) m_Count += m_ReCount;
|
|||
|
|
memcpy(Strage, &Strage[1], sizeof(double)*m_Strage);
|
|||
|
|
Strage[m_Strage] = m_CurPeak;
|
|||
|
|
m_Peak = 0.0;
|
|||
|
|
int i;
|
|||
|
|
for( i = 0; i <= m_Strage; i++ ){
|
|||
|
|
if( m_Peak < Strage[i] ) m_Peak = Strage[i];
|
|||
|
|
}
|
|||
|
|
m_CurPeak = 0.0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CSamplePeak::Sample(double d)
|
|||
|
|
{
|
|||
|
|
int r = 0;
|
|||
|
|
|
|||
|
|
if( m_CurPeak < d ){
|
|||
|
|
m_CurPeak = d;
|
|||
|
|
if( m_Peak < d ){
|
|||
|
|
m_Peak = d;
|
|||
|
|
r = 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( !m_Count ){
|
|||
|
|
Sync(0);
|
|||
|
|
r = 1;
|
|||
|
|
}
|
|||
|
|
m_Count--;
|
|||
|
|
return r;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// CAGC<47>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CAGC::CAGC()
|
|||
|
|
{
|
|||
|
|
m_MaxGain = 2048.0;
|
|||
|
|
m_StepGain = 3.0;
|
|||
|
|
m_MarkGain = 1.0;
|
|||
|
|
m_SpaceGain = 1.0;
|
|||
|
|
m_DeffGain = 12.0;
|
|||
|
|
m_Sync = 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CAGC::Sync(int Delay)
|
|||
|
|
{
|
|||
|
|
if( m_Sync ){
|
|||
|
|
Mark.Sync(Delay);
|
|||
|
|
Space.Sync(Delay);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double CAGC::SampleMark(double d)
|
|||
|
|
{
|
|||
|
|
if( Mark.Sample(d) ){
|
|||
|
|
double gain = Mark.GetPeak();
|
|||
|
|
if( gain ){
|
|||
|
|
gain = 8192.0 / gain;
|
|||
|
|
double ugain = m_MarkGain * m_StepGain;
|
|||
|
|
double dgain = m_MarkGain / m_StepGain;
|
|||
|
|
if( ugain < gain ){
|
|||
|
|
m_MarkGain = ugain;
|
|||
|
|
}
|
|||
|
|
else if( dgain > gain ){
|
|||
|
|
m_MarkGain = dgain;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_MarkGain = gain;
|
|||
|
|
}
|
|||
|
|
if( m_MarkGain > m_MaxGain ) m_MarkGain = m_MaxGain;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_MarkGain = 1.0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return d * m_MarkGain;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double CAGC::SampleSpace(double d)
|
|||
|
|
{
|
|||
|
|
if( Space.Sample(d) ){
|
|||
|
|
double gain = Space.GetPeak();
|
|||
|
|
if( gain ){
|
|||
|
|
gain = 8192.0 / gain;
|
|||
|
|
double ugain = m_SpaceGain * m_StepGain;
|
|||
|
|
double dgain = m_SpaceGain / m_StepGain;
|
|||
|
|
if( ugain < gain ){
|
|||
|
|
m_SpaceGain = ugain;
|
|||
|
|
}
|
|||
|
|
else if( dgain > gain ){
|
|||
|
|
m_SpaceGain = dgain;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_SpaceGain = gain;
|
|||
|
|
}
|
|||
|
|
if( m_SpaceGain > m_MaxGain ) m_SpaceGain = m_MaxGain;
|
|||
|
|
if( m_SpaceGain > m_MarkGain ){
|
|||
|
|
if( m_SpaceGain > m_MarkGain * m_DeffGain ){
|
|||
|
|
m_SpaceGain = m_MarkGain * m_DeffGain;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( m_SpaceGain * m_DeffGain < m_MarkGain ){
|
|||
|
|
m_SpaceGain = m_MarkGain / m_DeffGain;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_SpaceGain = 1.0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return d * m_SpaceGain;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// CATC<54>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CATC::CATC()
|
|||
|
|
{
|
|||
|
|
m_Low = 0;
|
|||
|
|
m_High = 16384.0;
|
|||
|
|
m_CurLow = MAXDOUBLE;
|
|||
|
|
m_CurHigh = -MAXDOUBLE;
|
|||
|
|
m_Max = 4;
|
|||
|
|
m_Cnt = 0;
|
|||
|
|
int i;
|
|||
|
|
for( i = 0; i < ATCMAX; i++ ){
|
|||
|
|
m_LowList[i] = m_Low;
|
|||
|
|
m_HighList[i] = m_High;
|
|||
|
|
}
|
|||
|
|
m_iir.MakeIIR(100, DemSamp, 3, 0, 0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double CATC::Do(double d)
|
|||
|
|
{
|
|||
|
|
if( m_CurLow > d ) m_CurLow = d;
|
|||
|
|
if( m_CurHigh < d ) m_CurHigh = d;
|
|||
|
|
// if( m_Low > d ) m_Low = d;
|
|||
|
|
// if( m_High < d ) m_High = d;
|
|||
|
|
if( !m_Cnt ){
|
|||
|
|
m_Cnt = 64;
|
|||
|
|
if( m_CurLow > (ATCC-ATCW) ) m_CurLow = (ATCC-ATCW);
|
|||
|
|
if( m_CurHigh < (ATCC+ATCW) ) m_CurHigh = (ATCC+ATCW);
|
|||
|
|
if( m_Max ){
|
|||
|
|
memcpy(m_LowList, &m_LowList[1], (m_Max)*sizeof(double));
|
|||
|
|
memcpy(m_HighList, &m_HighList[1], (m_Max)*sizeof(double));
|
|||
|
|
}
|
|||
|
|
m_LowList[m_Max] = m_CurLow;
|
|||
|
|
m_HighList[m_Max] = m_CurHigh;
|
|||
|
|
int i;
|
|||
|
|
m_Low = m_LowList[0];
|
|||
|
|
m_High = m_HighList[0];
|
|||
|
|
for( i = 1; i <= m_Max; i++ ){
|
|||
|
|
if( m_Low > m_LowList[i] ) m_Low = m_LowList[i];
|
|||
|
|
if( m_High < m_HighList[i] ) m_High = m_HighList[i];
|
|||
|
|
}
|
|||
|
|
m_CurLow = MAXDOUBLE;
|
|||
|
|
m_CurHigh = -MAXDOUBLE;
|
|||
|
|
}
|
|||
|
|
m_Cnt--;
|
|||
|
|
double th = ((m_High + m_Low)*0.5);
|
|||
|
|
th = m_iir.Do(th);
|
|||
|
|
if( m_High > m_Low ){
|
|||
|
|
d = (d - th) * 1.1 + th;
|
|||
|
|
}
|
|||
|
|
d += (ATCC - th);
|
|||
|
|
return d;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
// CFIR<49>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
__fastcall CFIR::CFIR()
|
|||
|
|
{
|
|||
|
|
m_pZ = NULL;
|
|||
|
|
m_pH = NULL;
|
|||
|
|
m_Tap = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
__fastcall CFIR::~CFIR()
|
|||
|
|
{
|
|||
|
|
if( m_pZ ) delete[] m_pZ;
|
|||
|
|
if( m_pH ) delete[] m_pH;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFIR::Create(int tap, int type, double fs, double fcl, double fch, double att, double gain)
|
|||
|
|
{
|
|||
|
|
m_Tap = tap;
|
|||
|
|
if( m_pZ ) delete[] m_pZ;
|
|||
|
|
if( m_pH ) delete[] m_pH;
|
|||
|
|
m_pZ = new double[tap+1];
|
|||
|
|
m_pH = new double[tap+1];
|
|||
|
|
memset(m_pZ, 0, sizeof(double)*(tap+1));
|
|||
|
|
::MakeFilter(m_pH, tap, type, fs, fcl, fch, att, gain);
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
double __fastcall CFIR::Do(double d)
|
|||
|
|
{
|
|||
|
|
return DoFIR(m_pH, m_pZ, d, m_Tap);
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFIR::SaveCoef(LPCSTR pName)
|
|||
|
|
{
|
|||
|
|
FILE *fp;
|
|||
|
|
if( (fp = fopen(pName, "wt")) != NULL ){
|
|||
|
|
int i;
|
|||
|
|
for( i = 0; i <= m_Tap; i++ ){
|
|||
|
|
fprintf(fp, "H[%u]=%lf\n", i, m_pH[i]);
|
|||
|
|
}
|
|||
|
|
fclose(fp);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
// CFIR2<52>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
__fastcall CFIR2::CFIR2()
|
|||
|
|
{
|
|||
|
|
m_pZ = NULL;
|
|||
|
|
m_pH = NULL;
|
|||
|
|
m_pZP = NULL;
|
|||
|
|
m_W = 0;
|
|||
|
|
m_Tap = 0;
|
|||
|
|
m_fs = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
__fastcall CFIR2::~CFIR2()
|
|||
|
|
{
|
|||
|
|
if( m_pZ ) delete[] m_pZ;
|
|||
|
|
if( m_pH ) delete[] m_pH;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFIR2::Delete(void)
|
|||
|
|
{
|
|||
|
|
if( m_pZ ) delete[] m_pZ;
|
|||
|
|
if( m_pH ) delete[] m_pH;
|
|||
|
|
m_pZ = NULL;
|
|||
|
|
m_pH = NULL;
|
|||
|
|
m_pZP = NULL;
|
|||
|
|
m_W = 0;
|
|||
|
|
m_Tap = 0;
|
|||
|
|
m_fs = 0;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFIR2::Create(int tap, int type, double fs, double fcl, double fch, double att, double gain)
|
|||
|
|
{
|
|||
|
|
if( (m_Tap != tap) || !m_pZ || !m_pH ){
|
|||
|
|
if( m_pZ ) delete[] m_pZ;
|
|||
|
|
m_pZ = new double[(tap+1)*2];
|
|||
|
|
memset(m_pZ, 0, sizeof(double)*(tap+1)*2);
|
|||
|
|
if( m_pH ) delete[] m_pH;
|
|||
|
|
m_pH = new double[tap+1];
|
|||
|
|
m_W = 0;
|
|||
|
|
}
|
|||
|
|
m_Tap = tap;
|
|||
|
|
m_TapHalf = tap/2;
|
|||
|
|
m_fs = fs;
|
|||
|
|
::MakeFilter(m_pH, tap, type, fs, fcl, fch, att, gain);
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFIR2::Create(int tap, double fs, double fcl, double fch)
|
|||
|
|
{
|
|||
|
|
if( (m_Tap != tap) || !m_pZ || !m_pH ){
|
|||
|
|
if( m_pZ ) delete[] m_pZ;
|
|||
|
|
m_pZ = new double[(tap+1)*2];
|
|||
|
|
memset(m_pZ, 0, sizeof(double)*(tap+1)*2);
|
|||
|
|
if( m_pH ) delete[] m_pH;
|
|||
|
|
m_pH = new double[tap+1];
|
|||
|
|
m_W = 0;
|
|||
|
|
}
|
|||
|
|
m_Tap = tap;
|
|||
|
|
m_TapHalf = tap/2;
|
|||
|
|
m_fs = fs;
|
|||
|
|
::MakeHilbert(m_pH, tap, fs, fcl, fch);
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFIR2::CreateSamp(int tap, double fs, const double *pSmpFQ)
|
|||
|
|
{
|
|||
|
|
if( (m_Tap != tap) || !m_pZ || !m_pH ){
|
|||
|
|
if( m_pZ ) delete[] m_pZ;
|
|||
|
|
m_pZ = new double[(tap+1)*2];
|
|||
|
|
memset(m_pZ, 0, sizeof(double)*(tap+1)*2);
|
|||
|
|
if( m_pH ) delete[] m_pH;
|
|||
|
|
m_pH = new double[tap+1];
|
|||
|
|
m_W = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int htap = tap/2;
|
|||
|
|
int i, j;
|
|||
|
|
double *pSamp = new double[tap+1];
|
|||
|
|
memcpy(pSamp, pSmpFQ, sizeof(double)*(tap/2));
|
|||
|
|
for( i = 0; i < tap/2; i++ ){
|
|||
|
|
pSamp[tap-i] = pSamp[i];
|
|||
|
|
}
|
|||
|
|
pSamp[tap/2] = pSamp[tap/2 - 1];
|
|||
|
|
double *pH = new double[tap+1];
|
|||
|
|
double re, fm;
|
|||
|
|
|
|||
|
|
for( i = 0; i <= htap; i++ ){
|
|||
|
|
re = 0.0;
|
|||
|
|
for( j = 0; j < tap; j++ ){
|
|||
|
|
fm = 2.0 * PI * double((i*j)%tap)/double(tap);
|
|||
|
|
re += pSamp[j] * cos(fm);
|
|||
|
|
}
|
|||
|
|
pH[i] = re / tap;
|
|||
|
|
}
|
|||
|
|
#if 0
|
|||
|
|
fm = 0;
|
|||
|
|
for( i = 0; i <= htap; i++ ){
|
|||
|
|
fm += pH[i];
|
|||
|
|
}
|
|||
|
|
fm = 0.5 / fm;
|
|||
|
|
for( i = 0; i <= htap; i++ ){
|
|||
|
|
pH[i] *= fm;
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
for( i = 0; i <= htap; i++ ) m_pH[htap-i] = pH[i];
|
|||
|
|
for( i = 0; i < htap; i++ ) m_pH[tap-i] = m_pH[i];
|
|||
|
|
delete[] pH;
|
|||
|
|
delete[] pSamp;
|
|||
|
|
|
|||
|
|
m_Tap = tap;
|
|||
|
|
m_TapHalf = htap;
|
|||
|
|
m_fs = fs;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFIR2::Clear(void)
|
|||
|
|
{
|
|||
|
|
if( m_pZ ) memset(m_pZ, 0, sizeof(double)*(m_Tap+1)*2);
|
|||
|
|
m_W = 0;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
double __fastcall CFIR2::Do(double d)
|
|||
|
|
{
|
|||
|
|
double *dp1 = &m_pZ[m_W+m_Tap+1];
|
|||
|
|
m_pZP = dp1;
|
|||
|
|
*dp1 = d;
|
|||
|
|
m_pZ[m_W] = d;
|
|||
|
|
d = 0;
|
|||
|
|
double *hp = m_pH;
|
|||
|
|
for( int i = 0; i <= m_Tap; i++ ){
|
|||
|
|
d += (*dp1--) * (*hp++);
|
|||
|
|
}
|
|||
|
|
m_W++;
|
|||
|
|
if( m_W > m_Tap ) m_W = 0;
|
|||
|
|
return d;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
double __fastcall CFIR2::Do(double *hp)
|
|||
|
|
{
|
|||
|
|
double d = 0;
|
|||
|
|
double *dp = m_pZP;
|
|||
|
|
for( int i = 0; i <= m_Tap; i++ ){
|
|||
|
|
d += (*dp--) * (*hp++);
|
|||
|
|
}
|
|||
|
|
return d;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFIR2::Do(CLX &z, double d)
|
|||
|
|
{
|
|||
|
|
double *dp1 = &m_pZ[m_W+m_Tap+1];
|
|||
|
|
m_pZP = dp1;
|
|||
|
|
*dp1 = d;
|
|||
|
|
m_pZ[m_W] = d;
|
|||
|
|
d = 0;
|
|||
|
|
double *hp = m_pH;
|
|||
|
|
for( int i = 0; i <= m_Tap; i++ ){
|
|||
|
|
d += (*dp1--) * (*hp++);
|
|||
|
|
}
|
|||
|
|
z.j = d;
|
|||
|
|
z.r = m_pZ[m_W+m_TapHalf+1];
|
|||
|
|
m_W++;
|
|||
|
|
if( m_W > m_Tap ) m_W = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
// CFIRX<52>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
__fastcall CFIRX::CFIRX()
|
|||
|
|
{
|
|||
|
|
m_pZ = NULL;
|
|||
|
|
m_pH = NULL;
|
|||
|
|
m_pZP = NULL;
|
|||
|
|
m_W = 0;
|
|||
|
|
m_Tap = 0;
|
|||
|
|
m_fs = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
__fastcall CFIRX::~CFIRX()
|
|||
|
|
{
|
|||
|
|
if( m_pZ ) delete[] m_pZ;
|
|||
|
|
if( m_pH ) delete[] m_pH;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFIRX::Create(int tap, int type, double fs, double fcl, double fch, double att, double gain)
|
|||
|
|
{
|
|||
|
|
if( (m_Tap != tap) || !m_pZ || !m_pH ){
|
|||
|
|
if( m_pZ ) delete[] m_pZ;
|
|||
|
|
m_pZ = new CLX[(tap+1)*2];
|
|||
|
|
memset(m_pZ, 0, sizeof(CLX)*(tap+1)*2);
|
|||
|
|
if( m_pH ) delete[] m_pH;
|
|||
|
|
m_pH = new double[tap+1];
|
|||
|
|
m_W = 0;
|
|||
|
|
}
|
|||
|
|
m_Tap = tap;
|
|||
|
|
m_TapHalf = tap/2;
|
|||
|
|
m_fs = fs;
|
|||
|
|
::MakeFilter(m_pH, tap, type, fs, fcl, fch, att, gain);
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFIRX::Clear(void)
|
|||
|
|
{
|
|||
|
|
if( m_pZ ) memset(m_pZ, 0, sizeof(CLX)*(m_Tap+1)*2);
|
|||
|
|
m_W = 0;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFIRX::Do(CLX &d)
|
|||
|
|
{
|
|||
|
|
CLX *dp1 = &m_pZ[m_W+m_Tap+1];
|
|||
|
|
m_pZP = dp1;
|
|||
|
|
*dp1 = d;
|
|||
|
|
m_pZ[m_W] = d;
|
|||
|
|
CLX z = 0;
|
|||
|
|
double *hp = m_pH;
|
|||
|
|
for( int i = 0; i <= m_Tap; i++, dp1-- ){
|
|||
|
|
z.r += dp1->r * (*hp);
|
|||
|
|
z.j += dp1->j * (*hp++);
|
|||
|
|
}
|
|||
|
|
m_W++;
|
|||
|
|
if( m_W > m_Tap ) m_W = 0;
|
|||
|
|
d = z;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*=============================================================================
|
|||
|
|
CSlideFFT<EFBFBD>N<EFBFBD><EFBFBD><EFBFBD>X <EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>C<EFBFBD>f<EFBFBD>B<EFBFBD><EFBFBD><EFBFBD>O<EFBFBD>@FFT
|
|||
|
|
=============================================================================*/
|
|||
|
|
#define SLIDE_WINDOW_COEFF 0.9999
|
|||
|
|
__fastcall CSlideFFT::CSlideFFT(void)
|
|||
|
|
{
|
|||
|
|
m_Length = 0;
|
|||
|
|
m_Base = 0;
|
|||
|
|
m_Tones = 0;
|
|||
|
|
m_kWindow = 0;
|
|||
|
|
m_pBase = NULL;
|
|||
|
|
m_pCur = m_pEnd = NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------------------------
|
|||
|
|
__fastcall CSlideFFT::~CSlideFFT()
|
|||
|
|
{
|
|||
|
|
if( m_pBase ) delete[] m_pBase;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------------------------
|
|||
|
|
void __fastcall CSlideFFT::Create(int len, int base, int tones)
|
|||
|
|
{
|
|||
|
|
#if LOGFFT
|
|||
|
|
FILE *fp = fopen("SLIDERFFT.txt", "wt");
|
|||
|
|
fprintf(fp, "len=%d, base=%d, tones=%d\n", len, base, tones);
|
|||
|
|
fclose(fp);
|
|||
|
|
#endif
|
|||
|
|
if( !m_pBase || (len != m_Length) ){
|
|||
|
|
if( m_pBase ) delete[] m_pBase;
|
|||
|
|
m_pBase = new CLX[len];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
memset(m_pBase, 0, sizeof(CLX)*len);
|
|||
|
|
memset(m_tWindow, 0, sizeof(m_tWindow));
|
|||
|
|
memset(m_tData, 0, sizeof(m_tData));
|
|||
|
|
|
|||
|
|
m_Length = len;
|
|||
|
|
m_Base = base;
|
|||
|
|
m_Tones = tones;
|
|||
|
|
|
|||
|
|
double k = 2.0 * PI / double(len);
|
|||
|
|
for(int i = 0; i < tones; i++){
|
|||
|
|
m_tWindow[i].r = cos((i+base) * k) * SLIDE_WINDOW_COEFF;
|
|||
|
|
m_tWindow[i].j = sin((i+base) * k) * SLIDE_WINDOW_COEFF;
|
|||
|
|
}
|
|||
|
|
m_kWindow = pow(SLIDE_WINDOW_COEFF, len);
|
|||
|
|
m_pCur = m_pBase;
|
|||
|
|
m_pEnd = &m_pBase[m_Length];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------------------------
|
|||
|
|
CLX* __fastcall CSlideFFT::Do(const CLX &zIn)
|
|||
|
|
{
|
|||
|
|
CLX z;
|
|||
|
|
|
|||
|
|
if( m_pCur >= m_pEnd ) m_pCur = m_pBase;
|
|||
|
|
z = *m_pCur;
|
|||
|
|
*m_pCur = zIn;
|
|||
|
|
m_pCur++;
|
|||
|
|
z *= m_kWindow;
|
|||
|
|
|
|||
|
|
CLX *pData = m_tData;
|
|||
|
|
CLX *pWindow = m_tWindow;
|
|||
|
|
for( int i = 0; i < m_Tones; i++, pData++ ){
|
|||
|
|
*pData -= z;
|
|||
|
|
*pData += zIn;
|
|||
|
|
*pData *= *pWindow++;
|
|||
|
|
}
|
|||
|
|
return m_tData;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*=============================================================================
|
|||
|
|
CPHASE<EFBFBD>N<EFBFBD><EFBFBD><EFBFBD>X
|
|||
|
|
=============================================================================*/
|
|||
|
|
__fastcall CPHASE::CPHASE()
|
|||
|
|
{
|
|||
|
|
m_TONES = 4;
|
|||
|
|
m_SHIFT = 170.0;
|
|||
|
|
m_SampleFreq = 11025.0*0.5;
|
|||
|
|
m_CarrierFreq = 1750;
|
|||
|
|
m_MixerFreq = 0;
|
|||
|
|
SetSampleFreq(m_SampleFreq);
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------------------------
|
|||
|
|
void __fastcall CPHASE::ShowPara(void)
|
|||
|
|
{
|
|||
|
|
/*
|
|||
|
|
if( Application->MainForm ){
|
|||
|
|
char bf[256];
|
|||
|
|
sprintf(bf, "Car=%.lf, Shift=%.lf", m_CarrierFreq, m_SHIFT);
|
|||
|
|
Application->MainForm->Caption = bf;
|
|||
|
|
}
|
|||
|
|
*/
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------------------------
|
|||
|
|
void __fastcall CPHASE::SetSampleFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_SampleFreq = f;
|
|||
|
|
Create();
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------------------------
|
|||
|
|
void __fastcall CPHASE::Create(void)
|
|||
|
|
{
|
|||
|
|
// m_fftSHIFT = m_SHIFT * (m_TONES + 1) / m_TONES;
|
|||
|
|
m_fftSHIFT = m_SHIFT * m_TONES / (m_TONES - 1);
|
|||
|
|
m_SymbolLen = m_TONES * m_SampleFreq / m_fftSHIFT;
|
|||
|
|
m_BASEPOINT = int(CPHASE_BASEFREQ * m_TONES / m_fftSHIFT);
|
|||
|
|
|
|||
|
|
m_MixerFreq = double(m_BASEPOINT) * m_SampleFreq / m_SymbolLen;
|
|||
|
|
m_VCO.SetSampleFreq(m_SampleFreq);
|
|||
|
|
m_Hilbert.Create(20, m_SampleFreq, 25.0, m_SampleFreq*0.5 - 25.0);
|
|||
|
|
m_Hilbert.Clear();
|
|||
|
|
SetCarrierFreq(m_CarrierFreq);
|
|||
|
|
m_SlideFFT.Create(int(m_SymbolLen + 0.5), m_BASEPOINT, m_TONES);
|
|||
|
|
m_AGC.SetSampleFreq(m_SampleFreq);
|
|||
|
|
m_AGC.SetCarrierFreq(m_CarrierFreq);
|
|||
|
|
// m_LPF.Create(192, ffBEF, m_SampleFreq, 85.0 - 20, 85.0 + 20, 60, 1.0);
|
|||
|
|
#if LOGFFT
|
|||
|
|
m_fp = fopen("FFT.txt", "wt");
|
|||
|
|
#endif
|
|||
|
|
// ShowPara();
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------------------------
|
|||
|
|
void __fastcall CPHASE::SetShift(double f)
|
|||
|
|
{
|
|||
|
|
m_SHIFT = f;
|
|||
|
|
Create();
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------------------------
|
|||
|
|
void __fastcall CPHASE::SetCarrierFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_CarrierFreq = f;
|
|||
|
|
m_VCO.SetFreeFreq(m_CarrierFreq - m_MixerFreq);
|
|||
|
|
m_AGC.SetCarrierFreq(m_CarrierFreq);
|
|||
|
|
// ShowPara();
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------------------------
|
|||
|
|
CLX* __fastcall CPHASE::Do(double d)
|
|||
|
|
{
|
|||
|
|
m_Hilbert.Do(m_sig, d); // <20><><EFBFBD>f<EFBFBD><66><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
CLX z;
|
|||
|
|
z.r = m_VCO.Do();
|
|||
|
|
z.j = m_VCO.DoCos();
|
|||
|
|
z *= m_sig; // <20><><EFBFBD>g<EFBFBD><67><EFBFBD>ϊ<EFBFBD>
|
|||
|
|
|
|||
|
|
// m_LPF.Do(z);
|
|||
|
|
return m_SlideFFT.Do(z);
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------------------------
|
|||
|
|
void __fastcall CPHASE::DoFSK(double d)
|
|||
|
|
{
|
|||
|
|
// d = m_AGC.Do(d);
|
|||
|
|
CLX *pFFT = Do(d);
|
|||
|
|
m_dm = pFFT[0].vAbs();
|
|||
|
|
m_ds = pFFT[m_TONES-1].vAbs();
|
|||
|
|
|
|||
|
|
#if LOGFFT
|
|||
|
|
for( int i = 0; i < m_TONES; i++ ){
|
|||
|
|
if( i ) fprintf(m_fp, ",");
|
|||
|
|
fprintf(m_fp, "%.0lf", pFFT[i].vAbs());
|
|||
|
|
}
|
|||
|
|
fprintf(m_fp, "\n");
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------------------------
|
|||
|
|
void __fastcall DoAvg(double &av, double in, double factor)
|
|||
|
|
{
|
|||
|
|
av = av * (1.0 - factor) + (in * factor);
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
__fastcall CFAVG::CFAVG()
|
|||
|
|
{
|
|||
|
|
Create(16);
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFAVG::Reset(void)
|
|||
|
|
{
|
|||
|
|
m_Cnt = 0;
|
|||
|
|
m_Sum = 0;
|
|||
|
|
m_Avg = 0;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFAVG::Reset(double d)
|
|||
|
|
{
|
|||
|
|
m_Cnt = m_Max;
|
|||
|
|
m_Sum = d * m_Max;
|
|||
|
|
m_Avg = d;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CFAVG::Create(int max)
|
|||
|
|
{
|
|||
|
|
m_Max = max;
|
|||
|
|
m_Mul = 1.0 / m_Max;
|
|||
|
|
Reset();
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
double __fastcall CFAVG::DoZ(double d)
|
|||
|
|
{
|
|||
|
|
m_Sum += d;
|
|||
|
|
if( m_Cnt < m_Max ){
|
|||
|
|
m_Cnt++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_Sum -= m_Avg;
|
|||
|
|
}
|
|||
|
|
m_Avg = m_Sum * m_Mul;
|
|||
|
|
return m_Avg;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
double __fastcall CFAVG::Do(double d)
|
|||
|
|
{
|
|||
|
|
m_Sum += d;
|
|||
|
|
if( m_Cnt < m_Max ){
|
|||
|
|
m_Cnt++;
|
|||
|
|
m_Avg = m_Sum / m_Cnt;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_Sum -= m_Avg;
|
|||
|
|
m_Avg = m_Sum * m_Mul;
|
|||
|
|
}
|
|||
|
|
return m_Avg;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// CAGC<47>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
__fastcall CAGCX::CAGCX()
|
|||
|
|
{
|
|||
|
|
m_fc = 1000.0;
|
|||
|
|
m_MonitorFreq = SampFreq/2048;
|
|||
|
|
m_SampleFreq = SampFreq;
|
|||
|
|
m_CarrierFreq = 1750.0;
|
|||
|
|
m_LimitGain = 0.005;
|
|||
|
|
m_AvgOver.Create(4);
|
|||
|
|
Create();
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
void __fastcall CAGCX::Create(void)
|
|||
|
|
{
|
|||
|
|
m_Count = 0;
|
|||
|
|
m_Max = -1.0;
|
|||
|
|
m_Min = 1.0;
|
|||
|
|
m_d = 0;
|
|||
|
|
m_agc = 1.0;
|
|||
|
|
// m_Level.Create(ffLPF, 0.3, m_MonitorFreq, 3, 0, 0);
|
|||
|
|
SetCarrierFreq(m_CarrierFreq);
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
void __fastcall CAGCX::SetCarrierFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_CarrierFreq = f;
|
|||
|
|
if( m_CarrierFreq >= 1000.0 ){
|
|||
|
|
m_Gain = (m_CarrierFreq / 1000.0);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
500 0.003 333
|
|||
|
|
1000 0.0035 285 1.0 1.0
|
|||
|
|
1500 0.005 200 1.4 1.5
|
|||
|
|
1800 0.006 166 1.71
|
|||
|
|
2000 0.008 125 2.3 2.0
|
|||
|
|
2100 0.01 100 2.85 2.1
|
|||
|
|
2200 0.012 83 3.4 2.2
|
|||
|
|
2300 0.015 66 4.3 2.3
|
|||
|
|
2400 0.025 40 7.1 2.4
|
|||
|
|
2500 0.028 36 7.9 2.5
|
|||
|
|
2600 0.030 33 8.6 2.6
|
|||
|
|
*/
|
|||
|
|
if( m_Gain >= 2.35 ){
|
|||
|
|
m_Gain *= 7.1 / 2.4;
|
|||
|
|
}
|
|||
|
|
else if( m_Gain >= 2.25 ){
|
|||
|
|
m_Gain *= 4.3 / 2.3;
|
|||
|
|
}
|
|||
|
|
else if( m_Gain >= 2.15 ){
|
|||
|
|
m_Gain *= 3.4 / 2.2;
|
|||
|
|
}
|
|||
|
|
else if( m_Gain >= 2.05 ){
|
|||
|
|
m_Gain *= 2.9 / 2.1;
|
|||
|
|
}
|
|||
|
|
else if( m_Gain >= 1.8 ){
|
|||
|
|
m_Gain *= 2.3 / 2.2;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_Gain = 1.0;
|
|||
|
|
}
|
|||
|
|
SetFC(m_fc);
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
void __fastcall CAGCX::SetFC(double fc)
|
|||
|
|
{
|
|||
|
|
m_fc = fc;
|
|||
|
|
if( fc > m_CarrierFreq*0.45 ) fc = m_CarrierFreq*0.45;
|
|||
|
|
// m_LPF.Create(ffLPF, fc, m_CarrierFreq, 1, 0, 0);
|
|||
|
|
m_LPF.MakeIIR(fc, m_CarrierFreq, 1, 0, 0);
|
|||
|
|
m_d = 0;
|
|||
|
|
m_TLimit = m_SampleFreq*0.8/m_CarrierFreq;
|
|||
|
|
m_AvgOver.Reset(1.0);
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
void __fastcall CAGCX::Reset(void)
|
|||
|
|
{
|
|||
|
|
m_Max = -1.0;
|
|||
|
|
m_Min = 1.0;
|
|||
|
|
m_agc = 1.0;
|
|||
|
|
m_d = 0;
|
|||
|
|
m_Count = 0;
|
|||
|
|
for( int i = 0; i < 12; i++ ){
|
|||
|
|
m_LPF.Do(1.0);
|
|||
|
|
// m_Level.Do(0);
|
|||
|
|
}
|
|||
|
|
m_AvgOver.Reset(1.0);
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
double __fastcall CAGCX::Do(double d)
|
|||
|
|
{
|
|||
|
|
if( m_Max < d ) m_Max = d;
|
|||
|
|
if( m_Min > d ) m_Min = d;
|
|||
|
|
if( (d >= 0) && (m_d < 0) && (m_Count >= m_TLimit) ){
|
|||
|
|
double amp = m_Max - m_Min;
|
|||
|
|
if( amp > 0.1 ){
|
|||
|
|
m_agc = m_LPF.Do(5.0/amp);
|
|||
|
|
if( m_agc >= 1.0 ) m_agc = 1.0;
|
|||
|
|
m_Max = -32768.0;
|
|||
|
|
m_Min = 32768.0;
|
|||
|
|
}
|
|||
|
|
m_Count = 0;
|
|||
|
|
}
|
|||
|
|
m_Count++;
|
|||
|
|
m_d = d;
|
|||
|
|
d *= m_agc;
|
|||
|
|
if( d > 2.5 ){ d = 2.5; } else if( d < -2.5 ){ d = -2.5; }
|
|||
|
|
return d;
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
BOOL __fastcall CAGCX::GetOver(void)
|
|||
|
|
{
|
|||
|
|
// 5.0 / (65536 * 0.666)
|
|||
|
|
return (m_AvgOver.Do(m_agc) < 0.0001146);
|
|||
|
|
// return (m_agc < 0.0001146);
|
|||
|
|
}
|
|||
|
|
/********************************************************
|
|||
|
|
CAMPCONT class by JE3HHT on Sep.2010
|
|||
|
|
*********************************************************/
|
|||
|
|
__fastcall CAMPCONT::CAMPCONT()
|
|||
|
|
{
|
|||
|
|
m_Max = g_SinTable.m_Size / 4;
|
|||
|
|
m_iMax = g_SinTable.m_Size / 4;
|
|||
|
|
m_Cnt = m_Max;
|
|||
|
|
m_S = 0;
|
|||
|
|
SetMax(16);
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CAMPCONT::SetMax(int max)
|
|||
|
|
{
|
|||
|
|
m_ADD = m_Max / double(max);
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall CAMPCONT::Reset(void)
|
|||
|
|
{
|
|||
|
|
m_Cnt = m_Max;
|
|||
|
|
m_S = 0;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
double __fastcall CAMPCONT::Do(int s)
|
|||
|
|
{
|
|||
|
|
if( s != m_S ){
|
|||
|
|
m_Cnt = 0.0;
|
|||
|
|
m_S = s;
|
|||
|
|
}
|
|||
|
|
int r = m_Cnt;
|
|||
|
|
if( r >= m_Max ) return s;
|
|||
|
|
m_Cnt += m_ADD;
|
|||
|
|
if( s ){
|
|||
|
|
return g_SinTable.m_tSin[r];
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
return g_SinTable.m_tSin[r+m_iMax];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/********************************************************
|
|||
|
|
CAA6YQ class by JE3HHT on Sep.2010
|
|||
|
|
*********************************************************/
|
|||
|
|
__fastcall CAA6YQ::CAA6YQ(void)
|
|||
|
|
{
|
|||
|
|
m_fEnabled = FALSE;
|
|||
|
|
m_bpfTaps = 512;
|
|||
|
|
m_bpfFW = 35.0;
|
|||
|
|
m_befTaps = 256;
|
|||
|
|
m_befFW = 15.0;
|
|||
|
|
m_afcERR = 5.0;
|
|||
|
|
|
|||
|
|
m_dblMark = 2125.0;
|
|||
|
|
m_dblSpace = 2295.0;
|
|||
|
|
m_dblMarkAFC = m_dblMark;
|
|||
|
|
m_dblSpaceAFC = m_dblSpace;
|
|||
|
|
Create();
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
void __fastcall CAA6YQ::Create(void)
|
|||
|
|
{
|
|||
|
|
m_BPF.Create(m_bpfTaps, ffBPF, SampFreq, m_dblMark-m_bpfFW, m_dblSpace+m_bpfFW, 60.0, 1.0);
|
|||
|
|
double fc = (m_dblMark + m_dblSpace)/2.0;
|
|||
|
|
m_BEF.Create(m_befTaps, ffBEF, SampFreq, fc-m_befFW, fc+m_befFW, 10.0, 1.0);
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
void __fastcall CAA6YQ::SetMarkFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_dblMark = f;
|
|||
|
|
m_dblMarkAFC = f;
|
|||
|
|
if( m_fEnabled ) Create();
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
void __fastcall CAA6YQ::SetSpaceFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_dblSpace = f;
|
|||
|
|
m_dblSpaceAFC = f;
|
|||
|
|
if( m_fEnabled ) Create();
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
void __fastcall CAA6YQ::SetMarkFreqByAFC(double f)
|
|||
|
|
{
|
|||
|
|
m_dblMark = f;
|
|||
|
|
double df = fabs(f - m_dblMarkAFC);
|
|||
|
|
if( df >= m_afcERR ){
|
|||
|
|
m_dblMarkAFC = f;
|
|||
|
|
if( m_fEnabled ) Create();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
void __fastcall CAA6YQ::SetSpaceFreqByAFC(double f)
|
|||
|
|
{
|
|||
|
|
m_dblSpace = f;
|
|||
|
|
double df = fabs(f - m_dblSpaceAFC);
|
|||
|
|
if( df >= m_afcERR ){
|
|||
|
|
m_dblSpaceAFC = f;
|
|||
|
|
if( m_fEnabled ) Create();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
double __fastcall CAA6YQ::Do(double d)
|
|||
|
|
{
|
|||
|
|
return m_BEF.Do(m_BPF.Do(d));
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
|
|||
|
|
|