⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 demodulator.cpp

📁 QAM module to use in Java with an easy interface and powerful performance
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//---------------------------------------------------------------------------


#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 + -