/////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2018 F4HKW // // for F4EXB / SDRAngel // // using LeanSDR Framework (C) 2016 F4DAV // // // // 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 // // // // 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_DATVDEMOD_H #define INCLUDE_DATVDEMOD_H class DeviceSourceAPI; class ThreadedBasebandSampleSink; class DownChannelizer; #define rfFilterFftLength 1024 //LeanSDR #include "leansdr/framework.h" #include "leansdr/generic.h" #include "leansdr/dsp.h" #include "leansdr/sdr.h" #include "leansdr/dvb.h" #include "leansdr/rs.h" #include "leansdr/filtergen.h" #include "leansdr/hdlc.h" #include "leansdr/iess.h" #include "datvconstellation.h" #include "datvvideoplayer.h" #include "datvideostream.h" #include "datvideorender.h" #include "channel/channelsinkapi.h" #include "dsp/basebandsamplesink.h" #include "dsp/devicesamplesource.h" #include "dsp/dspcommands.h" #include "dsp/downchannelizer.h" #include "dsp/fftfilt.h" #include "dsp/nco.h" #include "dsp/interpolator.h" #include "dsp/movingaverage.h" #include "dsp/agc.h" #include "audio/audiofifo.h" #include "util/message.h" #include "util/movingaverage.h" #include enum DATVModulation { BPSK, QPSK, PSK8, APSK16, APSK32, APSK64E, QAM16, QAM64, QAM256 }; enum dvb_version { DVB_S, DVB_S2 }; enum dvb_sampler { SAMP_NEAREST, SAMP_LINEAR, SAMP_RRC }; inline int decimation(float Fin, float Fout) { int d = Fin / Fout; return std::max(d, 1); } struct config { dvb_version standard; dvb_sampler sampler; int buf_factor; // Buffer sizing float Fs; // Sampling frequency (Hz) float Fderot; // Shift the signal (Hz). Note: Ftune is faster int anf; // Number of auto notch filters bool cnr; // Measure CNR unsigned int decim; // Decimation, 0=auto float Fm; // QPSK symbol rate (Hz) leansdr::cstln_lut::predef constellation; leansdr::code_rate fec; float Ftune; // Bias frequency for the QPSK demodulator (Hz) bool allow_drift; bool fastlock; bool viterbi; bool hard_metric; bool resample; float resample_rej; // Approx. filter rejection in dB int rrc_steps; // Discrete steps between symbols, 0=auto float rrc_rej; // Approx. RRC filter rejection in dB float rolloff; // Roll-off 0..1 bool hdlc; // Expect HDLC frames instead of MPEG packets bool packetized; // Output frames with 16-bit BE length float Finfo; // Desired refresh rate on fd_info (Hz) config() : standard(DVB_S), sampler(SAMP_LINEAR), buf_factor(4), Fs(2.4e6), Fderot(0), anf(0), cnr(false), decim(0), Fm(2e6), constellation(leansdr::cstln_lut::QPSK), fec(leansdr::FEC12), Ftune(0), allow_drift(false), fastlock(true), viterbi(false), hard_metric(false), resample(false), resample_rej(10), rrc_steps(0), rrc_rej(10), rolloff(0.35), hdlc(false), packetized(false), Finfo(5) { } }; struct DATVConfig { int intMsps; int intRFBandwidth; int intCenterFrequency; dvb_version enmStandard; DATVModulation enmModulation; leansdr::code_rate enmFEC; int intSampleRate; int intSymbolRate; int intNotchFilters; bool blnAllowDrift; bool blnFastLock; dvb_sampler enmFilter; bool blnHardMetric; float fltRollOff; bool blnViterbi; int intExcursion; DATVConfig() : intMsps(1024000), intRFBandwidth(1024000), intCenterFrequency(0), enmStandard(DVB_S), enmModulation(BPSK), enmFEC(leansdr::FEC12), intSampleRate(1024000), intSymbolRate(250000), intNotchFilters(1), blnAllowDrift(false), blnFastLock(false), enmFilter(SAMP_LINEAR), blnHardMetric(false), fltRollOff(0.35), blnViterbi(false), intExcursion(10) { } }; class DATVDemod : public BasebandSampleSink, public ChannelSinkAPI { Q_OBJECT public: DATVDemod(DeviceSourceAPI *); ~DATVDemod(); virtual void destroy() { delete this; } virtual void getIdentifier(QString& id) { id = objectName(); } virtual void getTitle(QString& title) { title = objectName(); } virtual qint64 getCenterFrequency() const { return m_objRunning.intCenterFrequency; } virtual QByteArray serialize() const { return QByteArray(); } virtual bool deserialize(const QByteArray& data) { (void) data; return false; } void configure( MessageQueue* objMessageQueue, int intRFBandwidth, int intCenterFrequency, dvb_version enmStandard, DATVModulation enmModulation, leansdr::code_rate enmFEC, int intSymbolRate, int intNotchFilters, bool blnAllowDrift, bool blnFastLock, dvb_sampler enmFilter, bool blnHardMetric, float fltRollOff, bool blnViterbi, int intfltExcursion); virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po); virtual void start(); virtual void stop(); virtual bool handleMessage(const Message& cmd); bool SetTVScreen(TVScreen *objScreen); DATVideostream * SetVideoRender(DATVideoRender *objScreen); bool PlayVideo(bool blnStartStop); void InitDATVParameters( int intMsps, int intRFBandwidth, int intCenterFrequency, dvb_version enmStandard, DATVModulation enmModulation, leansdr::code_rate enmFEC, int intSampleRate, int intSymbolRate, int intNotchFilters, bool blnAllowDrift, bool blnFastLock, dvb_sampler enmFilter, bool blnHardMetric, float fltRollOff, bool blnViterbi, int intEExcursion); void CleanUpDATVFramework(bool blnRelease); int GetSampleRate(); void InitDATVFramework(); double getMagSq() const { return m_objMagSqAverage; } //!< Beware this is scaled to 2^30 static const QString m_channelIdURI; static const QString m_channelId; class MsgConfigureChannelizer : public Message { MESSAGE_CLASS_DECLARATION public: int getCenterFrequency() const { return m_centerFrequency; } static MsgConfigureChannelizer* create(int centerFrequency) { return new MsgConfigureChannelizer(centerFrequency); } private: int m_centerFrequency; MsgConfigureChannelizer(int centerFrequency) : Message(), m_centerFrequency(centerFrequency) {} }; private: class MsgConfigureDATVDemod : public Message { MESSAGE_CLASS_DECLARATION public: static MsgConfigureDATVDemod* create( int intRFBandwidth, int intCenterFrequency, dvb_version enmStandard, DATVModulation enmModulation, leansdr::code_rate enmFEC, int intSymbolRate, int intNotchFilters, bool blnAllowDrift, bool blnFastLock, dvb_sampler enmFilter, bool blnHardMetric, float fltRollOff, bool blnViterbi, int intExcursion) { return new MsgConfigureDATVDemod( intRFBandwidth, intCenterFrequency, enmStandard, enmModulation, enmFEC, intSymbolRate, intNotchFilters, blnAllowDrift, blnFastLock, enmFilter, blnHardMetric, fltRollOff, blnViterbi, intExcursion); } DATVConfig m_objMsgConfig; private: MsgConfigureDATVDemod( int intRFBandwidth, int intCenterFrequency, dvb_version enmStandard, DATVModulation enmModulation, leansdr::code_rate enmFEC, int intSymbolRate, int intNotchFilters, bool blnAllowDrift, bool blnFastLock, dvb_sampler enmFilter, bool blnHardMetric, float fltRollOff, bool blnViterbi, int intExcursion) : Message() { m_objMsgConfig.intRFBandwidth = intRFBandwidth; m_objMsgConfig.intCenterFrequency = intCenterFrequency; m_objMsgConfig.enmStandard = enmStandard; m_objMsgConfig.enmModulation = enmModulation; m_objMsgConfig.enmFEC = enmFEC; m_objMsgConfig.intSymbolRate = intSymbolRate; m_objMsgConfig.intNotchFilters = intNotchFilters; m_objMsgConfig.blnAllowDrift = blnAllowDrift; m_objMsgConfig.blnFastLock = blnFastLock; m_objMsgConfig.enmFilter= enmFilter; m_objMsgConfig.blnHardMetric = blnHardMetric; m_objMsgConfig.fltRollOff = fltRollOff; m_objMsgConfig.blnViterbi = blnViterbi; m_objMsgConfig.intExcursion = intExcursion; } }; unsigned long m_lngExpectedReadIQ; long m_lngReadIQ; //************** LEANDBV Parameters ************** unsigned long BUF_BASEBAND; unsigned long BUF_SYMBOLS; unsigned long BUF_BYTES; unsigned long BUF_MPEGBYTES; unsigned long BUF_PACKETS; unsigned long BUF_SLOW; //************** LEANDBV Scheduler *************** leansdr::scheduler * m_objScheduler; struct config m_objCfg; bool m_blnDVBInitialized; bool m_blnNeedConfigUpdate; //LeanSDR Pipe Buffer // INPUT leansdr::pipebuf *p_rawiq; leansdr::pipewriter *p_rawiq_writer; leansdr::pipebuf *p_preprocessed; // NOTCH FILTER leansdr::auto_notch *r_auto_notch; leansdr::pipebuf *p_autonotched; // FREQUENCY CORRECTION : DEROTATOR leansdr::pipebuf *p_derot; leansdr::rotator *r_derot; // CNR ESTIMATION leansdr::pipebuf *p_cnr; leansdr::cnr_fft *r_cnr; //FILTERING leansdr::fir_filter *r_resample; leansdr::pipebuf *p_resampled; float *coeffs; int ncoeffs; // OUTPUT PREPROCESSED DATA leansdr::sampler_interface *sampler; float *coeffs_sampler; int ncoeffs_sampler; leansdr::pipebuf *p_symbols; leansdr::pipebuf *p_freq; leansdr::pipebuf *p_ss; leansdr::pipebuf *p_mer; leansdr::pipebuf *p_sampled; //DECIMATION leansdr::pipebuf *p_decimated; leansdr::decimator *p_decim; //PROCESSED DATA MONITORING leansdr::file_writer *r_ppout; //GENERIC CONSTELLATION RECEIVER leansdr::cstln_receiver *m_objDemodulator; // DECONVOLUTION AND SYNCHRONIZATION leansdr::pipebuf *p_bytes; leansdr::deconvol_sync_simple *r_deconv; leansdr::viterbi_sync *r; leansdr::pipebuf *p_descrambled; leansdr::pipebuf *p_frames; leansdr::etr192_descrambler * r_etr192_descrambler; leansdr::hdlc_sync *r_sync; leansdr::pipebuf *p_mpegbytes; leansdr::pipebuf *p_lock; leansdr::pipebuf *p_locktime; leansdr::mpeg_sync *r_sync_mpeg; // DEINTERLEAVING leansdr::pipebuf > *p_rspackets; leansdr::deinterleaver *r_deinter; // REED-SOLOMON leansdr::pipebuf *p_vbitcount; leansdr::pipebuf *p_verrcount; leansdr::pipebuf *p_rtspackets; leansdr::rs_decoder *r_rsdec; // BER ESTIMATION leansdr::pipebuf *p_vber; leansdr::rate_estimator *r_vber; // DERANDOMIZATION leansdr::pipebuf *p_tspackets; leansdr::derandomizer *r_derand; //OUTPUT leansdr::file_writer *r_stdout; leansdr::datvvideoplayer *r_videoplayer; //CONSTELLATION leansdr::datvconstellation *r_scope_symbols; DeviceSourceAPI* m_deviceAPI; ThreadedBasebandSampleSink* m_threadedChannelizer; DownChannelizer* m_channelizer; //*************** DATV PARAMETERS *************** TVScreen * m_objRegisteredTVScreen; DATVideoRender * m_objRegisteredVideoRender; DATVideostream * m_objVideoStream; DATVideoRenderThread * m_objRenderThread; fftfilt * m_objRFFilter; NCO m_objNCO; bool m_blnInitialized; bool m_blnRenderingVideo; bool m_blnStartStopVideo; DATVModulation m_enmModulation; DATVConfig m_objRunning; MovingAverageUtil m_objMagSqAverage; QMutex m_objSettingsMutex; void ApplySettings(); }; #endif // INCLUDE_DATVDEMOD_H