mirror of
https://github.com/n5ac/mmsstv.git
synced 2025-12-06 04:12:03 +01:00
3089 lines
67 KiB
C++
3089 lines
67 KiB
C++
|
|
//Copyright+LGPL
|
|||
|
|
|
|||
|
|
//-----------------------------------------------------------------------------------------------------------------------------------------------
|
|||
|
|
// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba
|
|||
|
|
//-----------------------------------------------------------------------------------------------------------------------------------------------
|
|||
|
|
// This file is part of MMSSTV.
|
|||
|
|
|
|||
|
|
// MMSSTV 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.
|
|||
|
|
|
|||
|
|
// MMSSTV 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> //ja7ude 0521
|
|||
|
|
#pragma hdrstop
|
|||
|
|
|
|||
|
|
#include "sstv.h"
|
|||
|
|
|
|||
|
|
double g_dblToneOffset = 0.0;
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
// VCO<43>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CTICK::CTICK()
|
|||
|
|
{
|
|||
|
|
ptbl[0] = new int[CLOCKMAX];
|
|||
|
|
memset(ptbl[0], 0, sizeof(int[CLOCKMAX]));
|
|||
|
|
ptbl[1] = new int[CLOCKMAX];
|
|||
|
|
memset(ptbl[1], 0, sizeof(int[CLOCKMAX]));
|
|||
|
|
}
|
|||
|
|
CTICK::~CTICK()
|
|||
|
|
{
|
|||
|
|
delete ptbl[0];
|
|||
|
|
delete ptbl[1];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
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 + g_dblToneOffset;
|
|||
|
|
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);
|
|||
|
|
while( m_z >= m_TableSize ){
|
|||
|
|
m_z -= m_TableSize;
|
|||
|
|
}
|
|||
|
|
while( m_z < 0 ){
|
|||
|
|
m_z += m_TableSize;
|
|||
|
|
}
|
|||
|
|
return pSinTbl[int(m_z)];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// CScope<70>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CScope::CScope()
|
|||
|
|
{
|
|||
|
|
m_ScopeSize = SCOPESIZE;
|
|||
|
|
m_DataFlag = 1;
|
|||
|
|
|
|||
|
|
pScopeData = NULL;
|
|||
|
|
m_wp = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CScope::~CScope()
|
|||
|
|
{
|
|||
|
|
m_DataFlag = 1;
|
|||
|
|
if( pScopeData != NULL ){
|
|||
|
|
delete pScopeData;
|
|||
|
|
pScopeData = NULL;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CScope::InitMem(void)
|
|||
|
|
{
|
|||
|
|
if( pScopeData == NULL ){
|
|||
|
|
pScopeData = new double[m_ScopeSize];
|
|||
|
|
memset(pScopeData, 0, sizeof(double)*m_ScopeSize);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
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;
|
|||
|
|
InitMem();
|
|||
|
|
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) / 1000000.0;
|
|||
|
|
// return d;
|
|||
|
|
return DoFIR(H, Z, d, NOISEBPFTAP); // <20>ш搧<D188><E690A7>
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// CPLL<4C>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CPLL::CPLL()
|
|||
|
|
{
|
|||
|
|
m_err = 0;
|
|||
|
|
m_out = 0;
|
|||
|
|
m_vcoout = 0;
|
|||
|
|
m_vcogain = 1.0;
|
|||
|
|
m_outgain = 32768.0 * m_vcogain;
|
|||
|
|
m_SampleFreq = SampFreq;
|
|||
|
|
// m_Shift = 800.0;
|
|||
|
|
// m_FreeFreq = (1500 + 2300)/2;
|
|||
|
|
m_loopOrder = 1;
|
|||
|
|
m_loopFC = 1500.0;
|
|||
|
|
m_outOrder = 3;
|
|||
|
|
m_outFC = 900.0;
|
|||
|
|
SetWidth(0);
|
|||
|
|
// SetFreeFreq(1500, 2300);
|
|||
|
|
SetSampleFreq(m_SampleFreq);
|
|||
|
|
|
|||
|
|
m_Max = 1.0;
|
|||
|
|
m_Min = -1.0;
|
|||
|
|
m_d = 0;
|
|||
|
|
m_agc = 1.0;
|
|||
|
|
m_agca = 0.0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CPLL::SetWidth(int fNarrow)
|
|||
|
|
{
|
|||
|
|
if( fNarrow ){
|
|||
|
|
m_Shift = NARROW_BW;
|
|||
|
|
m_FreeFreq = NARROW_CENTER;
|
|||
|
|
SetFreeFreq(NARROW_LOW, NARROW_HIGH);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_Shift = 800.0;
|
|||
|
|
m_FreeFreq = (1500 + 2300)*0.5;
|
|||
|
|
SetFreeFreq(1500, 2300);
|
|||
|
|
}
|
|||
|
|
SetVcoGain(m_vcogain);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CPLL::SetVcoGain(double g)
|
|||
|
|
{
|
|||
|
|
m_vcogain = g;
|
|||
|
|
vco.SetGain(-m_Shift * g);
|
|||
|
|
m_outgain = 32768.0 * m_vcogain;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CPLL::MakeLoopLPF(void)
|
|||
|
|
{
|
|||
|
|
loopLPF.MakeIIR(m_loopFC, m_SampleFreq, m_loopOrder, 0, 0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CPLL::MakeOutLPF(void)
|
|||
|
|
{
|
|||
|
|
outLPF.MakeIIR(m_outFC, m_SampleFreq, m_outOrder, 0, 0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CPLL::SetFreeFreq(double f1, double f2)
|
|||
|
|
{
|
|||
|
|
m_FreeFreq = (f1 + f2)/2.0;
|
|||
|
|
m_Shift = (f2 - f1);
|
|||
|
|
vco.SetFreeFreq(m_FreeFreq + g_dblToneOffset);
|
|||
|
|
vco.SetGain(-m_Shift * m_vcogain);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CPLL::SetSampleFreq(double f)
|
|||
|
|
{
|
|||
|
|
m_SampleFreq = f;
|
|||
|
|
vco.SetSampleFreq(f);
|
|||
|
|
vco.SetFreeFreq(m_FreeFreq + g_dblToneOffset);
|
|||
|
|
SetVcoGain(1.0);
|
|||
|
|
MakeLoopLPF();
|
|||
|
|
MakeOutLPF();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double CPLL::Do(double d)
|
|||
|
|
{
|
|||
|
|
if( m_Max < d ) m_Max = d;
|
|||
|
|
if( m_Min > d ) m_Min = d;
|
|||
|
|
if( (d >= 0) && (m_d < 0) ){
|
|||
|
|
m_agc = m_Max - m_Min;
|
|||
|
|
m_d = (5.0/m_agc);
|
|||
|
|
m_agc = (m_agca + m_d) * 0.5;
|
|||
|
|
m_agca = m_d;
|
|||
|
|
m_Max = 1.0;
|
|||
|
|
m_Min = -1.0;
|
|||
|
|
}
|
|||
|
|
m_d = d;
|
|||
|
|
d *= m_agc;
|
|||
|
|
// Loop Filter
|
|||
|
|
m_out = loopLPF.Do(m_err);
|
|||
|
|
if( m_out > 1.5 ){
|
|||
|
|
m_out = 1.5;
|
|||
|
|
}
|
|||
|
|
else if( m_out < -1.5 ){
|
|||
|
|
m_out = -1.5;
|
|||
|
|
}
|
|||
|
|
// VCO
|
|||
|
|
m_vcoout = vco.Do(m_out);
|
|||
|
|
// <20>ʑ<EFBFBD><CA91><EFBFBD><EFBFBD>r
|
|||
|
|
m_err = m_vcoout * d;
|
|||
|
|
return outLPF.Do(m_out) * m_outgain;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// CFQC<51>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CFQC::CFQC()
|
|||
|
|
{
|
|||
|
|
m_Type = 0;
|
|||
|
|
|
|||
|
|
m_Limit = 1;
|
|||
|
|
m_d = 0;
|
|||
|
|
m_Count = 0;
|
|||
|
|
m_ACount = 0;
|
|||
|
|
m_fq = ZEROFQ;
|
|||
|
|
m_d = 0;
|
|||
|
|
m_out = 0;
|
|||
|
|
m_outOrder = 3;
|
|||
|
|
m_outFC = 900;
|
|||
|
|
m_SmoozFq = 2200;
|
|||
|
|
m_SampFreq = SampFreq;
|
|||
|
|
m_Timer = m_STimer = int(m_SampFreq);
|
|||
|
|
SetWidth(0);
|
|||
|
|
CalcLPF();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFQC::SetWidth(int fNarrow)
|
|||
|
|
{
|
|||
|
|
if( fNarrow ){
|
|||
|
|
m_BWH = NARROW_BWH;
|
|||
|
|
m_CenterFQ = NARROW_CENTER + g_dblToneOffset;
|
|||
|
|
m_HighFQ = 2400.0 + g_dblToneOffset;
|
|||
|
|
m_LowFQ = NARROW_AFCLOW + g_dblToneOffset;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_BWH = 400.0;
|
|||
|
|
m_CenterFQ = 1900.0 + g_dblToneOffset;
|
|||
|
|
m_HighFQ = 2400.0 + g_dblToneOffset;
|
|||
|
|
m_LowFQ = 1000.0 + g_dblToneOffset;
|
|||
|
|
}
|
|||
|
|
m_HighVal = (m_HighFQ - m_CenterFQ) / m_BWH;
|
|||
|
|
m_LowVal = (m_LowFQ - m_CenterFQ) / m_BWH;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFQC::Clear(void)
|
|||
|
|
{
|
|||
|
|
m_d = 0;
|
|||
|
|
m_Count = 0;
|
|||
|
|
m_ACount = 0;
|
|||
|
|
m_fq = ZEROFQ;
|
|||
|
|
m_d = 0;
|
|||
|
|
m_out = 0;
|
|||
|
|
m_Timer = m_STimer;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFQC::SetSampFreq(double fq)
|
|||
|
|
{
|
|||
|
|
m_SampFreq = fq;
|
|||
|
|
CalcLPF();
|
|||
|
|
m_STimer = int(m_SampFreq);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CFQC::CalcLPF(void)
|
|||
|
|
{
|
|||
|
|
m_iir.MakeIIR(m_outFC, m_SampFreq, m_outOrder, 0, 0);
|
|||
|
|
if( m_SmoozFq < 500 ) m_SmoozFq = 500.0;
|
|||
|
|
m_fir.SetCount(m_SampFreq/m_SmoozFq);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double CFQC::Do(double d)
|
|||
|
|
{
|
|||
|
|
double count;
|
|||
|
|
double offset;
|
|||
|
|
|
|||
|
|
if( d >= 0 ){
|
|||
|
|
if( m_d < 0 ){
|
|||
|
|
count = m_Count - m_ACount;
|
|||
|
|
offset = d/(d - m_d);
|
|||
|
|
m_ACount = m_Count - offset;
|
|||
|
|
count -= offset;
|
|||
|
|
if( count >= 1.0 ){
|
|||
|
|
m_fq = m_SampFreq * 0.5 / count;
|
|||
|
|
if( m_Limit ){
|
|||
|
|
if( m_fq > m_HighFQ ){
|
|||
|
|
m_fq = m_HighVal;
|
|||
|
|
}
|
|||
|
|
else if( m_fq < m_LowFQ ){
|
|||
|
|
m_fq = m_LowVal;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fq -= m_CenterFQ;
|
|||
|
|
m_fq /= m_BWH;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fq -= m_CenterFQ;
|
|||
|
|
m_fq /= m_BWH;
|
|||
|
|
m_Timer = m_STimer;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( m_d >= 0 ){
|
|||
|
|
count = m_Count - m_ACount;
|
|||
|
|
offset = d/(d - m_d);
|
|||
|
|
m_ACount = m_Count - offset;
|
|||
|
|
count -= offset;
|
|||
|
|
if( count >= 1.0 ){
|
|||
|
|
m_fq = m_SampFreq * 0.5 / count;
|
|||
|
|
if( m_Limit ){
|
|||
|
|
if( m_fq > m_HighFQ ){
|
|||
|
|
m_fq = m_HighVal;
|
|||
|
|
}
|
|||
|
|
else if( m_fq < m_LowFQ ){
|
|||
|
|
m_fq = m_LowVal;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fq -= m_CenterFQ;
|
|||
|
|
m_fq /= m_BWH;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fq -= m_CenterFQ;
|
|||
|
|
m_fq /= m_BWH;
|
|||
|
|
m_Timer = m_STimer;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( !m_Limit && m_Timer ){
|
|||
|
|
m_Timer--;
|
|||
|
|
if( !m_Timer ) m_fq = -m_CenterFQ/m_BWH;
|
|||
|
|
}
|
|||
|
|
switch(m_Type){
|
|||
|
|
case 0: // IIR
|
|||
|
|
m_out = m_iir.Do(m_fq);
|
|||
|
|
break;
|
|||
|
|
case 1: // FIR
|
|||
|
|
m_out = m_fir.Avg(m_fq);
|
|||
|
|
break;
|
|||
|
|
default: // OFF
|
|||
|
|
m_out = m_fq;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
m_d = d;
|
|||
|
|
m_Count++;
|
|||
|
|
return -(m_out * 16384);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
CSSTVSET SSTVSET;
|
|||
|
|
LPCSTR SSTVModeList[]={
|
|||
|
|
"Robot 36", "Robot 72", "AVT 90", "Scottie 1", "Scottie 2", "ScottieDX",
|
|||
|
|
"Martin 1", "Martin 2", "SC2 180", "SC2 120", "SC2 60",
|
|||
|
|
"PD50", "PD90", "PD120", "PD160", "PD180", "PD240", "PD290",
|
|||
|
|
"P3", "P5", "P7",
|
|||
|
|
"MR73", "MR90", "MR115", "MR140", "MR175",
|
|||
|
|
"MP73", "MP115", "MP140", "MP175",
|
|||
|
|
"ML180", "ML240", "ML280", "ML320",
|
|||
|
|
"Robot 24", "B/W 8", "B/W 12",
|
|||
|
|
"MP73-N", "MP110-N", "MP140-N","MC110-N","MC140-N","MC180-N",
|
|||
|
|
};
|
|||
|
|
const BYTE SSTVModeOdr[]={
|
|||
|
|
smRM8,
|
|||
|
|
smRM12,
|
|||
|
|
smR24,
|
|||
|
|
smR36,
|
|||
|
|
smR72,
|
|||
|
|
smAVT,
|
|||
|
|
smSCT1,
|
|||
|
|
smSCT2,
|
|||
|
|
smSCTDX,
|
|||
|
|
smMRT1,
|
|||
|
|
smMRT2,
|
|||
|
|
smSC2_180,
|
|||
|
|
smSC2_120,
|
|||
|
|
smSC2_60,
|
|||
|
|
smPD50,
|
|||
|
|
smPD90,
|
|||
|
|
smPD120,
|
|||
|
|
smPD160,
|
|||
|
|
smPD180,
|
|||
|
|
smPD240,
|
|||
|
|
smPD290,
|
|||
|
|
smP3,
|
|||
|
|
smP5,
|
|||
|
|
smP7,
|
|||
|
|
smMP73,
|
|||
|
|
smMP115,
|
|||
|
|
smMP140,
|
|||
|
|
smMP175,
|
|||
|
|
smMR73,
|
|||
|
|
smMR90,
|
|||
|
|
smMR115,
|
|||
|
|
smMR140,
|
|||
|
|
smMR175,
|
|||
|
|
smML180,
|
|||
|
|
smML240,
|
|||
|
|
smML280,
|
|||
|
|
smML320,
|
|||
|
|
smMN73,
|
|||
|
|
smMN110,
|
|||
|
|
smMN140,
|
|||
|
|
smMC110,
|
|||
|
|
smMC140,
|
|||
|
|
smMC180,
|
|||
|
|
};
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
BOOL __fastcall IsNarrowMode(int mode)
|
|||
|
|
{
|
|||
|
|
switch(mode){
|
|||
|
|
case smMN73:
|
|||
|
|
case smMN110:
|
|||
|
|
case smMN140:
|
|||
|
|
case smMC110:
|
|||
|
|
case smMC140:
|
|||
|
|
case smMC180:
|
|||
|
|
return TRUE;
|
|||
|
|
default:
|
|||
|
|
return FALSE;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// CSSTVDEM<45>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CSSTVSET::CSSTVSET()
|
|||
|
|
{
|
|||
|
|
m_fNarrow = m_fTxNarrow = 0;
|
|||
|
|
m_TxMode = smSCT1;
|
|||
|
|
SetMode(smSCT1);
|
|||
|
|
InitIntervalPara();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVSET::InitIntervalPara(void)
|
|||
|
|
{
|
|||
|
|
for( int i = 0; i < smEND; i++ ){
|
|||
|
|
m_MS[i] = GetTiming(i) * m_SampFreq / 1000.0;
|
|||
|
|
}
|
|||
|
|
m_MS[2] = 0; // AVT
|
|||
|
|
// m_MSLL = 100.0 * m_SampFreq / 1000.0; // Lowest
|
|||
|
|
// m_MSL = 147.0 * m_SampFreq / 1000.0; // Lowest
|
|||
|
|
// m_MSH = 1050.0 * 3 * m_SampFreq / 1000.0; // Highest
|
|||
|
|
m_MSLL = 50.0 * m_SampFreq / 1000.0; // Lowest
|
|||
|
|
m_MSL = 63.0 * m_SampFreq / 1000.0; // Lowest
|
|||
|
|
m_MSH = 1390.0 * 3 * m_SampFreq / 1000.0; // Highest
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVSET::SetMode(int mode)
|
|||
|
|
{
|
|||
|
|
m_SampFreq = sys.m_SampFreq;
|
|||
|
|
m_Mode = mode;
|
|||
|
|
m_fNarrow = IsNarrowMode(mode);
|
|||
|
|
SetSampFreq();
|
|||
|
|
m_WD = int(m_TW);
|
|||
|
|
m_LM = int(m_TW * m_L) + 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVSET::SetTxMode(int mode)
|
|||
|
|
{
|
|||
|
|
m_TxSampFreq = sys.m_SampFreq + sys.m_TxSampOff;
|
|||
|
|
m_TxMode = mode;
|
|||
|
|
m_fTxNarrow = IsNarrowMode(mode);
|
|||
|
|
SetTxSampFreq();
|
|||
|
|
m_TWD = int(m_TTW);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVSET::GetBitmapSize(int &w, int &h, int mode)
|
|||
|
|
{
|
|||
|
|
switch(mode){
|
|||
|
|
case smPD120:
|
|||
|
|
case smPD180:
|
|||
|
|
case smPD240:
|
|||
|
|
case smP3:
|
|||
|
|
case smP5:
|
|||
|
|
case smP7:
|
|||
|
|
case smML180:
|
|||
|
|
case smML240:
|
|||
|
|
case smML280:
|
|||
|
|
case smML320:
|
|||
|
|
w = 640;
|
|||
|
|
h = 496;
|
|||
|
|
break;
|
|||
|
|
case smPD160:
|
|||
|
|
w = 512;
|
|||
|
|
h = 400;
|
|||
|
|
break;
|
|||
|
|
case smPD290:
|
|||
|
|
w = 800;
|
|||
|
|
h = 616;
|
|||
|
|
break;
|
|||
|
|
default: // SCT1
|
|||
|
|
w = 320;
|
|||
|
|
h = 256;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVSET::GetPictureSize(int &w, int &h, int &hp, int mode)
|
|||
|
|
{
|
|||
|
|
GetBitmapSize(w, h, mode);
|
|||
|
|
switch(mode){
|
|||
|
|
case smRM8:
|
|||
|
|
case smRM12:
|
|||
|
|
case smR24:
|
|||
|
|
case smR36:
|
|||
|
|
case smR72:
|
|||
|
|
case smAVT:
|
|||
|
|
hp = 240;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
hp = h;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVSET::SetSampFreq(void)
|
|||
|
|
{
|
|||
|
|
switch(m_Mode){
|
|||
|
|
case smR36:
|
|||
|
|
m_KS = 88.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_KS2 = 44.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 12.0 * m_SampFreq / 1000.0;
|
|||
|
|
// m_OFP = 10.8 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.7 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = (88.0 + 1.25) * m_SampFreq / 1000.0;
|
|||
|
|
m_CG = (88.0 + 3.5) * SampFreq/1000.0;
|
|||
|
|
m_SB = 94.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_CB = m_SB + m_KS2;
|
|||
|
|
m_L = 240;
|
|||
|
|
break;
|
|||
|
|
case smR72:
|
|||
|
|
m_KS = 138.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_KS2 = 69.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 12.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.7 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = 144.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_CG = m_SG + m_KS2;
|
|||
|
|
m_SB = 219.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_CB = m_SB + m_KS2;
|
|||
|
|
m_L = 240;
|
|||
|
|
break;
|
|||
|
|
case smAVT:
|
|||
|
|
m_KS = 125.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 0.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 0.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 240;
|
|||
|
|
break;
|
|||
|
|
case smSCT2:
|
|||
|
|
m_KS = 88.064 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 10.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.8 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = 89.564 * m_SampFreq / 1000.0;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smSCTDX:
|
|||
|
|
m_KS = 345.6 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 10.5 * m_SampFreq / 1000.0;
|
|||
|
|
// m_OFP = 9.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.2 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = 347.1 * m_SampFreq / 1000.0;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smMRT1:
|
|||
|
|
m_KS = 146.432 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 5.434 * m_SampFreq / 1000.0;
|
|||
|
|
// m_OFP = 7.3 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 7.2 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = 147.004 * m_SampFreq / 1000.0;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smMRT2:
|
|||
|
|
m_KS = 73.216 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 5.434 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 7.4 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = 73.788 * m_SampFreq / 1000.0;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smSC2_180:
|
|||
|
|
m_KS = 235.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 6.0437 * m_SampFreq / 1000.0;
|
|||
|
|
// m_OFP = 7.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 7.8 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smSC2_120:
|
|||
|
|
m_KS = 156.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 6.02248 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 7.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smSC2_60:
|
|||
|
|
m_KS = 78.128 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 6.0006 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 7.9 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smPD50:
|
|||
|
|
m_KS = 91.520 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 22.080 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 19.300 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 128;
|
|||
|
|
break;
|
|||
|
|
case smPD90:
|
|||
|
|
m_KS = 170.240 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 22.080 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 18.900 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 128;
|
|||
|
|
break;
|
|||
|
|
case smPD120:
|
|||
|
|
m_KS = 121.600 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 22.080 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 19.400 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 248;
|
|||
|
|
break;
|
|||
|
|
case smPD160:
|
|||
|
|
m_KS = 195.584 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 22.080 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 18.900 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 200;
|
|||
|
|
break;
|
|||
|
|
case smPD180:
|
|||
|
|
m_KS = 183.04 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 22.080 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 18.900 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 248;
|
|||
|
|
break;
|
|||
|
|
case smPD240:
|
|||
|
|
m_KS = 244.48 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 22.080 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 18.900 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 248;
|
|||
|
|
break;
|
|||
|
|
case smPD290:
|
|||
|
|
m_KS = 228.80 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 22.080 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 18.900 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 616/2;
|
|||
|
|
break;
|
|||
|
|
case smP3:
|
|||
|
|
m_KS = 133.333 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = (5.208 + 1.042) * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 7.80 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = (133.333 + 1.042) * m_SampFreq / 1000.0;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 496;
|
|||
|
|
break;
|
|||
|
|
case smP5:
|
|||
|
|
m_KS = 200.000 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = (7.813 + 1.562375) * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 9.20 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = (200.000 + 1.562375) * m_SampFreq / 1000.0;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 496;
|
|||
|
|
break;
|
|||
|
|
case smP7:
|
|||
|
|
m_KS = 266.667 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = (10.417 + 2.083) * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 11.50 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = (266.667 + 2.083) * m_SampFreq / 1000.0;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 496;
|
|||
|
|
break;
|
|||
|
|
case smMR73:
|
|||
|
|
//|--KS--|--KS2--|--KS2--|
|
|||
|
|
// SG CG=SB CB
|
|||
|
|
m_KS = 138.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_KS2 = m_KS * 0.5;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.6 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS + 0.1;
|
|||
|
|
m_CG = m_SG + m_KS2;
|
|||
|
|
m_SB = m_CG + 0.1;
|
|||
|
|
m_CB = m_SB + m_KS2;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smMR90:
|
|||
|
|
m_KS = 171.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_KS2 = m_KS * 0.5;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.6 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS + 0.1;
|
|||
|
|
m_CG = m_SG + m_KS2;
|
|||
|
|
m_SB = m_CG + 0.1;
|
|||
|
|
m_CB = m_SB + m_KS2;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smMR115:
|
|||
|
|
m_KS = 220.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_KS2 = m_KS * 0.5;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.6 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS + 0.1;
|
|||
|
|
m_CG = m_SG + m_KS2;
|
|||
|
|
m_SB = m_CG + 0.1;
|
|||
|
|
m_CB = m_SB + m_KS2;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smMR140:
|
|||
|
|
m_KS = 269.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_KS2 = m_KS * 0.5;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.6 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS + 0.1;
|
|||
|
|
m_CG = m_SG + m_KS2;
|
|||
|
|
m_SB = m_CG + 0.1;
|
|||
|
|
m_CB = m_SB + m_KS2;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smMR175:
|
|||
|
|
m_KS = 337.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_KS2 = m_KS * 0.5;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.6 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS + 0.1;
|
|||
|
|
m_CG = m_SG + m_KS2;
|
|||
|
|
m_SB = m_CG + 0.1;
|
|||
|
|
m_CB = m_SB + m_KS2;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smMP73:
|
|||
|
|
m_KS = 140.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 128;
|
|||
|
|
break;
|
|||
|
|
case smMP115:
|
|||
|
|
m_KS = 223.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 128;
|
|||
|
|
break;
|
|||
|
|
case smMP140:
|
|||
|
|
m_KS = 270.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 128;
|
|||
|
|
break;
|
|||
|
|
case smMP175:
|
|||
|
|
m_KS = 340.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 128;
|
|||
|
|
break;
|
|||
|
|
case smML180:
|
|||
|
|
m_KS = 176.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_KS2 = m_KS * 0.5;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.6 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS + 0.1;
|
|||
|
|
m_CG = m_SG + m_KS2;
|
|||
|
|
m_SB = m_CG + 0.1;
|
|||
|
|
m_CB = m_SB + m_KS2;
|
|||
|
|
m_L = 496;
|
|||
|
|
break;
|
|||
|
|
case smML240:
|
|||
|
|
m_KS = 236.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_KS2 = m_KS * 0.5;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.6 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS + 0.1;
|
|||
|
|
m_CG = m_SG + m_KS2;
|
|||
|
|
m_SB = m_CG + 0.1;
|
|||
|
|
m_CB = m_SB + m_KS2;
|
|||
|
|
m_L = 496;
|
|||
|
|
break;
|
|||
|
|
case smML280:
|
|||
|
|
m_KS = 277.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_KS2 = m_KS * 0.5;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.6 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS + 0.1;
|
|||
|
|
m_CG = m_SG + m_KS2;
|
|||
|
|
m_SB = m_CG + 0.1;
|
|||
|
|
m_CB = m_SB + m_KS2;
|
|||
|
|
m_L = 496;
|
|||
|
|
break;
|
|||
|
|
case smML320:
|
|||
|
|
m_KS = 317.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_KS2 = m_KS * 0.5;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.6 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS + 0.1;
|
|||
|
|
m_CG = m_SG + m_KS2;
|
|||
|
|
m_SB = m_CG + 0.1;
|
|||
|
|
m_CB = m_SB + m_KS2;
|
|||
|
|
m_L = 496;
|
|||
|
|
break;
|
|||
|
|
case smR24:
|
|||
|
|
m_KS = 92.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_KS2 = 46.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 8.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 8.1 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS + 4.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_CG = m_SG + m_KS2;
|
|||
|
|
m_SB = m_CG + 4.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_CB = m_SB + m_KS2;
|
|||
|
|
m_L = 120;
|
|||
|
|
break;
|
|||
|
|
case smRM8:
|
|||
|
|
m_KS = 58.89709 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 8.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 8.2 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 120;
|
|||
|
|
break;
|
|||
|
|
case smRM12:
|
|||
|
|
m_KS = 92.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 8.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 8.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 120;
|
|||
|
|
break;
|
|||
|
|
case smMN73:
|
|||
|
|
m_KS = 140.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 128;
|
|||
|
|
break;
|
|||
|
|
case smMN110:
|
|||
|
|
m_KS = 212.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 128;
|
|||
|
|
break;
|
|||
|
|
case smMN140:
|
|||
|
|
m_KS = 270.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 10.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 128;
|
|||
|
|
break;
|
|||
|
|
case smMC110:
|
|||
|
|
m_KS = 140.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 8.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 8.95 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smMC140:
|
|||
|
|
m_KS = 180.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 8.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 8.75 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
case smMC180:
|
|||
|
|
m_KS = 232.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 8.0 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 8.75 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = m_KS;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
// case smSCT1:
|
|||
|
|
default: // SCT1
|
|||
|
|
m_KS = 138.24 * m_SampFreq / 1000.0;
|
|||
|
|
m_OF = 10.5 * m_SampFreq / 1000.0;
|
|||
|
|
m_OFP = 10.7 * m_SampFreq / 1000.0;
|
|||
|
|
m_SG = 139.74 * m_SampFreq / 1000.0;
|
|||
|
|
m_CG = m_KS + m_SG;
|
|||
|
|
m_SB = m_SG + m_SG;
|
|||
|
|
m_CB = m_KS + m_SB;
|
|||
|
|
m_L = 256;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
m_TW = GetTiming(m_Mode) * m_SampFreq / 1000.0;
|
|||
|
|
switch(m_Mode){
|
|||
|
|
case smPD120:
|
|||
|
|
case smPD160:
|
|||
|
|
case smPD180:
|
|||
|
|
case smPD240:
|
|||
|
|
case smPD290:
|
|||
|
|
case smP3:
|
|||
|
|
case smP5:
|
|||
|
|
case smP7:
|
|||
|
|
m_KSS = (m_KS - m_KS/480.0); // TW for Y or RGB mode
|
|||
|
|
m_KS2S = (m_KS2 - m_KS2/480.0); // TW for Ry, By
|
|||
|
|
m_KSB = (m_KSS / 1280.0); // TW for black adjutment
|
|||
|
|
break;
|
|||
|
|
case smMP73:
|
|||
|
|
case smMN73:
|
|||
|
|
case smSCTDX:
|
|||
|
|
m_KSS = (m_KS - m_KS/1280.0); // TW for Y or RGB mode
|
|||
|
|
m_KS2S = (m_KS2 - m_KS2/1280.0); // TW for Ry, By
|
|||
|
|
m_KSB = m_KSS / 1280.0;
|
|||
|
|
break;
|
|||
|
|
case smSC2_180:
|
|||
|
|
case smMP115:
|
|||
|
|
case smMP140:
|
|||
|
|
case smMP175:
|
|||
|
|
case smMR90:
|
|||
|
|
case smMR115:
|
|||
|
|
case smMR140:
|
|||
|
|
case smMR175:
|
|||
|
|
case smML180:
|
|||
|
|
case smML240:
|
|||
|
|
case smML280:
|
|||
|
|
case smML320:
|
|||
|
|
case smMN110:
|
|||
|
|
case smMN140:
|
|||
|
|
case smMC110:
|
|||
|
|
case smMC140:
|
|||
|
|
case smMC180:
|
|||
|
|
m_KSS = m_KS; // TW for Y or RGB mode
|
|||
|
|
m_KS2S = m_KS2; // TW for Ry, By
|
|||
|
|
m_KSB = m_KSS / 1280.0;
|
|||
|
|
break;
|
|||
|
|
case smMR73:
|
|||
|
|
m_KSS = (m_KS - m_KS/640.0); // TW for Y or RGB mode
|
|||
|
|
m_KS2S = (m_KS2 - m_KS2/1024.0); // TW for Ry, By
|
|||
|
|
m_KSB = m_KSS / 1024.0;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
m_KSS = (m_KS - m_KS/240.0); // TW for Y or RGB mode
|
|||
|
|
m_KS2S = (m_KS2 - m_KS2/240.0); // TW for Ry, By
|
|||
|
|
m_KSB = (m_KSS / 640.0); // TW for black adjutment
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
switch(m_Mode){
|
|||
|
|
case smMRT1:
|
|||
|
|
case smMRT2:
|
|||
|
|
case smSC2_60:
|
|||
|
|
case smSC2_120:
|
|||
|
|
case smSC2_180:
|
|||
|
|
case smMC110:
|
|||
|
|
case smMC140:
|
|||
|
|
case smMC180:
|
|||
|
|
m_AFCW = 2.0 * SampFreq / 1000.0;
|
|||
|
|
m_AFCB = 1.0 * SampFreq / 1000.0;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
m_AFCW = 3.0 * SampFreq / 1000.0;
|
|||
|
|
m_AFCB = 1.5 * SampFreq / 1000.0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if( !m_KSB ) m_KSB++;
|
|||
|
|
|
|||
|
|
if( sys.m_bCQ100 ){
|
|||
|
|
double d = m_OFP * 1000.0 / SampFreq;
|
|||
|
|
m_OFP = (d + (1100.0/g_dblToneOffset)) * SampFreq / 1000.0;
|
|||
|
|
}
|
|||
|
|
m_AFCE = m_AFCB + m_AFCW;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double CSSTVSET::GetTiming(int mode)
|
|||
|
|
{
|
|||
|
|
switch(mode){
|
|||
|
|
case smR36:
|
|||
|
|
return 150.0;
|
|||
|
|
case smR72:
|
|||
|
|
return 300.0;
|
|||
|
|
case smAVT:
|
|||
|
|
return 375;
|
|||
|
|
case smSCT2:
|
|||
|
|
return 277.692;
|
|||
|
|
case smSCTDX:
|
|||
|
|
return 1050.3;
|
|||
|
|
case smMRT1:
|
|||
|
|
return 446.446;
|
|||
|
|
case smMRT2:
|
|||
|
|
return 226.798;
|
|||
|
|
case smSC2_180:
|
|||
|
|
return 711.0437;
|
|||
|
|
case smSC2_120:
|
|||
|
|
return 475.52248;
|
|||
|
|
case smSC2_60:
|
|||
|
|
return 240.3846;
|
|||
|
|
case smPD50:
|
|||
|
|
return 388.160;
|
|||
|
|
case smPD90:
|
|||
|
|
return 703.040;
|
|||
|
|
case smPD120:
|
|||
|
|
return 508.480;
|
|||
|
|
case smPD160:
|
|||
|
|
return 804.416;
|
|||
|
|
case smPD180:
|
|||
|
|
return 754.24;
|
|||
|
|
case smPD240:
|
|||
|
|
return 1000.00;
|
|||
|
|
case smPD290:
|
|||
|
|
return 937.28;
|
|||
|
|
case smP3:
|
|||
|
|
return 409.375;
|
|||
|
|
case smP5:
|
|||
|
|
return 614.0625;
|
|||
|
|
case smP7:
|
|||
|
|
return 818.75;
|
|||
|
|
case smMR73:
|
|||
|
|
return 286.3;
|
|||
|
|
case smMR90:
|
|||
|
|
return 352.3;
|
|||
|
|
case smMR115:
|
|||
|
|
return 450.3;
|
|||
|
|
case smMR140:
|
|||
|
|
return 548.3; //269*2 + 10;
|
|||
|
|
case smMR175:
|
|||
|
|
return 684.3; //337*2 + 10;
|
|||
|
|
case smMP73:
|
|||
|
|
return 570.0;
|
|||
|
|
case smMP115:
|
|||
|
|
return 902.0;
|
|||
|
|
case smMP140:
|
|||
|
|
return 1090.0;
|
|||
|
|
case smMP175:
|
|||
|
|
return 1370.0;
|
|||
|
|
case smML180:
|
|||
|
|
return 363.3;
|
|||
|
|
case smML240:
|
|||
|
|
return 483.3;
|
|||
|
|
case smML280:
|
|||
|
|
return 565.3;
|
|||
|
|
case smML320:
|
|||
|
|
return 645.3;
|
|||
|
|
case smR24:
|
|||
|
|
return 200.0;
|
|||
|
|
case smRM8:
|
|||
|
|
return 66.89709;
|
|||
|
|
case smRM12:
|
|||
|
|
return 100.0;
|
|||
|
|
case smMN73:
|
|||
|
|
return 570.0;
|
|||
|
|
case smMN110:
|
|||
|
|
return 858.0;
|
|||
|
|
case smMN140:
|
|||
|
|
return 1090.0;
|
|||
|
|
case smMC110:
|
|||
|
|
return 428.5;
|
|||
|
|
case smMC140:
|
|||
|
|
return 548.5;
|
|||
|
|
case smMC180:
|
|||
|
|
return 704.5;
|
|||
|
|
default: // smSCT1
|
|||
|
|
return 428.22;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVSET::SetTxSampFreq(void)
|
|||
|
|
{
|
|||
|
|
int dm1, dm2;
|
|||
|
|
GetPictureSize(dm1, dm2, m_TL, m_TxMode);
|
|||
|
|
m_TTW = GetTiming(m_TxMode) * m_TxSampFreq / 1000.0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// CSSTVDEM<45>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
int CSYNCINT::SyncCheckSub(int am)
|
|||
|
|
{
|
|||
|
|
int i = MSYNCLINE-1;
|
|||
|
|
|
|||
|
|
int e;
|
|||
|
|
switch(am){
|
|||
|
|
case smSC2_60:
|
|||
|
|
case smSC2_120:
|
|||
|
|
return 0;
|
|||
|
|
case smR24:
|
|||
|
|
case smR36:
|
|||
|
|
case smMRT2:
|
|||
|
|
case smPD50:
|
|||
|
|
case smPD240:
|
|||
|
|
if( m_fNarrow ) return 0;
|
|||
|
|
e = MSYNCLINE - 4;
|
|||
|
|
break;
|
|||
|
|
case smRM8:
|
|||
|
|
case smRM12:
|
|||
|
|
if( m_fNarrow ) return 0;
|
|||
|
|
e = 0;
|
|||
|
|
break;
|
|||
|
|
case smMN73:
|
|||
|
|
case smMN110:
|
|||
|
|
case smMN140:
|
|||
|
|
case smMC110:
|
|||
|
|
case smMC140:
|
|||
|
|
case smMC180:
|
|||
|
|
if( !m_fNarrow ) return 0;
|
|||
|
|
e = MSYNCLINE - 5;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
if( m_fNarrow ) return 0;
|
|||
|
|
e = MSYNCLINE - 3;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
DWORD deff = (3 * SampFreq) / 1000;
|
|||
|
|
DWORD cml = SSTVSET.m_MS[am];
|
|||
|
|
DWORD cmh = cml + deff;
|
|||
|
|
cml -= deff;
|
|||
|
|
DWORD w;
|
|||
|
|
for( i--; i >= e; i-- ){
|
|||
|
|
w = m_MSyncList[i];
|
|||
|
|
int f = 0;
|
|||
|
|
if( w > SSTVSET.m_MSL ){
|
|||
|
|
if( m_fNarrow ){
|
|||
|
|
for( int k = 1; k <= 2; k++ ){
|
|||
|
|
DWORD ww = w / k;
|
|||
|
|
if( (ww > cml) && (ww < cmh) ) f = 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
for( int k = 1; k <= 3; k++ ){
|
|||
|
|
DWORD ww = w / k;
|
|||
|
|
if( (ww > cml) && (ww < cmh) ) f = 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( !f ) return 0;
|
|||
|
|
}
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CSYNCINT::SyncCheck(void)
|
|||
|
|
{
|
|||
|
|
DWORD deff = (3 * SampFreq) / 1000;
|
|||
|
|
|
|||
|
|
DWORD w = m_MSyncList[MSYNCLINE-1];
|
|||
|
|
for( int k = 1; k <= 3; k++ ){
|
|||
|
|
DWORD ww = w / k;
|
|||
|
|
if( (ww > SSTVSET.m_MSL) && (ww < SSTVSET.m_MSH) ){
|
|||
|
|
for( int i = 0; i < smEND; i++ ){
|
|||
|
|
if( SSTVSET.m_MS[i] && (ww > (SSTVSET.m_MS[i]-deff)) && (ww < (SSTVSET.m_MS[i]+deff)) ){
|
|||
|
|
if( SyncCheckSub(i) ){
|
|||
|
|
return i + 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSYNCINT::SyncInc(void)
|
|||
|
|
{
|
|||
|
|
m_MSyncCnt++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSYNCINT::SyncTrig(int d)
|
|||
|
|
{
|
|||
|
|
m_MSyncIntMax = d;
|
|||
|
|
m_MSyncIntPos = m_MSyncCnt;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSYNCINT::SyncMax(int d)
|
|||
|
|
{
|
|||
|
|
if( m_MSyncIntMax < d ){
|
|||
|
|
m_MSyncIntMax = d;
|
|||
|
|
m_MSyncIntPos = m_MSyncCnt;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CSYNCINT::SyncStart(void)
|
|||
|
|
{
|
|||
|
|
int ss = 0;
|
|||
|
|
if( m_MSyncIntMax ){
|
|||
|
|
if( (m_MSyncIntPos - m_MSyncACnt) > SSTVSET.m_MSLL ){
|
|||
|
|
m_MSyncACnt = m_MSyncIntPos - m_MSyncACnt;
|
|||
|
|
memcpy(m_MSyncList, &m_MSyncList[1], sizeof(int) * (MSYNCLINE - 1));
|
|||
|
|
m_MSyncList[MSYNCLINE - 1] = m_MSyncACnt;
|
|||
|
|
if( m_MSyncACnt > SSTVSET.m_MSL ){
|
|||
|
|
ss = SyncCheck();
|
|||
|
|
}
|
|||
|
|
m_MSyncACnt = m_MSyncIntPos;
|
|||
|
|
}
|
|||
|
|
m_MSyncIntMax = 0;
|
|||
|
|
}
|
|||
|
|
return ss;
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// CSSTVDEM<45>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CSSTVDEM::CSSTVDEM()
|
|||
|
|
{
|
|||
|
|
m_bpf = 1; // wide
|
|||
|
|
m_ad = 0;
|
|||
|
|
|
|||
|
|
m_StgBuf = NULL;
|
|||
|
|
m_StgB12 = NULL;
|
|||
|
|
m_BWidth = 1400 * SampFreq / 1000;
|
|||
|
|
int n = SSTVDEMBUFMAX * m_BWidth;
|
|||
|
|
m_Buf = new short[n];
|
|||
|
|
m_B12 = new short[n];
|
|||
|
|
::VirtualLock(m_Buf, n);
|
|||
|
|
::VirtualLock(m_B12, n);
|
|||
|
|
memset(m_Buf, 0, n);
|
|||
|
|
memset(m_B12, 0, n);
|
|||
|
|
|
|||
|
|
m_pll.SetSampleFreq(SampFreq);
|
|||
|
|
m_pll.SetVcoGain(1.0);
|
|||
|
|
m_pll.SetFreeFreq(1500, 2300);
|
|||
|
|
m_pll.m_loopOrder = 1;
|
|||
|
|
m_pll.m_loopFC = 1500;
|
|||
|
|
m_pll.m_outOrder = 3;
|
|||
|
|
m_pll.m_outFC = 900;
|
|||
|
|
m_pll.MakeLoopLPF();
|
|||
|
|
m_pll.MakeOutLPF();
|
|||
|
|
|
|||
|
|
memset(HBPF, 0, sizeof(HBPF));
|
|||
|
|
memset(HBPFS, 0, sizeof(HBPFS));
|
|||
|
|
memset(HBPFN, 0, sizeof(HBPFN));
|
|||
|
|
// memset(Z, 0, sizeof(Z));
|
|||
|
|
CalcBPF();
|
|||
|
|
|
|||
|
|
m_iir11.SetFreq(1080 + g_dblToneOffset, SampFreq, 80.0);
|
|||
|
|
m_iir12.SetFreq(1200 + g_dblToneOffset, SampFreq, 100.0);
|
|||
|
|
m_iir13.SetFreq(1320 + g_dblToneOffset, SampFreq, 80.0);
|
|||
|
|
m_iir19.SetFreq(1900 + g_dblToneOffset, SampFreq, 100.0);
|
|||
|
|
m_iirfsk.SetFreq(FSKSPACE + g_dblToneOffset, SampFreq, 100.0);
|
|||
|
|
m_lpf11.MakeIIR(50, SampFreq, 2, 0, 0);
|
|||
|
|
m_lpf12.MakeIIR(50, SampFreq, 2, 0, 0);
|
|||
|
|
m_lpf13.MakeIIR(50, SampFreq, 2, 0, 0);
|
|||
|
|
m_lpf19.MakeIIR(50, SampFreq, 2, 0, 0);
|
|||
|
|
m_lpffsk.MakeIIR(50, SampFreq, 2, 0, 0);
|
|||
|
|
|
|||
|
|
pRep = NULL;
|
|||
|
|
|
|||
|
|
m_wPage = m_rPage = 0;
|
|||
|
|
m_wBase = 0;
|
|||
|
|
m_wCnt = 0;
|
|||
|
|
m_rBase = 0;
|
|||
|
|
m_Skip = 0;
|
|||
|
|
m_Sync = 0;
|
|||
|
|
m_SyncMode = 0;
|
|||
|
|
m_ScopeFlag = 0;
|
|||
|
|
m_LoopBack = 0;
|
|||
|
|
m_Lost = 0;
|
|||
|
|
|
|||
|
|
m_lvl.m_agcfast = 1;
|
|||
|
|
m_afc = 1;
|
|||
|
|
|
|||
|
|
m_Tick = 0;
|
|||
|
|
pTick = NULL;
|
|||
|
|
m_Avg.SetCount(2.5*SampFreq/1000.0);
|
|||
|
|
m_AFCAVG.SetCount(15);
|
|||
|
|
m_AFCFQ = 0;
|
|||
|
|
m_AFCInt = 100 * SampFreq / 1000.0;
|
|||
|
|
m_AFCDis = 0;
|
|||
|
|
|
|||
|
|
m_sint1.Reset();
|
|||
|
|
m_sint2.Reset();
|
|||
|
|
m_sint3.m_fNarrow = TRUE;
|
|||
|
|
m_sint3.Reset();
|
|||
|
|
m_MSync = 1; // Sync remote start ON
|
|||
|
|
m_SyncRestart = 1;
|
|||
|
|
m_SyncAVT = 0;
|
|||
|
|
|
|||
|
|
m_SenseLvl = 1;
|
|||
|
|
SetSenseLvl();
|
|||
|
|
|
|||
|
|
m_Type = 2;
|
|||
|
|
m_ReqSave = 0;
|
|||
|
|
m_LevelType = 0;
|
|||
|
|
|
|||
|
|
m_fskrec = 0;
|
|||
|
|
m_fskNRrec = 0;
|
|||
|
|
m_fskdecode = 0;
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
|
|||
|
|
m_Repeater = 0;
|
|||
|
|
m_RepSQ = 6000;
|
|||
|
|
m_RepTone = 1750;
|
|||
|
|
m_repmode = 0;
|
|||
|
|
m_repANS = m_repRLY = m_repRX = m_repTX = 0;
|
|||
|
|
InitRepeater();
|
|||
|
|
SetRepSenseLvl();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CSSTVDEM::~CSSTVDEM()
|
|||
|
|
{
|
|||
|
|
::VirtualUnlock(m_Buf, SSTVDEMBUFMAX * m_BWidth);
|
|||
|
|
::VirtualUnlock(m_B12, SSTVDEMBUFMAX * m_BWidth);
|
|||
|
|
delete m_B12;
|
|||
|
|
delete m_Buf;
|
|||
|
|
FreeRxBuff();
|
|||
|
|
if( pRep != NULL ){
|
|||
|
|
delete pRep;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::CalcBPF(double *H1, double *H2, double *H3, int &bpftap, int bpf, int mode)
|
|||
|
|
{
|
|||
|
|
int lfq = (m_SyncRestart ? 1100 : 1200) + g_dblToneOffset;
|
|||
|
|
int lfq2 = 400 + g_dblToneOffset;
|
|||
|
|
if( lfq2 < 50 ) lfq2 = 50;
|
|||
|
|
switch(bpf){
|
|||
|
|
case 1: // Wide
|
|||
|
|
bpftap = 24 * SampFreq / 11025.0;
|
|||
|
|
MakeFilter(H1, bpftap, ffBPF, SampFreq, lfq, 2600 + g_dblToneOffset, 20, 1.0);
|
|||
|
|
MakeFilter(H2, bpftap, ffBPF, SampFreq, lfq2, 2500 + g_dblToneOffset, 20, 1.0);
|
|||
|
|
// MakeFilter(H3, bpftap, ffBPF, SampFreq, NARROW_BPFLOW-200, NARROW_BPFHIGH, 20, 1.0);
|
|||
|
|
break;
|
|||
|
|
case 2: // Narrow
|
|||
|
|
bpftap = 64 * SampFreq / 11025.0;
|
|||
|
|
MakeFilter(H1, bpftap, ffBPF, SampFreq, lfq, 2500 + g_dblToneOffset, 40, 1.0);
|
|||
|
|
MakeFilter(H2, bpftap, ffBPF, SampFreq, lfq2, 2500 + g_dblToneOffset, 20, 1.0);
|
|||
|
|
// MakeFilter(H3, bpftap, ffBPF, SampFreq, NARROW_BPFLOW-100, NARROW_BPFHIGH, 40, 1.0);
|
|||
|
|
break;
|
|||
|
|
case 3: // Very Narrow
|
|||
|
|
bpftap = 96 * SampFreq / 11025.0;
|
|||
|
|
MakeFilter(H1, bpftap, ffBPF, SampFreq, lfq, 2400 + g_dblToneOffset, 50, 1.0);
|
|||
|
|
MakeFilter(H2, bpftap, ffBPF, SampFreq, lfq2, 2500 + g_dblToneOffset, 20, 1.0);
|
|||
|
|
// MakeFilter(H3, bpftap, ffBPF, SampFreq, NARROW_BPFLOW, NARROW_BPFHIGH, 50, 1.0);
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
bpftap = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
CalcNarrowBPF(H3, bpftap, bpf, mode);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::CalcNarrowBPF(double *H3, int bpftap, int bpf, int mode)
|
|||
|
|
{
|
|||
|
|
int low, high;
|
|||
|
|
switch(mode){
|
|||
|
|
case smMN73:
|
|||
|
|
low = 1600; high = 2500;
|
|||
|
|
break;
|
|||
|
|
case smMN110:
|
|||
|
|
low = 1600; high = 2500;
|
|||
|
|
break;
|
|||
|
|
case smMN140:
|
|||
|
|
low = 1700; high = 2400;
|
|||
|
|
break;
|
|||
|
|
case smMC110:
|
|||
|
|
low = 1600; high = 2500;
|
|||
|
|
break;
|
|||
|
|
case smMC140:
|
|||
|
|
low = 1650; high = 2500;
|
|||
|
|
break;
|
|||
|
|
case smMC180:
|
|||
|
|
low = 1700; high = 2400;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
low = 1600; high = 2500;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
low += g_dblToneOffset;
|
|||
|
|
high += g_dblToneOffset;
|
|||
|
|
switch(bpf){
|
|||
|
|
case 1: // Wide
|
|||
|
|
MakeFilter(H3, bpftap, ffBPF, SampFreq, low-200, high, 20, 1.0);
|
|||
|
|
break;
|
|||
|
|
case 2: // Narrow
|
|||
|
|
MakeFilter(H3, bpftap, ffBPF, SampFreq, low-100, high, 40, 1.0);
|
|||
|
|
break;
|
|||
|
|
case 3: // Very Narrow
|
|||
|
|
MakeFilter(H3, bpftap, ffBPF, SampFreq, low, high, 50, 1.0);
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::CalcBPF(void)
|
|||
|
|
{
|
|||
|
|
CalcBPF(HBPF, HBPFS, HBPFN, m_bpftap, m_bpf, SSTVSET.m_Mode);
|
|||
|
|
m_BPF.Create(m_bpftap);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::SetBPF(int bpf)
|
|||
|
|
{
|
|||
|
|
if( bpf != m_bpf ){
|
|||
|
|
int delay = m_bpftap;
|
|||
|
|
m_bpf = bpf;
|
|||
|
|
CalcBPF();
|
|||
|
|
if( m_Sync ){
|
|||
|
|
delay = (m_bpftap - delay) / 2;
|
|||
|
|
m_Skip = delay;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::FreeRxBuff(void)
|
|||
|
|
{
|
|||
|
|
if( m_StgBuf != NULL ){
|
|||
|
|
delete m_StgB12;
|
|||
|
|
delete m_StgBuf;
|
|||
|
|
m_StgBuf = NULL;
|
|||
|
|
m_StgB12 = NULL;
|
|||
|
|
m_wStgLine = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::OpenCloseRxBuff(void)
|
|||
|
|
{
|
|||
|
|
if( m_Sync ) return;
|
|||
|
|
|
|||
|
|
if( sys.m_UseRxBuff == 1 ){
|
|||
|
|
if( m_StgBuf == NULL ){
|
|||
|
|
int n = 257 * 1100 * SampFreq / 1000;
|
|||
|
|
m_StgBuf = new short[n];
|
|||
|
|
m_StgB12 = new short[n];
|
|||
|
|
memset(m_StgBuf, 0, n);
|
|||
|
|
memset(m_StgB12, 0, n);
|
|||
|
|
m_RxBufAllocSize = n;
|
|||
|
|
m_wStgLine = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
FreeRxBuff();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::Idle(double d)
|
|||
|
|
{
|
|||
|
|
if( !sys.m_TestDem ) m_lvl.Do(d);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::SetTickFreq(int f)
|
|||
|
|
{
|
|||
|
|
if( !f ) f = 1200;
|
|||
|
|
m_iir12.SetFreq(f + g_dblToneOffset, SampFreq, 100.0);
|
|||
|
|
m_TickFreq = f;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::InitAFC(void)
|
|||
|
|
{
|
|||
|
|
m_AFCAVG.SetCount(m_AFCAVG.Max);
|
|||
|
|
if( m_fNarrow ){
|
|||
|
|
m_AFCData = m_AFCLock = (NARROW_CENTER-NARROW_SYNC)*16384/NARROW_BWH;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_AFCData = m_AFCLock = ((1900-1200)*16384)/400.0;
|
|||
|
|
}
|
|||
|
|
m_AFCFlag = 0;
|
|||
|
|
m_AFCDiff = 0.0;
|
|||
|
|
m_AFCGard = 10;
|
|||
|
|
m_AFCCount = 0;
|
|||
|
|
m_AFCDis = 0;
|
|||
|
|
InitTone(0);
|
|||
|
|
if( m_fNarrow ){
|
|||
|
|
m_AFC_LowVal = (NARROW_CENTER - NARROW_AFCLOW) * 16384.0 / NARROW_BWH; // (Center - SyncLow) * 16384 / BWH
|
|||
|
|
m_AFC_HighVal = (NARROW_CENTER - NARROW_AFCHIGH) * 16384.0 / NARROW_BWH; // (Center - SyncHigh) * 16384 / BWH
|
|||
|
|
m_AFC_SyncVal = (NARROW_CENTER - NARROW_SYNC) * 16384.0 / NARROW_BWH; // (Center - Sync) * 16384 / BWH
|
|||
|
|
m_AFC_BWH = NARROW_BWH / 16384.0; // BWH / 16384.0;
|
|||
|
|
if( sys.m_bCQ100 ){
|
|||
|
|
m_AFC_LowVal = (NARROW_CENTER - NARROW_SYNC - 50) * 16384.0 / NARROW_BWH; // (Center - SyncLow) * 16384 / BWH
|
|||
|
|
m_AFC_HighVal = (NARROW_CENTER - NARROW_SYNC + 50) * 16384.0 / NARROW_BWH; // (Center - SyncHigh) * 16384 / BWH
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_AFC_LowVal = (1900 - 1000) * 16384.0 / 400; // (Center - SyncLow) * 16384 / BWH
|
|||
|
|
m_AFC_HighVal = (1900 - 1325) * 16384.0 / 400; // (Center - SyncHigh) * 16384 / BWH
|
|||
|
|
m_AFC_SyncVal = (1900 - 1200) * 16384.0 / 400; // (Center - Sync) * 16384 / BWH
|
|||
|
|
m_AFC_BWH = 400 / 16384.0; // BWH / 16384.0;
|
|||
|
|
if( sys.m_bCQ100 ){
|
|||
|
|
m_AFC_LowVal = (1900 - 1200 - 50) * 16384.0 / 400; // (Center - SyncLow) * 16384 / BWH
|
|||
|
|
m_AFC_HighVal = (1900 - 1200 + 50) * 16384.0 / 400; // (Center - SyncHigh) * 16384 / BWH
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::InitTone(int dfq)
|
|||
|
|
{
|
|||
|
|
if( m_AFCFQ != dfq ){
|
|||
|
|
m_iir11.SetFreq(1080+dfq + g_dblToneOffset, SampFreq, 80.0);
|
|||
|
|
m_iir12.SetFreq(1200+dfq + g_dblToneOffset, SampFreq, 100.0);
|
|||
|
|
m_iir13.SetFreq(1320+dfq + g_dblToneOffset, SampFreq, 80.0);
|
|||
|
|
m_iir19.SetFreq(1900+dfq + g_dblToneOffset, SampFreq, 100.0);
|
|||
|
|
m_iirfsk.SetFreq(FSKSPACE+dfq + g_dblToneOffset, SampFreq, 100.0);
|
|||
|
|
m_AFCFQ = dfq;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::SetWidth(int fNarrow)
|
|||
|
|
{
|
|||
|
|
if( m_fNarrow != fNarrow ){
|
|||
|
|
m_fNarrow = fNarrow;
|
|||
|
|
m_hill.SetWidth(fNarrow);
|
|||
|
|
m_fqc.SetWidth(fNarrow);
|
|||
|
|
m_pll.SetWidth(fNarrow);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::Start(void)
|
|||
|
|
{
|
|||
|
|
SetWidth(IsNarrowMode(SSTVSET.m_Mode));
|
|||
|
|
|
|||
|
|
InitAFC();
|
|||
|
|
m_fqc.Clear();
|
|||
|
|
m_SyncMode = -1;
|
|||
|
|
m_Sync = 0;
|
|||
|
|
m_Skip = 0;
|
|||
|
|
m_wPage = m_rPage = 0;
|
|||
|
|
m_wBase = 0;
|
|||
|
|
m_wLine = 0;
|
|||
|
|
m_wCnt = 0;
|
|||
|
|
m_rBase = 0;
|
|||
|
|
OpenCloseRxBuff();
|
|||
|
|
m_wBgn = 2;
|
|||
|
|
m_Lost = 0;
|
|||
|
|
|
|||
|
|
int eg = SSTVSET.m_WD + SSTVSET.m_KSB + SSTVSET.m_KSB;
|
|||
|
|
int i, j;
|
|||
|
|
for( i = 0; i < SSTVDEMBUFMAX; i++ ){
|
|||
|
|
for( j = SSTVSET.m_WD; j < eg; j++ ){
|
|||
|
|
m_Buf[i*m_BWidth + j] = -16384;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_Sync = 1;
|
|||
|
|
m_SyncMode = 0;
|
|||
|
|
SetWidth(m_fNarrow);
|
|||
|
|
if( m_fNarrow ) CalcNarrowBPF(HBPFN, m_bpftap, m_bpf, SSTVSET.m_Mode);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::Start(int mode, int f)
|
|||
|
|
{
|
|||
|
|
m_fqc.Clear();
|
|||
|
|
m_sint1.Reset();
|
|||
|
|
m_sint2.Reset();
|
|||
|
|
m_sint3.Reset();
|
|||
|
|
m_wBgn = 0;
|
|||
|
|
m_rBase = 0;
|
|||
|
|
m_SyncMode = 0;
|
|||
|
|
SSTVSET.SetMode(mode);
|
|||
|
|
m_Sync = 0;
|
|||
|
|
SetWidth(IsNarrowMode(mode));
|
|||
|
|
if( f ){
|
|||
|
|
Start();
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_SyncMode = -1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::Stop(void)
|
|||
|
|
{
|
|||
|
|
if( m_AFCFQ ){
|
|||
|
|
if( m_fskdecode ){
|
|||
|
|
m_iir11.SetFreq(1080 + g_dblToneOffset, SampFreq, 80.0);
|
|||
|
|
m_iir12.SetFreq(1200 + g_dblToneOffset, SampFreq, 100.0);
|
|||
|
|
m_iir13.SetFreq(1320 + g_dblToneOffset, SampFreq, 80.0);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
InitTone(0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
m_fqc.Clear();
|
|||
|
|
m_sint1.Reset();
|
|||
|
|
m_sint2.Reset();
|
|||
|
|
m_sint3.Reset();
|
|||
|
|
m_wBgn = 0;
|
|||
|
|
m_SyncMode = 512;
|
|||
|
|
m_Sync = 0;
|
|||
|
|
m_SyncAVT = 0;
|
|||
|
|
m_Skip = 0;
|
|||
|
|
SetWidth(0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::SetSenseLvl(void)
|
|||
|
|
{
|
|||
|
|
switch(m_SenseLvl){
|
|||
|
|
case 1:
|
|||
|
|
m_SLvl = 3500;
|
|||
|
|
m_SLvl2 = m_SLvl * 0.5;
|
|||
|
|
m_SLvl3 = 5700;
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
m_SLvl = 4800;
|
|||
|
|
m_SLvl2 = m_SLvl * 0.5;
|
|||
|
|
m_SLvl3 = 6800;
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
m_SLvl = 6000;
|
|||
|
|
m_SLvl2 = m_SLvl * 0.5;
|
|||
|
|
m_SLvl3 = 8000;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
m_SLvl = 2400;
|
|||
|
|
m_SLvl2 = m_SLvl * 0.5;
|
|||
|
|
m_SLvl3 = 5000;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::Do(double s)
|
|||
|
|
{
|
|||
|
|
if( (s > 24578.0) || (s < -24578.0) ){
|
|||
|
|
m_OverFlow = 1;
|
|||
|
|
}
|
|||
|
|
double d = (s + m_ad) * 0.5; // LPF
|
|||
|
|
m_ad = s;
|
|||
|
|
if( m_bpf ){
|
|||
|
|
if( m_Sync || (m_SyncMode >= 3) ){
|
|||
|
|
d = m_BPF.Do(d, m_fNarrow ? HBPFN : HBPF);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
d = m_BPF.Do(d, HBPFS);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
m_lvl.Do(d);
|
|||
|
|
double ad = m_lvl.AGC(d);
|
|||
|
|
|
|||
|
|
d = ad * 32;
|
|||
|
|
if( d > 16384.0 ) d = 16384.0;
|
|||
|
|
if( d < -16384.0 ) d = -16384.0;
|
|||
|
|
|
|||
|
|
double d11;
|
|||
|
|
double d12;
|
|||
|
|
double d13;
|
|||
|
|
double d19;
|
|||
|
|
double dsp;
|
|||
|
|
|
|||
|
|
d12 = m_iir12.Do(d);
|
|||
|
|
if( d12 < 0.0 ) d12 = -d12;
|
|||
|
|
d12 = m_lpf12.Do(d12);
|
|||
|
|
|
|||
|
|
d19 = m_iir19.Do(d);
|
|||
|
|
if( d19 < 0.0 ) d19 = -d19;
|
|||
|
|
d19 = m_lpf19.Do(d19);
|
|||
|
|
|
|||
|
|
dsp = m_iirfsk.Do(d);
|
|||
|
|
if( dsp < 0.0 ) dsp = -dsp;
|
|||
|
|
dsp = m_lpffsk.Do(dsp);
|
|||
|
|
DecodeFSK(int(d19), int(dsp));
|
|||
|
|
|
|||
|
|
if( m_Repeater && !m_Sync && (pRep != NULL) ){
|
|||
|
|
double dsp;
|
|||
|
|
dsp = pRep->m_iirrep.Do(d);
|
|||
|
|
if( dsp < 0.0 ) dsp = -dsp;
|
|||
|
|
dsp = pRep->m_lpfrep.Do(dsp);
|
|||
|
|
if( m_RepSQ ){
|
|||
|
|
m_repsig = pRep->m_lmsrep.Sig(m_ad);
|
|||
|
|
}
|
|||
|
|
Repeater(int(dsp), int(d12), int(d19));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if( m_fNarrow ){
|
|||
|
|
if( m_ScopeFlag ){
|
|||
|
|
m_Scope[0].WriteData(d19);
|
|||
|
|
}
|
|||
|
|
if( m_LevelType ) m_SyncLvl.Do(d19);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( m_ScopeFlag ){
|
|||
|
|
m_Scope[0].WriteData(d12);
|
|||
|
|
}
|
|||
|
|
if( m_LevelType ) m_SyncLvl.Do(d12);
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
if( m_Tick && (pTick != NULL) ){
|
|||
|
|
pTick->Write(d12);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if( !m_Sync || m_SyncRestart || m_SyncAVT ){
|
|||
|
|
m_sint1.SyncInc();
|
|||
|
|
m_sint2.SyncInc();
|
|||
|
|
m_sint3.SyncInc();
|
|||
|
|
d11 = m_iir11.Do(d);
|
|||
|
|
if( d11 < 0.0 ) d11 = -d11;
|
|||
|
|
d11 = m_lpf11.Do(d11);
|
|||
|
|
|
|||
|
|
switch(m_SyncMode){
|
|||
|
|
case 0: // <20><><EFBFBD><EFBFBD><EFBFBD>J<EFBFBD>n
|
|||
|
|
if( !m_Sync && m_MSync ){
|
|||
|
|
m_VisData = m_sint1.SyncStart();
|
|||
|
|
if( m_VisData > 0 ){
|
|||
|
|
SSTVSET.SetMode(m_VisData-1);
|
|||
|
|
Start();
|
|||
|
|
}
|
|||
|
|
else if( (d12 > d19) && (d12 > m_SLvl2) && ((d12-d19) >= m_SLvl2) ){
|
|||
|
|
m_sint2.SyncMax(d12);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_VisData = m_sint2.SyncStart();
|
|||
|
|
if( m_VisData > 0 ){
|
|||
|
|
m_VisData--;
|
|||
|
|
switch(m_VisData){
|
|||
|
|
case smSCT1:
|
|||
|
|
case smMRT1:
|
|||
|
|
case smMRT2:
|
|||
|
|
case smSC2_180:
|
|||
|
|
SSTVSET.SetMode(m_VisData);
|
|||
|
|
Start();
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
#if NARROW_SYNC == 1900
|
|||
|
|
if( (d19 > d12) && (d19 > dsp) && (d19 > m_SLvl3) && ((d19-d12) >= m_SLvl3) && ((d19-dsp) >= m_SLvl) ){
|
|||
|
|
if( m_sint3.m_SyncPhase ){
|
|||
|
|
m_sint3.SyncMax(d19);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_sint3.SyncTrig(d19);
|
|||
|
|
m_sint3.m_SyncPhase++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if( m_sint3.m_SyncPhase ){
|
|||
|
|
m_sint3.m_SyncPhase = 0;
|
|||
|
|
m_VisData = m_sint3.SyncStart();
|
|||
|
|
if( m_VisData > 0 ){
|
|||
|
|
m_VisData--;
|
|||
|
|
SSTVSET.SetMode(m_VisData);
|
|||
|
|
Start();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
if( (d12 > d19) && (d12 > m_SLvl) && ((d12-d19) >= m_SLvl) ){
|
|||
|
|
m_SyncMode++;
|
|||
|
|
m_SyncTime = 15 * sys.m_SampFreq/1000;
|
|||
|
|
if( !m_Sync && m_MSync ) m_sint1.SyncTrig(d12);
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 1: // 1200Hz(30ms)<29>̌p<CC8C><70><EFBFBD>`<60>F<EFBFBD>b<EFBFBD>N
|
|||
|
|
if( !m_Sync && m_MSync ){
|
|||
|
|
if( (d12 > d19) && (d12 > m_SLvl2) && ((d12-d19) >= m_SLvl2) ){
|
|||
|
|
m_sint2.SyncMax(d12);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( (d12 > d19) && (d12 > m_SLvl) && ((d12-d19) >= m_SLvl) ){
|
|||
|
|
if( !m_Sync && m_MSync ){
|
|||
|
|
m_sint1.SyncMax(d12);
|
|||
|
|
}
|
|||
|
|
m_SyncTime--;
|
|||
|
|
if( !m_SyncTime ){
|
|||
|
|
m_SyncMode++;
|
|||
|
|
m_SyncTime = 30 * sys.m_SampFreq/1000;
|
|||
|
|
m_VisData = 0;
|
|||
|
|
m_VisCnt = 8;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_SyncMode = 0;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 2: // Vis decode
|
|||
|
|
case 9:
|
|||
|
|
d13 = m_iir13.Do(d);
|
|||
|
|
if( d13 < 0.0 ) d13 = -d13;
|
|||
|
|
d13 = m_lpf13.Do(d13);
|
|||
|
|
m_SyncTime--;
|
|||
|
|
if( !m_SyncTime ){
|
|||
|
|
if( ((d11 < d19) && (d13 < d19)) ||
|
|||
|
|
(fabs(d11-d13) < (m_SLvl2)) ){
|
|||
|
|
m_SyncMode = 0;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_SyncTime = 30 * sys.m_SampFreq/1000;
|
|||
|
|
m_VisData = m_VisData >> 1;
|
|||
|
|
if( d11 > d13 ) m_VisData |= 0x0080;
|
|||
|
|
m_VisCnt--;
|
|||
|
|
if( !m_VisCnt ){
|
|||
|
|
if( m_SyncMode == 2 ){
|
|||
|
|
m_SyncMode++;
|
|||
|
|
switch(m_VisData){
|
|||
|
|
case 0x82: // RM8
|
|||
|
|
m_NextMode = smRM8;
|
|||
|
|
break;
|
|||
|
|
case 0x86: // RM12
|
|||
|
|
m_NextMode = smRM12;
|
|||
|
|
break;
|
|||
|
|
case 0x84: // R24
|
|||
|
|
m_NextMode = smR24;
|
|||
|
|
break;
|
|||
|
|
case 0x88: // R36
|
|||
|
|
m_NextMode = smR36;
|
|||
|
|
break;
|
|||
|
|
case 0x0c: // R72
|
|||
|
|
m_NextMode = smR72;
|
|||
|
|
break;
|
|||
|
|
case 0x44: // AVT
|
|||
|
|
m_NextMode = smAVT;
|
|||
|
|
break;
|
|||
|
|
case 0x3c: // SCT1
|
|||
|
|
m_NextMode = smSCT1;
|
|||
|
|
break;
|
|||
|
|
case 0xb8: // SCT2
|
|||
|
|
m_NextMode = smSCT2;
|
|||
|
|
break;
|
|||
|
|
case 0xcc: // SCTDX
|
|||
|
|
m_NextMode = smSCTDX;
|
|||
|
|
break;
|
|||
|
|
case 0xac: // MRT1
|
|||
|
|
m_NextMode = smMRT1;
|
|||
|
|
break;
|
|||
|
|
case 0x28: // MRT2
|
|||
|
|
m_NextMode = smMRT2;
|
|||
|
|
break;
|
|||
|
|
case 0xb7: // SC2-180 $37 00110111
|
|||
|
|
m_NextMode = smSC2_180;
|
|||
|
|
break;
|
|||
|
|
case 0x3f: // SC2-120 $3f 00111111
|
|||
|
|
m_NextMode = smSC2_120;
|
|||
|
|
break;
|
|||
|
|
case 0xbb: // SC2-60 $3b 10111011
|
|||
|
|
m_NextMode = smSC2_60;
|
|||
|
|
break;
|
|||
|
|
case 0xdd: // PD50 $5d 01011101
|
|||
|
|
m_NextMode = smPD50;
|
|||
|
|
break;
|
|||
|
|
case 0x63: // PD90 $63 01100011
|
|||
|
|
m_NextMode = smPD90;
|
|||
|
|
break;
|
|||
|
|
case 0x5f: // PD120 $5f 01011111
|
|||
|
|
m_NextMode = smPD120;
|
|||
|
|
break;
|
|||
|
|
case 0xe2: // PD160 $62 11100010
|
|||
|
|
m_NextMode = smPD160;
|
|||
|
|
break;
|
|||
|
|
case 0x60: // PD180 $60 01100000
|
|||
|
|
m_NextMode = smPD180;
|
|||
|
|
break;
|
|||
|
|
case 0xe1: // PD240 $61 11100001
|
|||
|
|
m_NextMode = smPD240;
|
|||
|
|
break;
|
|||
|
|
case 0xde: // PD290 $5e 11011110
|
|||
|
|
m_NextMode = smPD290;
|
|||
|
|
break;
|
|||
|
|
case 0x71: // P3 $71 01110001
|
|||
|
|
m_NextMode = smP3;
|
|||
|
|
break;
|
|||
|
|
case 0x72: // P5 $71 01110010
|
|||
|
|
m_NextMode = smP5;
|
|||
|
|
break;
|
|||
|
|
case 0xf3: // P7 $73 11110011
|
|||
|
|
m_NextMode = smP7;
|
|||
|
|
break;
|
|||
|
|
case 0x23: // MM <20>g<EFBFBD><67> VIS
|
|||
|
|
m_SyncMode = 9;
|
|||
|
|
m_VisData = 0;
|
|||
|
|
m_VisCnt = 8;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
m_SyncMode = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else { // <20>g<EFBFBD><67> VIS
|
|||
|
|
m_SyncMode = 3;
|
|||
|
|
switch(m_VisData){
|
|||
|
|
case 0x45: // MR73
|
|||
|
|
m_NextMode = smMR73;
|
|||
|
|
break;
|
|||
|
|
case 0x46: // MR90
|
|||
|
|
m_NextMode = smMR90;
|
|||
|
|
break;
|
|||
|
|
case 0x49: // MR115
|
|||
|
|
m_NextMode = smMR115;
|
|||
|
|
break;
|
|||
|
|
case 0x4a: // MR140
|
|||
|
|
m_NextMode = smMR140;
|
|||
|
|
break;
|
|||
|
|
case 0x4c: // MR175
|
|||
|
|
m_NextMode = smMR175;
|
|||
|
|
break;
|
|||
|
|
case 0x25: // MP73
|
|||
|
|
m_NextMode = smMP73;
|
|||
|
|
break;
|
|||
|
|
case 0x29: // MP115
|
|||
|
|
m_NextMode = smMP115;
|
|||
|
|
break;
|
|||
|
|
case 0x2a: // MP140
|
|||
|
|
m_NextMode = smMP140;
|
|||
|
|
break;
|
|||
|
|
case 0x2c: // MP175
|
|||
|
|
m_NextMode = smMP175;
|
|||
|
|
break;
|
|||
|
|
case 0x85: // ML180
|
|||
|
|
m_NextMode = smML180;
|
|||
|
|
break;
|
|||
|
|
case 0x86: // ML240
|
|||
|
|
m_NextMode = smML240;
|
|||
|
|
break;
|
|||
|
|
case 0x89: // ML280
|
|||
|
|
m_NextMode = smML280;
|
|||
|
|
break;
|
|||
|
|
case 0x8a: // ML320
|
|||
|
|
m_NextMode = smML320;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
m_SyncMode = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 3: // 1200Hz(30ms)<29>̃`<60>F<EFBFBD>b<EFBFBD>N
|
|||
|
|
if( !m_Sync ){
|
|||
|
|
m_pll.Do(ad);
|
|||
|
|
}
|
|||
|
|
m_SyncTime--;
|
|||
|
|
if( !m_SyncTime ){
|
|||
|
|
if( (d12 > d19) &&(d12 > m_SLvl) ){
|
|||
|
|
if( m_Sync ){
|
|||
|
|
if( m_rBase >= (SSTVSET.m_LM * 65/100) ){
|
|||
|
|
m_ReqSave = 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( m_NextMode == smAVT ){
|
|||
|
|
m_SyncTime = ((9 + 910 + 910 + 5311.9424 + 0.30514375) * sys.m_SampFreq / 1000.0);
|
|||
|
|
m_SyncMode++;
|
|||
|
|
m_SyncAVT = 1;
|
|||
|
|
m_Sync = 0;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_SyncMode = 256;
|
|||
|
|
}
|
|||
|
|
SSTVSET.SetMode(m_NextMode);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_SyncMode = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 4: // AVT<56><54>1900Hz<48>M<EFBFBD><4D><EFBFBD>҂<EFBFBD>
|
|||
|
|
m_SyncTime--;
|
|||
|
|
if( !m_SyncTime ){ m_SyncMode = 256; break;}
|
|||
|
|
|
|||
|
|
d = m_pll.Do(ad);
|
|||
|
|
if( (d >= -1000) && (d <= 1000) ){ // First atack
|
|||
|
|
m_SyncMode++;
|
|||
|
|
m_SyncATime = 9.7646 * 0.5 * sys.m_SampFreq / 1000;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 5:
|
|||
|
|
m_SyncTime--;
|
|||
|
|
if( !m_SyncTime ){ m_SyncMode = 256; break;}
|
|||
|
|
|
|||
|
|
d = m_pll.Do(ad);
|
|||
|
|
if( (d >= -800) && (d <= 800) ){ // 2nd atack
|
|||
|
|
m_SyncATime--;
|
|||
|
|
if( !m_SyncATime ){
|
|||
|
|
m_SyncMode++;
|
|||
|
|
m_SyncATime = 9.7646 * sys.m_SampFreq / 1000;
|
|||
|
|
m_VisData = 0;
|
|||
|
|
m_VisCnt = 16;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_SyncMode = 4;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 6:
|
|||
|
|
m_SyncTime--;
|
|||
|
|
if( !m_SyncTime ){ m_SyncMode = 256; break;}
|
|||
|
|
|
|||
|
|
d = m_pll.Do(ad);
|
|||
|
|
m_SyncATime--;
|
|||
|
|
if( !m_SyncATime ){
|
|||
|
|
if( (d >= 8000)||(d < -8000) ){
|
|||
|
|
m_SyncATime = 9.7646 * sys.m_SampFreq / 1000;
|
|||
|
|
m_VisData = m_VisData << 1;
|
|||
|
|
if( d > 0 ) m_VisData |= 0x00000001;
|
|||
|
|
m_VisCnt--;
|
|||
|
|
if( !m_VisCnt ){
|
|||
|
|
int l = m_VisData & 0x00ff;
|
|||
|
|
int h = (m_VisData >> 8) & 0x00ff;
|
|||
|
|
if( ((l + h) == 0x00ff) && (l >= 0xa0) && (l <= 0xbf) && (h >= 0x40) && (h <= 0x5f) ){
|
|||
|
|
if( h != 0x40 ){
|
|||
|
|
m_SyncATime = 9.7646 * 0.7 * sys.m_SampFreq / 1000;
|
|||
|
|
m_SyncTime = ((double(h - 0x40) * 165.9982) - 0.8) * sys.m_SampFreq / 1000;
|
|||
|
|
m_SyncMode++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( !m_SyncTime || (m_SyncTime >= 9.7646 * SampFreq / 1000) ){
|
|||
|
|
m_SyncTime = ((9.7646 * 0.5) - 0.8) * sys.m_SampFreq / 1000;
|
|||
|
|
}
|
|||
|
|
m_SyncMode = 8;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_SyncMode = 4;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_SyncMode = 4;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 7: // <20><><EFBFBD><EFBFBD>
|
|||
|
|
d = m_pll.Do(ad);
|
|||
|
|
if( (d >= -1000) && (d <= 1000) ){ // First atack
|
|||
|
|
m_SyncMode = 5;
|
|||
|
|
m_SyncATime = 9.7646 * 0.5 * sys.m_SampFreq / 1000;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_SyncATime--;
|
|||
|
|
if( !m_SyncATime ){
|
|||
|
|
m_SyncMode = 4;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 8:
|
|||
|
|
m_SyncMode--;
|
|||
|
|
if( !m_SyncMode ){
|
|||
|
|
Start();
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 256: // <20><><EFBFBD><EFBFBD><EFBFBD>J<EFBFBD>n
|
|||
|
|
Start();
|
|||
|
|
break;
|
|||
|
|
case 512: // 0.5s<EFBFBD>̃E<EFBFBD>G<EFBFBD>C<EFBFBD>g
|
|||
|
|
m_SyncTime = SampFreq * 0.5;
|
|||
|
|
m_SyncMode++;
|
|||
|
|
break;
|
|||
|
|
case 513:
|
|||
|
|
m_SyncTime--;
|
|||
|
|
if( !m_SyncTime ){
|
|||
|
|
m_SyncMode = 0;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( m_Sync ){
|
|||
|
|
switch(m_Type){
|
|||
|
|
case 0: // PLL
|
|||
|
|
if( m_afc && (m_lvl.m_CurMax > 16) && (SSTVSET.m_Mode != smAVT) ) SyncFreq(m_fqc.Do(m_lvl.m_Cur));
|
|||
|
|
d = m_pll.Do(m_lvl.m_Cur);
|
|||
|
|
break;
|
|||
|
|
case 1: // Zero-crossing
|
|||
|
|
d = m_fqc.Do(m_lvl.m_Cur);
|
|||
|
|
if( m_afc && (m_lvl.m_CurMax > 16) && (SSTVSET.m_Mode != smAVT) ) SyncFreq(d);
|
|||
|
|
break;
|
|||
|
|
default: // Hilbert
|
|||
|
|
d = m_hill.Do(m_lvl.m_Cur);
|
|||
|
|
if( m_afc && (m_lvl.m_CurMax > 16) && (SSTVSET.m_Mode != smAVT) ) SyncFreq(d);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if( m_afc ) d += m_AFCDiff;
|
|||
|
|
if( m_Skip ){
|
|||
|
|
if( m_Skip > 0 ){
|
|||
|
|
m_Skip--;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
for( ; m_Skip; m_Skip++ ){
|
|||
|
|
int n = m_wBase + m_wCnt;
|
|||
|
|
m_Buf[n] = -d;
|
|||
|
|
m_B12[n] = 0;
|
|||
|
|
IncWP();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( m_ScopeFlag ){
|
|||
|
|
m_Scope[1].WriteData(d);
|
|||
|
|
}
|
|||
|
|
int n = m_wBase + m_wCnt;
|
|||
|
|
m_Buf[n] = -d;
|
|||
|
|
|
|||
|
|
#if NARROW_SYNC == 1200
|
|||
|
|
if( SSTVSET.m_Mode != smAVT ){
|
|||
|
|
m_B12[n] = d12;
|
|||
|
|
}
|
|||
|
|
#else
|
|||
|
|
if( m_fNarrow ){
|
|||
|
|
m_B12[n] = d19;
|
|||
|
|
}
|
|||
|
|
else if( SSTVSET.m_Mode != smAVT ){
|
|||
|
|
m_B12[n] = d12;
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
else {
|
|||
|
|
m_B12[n] = (d + 16384) * 0.25;
|
|||
|
|
}
|
|||
|
|
IncWP();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if( sys.m_TestDem ){
|
|||
|
|
switch(m_Type){
|
|||
|
|
case 0:
|
|||
|
|
m_CurSig = m_Avg.Avg(m_pll.Do(m_lvl.m_Cur));
|
|||
|
|
break;
|
|||
|
|
case 1:
|
|||
|
|
m_CurSig = m_Avg.Avg(m_fqc.Do(m_lvl.m_Cur));
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
m_CurSig = m_Avg.Avg(m_hill.Do(m_lvl.m_Cur));
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::IncWP(void)
|
|||
|
|
{
|
|||
|
|
m_wCnt++;
|
|||
|
|
if( m_wCnt >= SSTVSET.m_WD ){
|
|||
|
|
m_wCnt = 0;
|
|||
|
|
m_wPage++;
|
|||
|
|
m_wLine++;
|
|||
|
|
m_wBase += m_BWidth;
|
|||
|
|
if( m_wPage >= SSTVDEMBUFMAX ){
|
|||
|
|
m_wPage = 0;
|
|||
|
|
m_wBase = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::SyncFreq(double d)
|
|||
|
|
{
|
|||
|
|
/*
|
|||
|
|
double m_AFC_LowVal; // (Center - SyncLow) * 16384 / BWH
|
|||
|
|
double m_AFC_HighVal; // (Center - SyncHigh) * 16384 / BWH
|
|||
|
|
double m_AFC_SyncVal; // (Center - Sync) * 16384 / BWH
|
|||
|
|
double m_AFC_BWH; // BWH / 16384.0;
|
|||
|
|
*/
|
|||
|
|
d -= 128;
|
|||
|
|
|
|||
|
|
if( (d <= m_AFC_LowVal) && (d >= m_AFC_HighVal) ){
|
|||
|
|
if( !m_AFCDis && (m_AFCCount >= SSTVSET.m_AFCB) && (m_AFCCount <= SSTVSET.m_AFCE) ){
|
|||
|
|
m_AFCData = m_Avg.Avg(d);
|
|||
|
|
if( m_AFCCount == SSTVSET.m_AFCE ){
|
|||
|
|
if( m_AFCGard ){
|
|||
|
|
m_AFCLock = m_AFCAVG.SetData(m_AFCData);
|
|||
|
|
m_AFCGard = 0;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_AFCLock = m_AFCAVG.Avg(m_AFCData);
|
|||
|
|
}
|
|||
|
|
m_AFCDiff = m_AFC_SyncVal - m_AFCLock;
|
|||
|
|
m_AFCFlag = 15;
|
|||
|
|
InitTone(m_AFCDiff * m_AFC_BWH);
|
|||
|
|
m_AFCDis = m_AFCInt;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
m_AFCCount++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( (m_AFCCount >= SSTVSET.m_AFCB) && m_AFCGard ){
|
|||
|
|
m_AFCGard--;
|
|||
|
|
if( !m_AFCGard ) m_AFCAVG.SetData(m_AFCLock);
|
|||
|
|
}
|
|||
|
|
m_AFCCount = 0;
|
|||
|
|
if( m_AFCDis ) m_AFCDis--;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVDEM::DecodeFSK(int m, int s)
|
|||
|
|
{
|
|||
|
|
int d;
|
|||
|
|
switch(m_fskmode){
|
|||
|
|
case 0: // <20>X<EFBFBD>y<EFBFBD>[<5B>X<EFBFBD>L<EFBFBD><4C><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><41><EFBFBD>o
|
|||
|
|
d = ABS(m - s);
|
|||
|
|
if( (s > m) && (d >= 2048) ){
|
|||
|
|
m_fsktime = (FSKGARD/2) * SSTVSET.m_SampFreq/1000;
|
|||
|
|
m_fskmode++;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 1: // <20>X<EFBFBD>y<EFBFBD>[<5B>X<EFBFBD>L<EFBFBD><4C><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><41><EFBFBD>o(<28>A<EFBFBD><41>)
|
|||
|
|
d = ABS(m - s);
|
|||
|
|
if( (s > m) && (d >= 2048) ){
|
|||
|
|
m_fsktime--;
|
|||
|
|
if( !m_fsktime ){
|
|||
|
|
m_fsktime = FSKGARD * SSTVSET.m_SampFreq/1000;
|
|||
|
|
m_fskmode++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 2: // <20>X<EFBFBD>^<5E>[<5B>g<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD>̌<EFBFBD><CC8C>o
|
|||
|
|
d = ABS(m - s);
|
|||
|
|
m_fsktime--;
|
|||
|
|
if( !m_fsktime ){
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
}
|
|||
|
|
else if( (m > s) && (d >= 2048) ){
|
|||
|
|
m_fsktime = (FSKINTVAL/2) * SSTVSET.m_SampFreq/1000;
|
|||
|
|
m_fskmode++;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 3: // <20>X<EFBFBD>^<5E>[<5B>g<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD>̌<EFBFBD><CC8C>o(<28><><EFBFBD>ԓ_)
|
|||
|
|
m_fsktime--;
|
|||
|
|
if( !m_fsktime ){
|
|||
|
|
d = ABS(m - s);
|
|||
|
|
if( (m > s) && (d >= 2048) ){
|
|||
|
|
m_fsktime = 0;
|
|||
|
|
m_fsknextd = double(FSKINTVAL)/1000.0 * SSTVSET.m_SampFreq;
|
|||
|
|
m_fsknexti = m_fsknextd;
|
|||
|
|
m_fskbcnt = 0;
|
|||
|
|
m_fskc = 0;
|
|||
|
|
m_fskmode++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
m_fsktime++;
|
|||
|
|
if( m_fsktime >= m_fsknexti ){
|
|||
|
|
d = ABS(m - s);
|
|||
|
|
if( d < 2048 ){
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fsknextd += double(FSKINTVAL)/1000.0 * SSTVSET.m_SampFreq;
|
|||
|
|
m_fsknexti = m_fsknextd;
|
|||
|
|
m_fskc = BYTE(m_fskc >> 1);
|
|||
|
|
if( m > s ) m_fskc |= 0x20;
|
|||
|
|
m_fskbcnt++;
|
|||
|
|
if( m_fskbcnt >= 6 ){
|
|||
|
|
m_fskbcnt = 0;
|
|||
|
|
switch(m_fskmode){
|
|||
|
|
case 4: // First SYNC 0x2A
|
|||
|
|
if( m_fskc == 0x2a ){
|
|||
|
|
m_fskcnt = 0;
|
|||
|
|
m_fskbcnt = 0;
|
|||
|
|
m_fsks = 0;
|
|||
|
|
m_fskc = 0;
|
|||
|
|
m_fskmode++;
|
|||
|
|
}
|
|||
|
|
else if( m_fskc == 0x2d ){
|
|||
|
|
m_fskcnt = 0;
|
|||
|
|
m_fskbcnt = 0;
|
|||
|
|
m_fsks = 0;
|
|||
|
|
m_fskc = 0;
|
|||
|
|
m_fskmode = 16;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 5: // Store data
|
|||
|
|
if( m_fskc == 0x01 ){
|
|||
|
|
if( m_fskcnt >= 1 ){
|
|||
|
|
m_fskmode++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fsks = m_fskc ^ m_fsks;
|
|||
|
|
m_fskdata[m_fskcnt] = BYTE(m_fskc + 0x20);
|
|||
|
|
m_fskcnt++;
|
|||
|
|
if( m_fskcnt >= 17 ){
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 6: // Check XOR
|
|||
|
|
m_fsks &= 0x3f;
|
|||
|
|
if( (m_fskc == m_fsks) && m_fskdecode ){
|
|||
|
|
m_fskdata[m_fskcnt] = 0;
|
|||
|
|
StrCopy(m_fskcall, SkipSpace(LPCSTR(m_fskdata)), 16);
|
|||
|
|
clipsp(m_fskcall);
|
|||
|
|
m_fskrec = 1;
|
|||
|
|
m_fskmode++;
|
|||
|
|
|
|||
|
|
m_fskcnt = 0;
|
|||
|
|
m_fsks = 0;
|
|||
|
|
m_fskc = 0;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 7: // Store data
|
|||
|
|
if( m_fskc == 0x01 ){
|
|||
|
|
if( m_fskcnt >= 1 ){
|
|||
|
|
m_fskmode++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if( m_fskc == 0x02 ){
|
|||
|
|
m_fsks = 0x02;
|
|||
|
|
m_fskNR = 0;
|
|||
|
|
m_fskmode = 9;
|
|||
|
|
}
|
|||
|
|
else if( m_fskc >= 0x10 ){
|
|||
|
|
m_fsks = m_fskc ^ m_fsks;
|
|||
|
|
m_fskNRS[m_fskcnt] = BYTE(m_fskc + 0x20);
|
|||
|
|
m_fskcnt++;
|
|||
|
|
if( m_fskcnt >= 9 ){
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 8: // Check XOR
|
|||
|
|
m_fsks &= 0x3f;
|
|||
|
|
if( (m_fskc == m_fsks) && m_fskdecode ){
|
|||
|
|
m_fskNRS[m_fskcnt] = 0;
|
|||
|
|
clipsp(m_fskNRS);
|
|||
|
|
m_fskNRrec = 1;
|
|||
|
|
}
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
break;
|
|||
|
|
case 9:
|
|||
|
|
m_fsks = m_fskc ^ m_fsks;
|
|||
|
|
m_fskNR = m_fskNR << 6;
|
|||
|
|
m_fskNR += m_fskc;
|
|||
|
|
m_fskcnt++;
|
|||
|
|
if( m_fskcnt >= 2 ){
|
|||
|
|
m_fskmode++;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 10:
|
|||
|
|
m_fsks &= 0x3f;
|
|||
|
|
if( m_fskc == m_fsks ){
|
|||
|
|
sprintf(m_fskNRS, "%03u", m_fskNR);
|
|||
|
|
m_fskNRrec = 1;
|
|||
|
|
}
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
break;
|
|||
|
|
case 16:
|
|||
|
|
m_fsks = m_fskc ^ m_fsks;
|
|||
|
|
if( m_fskc == 0x15 ){
|
|||
|
|
m_fskmode++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 17:
|
|||
|
|
m_fsks = m_fskc ^ m_fsks;
|
|||
|
|
m_fskdata[0] = m_fskc;
|
|||
|
|
m_fskmode++;
|
|||
|
|
break;
|
|||
|
|
case 18:
|
|||
|
|
m_fsks &= 0x3f;
|
|||
|
|
if( m_fskc == m_fsks ){
|
|||
|
|
switch(m_fskdata[0]){
|
|||
|
|
case 0x02:
|
|||
|
|
m_NextMode = smMN73;
|
|||
|
|
break;
|
|||
|
|
case 0x04:
|
|||
|
|
m_NextMode = smMN110;
|
|||
|
|
break;
|
|||
|
|
case 0x05:
|
|||
|
|
m_NextMode = smMN140;
|
|||
|
|
break;
|
|||
|
|
case 0x14:
|
|||
|
|
m_NextMode = smMC110;
|
|||
|
|
break;
|
|||
|
|
case 0x15:
|
|||
|
|
m_NextMode = smMC140;
|
|||
|
|
break;
|
|||
|
|
case 0x16:
|
|||
|
|
m_NextMode = smMC180;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
m_NextMode = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if( (m_SyncRestart || !m_Sync) && m_NextMode && (m_SyncMode >= 0) ){
|
|||
|
|
SSTVSET.SetMode(m_NextMode);
|
|||
|
|
Start();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
m_fskmode = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
m_fskc = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// <20><><EFBFBD>s<EFBFBD>[<5B>^<5E>ϐ<EFBFBD><CF90>̏<EFBFBD><CC8F><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
void CSSTVDEM::InitRepeater(void)
|
|||
|
|
{
|
|||
|
|
if( sys.m_Repeater ){
|
|||
|
|
if( pRep == NULL ) pRep = new REPSET;
|
|||
|
|
pRep->m_iirrep.SetFreq(m_RepTone + g_dblToneOffset, SampFreq, 100.0);
|
|||
|
|
pRep->m_lpfrep.MakeIIR(50, SampFreq, 2, 0, 0);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
pRep = NULL;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// <20><><EFBFBD>s<EFBFBD>[<5B>^<5E><>ON/OFF
|
|||
|
|
void CSSTVDEM::SetRepeater(int sw)
|
|||
|
|
{
|
|||
|
|
if( sw != m_Repeater ){
|
|||
|
|
m_repmode = 0;
|
|||
|
|
m_Repeater = sw;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// <20><><EFBFBD>s<EFBFBD>[<5B>^<5E>g<EFBFBD>[<5B><><EFBFBD>̌<EFBFBD><CC8C>o<EFBFBD><6F><EFBFBD>x<EFBFBD>ݒ<EFBFBD>
|
|||
|
|
void CSSTVDEM::SetRepSenseLvl(void)
|
|||
|
|
{
|
|||
|
|
switch(sys.m_RepSenseLvl){
|
|||
|
|
case 0:
|
|||
|
|
m_RSLvl = 3072;
|
|||
|
|
break;
|
|||
|
|
case 1:
|
|||
|
|
m_RSLvl = 4096;
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
m_RSLvl = 6144;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
m_RSLvl = 8192;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
m_RSLvl2 = m_RSLvl / 2;
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// <20><><EFBFBD>s<EFBFBD>[<5B>^<5E>g<EFBFBD>[<5B><><EFBFBD>̌<EFBFBD><CC8C>o<EFBFBD><6F><EFBFBD><EFBFBD>
|
|||
|
|
void CSSTVDEM::Repeater(int d17, int d12, int d19)
|
|||
|
|
{
|
|||
|
|
int d1 = ABS(d17 - d12);
|
|||
|
|
int d2 = ABS(d17 - d19);
|
|||
|
|
#if 0
|
|||
|
|
m_repD1 = d1;
|
|||
|
|
m_repD2 = d2;
|
|||
|
|
#endif
|
|||
|
|
switch(m_repmode){
|
|||
|
|
case 0: // <20>g<EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD>o<EFBFBD>̃g<CC83><67><EFBFBD>K
|
|||
|
|
if( (d1 > m_RSLvl) && (d2 > m_RSLvl2) ){
|
|||
|
|
m_reptime = sys.m_RepTimeA * SSTVSET.m_SampFreq / 1000;
|
|||
|
|
m_repmode++;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 1: // <20>g<EFBFBD>[<5B><><EFBFBD>̎<EFBFBD><CC8E><EFBFBD><EFBFBD>̃`<60>F<EFBFBD>b<EFBFBD>N
|
|||
|
|
if( (d1 > m_RSLvl) && (d2 > m_RSLvl2) ){
|
|||
|
|
m_reptime--;
|
|||
|
|
if( !m_reptime ){
|
|||
|
|
m_repmode++;
|
|||
|
|
m_repcount = 10000 * SSTVSET.m_SampFreq / 1000;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_repmode = 0;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 2: // <20>g<EFBFBD>[<5B><><EFBFBD>̏I<CC8F><49><EFBFBD>̌<EFBFBD><CC8C>o
|
|||
|
|
m_repcount--;
|
|||
|
|
if( !m_repcount ){
|
|||
|
|
m_repmode = 0;
|
|||
|
|
}
|
|||
|
|
if( (d1 > m_RSLvl) && (d2 > m_RSLvl2) ){
|
|||
|
|
m_reptime = sys.m_RepTimeB * SSTVSET.m_SampFreq / 1000;
|
|||
|
|
m_repcount = 10000 * SSTVSET.m_SampFreq / 1000;
|
|||
|
|
if( !m_reptime ) m_reptime++;
|
|||
|
|
}
|
|||
|
|
else if( m_RepSQ && (m_repsig > m_RepSQ) ){
|
|||
|
|
m_reptime = sys.m_RepTimeB * SSTVSET.m_SampFreq / 1000;
|
|||
|
|
if( !m_reptime ) m_reptime++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_reptime--;
|
|||
|
|
if( !m_reptime ){
|
|||
|
|
m_repmode++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
// case 3: // 'K'<27>̑<EFBFBD><CC91>M<EFBFBD>҂<EFBFBD>
|
|||
|
|
// break;
|
|||
|
|
case 4:
|
|||
|
|
m_reptime = sys.m_RepTimeC * SSTVSET.m_SampFreq / 1000;
|
|||
|
|
m_repcount = sys.m_RepTimeA * SSTVSET.m_SampFreq / 1000;
|
|||
|
|
m_repmode++;
|
|||
|
|
break;
|
|||
|
|
case 5: // 10[s]<5D>̃^<5E>C<EFBFBD><43><EFBFBD>A<EFBFBD>E<EFBFBD>g<EFBFBD>҂<EFBFBD>
|
|||
|
|
m_reptime--;
|
|||
|
|
if( !m_reptime ){ // <20>^<5E>C<EFBFBD><43><EFBFBD>A<EFBFBD>E<EFBFBD>g<EFBFBD>ɂ<EFBFBD><C982><EFBFBD><EFBFBD>ҋ@
|
|||
|
|
m_repmode = 0;
|
|||
|
|
}
|
|||
|
|
else if( (d1 > m_RSLvl) && (d2 > m_RSLvl2) ){
|
|||
|
|
m_repcount--;
|
|||
|
|
if( !m_repcount ){
|
|||
|
|
m_repmode = 2;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_repcount = sys.m_RepTimeA * SSTVSET.m_SampFreq / 1000;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
// case 6: // <20><><EFBFBD>M<EFBFBD><4D>
|
|||
|
|
// break;
|
|||
|
|
case 7:
|
|||
|
|
m_reptime = sys.m_RepTimeD * SSTVSET.m_SampFreq / 1000;
|
|||
|
|
m_repcount = 20000 * SSTVSET.m_SampFreq / 1000;
|
|||
|
|
if( !m_reptime ) m_reptime++;
|
|||
|
|
m_repmode++;
|
|||
|
|
break;
|
|||
|
|
case 8: // <20><><EFBFBD>v<EFBFBD><76><EFBFBD>C<EFBFBD><43><EFBFBD>M<EFBFBD>O<EFBFBD>̃^<5E>C<EFBFBD>}
|
|||
|
|
m_repcount--;
|
|||
|
|
if( !m_repcount ){
|
|||
|
|
m_repmode = 0;
|
|||
|
|
}
|
|||
|
|
if( m_RepSQ && (m_repsig > m_RepSQ) ){
|
|||
|
|
m_reptime = sys.m_RepTimeD * SSTVSET.m_SampFreq / 1000;
|
|||
|
|
if( !m_reptime ) m_reptime++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_reptime--;
|
|||
|
|
if( !m_reptime ){
|
|||
|
|
m_repmode++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
// case 9: // <20><><EFBFBD>M<EFBFBD>g<EFBFBD><67><EFBFBD>K
|
|||
|
|
// break;
|
|||
|
|
// case 10: // <20><><EFBFBD>v<EFBFBD><76><EFBFBD>C<EFBFBD><43><EFBFBD>M<EFBFBD><4D>
|
|||
|
|
// break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//--------------------------------------------------------
|
|||
|
|
// CSSTVMOD<4F>N<EFBFBD><4E><EFBFBD>X
|
|||
|
|
CSSTVMOD::CSSTVMOD()
|
|||
|
|
{
|
|||
|
|
m_TXBuf = NULL;
|
|||
|
|
|
|||
|
|
m_bpf = 1;
|
|||
|
|
m_lpf = 0;
|
|||
|
|
m_lpffq = 2000;
|
|||
|
|
// memset(HBPF, 0, sizeof(HBPF));
|
|||
|
|
// memset(Z, 0, sizeof(Z));
|
|||
|
|
m_bpftap = 24;
|
|||
|
|
// MakeFilter(HBPF, m_bpftap, ffBPF, SampFreq, 700, 2800, 40, 1.0);
|
|||
|
|
int lfq = 700 + g_dblToneOffset;
|
|||
|
|
if( lfq < 100 ){
|
|||
|
|
m_BPF.Create(m_bpftap, ffLPF, SampFreq, 2800 + g_dblToneOffset, 2800 + g_dblToneOffset, 40, 1.0);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_BPF.Create(m_bpftap, ffBPF, SampFreq, lfq, 2800 + g_dblToneOffset, 40, 1.0);
|
|||
|
|
}
|
|||
|
|
m_outgain = 24578.0;
|
|||
|
|
InitGain();
|
|||
|
|
m_vco.SetSampleFreq(SampFreq);
|
|||
|
|
m_vco.VirtualLock();
|
|||
|
|
m_vco.SetFreeFreq(1100 + g_dblToneOffset);
|
|||
|
|
m_vco.SetGain(2300 - 1100);
|
|||
|
|
InitTXBuf();
|
|||
|
|
m_tune = 0;
|
|||
|
|
m_Lost = 0;
|
|||
|
|
m_TuneFreq = 1750;
|
|||
|
|
m_VariOut = 0;
|
|||
|
|
m_VariR = 298;
|
|||
|
|
m_VariG = 588;
|
|||
|
|
m_VariB = 110;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CSSTVMOD::~CSSTVMOD()
|
|||
|
|
{
|
|||
|
|
CloseTXBuf();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVMOD::OpenTXBuf(int s)
|
|||
|
|
{
|
|||
|
|
if( (s != m_TXBufLen) || (m_TXBuf == NULL) ){
|
|||
|
|
if( m_TXBuf != NULL ) delete m_TXBuf;
|
|||
|
|
if( s < 5 ) s = 5;
|
|||
|
|
if( s > 14 ) s = 14;
|
|||
|
|
m_TXBufLen = s;
|
|||
|
|
m_TXMax = m_TXBufLen * SampFreq;
|
|||
|
|
m_TXBuf = new short[m_TXMax];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVMOD::CloseTXBuf(void)
|
|||
|
|
{
|
|||
|
|
if( m_TXBuf != NULL ){
|
|||
|
|
delete m_TXBuf;
|
|||
|
|
m_TXBuf = NULL;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVMOD::InitTXBuf(void)
|
|||
|
|
{
|
|||
|
|
m_rPnt = m_wPnt = 0;
|
|||
|
|
m_Cnt = 0;
|
|||
|
|
m_rCnt = 0;
|
|||
|
|
|
|||
|
|
m_iPos = 0;
|
|||
|
|
m_dPos = 0;
|
|||
|
|
|
|||
|
|
m_wLine = 0;
|
|||
|
|
|
|||
|
|
m_RowCnt = 0;
|
|||
|
|
pRow = NULL;
|
|||
|
|
m_BPF.Clear();
|
|||
|
|
// memset(Z, 0, sizeof(Z));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVMOD::Write(short fq)
|
|||
|
|
{
|
|||
|
|
#if DEBUG_AFC
|
|||
|
|
fq += DEBUG_AFC;
|
|||
|
|
#endif
|
|||
|
|
m_TXBuf[m_wPnt] = fq;
|
|||
|
|
m_wPnt++;
|
|||
|
|
m_Cnt++;
|
|||
|
|
if( m_wPnt >= m_TXMax ) m_wPnt = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVMOD::Write(short fq, double tim)
|
|||
|
|
{
|
|||
|
|
m_dPos += (tim * SSTVSET.m_TxSampFreq)/1000.0;
|
|||
|
|
for( ; m_iPos < int(m_dPos); m_iPos++ ) Write(fq);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVMOD::WriteC(short fq, double cnt)
|
|||
|
|
{
|
|||
|
|
m_dPos += cnt;
|
|||
|
|
for( ; m_iPos < int(m_dPos); m_iPos++ ) Write(fq);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double CSSTVMOD::Do(void)
|
|||
|
|
{
|
|||
|
|
double d;
|
|||
|
|
if( sys.m_TestDem ){
|
|||
|
|
d = m_vco.Do(double(sys.m_TestDem - 1100)/double(2300-1100));
|
|||
|
|
d *= m_outgain;
|
|||
|
|
}
|
|||
|
|
else if( m_tune ){
|
|||
|
|
d = m_vco.Do((m_TuneFreq - 1100)/1200.0);
|
|||
|
|
d *= m_outgain;
|
|||
|
|
}
|
|||
|
|
else if( m_Cnt ){
|
|||
|
|
int f = m_TXBuf[m_rPnt];
|
|||
|
|
if( f > 0 ){
|
|||
|
|
d = double((f & 0x0fff) - 1100)/double(2300-1100);
|
|||
|
|
if( m_lpf ) d = avgLPF.Avg(d);
|
|||
|
|
d = m_vco.Do(d);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
d = 0;
|
|||
|
|
}
|
|||
|
|
m_Cnt--;
|
|||
|
|
m_rCnt++;
|
|||
|
|
m_rPnt++;
|
|||
|
|
if( m_rPnt >= m_TXMax ) m_rPnt = 0;
|
|||
|
|
if( m_VariOut ){
|
|||
|
|
switch(f & 0xf000){
|
|||
|
|
case 0x1000:
|
|||
|
|
d *= m_outgainR;
|
|||
|
|
break;
|
|||
|
|
case 0x2000:
|
|||
|
|
d *= m_outgainG;
|
|||
|
|
break;
|
|||
|
|
case 0x3000:
|
|||
|
|
d *= m_outgainB;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
d *= m_outgain;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
#if VARITEST
|
|||
|
|
d *= m_outgain/3;
|
|||
|
|
#else
|
|||
|
|
d *= m_outgain;
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if( m_RowCnt ){
|
|||
|
|
d = (double)(*pRow++);
|
|||
|
|
m_RowCnt--;
|
|||
|
|
m_rCnt++;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
d = double(1500-1100)/double(2300-1100);
|
|||
|
|
d *= m_outgain;
|
|||
|
|
// m_rCnt++;
|
|||
|
|
}
|
|||
|
|
// if( m_bpf ) d = DoFIR(HBPF, Z, d, m_bpftap);
|
|||
|
|
if( m_bpf ) d = m_BPF.Do(d);
|
|||
|
|
return d;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVMOD::CalcFilter(void)
|
|||
|
|
{
|
|||
|
|
if( m_bpftap ){
|
|||
|
|
int lfq = 700 + g_dblToneOffset;
|
|||
|
|
if( lfq < 100 ){
|
|||
|
|
m_BPF.Create(m_bpftap, ffLPF, SampFreq, 2800 + g_dblToneOffset, 2800 + g_dblToneOffset, 40, 1.0);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_BPF.Create(m_bpftap, ffBPF, SampFreq, lfq, 2800 + g_dblToneOffset, 40, 1.0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
avgLPF.SetCount(int(SampFreq/m_lpffq + 0.5));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVMOD::InitGain(void)
|
|||
|
|
{
|
|||
|
|
if( m_VariR > 1000 ) m_VariR = 1000;
|
|||
|
|
if( m_VariG > 1000 ) m_VariG = 1000;
|
|||
|
|
if( m_VariB > 1000 ) m_VariB = 1000;
|
|||
|
|
m_outgainR = m_outgain * double(m_VariR) * 0.001;
|
|||
|
|
m_outgainG = m_outgain * double(m_VariG) * 0.001;
|
|||
|
|
m_outgainB = m_outgain * double(m_VariB) * 0.001;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVMOD::WriteFSK(BYTE c)
|
|||
|
|
{
|
|||
|
|
int i;
|
|||
|
|
for( i = 0; i < 6; i++ ){
|
|||
|
|
Write(short(c & 0x01 ? 1900 : FSKSPACE), FSKINTVAL);
|
|||
|
|
c = BYTE(c >> 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CSSTVMOD::WriteCWID(char c)
|
|||
|
|
{
|
|||
|
|
const USHORT _tbl[]={
|
|||
|
|
// 0 1 2 3 4 5 6 7
|
|||
|
|
0x0005, 0x8005, 0xc005, 0xe005, 0xf005, 0xf805, 0x7805, 0x3805, // 0-7
|
|||
|
|
// 8 9 : ; < = > ?
|
|||
|
|
0x1805, 0x0805, 0x0000, 0x0000, 0x0000, 0x7005, 0xA805, 0xcc06, // 8
|
|||
|
|
// @ A B C D E F G
|
|||
|
|
0x0000, 0x8002, 0x7004, 0x5004, 0x6003, 0x8001, 0xd004, 0x2003, // @-G
|
|||
|
|
// H I J K L M N O
|
|||
|
|
0xf004, 0xc002, 0x8004, 0x4003, 0xb004, 0x0002, 0x4002, 0x0003, // H-O
|
|||
|
|
// P Q R S T U V W
|
|||
|
|
0x9004, 0x2004, 0xa003, 0xe003, 0x0001, 0xc003, 0xe004, 0x8003, // P-W
|
|||
|
|
// X Y Z
|
|||
|
|
0x6004, 0x4004, 0x3004, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // X-Z
|
|||
|
|
};
|
|||
|
|
int dot = sys.m_CWIDSpeed + 30;
|
|||
|
|
// int dot = sys.m_CWIDSlow ? 40 : 30;
|
|||
|
|
c = char(toupper(c));
|
|||
|
|
c &= 0x7f;
|
|||
|
|
int d;
|
|||
|
|
if( c == '.' ) c = 'R';
|
|||
|
|
if( c == '/' ){
|
|||
|
|
d = 0x6805;
|
|||
|
|
}
|
|||
|
|
else if( c == '@' ){
|
|||
|
|
Write(0, 250);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
else if( (c >= '0') && (c <= 'Z') ){
|
|||
|
|
c -= '0';
|
|||
|
|
d = _tbl[c];
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
d = 0;
|
|||
|
|
}
|
|||
|
|
int n = d & 0x00ff;
|
|||
|
|
if( !d ){
|
|||
|
|
Write(0, dot*7);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
for(int i = 0; i < n; i++ ){
|
|||
|
|
if( d & 0x8000 ){
|
|||
|
|
Write(short(sys.m_CWIDFreq), dot);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
Write(short(sys.m_CWIDFreq), dot*3);
|
|||
|
|
}
|
|||
|
|
Write(0, dot);
|
|||
|
|
d = d << 1;
|
|||
|
|
}
|
|||
|
|
Write(0, dot*2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CHILL::CHILL()
|
|||
|
|
{
|
|||
|
|
// memset(Z, 0, sizeof(Z));
|
|||
|
|
SetWidth(0);
|
|||
|
|
#if HILLDOUBLEBUF
|
|||
|
|
m_FIR.Create(m_tap);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
m_htap = m_tap / 2;
|
|||
|
|
MakeHilbert(H, m_tap, SampFreq, 100, SampFreq/2 - 100);
|
|||
|
|
m_A[0] = m_A[1] = m_A[2] = m_A[3] = 0;
|
|||
|
|
m_iir.MakeIIR(1800, SampFreq, 3, 0, 0);
|
|||
|
|
#if !HILLDOUBLEBUF
|
|||
|
|
m_ph = &Z[m_htap];
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall CHILL::SetWidth(int fNarrow)
|
|||
|
|
{
|
|||
|
|
if( fNarrow ){
|
|||
|
|
m_OFF = (2 * PI * (NARROW_CENTER + g_dblToneOffset)) / SampFreq;
|
|||
|
|
m_OUT = 32768.0 * SampFreq / (2 * PI * NARROW_BW);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_OFF = (2 * PI * (1900 + g_dblToneOffset)) / SampFreq;
|
|||
|
|
m_OUT = 32768.0 * SampFreq / (2 * PI * 800);
|
|||
|
|
}
|
|||
|
|
if( SampBase >= 40000 ){
|
|||
|
|
m_OFF *= 4;
|
|||
|
|
m_OUT *= 0.25;
|
|||
|
|
m_tap = 48; //48
|
|||
|
|
m_df = 2;
|
|||
|
|
}
|
|||
|
|
else if( SampBase >= 16000 ){
|
|||
|
|
m_OFF *= 2;
|
|||
|
|
m_OUT *= 0.5;
|
|||
|
|
m_tap = 24; //24
|
|||
|
|
m_df = 1;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_tap = 12; //12
|
|||
|
|
m_df = 0;
|
|||
|
|
}
|
|||
|
|
if( sys.m_bCQ100 ){
|
|||
|
|
m_tap *= 3;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double CHILL::Do(double d)
|
|||
|
|
{
|
|||
|
|
#if HILLDOUBLEBUF
|
|||
|
|
double a;
|
|||
|
|
m_FIR.Do(d, a, H);
|
|||
|
|
#else
|
|||
|
|
d = DoFIR(H, Z, d, m_tap);
|
|||
|
|
double a = *m_ph;
|
|||
|
|
#endif
|
|||
|
|
if( a ) a = atan2(d, a);
|
|||
|
|
d = a - m_A[0];
|
|||
|
|
switch(m_df){
|
|||
|
|
case 1:
|
|||
|
|
m_A[0] = m_A[1];
|
|||
|
|
m_A[1] = a;
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
m_A[0] = m_A[1];
|
|||
|
|
m_A[1] = m_A[2];
|
|||
|
|
m_A[2] = m_A[3];
|
|||
|
|
m_A[3] = a;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
m_A[0] = a;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if( d >= PI ){
|
|||
|
|
d = d - PI*2;
|
|||
|
|
}
|
|||
|
|
else if( d <= -PI ){
|
|||
|
|
d = d + PI*2;
|
|||
|
|
}
|
|||
|
|
d += m_OFF;
|
|||
|
|
return m_iir.Do(d * m_OUT);
|
|||
|
|
}
|
|||
|
|
|