diff --git a/plugins/channelrx/demoddatv/datvdemod.cpp b/plugins/channelrx/demoddatv/datvdemod.cpp index 9c125d731..d0bcbdb3d 100644 --- a/plugins/channelrx/demoddatv/datvdemod.cpp +++ b/plugins/channelrx/demoddatv/datvdemod.cpp @@ -37,6 +37,7 @@ const QString DATVDemod::m_channelId = "DATVDemod"; MESSAGE_CLASS_DEFINITION(DATVDemod::MsgConfigureDATVDemod, Message) MESSAGE_CLASS_DEFINITION(DATVDemod::MsgConfigureChannelizer, Message) +MESSAGE_CLASS_DEFINITION(DATVDemod::MsgReportModcodCstlnChange, Message) DATVDemod::DATVDemod(DeviceAPI *deviceAPI) : ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), @@ -50,6 +51,8 @@ DATVDemod::DATVDemod(DeviceAPI *deviceAPI) : m_blnRenderingVideo(false), m_blnStartStopVideo(false), m_cstlnSetByModcod(false), + m_modcodModulation(-1), + m_modcodCodeRate(-1), m_enmModulation(DATVDemodSettings::BPSK /*DATV_FM1*/), m_sampleRate(1024000), m_objSettingsMutex(QMutex::NonRecursive) @@ -1269,9 +1272,21 @@ void DATVDemod::feed(const SampleVector::const_iterator& begin, const SampleVect if (r_scope_symbols_dvbs2) { r_scope_symbols_dvbs2->calculate_cstln_points(); } + + if (getMessageQueueToGUI()) + { + MsgReportModcodCstlnChange *msg = MsgReportModcodCstlnChange::create( + getModulationFromLeanDVBCode(objDemodulatorDVBS2->cstln->m_typeCode), + getCodeRateFromLeanDVBCode(objDemodulatorDVBS2->cstln->m_rateCode) + ); + + getMessageQueueToGUI()->push(msg); + } } m_cstlnSetByModcod = objDemodulatorDVBS2->cstln->m_setByModcod; + m_modcodModulation = objDemodulatorDVBS2->m_modcodType; + m_modcodCodeRate = objDemodulatorDVBS2->m_modcodRate; } } @@ -1473,7 +1488,7 @@ DATVDemodSettings::DATVCodeRate DATVDemod::getCodeRateFromLeanDVBCode(int leanDV } else if (leanDVBCodeRate == leansdr::code_rate::FEC910) { return DATVDemodSettings::DATVCodeRate::FEC910; } else { - return DATVDemodSettings::DATVCodeRate::FEC12; + return DATVDemodSettings::DATVCodeRate::RATE_UNSET; } } @@ -1498,7 +1513,7 @@ DATVDemodSettings::DATVModulation DATVDemod::getModulationFromLeanDVBCode(int le } else if (leanDVBModulation == leansdr::cstln_base::predef::QPSK) { return DATVDemodSettings::DATVModulation::QPSK; } else { - return DATVDemodSettings::DATVModulation::BPSK; + return DATVDemodSettings::DATVModulation::MOD_UNSET; } } @@ -1531,7 +1546,7 @@ int DATVDemod::getLeanDVBCodeRateFromDATV(DATVDemodSettings::DATVCodeRate datvCo } else if (datvCodeRate == DATVDemodSettings::DATVCodeRate::FEC910) { return (int) leansdr::code_rate::FEC910; } else { - return (int) leansdr::code_rate::FEC12; + return -1; } } @@ -1556,6 +1571,6 @@ int DATVDemod::getLeanDVBModulationFromDATV(DATVDemodSettings::DATVModulation da } else if (datvModulation == DATVDemodSettings::DATVModulation::QPSK) { return (int) leansdr::cstln_base::predef::QPSK; } else { - return (int) leansdr::cstln_base::predef::BPSK; + return -1; } } diff --git a/plugins/channelrx/demoddatv/datvdemod.h b/plugins/channelrx/demoddatv/datvdemod.h index d29e01ecc..03b64ce07 100644 --- a/plugins/channelrx/demoddatv/datvdemod.h +++ b/plugins/channelrx/demoddatv/datvdemod.h @@ -185,6 +185,9 @@ public: void InitDATVFramework(); void InitDATVS2Framework(); 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; } static DATVDemodSettings::DATVCodeRate getCodeRateFromLeanDVBCode(int leanDVBCodeRate); static DATVDemodSettings::DATVModulation getModulationFromLeanDVBCode(int leanDVBModulation); static int getLeanDVBCodeRateFromDATV(DATVDemodSettings::DATVCodeRate datvCodeRate); @@ -236,6 +239,33 @@ public: { } }; + class MsgReportModcodCstlnChange : public Message { + MESSAGE_CLASS_DECLARATION + + public: + DATVDemodSettings::DATVModulation getModulation() const { return m_modulation; } + DATVDemodSettings::DATVCodeRate getCodeRate() const { return m_codeRate; } + + static MsgReportModcodCstlnChange* create(const DATVDemodSettings::DATVModulation& modulation, + const DATVDemodSettings::DATVCodeRate& codeRate) + { + return new MsgReportModcodCstlnChange(modulation, codeRate); + } + + private: + DATVDemodSettings::DATVModulation m_modulation; + DATVDemodSettings::DATVCodeRate m_codeRate; + + MsgReportModcodCstlnChange( + const DATVDemodSettings::DATVModulation& modulation, + const DATVDemodSettings::DATVCodeRate& codeRate + ) : + Message(), + m_modulation(modulation), + m_codeRate(codeRate) + { } + }; + private: unsigned long m_lngExpectedReadIQ; long m_lngReadIQ; @@ -386,6 +416,8 @@ private: bool m_blnRenderingVideo; bool m_blnStartStopVideo; bool m_cstlnSetByModcod; + int m_modcodModulation; + int m_modcodCodeRate; DATVDemodSettings::DATVModulation m_enmModulation; diff --git a/plugins/channelrx/demoddatv/datvdemodgui.cpp b/plugins/channelrx/demoddatv/datvdemodgui.cpp index 3ce2295fa..75a37a79e 100644 --- a/plugins/channelrx/demoddatv/datvdemodgui.cpp +++ b/plugins/channelrx/demoddatv/datvdemodgui.cpp @@ -99,10 +99,33 @@ bool DATVDemodGUI::deserialize(const QByteArray& arrData) } } -bool DATVDemodGUI::handleMessage(const Message& objMessage) +bool DATVDemodGUI::handleMessage(const Message& message) { - (void) objMessage; - return false; + if (DATVDemod::MsgReportModcodCstlnChange::match(message)) + { + DATVDemod::MsgReportModcodCstlnChange& notif = (DATVDemod::MsgReportModcodCstlnChange&) message; + m_settings.m_fec = notif.getCodeRate(); + m_settings.m_modulation = notif.getModulation(); + m_settings.validateSystemConfiguration(); + displaySystemConfiguration(); + } + else + { + return false; + } +} + +void DATVDemodGUI::handleInputMessages() +{ + Message* message; + + while ((message = getInputMessageQueue()->pop()) != 0) + { + if (handleMessage(*message)) + { + delete message; + } + } } void DATVDemodGUI::channelMarkerChangedByCursor() @@ -139,12 +162,16 @@ DATVDemodGUI::DATVDemodGUI(PluginAPI* objPluginAPI, DeviceUISet *deviceUISet, Ba m_deviceUISet(deviceUISet), m_objChannelMarker(this), m_blnBasicSettingsShown(false), - m_blnDoApplySettings(true) + m_blnDoApplySettings(true), + m_modcodModulationIndex(-1), + m_modcodCodeRateIndex(-1), + m_cstlnSetByModcod(false) { ui->setupUi(this); ui->screenTV->setColor(true); setAttribute(Qt::WA_DeleteOnClose, true); connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool))); + connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); m_objDATVDemod = (DATVDemod*) rxChannel; m_objDATVDemod->setMessageQueueToGUI(getInputMessageQueue()); @@ -193,6 +220,7 @@ DATVDemodGUI::DATVDemodGUI(PluginAPI* objPluginAPI, DeviceUISet *deviceUISet, Ba CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioMute); connect(audioMuteRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(audioSelect())); + resetToDefaults(); // does applySettings() } @@ -216,18 +244,27 @@ void DATVDemodGUI::displaySettings() m_objChannelMarker.setCenterFrequency(m_settings.m_centerFrequency); ui->deltaFrequency->setValue(m_settings.m_centerFrequency); m_objChannelMarker.setColor(m_settings.m_rgbColor); - ui->chkAllowDrift->setChecked(m_settings.m_allowDrift); - ui->chkFastlock->setChecked(m_settings.m_fastLock); - ui->cmbFilter->setCurrentIndex((int) m_settings.m_filter); + ui->chkAllowDrift->setChecked(m_settings.m_allowDrift); + ui->chkHardMetric->setChecked(m_settings.m_hardMetric); + ui->chkFastlock->setChecked(m_settings.m_fastLock); + ui->chkViterbi->setChecked(m_settings.m_viterbi); + + ui->chkAllowDrift->setEnabled(m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S); + ui->chkHardMetric->setEnabled(m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S); + ui->chkFastlock->setEnabled(m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S); + ui->chkViterbi->setEnabled(m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S); + + if (m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S) { + ui->statusText->clear(); + } + + ui->cmbFilter->setCurrentIndex((int) m_settings.m_filter); displayRRCParameters(((int) m_settings.m_filter == 2)); - ui->chkHardMetric->setChecked(m_settings.m_hardMetric); ui->spiRollOff->setValue((int) (m_settings.m_rollOff * 100.0f)); - ui->chkViterbi->setChecked(m_settings.m_viterbi); ui->audioMute->setChecked(m_settings.m_audioMute); - ui->cmbFEC->setCurrentIndex((int) m_settings.m_fec); - ui->cmbModulation->setCurrentIndex((int) m_settings.m_modulation); + displaySystemConfiguration(); ui->cmbStandard->setCurrentIndex((int) m_settings.m_standard); ui->spiNotchFilters->setValue(m_settings.m_notchFilters); ui->rfBandwidth->setValue(m_settings.m_rfBandwidth); @@ -241,12 +278,52 @@ void DATVDemodGUI::displaySettings() m_objChannelMarker.blockSignals(false); } +void DATVDemodGUI::displaySystemConfiguration() +{ + ui->cmbModulation->blockSignals(true); + ui->cmbFEC->blockSignals(true); + + std::vector modulations; + DATVDemodSettings::getAvailableModulations(m_settings.m_standard, modulations); + std::vector codeRates; + DATVDemodSettings::getAvailableCodeRates(m_settings.m_standard, m_settings.m_modulation, codeRates); + + ui->cmbModulation->clear(); + int modulationIndex = 0; + int i; + std::vector::const_iterator mIt = modulations.begin(); + + for (i = 0; mIt != modulations.end(); ++mIt, i++) + { + ui->cmbModulation->addItem(DATVDemodSettings::getStrFromModulation(*mIt)); + + if (m_settings.m_modulation == *mIt) { + modulationIndex = i; + } + } + + ui->cmbFEC->clear(); + int rateIndex = 0; + std::vector::const_iterator rIt = codeRates.begin(); + + for (i = 0; rIt != codeRates.end(); ++rIt, i++) + { + ui->cmbFEC->addItem(DATVDemodSettings::getStrFromCodeRate(*rIt)); + + if (m_settings.m_fec == *rIt) { + rateIndex = i; + } + } + + ui->cmbModulation->setCurrentIndex(modulationIndex); + ui->cmbFEC->setCurrentIndex(rateIndex); + + ui->cmbModulation->blockSignals(false); + ui->cmbFEC->blockSignals(false); +} + void DATVDemodGUI::applySettings(bool force) { - QString strStandard; - QString strModulation; - QString strFEC; - if (m_blnDoApplySettings) { qDebug("DATVDemodGUI::applySettings"); @@ -260,79 +337,6 @@ void DATVDemodGUI::applySettings(bool force) setTitleColor(m_objChannelMarker.getColor()); - strStandard = ui->cmbStandard->currentText(); - - if(strStandard=="DVB-S") { - m_settings.m_standard = DATVDemodSettings::DVB_S; - } else if (strStandard=="DVB-S2") { - m_settings.m_standard = DATVDemodSettings::DVB_S2; - } else { - m_settings.m_standard = DATVDemodSettings::DVB_S; - } - - //BPSK, QPSK, PSK8, APSK16, APSK32, APSK64E, QAM16, QAM64, QAM256 - - strModulation = ui->cmbModulation->currentText(); - - if(strModulation=="BPSK") { - m_settings.m_modulation = DATVDemodSettings::BPSK; - } - else if(strModulation=="QPSK") { - m_settings.m_modulation = DATVDemodSettings::QPSK; - } - else if(strModulation=="8PSK") { - m_settings.m_modulation = DATVDemodSettings::PSK8; - } - else if(strModulation=="16APSK") { - m_settings.m_modulation = DATVDemodSettings::APSK16; - } - else if(strModulation=="32APSK") { - m_settings.m_modulation = DATVDemodSettings::APSK32; - } - else if(strModulation=="64APSKE") { - m_settings.m_modulation = DATVDemodSettings::APSK64E; - } - else if(strModulation=="16QAM") { - m_settings.m_modulation = DATVDemodSettings::QAM16; - } - else if(strModulation=="64QAM") { - m_settings.m_modulation = DATVDemodSettings::QAM64; - } - else if(strModulation=="256QAM") { - m_settings.m_modulation = DATVDemodSettings::QAM256; - } else { - m_settings.m_modulation = DATVDemodSettings::BPSK; - } - - //Viterbi only for BPSK et QPSK - if ((m_settings.m_modulation != DATVDemodSettings::BPSK) - && (m_settings.m_modulation != DATVDemodSettings::QPSK)) - { - ui->chkViterbi->setChecked(false); - } - - strFEC = ui->cmbFEC->currentText(); - - if (strFEC == "1/2") { - m_settings.m_fec = DATVDemodSettings::FEC12; - } else if (strFEC == "2/3") { - m_settings.m_fec = DATVDemodSettings::FEC23; - } else if (strFEC == "3/4") { - m_settings.m_fec = DATVDemodSettings::FEC34; - } else if (strFEC == "5/6") { - m_settings.m_fec = DATVDemodSettings::FEC56; - } else if (strFEC == "7/8") { - m_settings.m_fec = DATVDemodSettings::FEC78; - } else if (strFEC == "4/5") { - m_settings.m_fec = DATVDemodSettings::FEC45; - } else if (strFEC == "8/9") { - m_settings.m_fec = DATVDemodSettings::FEC89; - } else if (strFEC == "9/10") { - m_settings.m_fec = DATVDemodSettings::FEC910; - } else { - m_settings.m_fec = DATVDemodSettings::FEC12; - } - if (ui->cmbFilter->currentIndex() == 0) { m_settings.m_filter = DATVDemodSettings::SAMP_LINEAR; } else if (ui->cmbFilter->currentIndex() == 1) { @@ -397,6 +401,28 @@ void DATVDemodGUI::tick() m_objMagSqAverage(m_objDATVDemod->getMagSq()); double magSqDB = CalcDb::dbPower(m_objMagSqAverage / (SDR_RX_SCALED*SDR_RX_SCALED)); ui->channePowerText->setText(tr("%1 dB").arg(magSqDB, 0, 'f', 1)); + + if ((m_modcodModulationIndex != m_objDATVDemod->getModcodModulation()) || (m_modcodCodeRateIndex != m_objDATVDemod->getModcodCodeRate())) + { + m_modcodModulationIndex = m_objDATVDemod->getModcodModulation(); + m_modcodCodeRateIndex = m_objDATVDemod->getModcodCodeRate(); + DATVDemodSettings::DATVModulation modulation = DATVDemod::getModulationFromLeanDVBCode(m_modcodModulationIndex); + DATVDemodSettings::DATVCodeRate rate = DATVDemod::getCodeRateFromLeanDVBCode(m_modcodCodeRateIndex); + QString modcodModulationStr = DATVDemodSettings::getStrFromModulation(modulation); + QString modcodCodeRateStr = DATVDemodSettings::getStrFromCodeRate(rate); + ui->statusText->setText(tr("MCOD %1 %2").arg(modcodModulationStr).arg(modcodCodeRateStr)); + } + + if (m_cstlnSetByModcod != m_objDATVDemod->isCstlnSetByModcod()) + { + m_cstlnSetByModcod = m_objDATVDemod->isCstlnSetByModcod(); + + if (m_cstlnSetByModcod) { + ui->statusText->setStyleSheet("QLabel { background-color : green; }"); + } else { + ui->statusText->setStyleSheet("QLabel { background:rgb(79,79,79); }"); + } + } } if((m_intLastDecodedData-m_intPreviousDecodedData)>=0) @@ -439,132 +465,48 @@ void DATVDemodGUI::tick() return; } -void DATVDemodGUI::on_cmbStandard_currentIndexChanged(const QString &arg1) +void DATVDemodGUI::on_cmbStandard_currentIndexChanged(int index) { - (void) arg1; - QString strStandard; + m_settings.m_standard = (DATVDemodSettings::dvb_version) index; - strStandard = ui->cmbStandard->currentText(); + ui->chkAllowDrift->setEnabled(m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S); + ui->chkHardMetric->setEnabled(m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S); + ui->chkFastlock->setEnabled(m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S); + ui->chkViterbi->setEnabled(m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S); - if(strStandard=="DVB-S2") - { - ui->cmbFEC->addItem("4/5"); - ui->cmbFEC->addItem("4/6"); - ui->cmbFEC->addItem("8/9"); - ui->cmbFEC->addItem("9/10"); - } - else - { - ui->cmbFEC->removeItem(8); - ui->cmbFEC->removeItem(7); - ui->cmbFEC->removeItem(6); - ui->cmbFEC->removeItem(5); + if (m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S) { + ui->statusText->clear(); } + m_settings.validateSystemConfiguration(); + displaySystemConfiguration(); applySettings(); } void DATVDemodGUI::on_cmbModulation_currentIndexChanged(const QString &arg1) { (void) arg1; - QString strModulation; - QString strFEC; + QString strModulation = ui->cmbModulation->currentText(); + m_settings.m_modulation = DATVDemodSettings::getModulationFromStr(strModulation); + m_settings.validateSystemConfiguration(); + displaySystemConfiguration(); - strFEC = ui->cmbFEC->currentText(); - - strModulation = ui->cmbModulation->currentText(); - - if(strModulation=="16APSK") + //Viterbi only for BPSK and QPSK + if ((m_settings.m_modulation != DATVDemodSettings::BPSK) + && (m_settings.m_modulation != DATVDemodSettings::QPSK)) { - if((strFEC!="2/3") - && (strFEC!="3/4") - && (strFEC!="4/5") - && (strFEC!="5/6") - && (strFEC!="4/6") - && (strFEC!="8/9") - && (strFEC!="9/10")) - { - //Reset modulation to 2/3 - - ui->cmbFEC->setCurrentIndex(1); - } - else - { - applySettings(); - } - } - else if(strModulation=="32APSK") - { - if((strFEC!="3/4") - && (strFEC!="4/5") - && (strFEC!="5/6") - && (strFEC!="8/9") - && (strFEC!="9/10")) - { - //Reset modulation to 3/4 - - ui->cmbFEC->setCurrentIndex(2); - } - else - { - applySettings(); - } - } - else - { - applySettings(); + ui->chkViterbi->setChecked(false); } + applySettings(); } void DATVDemodGUI::on_cmbFEC_currentIndexChanged(const QString &arg1) { (void) arg1; - QString strFEC; - - strFEC = ui->cmbFEC->currentText(); - - if(ui->cmbModulation->currentText()=="16APSK") - { - if((strFEC!="2/3") - && (strFEC!="3/4") - && (strFEC!="4/5") - && (strFEC!="5/6") - && (strFEC!="4/6") - && (strFEC!="8/9") - && (strFEC!="9/10")) - { - //Reset modulation to BPSK - - ui->cmbModulation->setCurrentIndex(0); - } - else - { - applySettings(); - } - } - else if(ui->cmbModulation->currentText()=="32APSK") - { - if((strFEC!="3/4") - && (strFEC!="4/5") - && (strFEC!="5/6") - && (strFEC!="8/9") - && (strFEC!="9/10")) - { - //Reset modulation to BPSK - - ui->cmbModulation->setCurrentIndex(0); - } - else - { - applySettings(); - } - } - else - { - applySettings(); - } - + QString strFEC = ui->cmbFEC->currentText(); + m_settings.m_fec = DATVDemodSettings::getCodeRateFromStr(strFEC); + applySettings(); } void DATVDemodGUI::on_chkViterbi_clicked() diff --git a/plugins/channelrx/demoddatv/datvdemodgui.h b/plugins/channelrx/demoddatv/datvdemodgui.h index c54efd4ed..7c4cfccad 100644 --- a/plugins/channelrx/demoddatv/datvdemodgui.h +++ b/plugins/channelrx/demoddatv/datvdemodgui.h @@ -58,7 +58,6 @@ public: bool deserialize(const QByteArray& arrData); virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } - virtual bool handleMessage(const Message& objMessage); static const QString m_strChannelID; @@ -69,10 +68,11 @@ private slots: void onWidgetRolled(QWidget* widget, bool rollDown); void onMenuDoubleClicked(); + void handleInputMessages(); void audioSelect(); void tick(); - void on_cmbStandard_currentIndexChanged(const QString &arg1); + void on_cmbStandard_currentIndexChanged(int index); void on_cmbModulation_currentIndexChanged(const QString &arg1); void on_cmbFEC_currentIndexChanged(const QString &arg1); void on_chkViterbi_clicked(); @@ -117,6 +117,9 @@ private: bool m_blnBasicSettingsShown; bool m_blnDoApplySettings; bool m_blnButtonPlayClicked; + int m_modcodModulationIndex; + int m_modcodCodeRateIndex; + bool m_cstlnSetByModcod; MovingAverageUtil m_objMagSqAverage; @@ -126,6 +129,7 @@ private: void blockApplySettings(bool blnBlock); void applySettings(bool force = false); void displaySettings(); + void displaySystemConfiguration(); QString formatBytes(qint64 intBytes); void displayRRCParameters(bool blnVisible); diff --git a/plugins/channelrx/demoddatv/datvdemodgui.ui b/plugins/channelrx/demoddatv/datvdemodgui.ui index 99d6974bf..c77ab81e8 100644 --- a/plugins/channelrx/demoddatv/datvdemodgui.ui +++ b/plugins/channelrx/demoddatv/datvdemodgui.ui @@ -717,6 +717,19 @@ 10 + + + + 100 + 10 + 151 + 19 + + + + ... + + diff --git a/plugins/channelrx/demoddatv/datvdemodsettings.cpp b/plugins/channelrx/demoddatv/datvdemodsettings.cpp index 5052a706e..58bc1aa44 100644 --- a/plugins/channelrx/demoddatv/datvdemodsettings.cpp +++ b/plugins/channelrx/demoddatv/datvdemodsettings.cpp @@ -40,7 +40,7 @@ void DATVDemodSettings::resetToDefaults() m_modulation = BPSK; m_fec = FEC12; m_symbolRate = 250000; - m_notchFilters = 1; + m_notchFilters = 0; m_allowDrift = false; m_fastLock = false; m_filter = SAMP_LINEAR; @@ -110,7 +110,7 @@ bool DATVDemodSettings::deserialize(const QByteArray& data) m_standard = (dvb_version) tmp; d.readS32(5, &tmp, (int) BPSK); - tmp = tmp < 0 ? 0 : tmp > (int) QAM256 ? (int) QAM256 : tmp; + tmp = tmp < 0 ? 0 : tmp >= (int) MOD_UNSET ? (int) MOD_UNSET - 1 : tmp; m_modulation = (DATVModulation) tmp; d.readBlob(6, &bytetmp); @@ -123,12 +123,12 @@ bool DATVDemodSettings::deserialize(const QByteArray& data) d.readString(8, &m_title, "DATV Demodulator"); d.readS32(9, &tmp, (int) FEC12); - tmp = tmp < 0 ? 0 : tmp >= (int) FEC_COUNT ? (int) FEC_COUNT - 1 : tmp; + tmp = tmp < 0 ? 0 : tmp >= (int) RATE_UNSET ? (int) RATE_UNSET - 1 : tmp; m_fec = (DATVCodeRate) tmp; d.readBool(10, &m_audioMute, false); d.readS32(11, &m_symbolRate, 250000); - d.readS32(12, &m_notchFilters, 1); + d.readS32(12, &m_notchFilters, 0); d.readBool(13, &m_allowDrift, false); d.readBool(14, &m_fastLock, false); @@ -144,6 +144,8 @@ bool DATVDemodSettings::deserialize(const QByteArray& data) d.readS32(21, &m_audioVolume, 0); d.readBool(22, &m_videoMute, false); + validateSystemConfiguration(); + return true; } else @@ -194,4 +196,253 @@ bool DATVDemodSettings::isDifferent(const DATVDemodSettings& other) || (m_symbolRate != other.m_symbolRate) || (m_excursion != other.m_excursion) || (m_standard != other.m_standard)); -} \ No newline at end of file +} + +void DATVDemodSettings::validateSystemConfiguration() +{ + qDebug("DATVDemodSettings::validateSystemConfiguration: m_standard: %d m_modulation: %d m_fec: %d", + (int) m_standard, (int) m_modulation, (int) m_fec); + + if (m_standard == DVB_S) + { + // The ETSI standard for DVB-S specify only QPSK (EN 300 421) with a later extension to BPSK (TR 101 198) + // but amateur radio also use extra modes thus only the modes very specific to DVB-S2(X) are restricted + if ((m_modulation == APSK16) || (m_modulation == APSK32) || (m_modulation == APSK64E)) + { + m_modulation = QPSK; // Fall back to QPSK + } + // Here we follow ETSI standard for DVB-S retaining only the valod code rates + if ((m_fec != FEC12) && (m_fec!= FEC23) && (m_fec!= FEC34) && (m_fec!= FEC56) && (m_fec!= FEC78)) { + m_fec = FEC12; + } + } + else if (m_standard == DVB_S2) + { + // Here we try to follow ETSI standard for DVB-S2 (EN 300 307 1) and DVB-S2X (EN 302 307 2) together for the available modes + if ((m_modulation == BPSK) || (m_modulation == QAM16) || (m_modulation == QAM64) || (m_modulation == QAM256)) + { + m_modulation = QPSK; // Fall back to QPSK + } + // Here we also try to follow ETSI standard depending on the modulation (EN 300 307 1 Table 1) + if (m_modulation == QPSK) + { + if ((m_fec != FEC14) && (m_fec != FEC13) && (m_fec != FEC25) + && (m_fec != FEC12) && (m_fec != FEC35) && (m_fec != FEC23) + && (m_fec != FEC34) && (m_fec != FEC45) && (m_fec != FEC56) + && (m_fec != FEC89) && (m_fec != FEC910)) { + m_fec = FEC12; + } + } + else if (m_modulation == PSK8) + { + if ((m_fec != FEC35) && (m_fec != FEC23) && (m_fec != FEC34) + && (m_fec != FEC56) && (m_fec != FEC89) && (m_fec != FEC910)) { + m_fec = FEC34; + } + } + else if (m_modulation == APSK16) + { + if ((m_fec != FEC23) && (m_fec != FEC34) && (m_fec != FEC45) + && (m_fec != FEC56) && (m_fec != FEC89) && (m_fec != FEC910)) { + m_fec = FEC34; + } + } + else if (m_modulation == APSK32) + { + if ((m_fec != FEC34) && (m_fec != FEC45) && (m_fec != FEC56) + && (m_fec != FEC89) && (m_fec != FEC910)) { + m_fec = FEC34; + } + } + // DVB-S2X has many mode code rates but here we deal only with the ones available + else if (m_modulation == APSK64E) + { + if ((m_fec != FEC45) && (m_fec != FEC56)) { + m_fec = FEC45; + } + } + } +} + +DATVDemodSettings::DATVModulation DATVDemodSettings::getModulationFromStr(const QString& str) +{ + if (str == "BPSK") { + return BPSK; + } else if (str == "QPSK") { + return QPSK; + } else if (str == "PSK8") { + return PSK8; + } else if (str == "APSK16") { + return APSK16; + } else if (str == "APSK32") { + return APSK32; + } else if (str == "APSK64E") { + return APSK64E; + } else if (str == "QAM16") { + return QAM16; + } else if (str == "QAM64") { + return QAM64; + } else if (str == "QAM256") { + return QAM256; + } else { + return MOD_UNSET; + } + +} + +DATVDemodSettings::DATVCodeRate DATVDemodSettings::getCodeRateFromStr(const QString& str) +{ + if (str == "1/4") { + return FEC14; + } else if (str == "1/3") { + return FEC13; + } else if (str == "2/5") { + return FEC25; + } else if (str == "1/2") { + return FEC12; + } else if (str == "3/5") { + return FEC35; + } else if (str == "2/3") { + return FEC23; + } else if (str == "3/4") { + return FEC34; + } else if (str == "4/5") { + return FEC45; + } else if (str == "5/6") { + return FEC56; + } else if (str == "8/9") { + return FEC89; + } else if (str == "9/10") { + return FEC910; + } else { + return RATE_UNSET; + } +} + +QString DATVDemodSettings::getStrFromModulation(const DATVModulation modulation) +{ + if (modulation == BPSK) { + return "BPSK"; + } else if (modulation == QPSK) { + return "QPSK"; + } else if (modulation == PSK8) { + return "PSK8"; + } else if (modulation == APSK16) { + return "APSK16"; + } else if (modulation == APSK32) { + return "APSK32"; + } else if (modulation == APSK64E) { + return "APSK64E"; + } else if (modulation == QAM16) { + return "QAM16"; + } else if (modulation == QAM64) { + return "QAM64"; + } else if (modulation == QAM256) { + return "QAM256"; + } else { + return "N/A"; + } +} + +QString DATVDemodSettings::getStrFromCodeRate(const DATVCodeRate codeRate) +{ + if (codeRate == FEC14) { + return "1/4"; + } else if (codeRate == FEC13) { + return "1/3"; + } else if (codeRate == FEC25) { + return "2/5"; + } else if (codeRate == FEC12) { + return "1/2"; + } else if (codeRate == FEC35) { + return "3/5"; + } else if (codeRate == FEC23) { + return "2/3"; + } else if (codeRate == FEC34) { + return "3/4"; + } else if (codeRate == FEC45) { + return "4/5"; + } else if (codeRate == FEC56) { + return "5/6"; + } else if (codeRate == FEC78) { + return "7/8"; + } else if (codeRate == FEC89) { + return "8/9"; + } else if (codeRate == FEC910) { + return "9/10"; + } else { + return "N/A"; + } +} + +void DATVDemodSettings::getAvailableModulations(dvb_version dvbStandard, std::vector& modulations) +{ + modulations.clear(); + + if (dvbStandard == DVB_S) + { + modulations.push_back(BPSK); + modulations.push_back(QPSK); + modulations.push_back(PSK8); + modulations.push_back(QAM16); + modulations.push_back(QAM64); + modulations.push_back(QAM256); + } + else if (dvbStandard == DVB_S2) + { + modulations.push_back(QPSK); + modulations.push_back(PSK8); + modulations.push_back(APSK16); + modulations.push_back(APSK32); + modulations.push_back(APSK64E); + } +} + +void DATVDemodSettings::getAvailableCodeRates(dvb_version dvbStandard, DATVModulation modulation, std::vector& codeRates) +{ + codeRates.clear(); + + if (dvbStandard == DVB_S) + { + codeRates.push_back(FEC12); + codeRates.push_back(FEC23); + codeRates.push_back(FEC34); + codeRates.push_back(FEC56); + codeRates.push_back(FEC78); + } + else if (dvbStandard == DVB_S2) + { + if (modulation == QPSK) + { + codeRates.push_back(FEC14); + codeRates.push_back(FEC13); + codeRates.push_back(FEC25); + codeRates.push_back(FEC12); + } + if ((modulation == QPSK) || (modulation == PSK8)) + { + codeRates.push_back(FEC35); + } + if ((modulation == QPSK) || (modulation == PSK8) || (modulation == APSK16)) + { + codeRates.push_back(FEC23); + } + if ((modulation == QPSK) || (modulation == PSK8) || (modulation == APSK16) || (modulation == APSK32)) + { + codeRates.push_back(FEC34); + } + if ((modulation == QPSK) || (modulation == APSK16) || (modulation == APSK32) || (modulation == APSK64E)) + { + codeRates.push_back(FEC45); + } + if ((modulation == QPSK) || (modulation == PSK8) || (modulation == APSK16) || (modulation == APSK32) || (modulation == APSK64E)) + { + codeRates.push_back(FEC56); + } + if ((modulation == QPSK) || (modulation == PSK8) || (modulation == APSK16) || (modulation == APSK32)) + { + codeRates.push_back(FEC89); + codeRates.push_back(FEC910); + } + } +} diff --git a/plugins/channelrx/demoddatv/datvdemodsettings.h b/plugins/channelrx/demoddatv/datvdemodsettings.h index 7f0b62714..4cca83f07 100644 --- a/plugins/channelrx/demoddatv/datvdemodsettings.h +++ b/plugins/channelrx/demoddatv/datvdemodsettings.h @@ -21,6 +21,7 @@ #include #include #include +#include class Serializable; @@ -34,33 +35,34 @@ struct DATVDemodSettings enum DATVModulation { - BPSK, + BPSK, // not DVB-S2 QPSK, PSK8, - APSK16, - APSK32, - APSK64E, - QAM16, - QAM64, - QAM256 + APSK16, // not DVB-S + APSK32, // not DVB-S + APSK64E, // not DVB-S + QAM16, // not DVB-S2 + QAM64, // not DVB-S2 + QAM256, // not DVB-S2 + MOD_UNSET }; enum DATVCodeRate { - FEC12, - FEC23, + FEC12, // DVB-S + FEC23, // DVB-S FEC46, - FEC34, - FEC56, + FEC34, // DVB-S + FEC56, // DVB-S FEC78, // DVB-S FEC45, FEC89, - FEC910, // DVB-S2 + FEC910, FEC14, FEC13, FEC25, FEC35, - FEC_COUNT + RATE_UNSET }; enum dvb_sampler @@ -99,6 +101,14 @@ struct DATVDemodSettings bool deserialize(const QByteArray& data); void debug(const QString& msg) const; bool isDifferent(const DATVDemodSettings& other); + void validateSystemConfiguration(); + + static DATVModulation getModulationFromStr(const QString& str); + static DATVCodeRate getCodeRateFromStr(const QString& str); + static QString getStrFromModulation(const DATVModulation modulation); + static QString getStrFromCodeRate(const DATVCodeRate codeRate); + static void getAvailableModulations(dvb_version dvbStandard, std::vector& modulations); + static void getAvailableCodeRates(dvb_version dvbStandard, DATVModulation modulation, std::vector& codeRates); }; #endif // PLUGINS_CHANNELRX_DEMODATV_DATVDEMODSETTINGS_H_ \ No newline at end of file diff --git a/plugins/channelrx/demoddatv/leansdr/dvbs2.h b/plugins/channelrx/demoddatv/leansdr/dvbs2.h index b99cee0bf..e8fcaeda8 100644 --- a/plugins/channelrx/demoddatv/leansdr/dvbs2.h +++ b/plugins/channelrx/demoddatv/leansdr/dvbs2.h @@ -472,7 +472,9 @@ struct s2_frame_receiver : runnable symbols_out(opt_writer(_symbols_out, MAX_SYMBOLS_PER_FRAME)), state_out(opt_writer(_state_out)), report_state(false), - scrambling(0) + scrambling(0), + m_modcodType(-1), + m_modcodRate(-1) { // Constellation for PLS qpsk = new cstln_lut(cstln_base::QPSK); @@ -795,6 +797,13 @@ struct s2_frame_receiver : runnable return; } #endif + // Store current MODCOD info + if (mcinfo->c != m_modcodType) { + m_modcodType = mcinfo->c; + } + if (mcinfo->rate != m_modcodRate) { + m_modcodRate = mcinfo->rate; + } // TBD Comparison of nsymbols is insufficient for DVB-S2X. if (!cstln || cstln->nsymbols != mcinfo->nsymbols) @@ -1196,6 +1205,8 @@ struct s2_frame_receiver : runnable // S2 constants s2_scrambling scrambling; s2_sof sof; + int m_modcodType; + int m_modcodRate; // Max size of one frame // static const int MAX_SLOTS = 360; static const int MAX_SLOTS = 240; // DEBUG match test signal