Example #1
0
            int ReceiveData(float[] incomingSamples, int startingIndex, int numSamples)
            {
                if (numSamples == 0)
                {
                    this.SymbolsCounter = 0;
                }

                int i, nProc;

                for (i = 0; i < numSamples; i += nProc)
                {
                    nProc = Math.Min(numSamples - i, DECFACTOR);
                    int nSym = Demodulator.Process(incomingSamples, startingIndex + i, nProc);
                    while (nSym-- > 0)
                    {
                        Decoder.Process(Demodulator.GetData(), DataScrambler.DataNext(), SCRAMBLE_MASK, out DataBlock[SymbolsCounter]);
                        SymbolsCounter++;
                        // Is probe sequence coming ?
                        if (SymbolsCounter >= CurrentMode.UnknownDataSymbols)
                        {
                            NextFunction = ReceiveProbe;
                            numSamples   = 0;
                            break;
                        }
                    }
                }
                return(i);
            }
Example #2
0
            int LookForSyncPreamble(float[] incomingSamples, int startingIndex, int numSamples)
            {
                if (numSamples == 0)
                {
                    SymbolsCounter = 0;
                }
                int i = 0;

                while (i < numSamples)
                {
                    // Feed the data into demodulator by DFAC chunks
                    int nProc = Math.Min(numSamples - i, DECFACTOR);
                    int nSymb = Demodulator.Process(incomingSamples, startingIndex + i, nProc);
                    while (nSymb-- > 0)
                    {
                        // If we went thru 3 preamble segments and did not catch it -
                        //  something is wrong -  start from the beginning
                        if (SymbolsCounter++ > (3 * 480))
                        {
                            NextFunction = Idle;
                            numSamples   = 0;   // This is how to terminate a loop!!!
                            break;
                        }
                        if (SyncCorr.Process(Demodulator.GetData()) > 0)
                        {
                            NextFunction = SyncDetected;
                            numSamples   = 0;   // This is how to terminate a loop!!!
                            break;
                        }
                    }
                    i += nProc;
                }
                return(i);
            }
Example #3
0
            // Initial state - looking for any reasonable amount of energy in signal
            int Idle(float[] incomingSamples, int startingIndex, int numSamples)
            {
                int i = 0;

                for (i = 0; i < numSamples; i++)
                {
                    float Sample = incomingSamples[startingIndex + i];
                    if ((Sample * Sample) > EnergyThreshold)
                    {
                        NextFunction = LookForCarrierEnergy;
                        numSamples   = 0;   // This is how to terminate a loop!!!
                    }
                }
                return(i);
            }
Example #4
0
            public void Init()
            {
                SyncCorr     = new Correlator(CORR_TYPE.DELTA_DIFF, 15 * 32, 9 * 32, 6 * 32, CorrTargetThreshold, CorrAverageThreshold, CorrEnergyThreshold);
                Demodulator  = new IQDemodulator(CARRIER_FREQ - 15, CARRIER_FREQ - 15, NUM_FREQ, ProcessingFrequency, SYMBOLRATE, SymbolFilterCoeffs);
                ProbeEncoder = new IQEncoder(BITS_PER_SYMBOL, Constellation.Table_1_to_1, Constellation.ITable_8PSK, Constellation.QTable_8PSK, EncodingType.SCRAMBLE_ADD);
                SymbDetector = new SymbolDetector();
                EOMDetector  = new BitCorrelator();
                FillSyncPatterns();
                SyncCorr.AddTarget(PreamblePattern);
                int FlipEOM = MILSTD_188.MSBFirst(MILSTD_188.EOM);

                EOMDetector.AddTarget(FlipEOM, 32);
                OutputData.Clear();
                InputFilter.Clear();

                PrevFunction = null;
                NextFunction = Idle;
            }
Example #5
0
            // Looking for any energy in carrier frequency
            int LookForCarrierEnergy(float[] incomingSamples, int startingIndex, int numSamples)
            {
                if (numSamples == 0)
                {
                    Demodulator.Init();
                }
                int i = 0;

                for (i = 0; i < numSamples; i++)
                {
                    float Sample = incomingSamples[startingIndex + i];
                    Demodulator.Process(Sample);
                    if (Demodulator.FrequencyEnergy > Demodulator.SignalEnergy * SignalThreshold)
                    {
                        NextFunction = LookForSymbolSync;
                        numSamples   = 0;   // This is how to terminate a loop!!!
                    }
                }
                return(i);
            }
Example #6
0
            void Process(int numSamples)
            {
                int Index = 0;
                int nProcessed;

                while (numSamples > 0)
                {
                    // If state function is called the very first time, then
                    // there will be a special call to indicate that. numSamples == 0 to tell that
                    // we are enering the state, so some state initialization can be done
                    while (PrevFunction != NextFunction)
                    {
                        PrevFunction = NextFunction;
                        NextFunction(InterpBuffer, Index, 0);
                    }
                    nProcessed  = NextFunction(InterpBuffer, Index, numSamples);
                    Index      += nProcessed;
                    numSamples -= nProcessed;
                }
            }
Example #7
0
            // Looking for symbol sync
            int LookForSymbolSync(float[] incomingSamples, int startingIndex, int numSamples)
            {
                if (numSamples == 0)
                {
                    Demodulator.Init();
                    Demodulator.StartCorrectionProcess(SYNC_TYPE.GARDNER_DD | SYNC_TYPE.GARDNER_NDA | SYNC_TYPE.QAMLD_NDA |
                                                       SYNC_TYPE.DIFF_NDA | SYNC_TYPE.ZERODET_NDA | SYNC_TYPE.PEAK_NDA | SYNC_TYPE.CORR_NDA,
                                                       SYMBOL_SYNC_SIZE);
                }
                int i, nProc;

                for (i = 0; i < numSamples; i += nProc)
                {
                    nProc = Math.Min(numSamples - i, DECFACTOR);
                    Demodulator.Process(incomingSamples, startingIndex + i, nProc);
                    if (Demodulator.IsSyncReady)
                    {
                        NextFunction = LookForSyncPreamble;
                        numSamples   = 0;   // This is how to terminate a loop!!!
                    }
                }
                return(i);
            }
Example #8
0
            int ReceiveProbe(float[] incomingSamples, int startingIndex, int numSamples)
            {
                if (numSamples == 0)
                {
                    LFSRState State = DataScrambler.State;  // Save current DataScrambler state
                    Array.Clear(Probe, 0, CurrentMode.ProbeDataSymbols);
                    // The last 2 probes for the interleaver are special -
                    //  they are not 0, but D1 and D2 values instead
                    if (ProbeCounter == (TotalPatternsInBlock - 2))
                    {
                        ChanSymbToTribit[CurrentMode.D1].CopyTo(Probe, 0); // Send 8 tribits
                        ChanSymbToTribit[CurrentMode.D1].CopyTo(Probe, 8); // Send 8 tribits
                    }
                    else if (ProbeCounter == (TotalPatternsInBlock - 1))
                    {
                        ChanSymbToTribit[CurrentMode.D2].CopyTo(Probe, 0); // Send 8 tribits
                        ChanSymbToTribit[CurrentMode.D2].CopyTo(Probe, 8); // Send 8 tribits
                    }

                    for (int k = 0; k < CurrentMode.ProbeDataSymbols; k++)
                    {
                        ProbeEncoder.Process(Probe[k], DataScrambler.DataNext(), SCRAMBLE_MASK, out ProbeTarget[k]);
                    }
                    ProbeCorr.AddTarget(ProbeTarget);
                    DataScrambler.State = State;    // Restore scrambler state

                    ProbeCounter++; if (ProbeCounter >= TotalPatternsInBlock)
                    {
                        ProbeCounter = 0;
                    }

                    Demodulator.RotateCorrection    *= Decoder.RotateCorrection;
                    Demodulator.FrequencyCorrection *= (IQ.UNITY + 0.05f * Decoder.FrequencyCorrection) / 1.05f;
                    ProbeCorr.StartCorrectionProcess();
//                    Demodulator.StartCorrectionProcess(SYNC_TYPE.GARDNER_DD | SYNC_TYPE.GARDNER_NDA | SYNC_TYPE.QAMLD_NDA |
//                                            SYNC_TYPE.DIFF_NDA | SYNC_TYPE.ZERODET_NDA | SYNC_TYPE.PEAK_NDA | SYNC_TYPE.CORR_NDA,
//                                                CurrentMode.UnknownDataSymbols + CurrentMode.ProbeDataSymbols);
                    Decoder.StartCorrectionProcess(CurrentMode.UnknownDataSymbols + CurrentMode.ProbeDataSymbols);
                    this.SymbolsCounter = 0;
                }

                int i, nProc;
                int Data;
                IQ  Symb;

                for (i = 0; i < numSamples; i += nProc)
                {
                    nProc = Math.Min(numSamples - i, DECFACTOR);
                    int nSymb = Demodulator.Process(incomingSamples, startingIndex + i, nProc);
                    while (nSymb-- > 0)
                    {
                        Symb = Demodulator.GetData();
                        ProbeCorr.Process(Symb);
                        Decoder.Process(Symb, DataScrambler.DataNext(), SCRAMBLE_MASK, out Data);
                        SymbolsCounter++;
                        // Is data sequence coming ?
                        if (SymbolsCounter >= CurrentMode.ProbeDataSymbols)
                        {
                            Demodulator.RotateCorrection    *= ProbeCorr.RotateCorrection;
                            Demodulator.FrequencyCorrection *= (IQ.UNITY + 0.05f * ProbeCorr.FrequencyCorrection) / 1.05f;
                            ProcessData();  // Process received data
                            NextFunction = ReceiveData;
                            numSamples   = 0;
                            break;
                        }
                    }
                }
                return(i);
            }
Example #9
0
            int SyncDetected(float[] incomingSamples, int startingIndex, int numSamples)
            {
                if (numSamples == 0)
                {
                    // Adjust demodulator
                    Demodulator.RotateCorrection = SyncCorr.RotateCorrection;

                    // Frequency Correction on receiving the first Sync block
                    // Only apply correction if the accumulated error will be more that 45 degrees
                    if (Math.Abs(SyncCorr.FrequencyCorrection.Degrees * SyncCorr.CorrelationMaxLength) > 45)
                    {
                        Demodulator.FrequencyCorrection = SyncCorr.FrequencyCorrection;
                    }
                    // Get the last 15*32 symbols
                    SyncCorr.GetLastData(SyncCorr.CorrelationMaxIndex, PreambleBlock, 15 * 32);
                    int D1, D2, Z, Cnt;
                    ProcessPreamble(out D1, out D2, out Cnt, out Z);
                    // Check for the reasonable values that we extracted from the preamble
                    // Get the mode from D1 and D2, verify counter
                    ModeInfo mi = MILSTD188_110B.modemModes[D1, D2];
                    if (Z == 0 && mi != null && Cnt < mi.PreambleSize)
                    {
                        this.CurrentMode = mi;
                        PreambuleCounter = Cnt;
                        if (PreambuleCounter == 0)
                        {
                            InitReceiveData();
                            NextFunction = ReceiveData;
                            numSamples   = 0;
                        }
                        else
                        {
                            PreambleIdx = 0;
                            SyncCorr.StartCorrectionProcess();
                        }
                    }
                    else
                    {
                        NextFunction = LookForSymbolSync;
                        numSamples   = 0;
                    }
                }

                int i, nProc;

                for (i = 0; i < numSamples; i += nProc)
                {
                    // Decode the preamble chunks
                    nProc = Math.Min(numSamples - i, DECFACTOR);
                    int nSym = Demodulator.Process(incomingSamples, startingIndex + i, nProc);
                    while (nSym-- > 0)
                    {
                        IQ IQData = Demodulator.GetData();
                        PreambleBlock[PreambleIdx++] = IQData;
                        SyncCorr.Process(IQData);
                        if (PreambleIdx >= PreambleBlock.Length)
                        {
                            // Do demodulator correction
                            Demodulator.RotateCorrection    *= SyncCorr.RotateCorrection;
                            Demodulator.FrequencyCorrection *= (IQ.UNITY + 0.05f * SyncCorr.FrequencyCorrection) / 1.05f;
                            int D1, D2, Z, Cnt;
                            ProcessPreamble(out D1, out D2, out Cnt, out Z);
                            // Check the values that we extracted from the preambule
                            // Get the mode from D1 and D2, verify counter
                            if (Z == 0 && D1 == CurrentMode.D1 && D2 == CurrentMode.D2 && Cnt == (PreambuleCounter - 1))
                            {
                                PreambuleCounter = Cnt;
                                if (PreambuleCounter == 0)
                                {
                                    InitReceiveData();
                                    NextFunction = ReceiveData;
                                    numSamples   = 0;
                                    break;
                                }
                                else
                                {
                                    PreambleIdx = 0;
                                    SyncCorr.StartCorrectionProcess();
                                }
                            }
                            else
                            {
                                NextFunction = LookForSymbolSync;
                                numSamples   = 0;
                                break;
                            }
                        }
                    }
                }
                return(i);
            }