/////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2019-2020 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation as version 3 of the License, or // // (at your option) any later version. // // // // This program 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 General Public License V3 for more details. // // // // You should have received a copy of the GNU General Public License // // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// #ifndef INCLUDE_CHIRPCHATDEMODSINK_H #define INCLUDE_CHIRPCHATDEMODSINK_H #include #include #include "dsp/channelsamplesink.h" #include "dsp/nco.h" #include "dsp/interpolator.h" #include "dsp/fftwindow.h" #include "util/message.h" #include "util/movingaverage.h" #include "chirpchatdemodsettings.h" class BasebandSampleSink; class FFTEngine; namespace ChirpChatDemodMsg { class MsgDecodeSymbols; } class MessageQueue; class ChirpChatDemodSink : public ChannelSampleSink { public: ChirpChatDemodSink(); ~ChirpChatDemodSink(); virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end); bool getDemodActive() const { return m_demodActive; } void setDecoderMessageQueue(MessageQueue *messageQueue) { m_decoderMsgQueue = messageQueue; } void setSpectrumSink(BasebandSampleSink* spectrumSink) { m_spectrumSink = spectrumSink; } void applyChannelSettings(int channelSampleRate, int bandwidth, int channelFrequencyOffset, bool force = false); void applySettings(const ChirpChatDemodSettings& settings, bool force = false); double getCurrentNoiseLevel() const { return m_magsqOffAvg.instantAverage() / (1< m_magsqOnAvg; MovingAverageUtil m_magsqOffAvg; MovingAverageUtil m_magsqTotalAvg; std::queue m_magsqQueue; unsigned int m_chirpCount; //!< Generic chirp counter unsigned int m_sfdSkip; //!< Number of samples in a SFD skip or slide (1/4) period unsigned int m_sfdSkipCounter; //!< Counter of skip or slide periods NCO m_nco; Interpolator m_interpolator; Real m_sampleDistanceRemain; Real m_interpolatorDistance; BasebandSampleSink* m_spectrumSink; Complex *m_spectrumBuffer; unsigned int m_nbSymbols; //!< Number of symbols = length of base FFT unsigned int m_nbSymbolsEff; //!< effective symbols considering DE bits unsigned int m_fftLength; //!< Length of base FFT unsigned int m_interpolatedFFTLength; //!< Length of interpolated FFT int m_deLength; //!< Number of FFT bins collated to represent one symbol int m_preambleTolerance; //!< Number of FFT bins to collate when looking for preamble void processSample(const Complex& ci); void initSF(unsigned int sf, unsigned int deBits, FFTWindow::Function fftWindow); //!< Init tables, FFTs, depending on spread factor void reset(); unsigned int argmax( const Complex *fftBins, unsigned int fftMult, unsigned int fftLength, double& magsqMax, double& magSqTotal, Complex *specBuffer, unsigned int specDecim ); unsigned int argmaxSpreaded( //!< count energy in adjacent bins for same symbol (needs DE bits > 0) const Complex *fftBins, unsigned int fftMult, unsigned int fftLength, double& magsqMax, double& magsqNoise, double& magSqTotal, Complex *specBuffer, unsigned int specDecim ); unsigned int extractMagnitudes( std::vector& magnitudes, const Complex *fftBins, unsigned int fftMult, unsigned int fftLength, double& magsqMax, double& magSqTotal, Complex *specBuffer, unsigned int specDecim ); void decimateSpectrum(Complex *in, Complex *out, unsigned int size, unsigned int decimation); int toSigned(int u, int intSize); unsigned int evalSymbol(unsigned int rawSymbol); }; #endif // INCLUDE_CHIRPCHATDEMODSINK_H