📄 demodulator.cpp
字号:
//---------------------------------------------------------------------------
#pragma hdrstop
#include "DeModulator.h"
#include "Settings_F.h"
#include "Spectrum.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
__fastcall Demodulator::Demodulator(void (__closure __fastcall *APacketCallBackFunc)(void))
{
PacketCallBackFunc=APacketCallBackFunc;
pd=new Plotdata(NUMBER_OF_CONSTELLATION_POINTS_TO_DRAW,clRed);
pdptr=0;
datadeformatter=0;
RXCharBuffPtr=0;
lockoffcntdown=0;
smse=0;
amatimeout=0;
RootRaisedCosine *rrc;
h.resize(gSettings.DemodMajor.Firsize);
rrc=new RootRaisedCosine(gSettings.DemodMajor.Firsize,gSettings.DemodMajor.Symbol_Freq,gSettings.DemodMajor.Alpha,h.begin());
delete rrc;
BuffSize=gSettings.DemodMajor.Firsize+1;
BuffPtr=0;
Buff.resize(BuffSize);
for(int i=0;i<BuffSize;i++){Buff[i].re=0.0;Buff[i].im=0.0;}
st.SetCallsPerSymbol(4);
AdjSum=0.0;
AdjCnt=0;
AdjSpeed=0.0;
LockCnt=0;
gSettings.DemodMinor.DCD=false;
gSettings.DemodMinor.Locked=false;
gSettings.DemodMinor.Acquisitionstage=Resetting;
gSettings.DemodMinor.Ama=false;
gSettings.DemodMinor.SlowLock=false;
TryingFreqSettingAMANotOnTimeoutCnt=SettingsForm->JvValidateEditCMATimeOut->Value;
switch(gSettings.DemodMajor.ConstalationSize)
{
case 16:
CmaFinishedThreshold=SettingsForm->JvValidateEditQAM16CMAThreshold->Value;
AmaFinishedThreshold=SettingsForm->JvValidateEditQAM16AMAThreshold->Value;
break;
case 64:
CmaFinishedThreshold=SettingsForm->JvValidateEditQAM64CMAThreshold->Value;
AmaFinishedThreshold=SettingsForm->JvValidateEditQAM64AMAThreshold->Value;
break;
};
Cma.mu.re=SettingsForm->JvValidateEditEqualizerStepSize->Value;
Cma.mu.im=SettingsForm->JvValidateEditEqualizerStepSize->Value;
FirSizeFactor=200000;
if(SettingsForm->JvComboBoxFIRSize->ItemIndex==1)FirSizeFactor=400000;
if(SettingsForm->JvComboBoxFIRSize->ItemIndex==2)FirSizeFactor=800000;
datadeformatter=new DataDeFormatter();
gSettings.DemodMajorAddCallBackNotificationFuction(SettingsHaveChanged);
}
__fastcall Demodulator::~Demodulator()
{
gSettings.DemodMajor.Active=false;
gSettings.DemodMajorRemoveCallBackNotificationFunction(SettingsHaveChanged);
if(datadeformatter)delete datadeformatter;
delete pd;
}
void __fastcall Demodulator::FFTScanningUpdate()
{
if(gSettings.DemodMinor.DCD)
{
if((TryingFreqSettingAMANotOnTimeoutCnt>0)&&(fs.WorkingSettingStillValid))return;
if((fs.WorkingSettingStillValid)&&(gSettings.DemodMajor.ConstalationSize==16))
{
gSettings.SetDemodMajor
(
true,//bool Active
64,//int ConstalationSize
1.0,//double Alpha
gSettings.DemodMajor.Gamma,//double Gamma
gSettings.DemodMajor.Firsize,//int Firsize
gSettings.DemodMajor.Freq,//double Freq
gSettings.DemodMajor.InterleavingLength,//int InterleavingLength
gSettings.DemodMajor.RSErrorPercent,//int RSErrorPercent
gSettings.DemodMajor.FramePriod//int FramePriod
);
gSettings.DemodMinor.DCD=true;
return;
}
}
else
{
gSettings.SetDemodMajor
(
true,//bool Active
16,//int ConstalationSize
1.0,//double Alpha
gSettings.DemodMajor.Gamma,//double Gamma
gSettings.DemodMajor.Firsize,//int Firsize
gSettings.DemodMajor.Freq,//double Freq
gSettings.DemodMajor.InterleavingLength,//int InterleavingLength
gSettings.DemodMajor.RSErrorPercent,//int RSErrorPercent
gSettings.DemodMajor.FramePriod//int FramePriod
);
}
if(fs.GetNextSetting())SetNewFrequencySettigs(fs.WorkingSettings);
else
{
gSettings.DemodMinor.DCD=false;
LockCnt=0;
AdjSpeed=0.0;
gSettings.DemodMinor.Locked=false;
gSettings.DemodMinor.Acquisitionstage=Resetting;
datadeformatter->GotFrame=false;
gSettings.DemodMinor.Ama=false;
gSettings.DemodMinor.SlowLock=false;
}
}
void __fastcall Demodulator::SetNewFrequencySettigs(FrequencySetting fsetngs)
{
if(fsetngs.SignalPower<1.0)return;
//try different levels of workload for the demod fir filter
//int FirSize=fsetngs.Gamma*200000/fsetngs.Freq; //low
//int FirSize=fsetngs.Gamma*400000/fsetngs.Freq; //medium
//int FirSize=fsetngs.Gamma*800000/fsetngs.Freq; //high
int FirSize=fsetngs.Gamma*FirSizeFactor/fsetngs.Freq; // use setting page
gSettings.SetDemodMajor
(
true,//bool Active
16,//gSettings.DemodMajor.ConstalationSize,//int ConstalationSize
1.0,//double Alpha
fsetngs.Gamma,//double Gamma
FirSize,//gSettings.DemodMajor.Firsize,//int Firsize
fsetngs.Freq,//double Freq
gSettings.DemodMajor.InterleavingLength,//int InterleavingLength
gSettings.DemodMajor.RSErrorPercent,//int RSErrorPercent
gSettings.DemodMajor.FramePriod//int FramePriod
);
gSettings.DemodMinor.DCD=true;
}
void __fastcall Demodulator::Update(short * Data, int size)
{
for(int i=0;i<size;i+=2)
{
double sig=(((double)Data[i])+((double)Data[i+1]))/1000.0;
Buff[BuffPtr].re=sig*Wt.WTCosValue();
Buff[BuffPtr].im=sig*Wt.WTSinValue();
BuffPtr++;BuffPtr%=BuffSize;
Wt.WTnextFrame();
st.Pos+=1.0;
if(st.Pos>=st.FramesPerRightFrame)
{
st.CaculateNextRightPos();
if((st.OverSampleCnt==1)||(st.OverSampleCnt==3))
{
Wt.AdvanceFractionOfWave(AdjSpeed/4.0);
st.AdjustByFractionOfCall((-AdjSpeed)/gSettings.DemodMajor.Gamma);
continue;
}
if(sig>=65.532)Cliping=true;
double lastp=st.Pos;
double thisp=1-lastp;
PtComplex point;
point.re=0;point.im=0;
int lbptr;
for(register int i=0;i<(gSettings.DemodMajor.Firsize);i++)
{
lbptr=BuffPtr;
BuffPtr++;BuffPtr%=BuffSize;
point.im+=h[i]*(Buff[BuffPtr].im*thisp+Buff[lbptr].im*lastp);
point.re+=h[i]*(Buff[BuffPtr].re*thisp+Buff[lbptr].re*lastp);
}
BuffPtr++;BuffPtr%=BuffSize;
point.re*=dd.PowerMultiplyer;
point.im*=dd.PowerMultiplyer;
if((fabs(point.re)>3.0)||(fabs(point.im)>3.0)){point.re=0;point.im=0;}
if(st.FirstFrame)
{
Cma.IterateOnNextUpdate=true;
Cma.Update(point);
pd->x[pdptr]=(Cma.y.re);
pd->y[pdptr]=(Cma.y.im);
pdptr++;pdptr%=NUMBER_OF_CONSTELLATION_POINTS_TO_DRAW;
}
else
{
Cma.IterateOnNextUpdate=false;
Cma.Update(point);
mgard.OffPointUpdate(point);
AcquisitionStateMachine();
Wt.AdvanceFractionOfWave(AdjSpeed/4.0);
st.AdjustByFractionOfCall((-AdjSpeed)/gSettings.DemodMajor.Gamma);
continue;
}
dd.Update(point);
if((!(gSettings.DemodMinor.SlowLock))&&(gSettings.DemodMinor.DCD))
{
// int PreSettleCntTo=15000; // a few symbols as to allow symbol timing and carrier timeing to settle before freq adj calculation has been made
// int FreqEstimationNumber=80000; // # of symbols that are used to fine tune the carrier frequency timeing
// int PostSettleCntTo=5000; // a few symbols as to allow symbol timing and carrier timeing to settle once the major adjustment has been made
int PreSettleCntTo=SettingsForm->JvValidateEditPreSymbolCnt->Value;
int FreqEstimationNumber=SettingsForm->JvValidateEditLockingSymbolCnt->Value;
int PostSettleCntTo=SettingsForm->JvValidateEditPostSymbolCnt->Value;
double move;
if(AdjCnt<FreqEstimationNumber)move=-dd.Angle/750;
else move=-dd.Angle/5000;
Wt.AdvanceFractionOfWave(move);
st.AdjustByFractionOfCall(4.0*(move)/(gSettings.DemodMajor.Gamma));
mgard.OnPointUpdate(point);
if(AdjCnt<FreqEstimationNumber)st.AdjustByFractionOfCall(mgard.GardShift/2);
else st.AdjustByFractionOfCall(mgard.GardShift/50.0);
if((LockCnt>PreSettleCntTo))
{
AdjSum+=move+AdjSpeed;
AdjCnt++;
if(AdjCnt>=FreqEstimationNumber)AdjSpeed=AdjSum/AdjCnt;
}
else
{
AdjCnt=0;
AdjSpeed=0.0;
AdjSum=0.0;
}
if((!(gSettings.DemodMinor.Locked))&&(AdjCnt>=(FreqEstimationNumber+PostSettleCntTo)))
{
Cma.ReInitLock();
gSettings.DemodMinor.Locked=true;
}
}
else
{
Wt.AdvanceFractionOfWave(-dd.Angle/30000);
st.AdjustByFractionOfCall(4.0*(dd.Angle/30000)/(gSettings.DemodMajor.Gamma));
mgard.OnPointUpdate(dd.RectifidedPoint);
st.AdjustByFractionOfCall(mgard.GardShift/1000);
}
Wt.AdvanceFractionOfWave(AdjSpeed/4.0);
st.AdjustByFractionOfCall((-AdjSpeed)/(gSettings.DemodMajor.Gamma));
int retword=datadeformatter->Update(&(Cma.y));
if(gSettings.DemodMinor.Acquisitionstage!=WaitingForLossOfLock)
{
retword=-3;
RXCharBuffPtr=0;
FirstPacket=true;
}
if(retword>=-1)
{
if(retword>=0)
{
RXCharBuff[RXCharBuffPtr]=retword;
RXCharBuffPtr++;RXCharBuffPtr%=RX_CHAR_BUFF_SIZE;
}
if((retword==-1)&&(lastretword>=0))
{
//--here we have a packet to return
//--call packet callback function
if(FirstPacket)
{
RXCharBuffPtr=0;
FirstPacket=false;
}
else PacketCallBackFunc();
//--
}
lastretword=retword;
}
if(gSettings.DemodMinor.Locked)Cma.Iterate();
}
}
if((SettingsForm->JvXPCheckboxAllwaysRunFFT->Checked)||(!datadeformatter->GotFrame))
{
fs.Update(Data,size);
FFTScanningUpdate();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -