///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 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_DATVDEMODSINK_H
#define INCLUDE_DATVDEMODSINK_H
//LeanSDR
#include "leansdr/framework.h"
#include "leansdr/generic.h"
#include "leansdr/dvb.h"
#include "leansdr/filtergen.h"
#include "leansdr/hdlc.h"
#include "leansdr/iess.h"
#include "datvconstellation.h"
#include "datvgauge.h"
#include "datvdvbs2constellation.h"
#include "datvvideoplayer.h"
#include "datvideostream.h"
#include "datvudpstream.h"
#include "datvideorender.h"
#include "datvdemodsettings.h"
#include "dsp/channelsamplesink.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/messagequeue.h"
#include "util/movingaverage.h"
class TVScreen;
class DATVideoRender;
class QLabel;
class LevelMeterSignalDB;
class DATVDemodSink : public ChannelSampleSink {
public:
DATVDemodSink();
~DATVDemodSink();
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end);
bool setTVScreen(TVScreen *objScreen);
void setMERLabel(QLabel *merLabel);
void setCNRLabel(QLabel *cnrLabel);
void setMERMeter(LevelMeterSignalDB *merMeter);
void setCNRMeter(LevelMeterSignalDB *cnrMeter);
void SetVideoRender(DATVideoRender *objScreen);
DATVideostream *getVideoStream() { return m_objVideoStream; }
bool audioActive();
bool audioDecodeOK();
bool videoActive();
bool videoDecodeOK();
bool playVideo();
void stopVideo();
int GetSampleRate();
double getMagSq() const { return m_objMagSqAverage; } //!< Beware this is scaled to 2^30
int getModcodModulation() const { return m_modcodModulation; }
int getModcodCodeRate() const { return m_modcodCodeRate; }
bool isCstlnSetByModcod() const { return m_cstlnSetByModcod; }
void setMessageQueueToGUI(MessageQueue *messageQueue) { m_messageQueueToGUI = messageQueue; }
AudioFifo *getAudioFifo() { return &m_audioFifo; }
void applySettings(const DATVDemodSettings& settings, bool force = false);
void applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force = false);
private:
struct config
{
DATVDemodSettings::dvb_version standard;
DATVDemodSettings::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(DATVDemodSettings::DVB_S),
sampler(DATVDemodSettings::SAMP_LINEAR),
buf_factor(4),
Fs(2.4e6),
Fderot(0),
anf(0),
cnr(true),
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)
{
}
};
inline int decimation(float Fin, float Fout) { int d = Fin / Fout; return std::max(d, 1); }
void CleanUpDATVFramework();
void ResetDATVFrameworkPointers();
void InitDATVFramework();
void InitDATVS2Framework();
static int getLeanDVBCodeRateFromDATV(DATVDemodSettings::DATVCodeRate datvCodeRate);
static int getLeanDVBModulationFromDATV(DATVDemodSettings::DATVModulation datvModulation);
MessageQueue *getMessageQueueToGUI() { return m_messageQueueToGUI; }
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;
//dvbs2
unsigned long BUF_SLOTS;
unsigned long BUF_FRAMES;
unsigned long BUF_S2PACKETS;
unsigned long S2_MAX_SYMBOLS;
//************** 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;
//dvb-s2
void *p_slots_dvbs2;
leansdr::pipebuf *p_cstln;
leansdr::pipebuf *p_cstln_pls;
leansdr::pipebuf *p_framelock;
void *m_objDemodulatorDVBS2;
void *p_fecframes;
void *p_bbframes;
void *p_s2_deinterleaver;
void *r_fecdec;
void *r_fecdecsoft;
void *r_fecdechelper;
void *p_deframer;
//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::datvvideoplayer *r_videoplayer;
//CONSTELLATION
leansdr::datvconstellation *r_scope_symbols;
leansdr::datvdvbs2constellation *r_scope_symbols_dvbs2;
leansdr::datvgauge *r_merGauge;
leansdr::datvgauge *r_cnrGauge;
//*************** DATV PARAMETERS ***************
TVScreen *m_objRegisteredTVScreen;
DATVideoRender *m_objRegisteredVideoRender;
DATVideostream *m_objVideoStream;
DATVUDPStream m_udpStream;
DATVideoRenderThread *m_objRenderThread;
QLabel *m_merLabel;
QLabel *m_cnrLabel;
LevelMeterSignalDB *m_merMeter;
LevelMeterSignalDB *m_cnrMeter;
// Audio
AudioFifo m_audioFifo;
fftfilt * m_objRFFilter;
NCO m_objNCO;
bool m_blnInitialized;
bool m_blnRenderingVideo;
bool m_cstlnSetByModcod;
int m_modcodModulation;
int m_modcodCodeRate;
DATVDemodSettings::DATVModulation m_enmModulation;
//DATVConfig m_objRunning;
DATVDemodSettings m_settings;
int m_channelSampleRate;
int m_channelFrequencyOffset;
MovingAverageUtil m_objMagSqAverage;
MessageQueue *m_messageQueueToGUI;
static const unsigned int m_rfFilterFftLength;
};
#endif // INCLUDE_DATVDEMODSINK_H