DATV demod: manage MODCOD changes in the GUI. Reworked settings validation against standard's system configurations

This commit is contained in:
f4exb 2019-07-17 02:51:46 +02:00
parent 35cd053485
commit 1119c64771
8 changed files with 497 additions and 219 deletions

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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<DATVDemodSettings::DATVModulation> modulations;
DATVDemodSettings::getAvailableModulations(m_settings.m_standard, modulations);
std::vector<DATVDemodSettings::DATVCodeRate> codeRates;
DATVDemodSettings::getAvailableCodeRates(m_settings.m_standard, m_settings.m_modulation, codeRates);
ui->cmbModulation->clear();
int modulationIndex = 0;
int i;
std::vector<DATVDemodSettings::DATVModulation>::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<DATVDemodSettings::DATVCodeRate>::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()

View File

@ -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<double, double, 4> 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);

View File

@ -717,6 +717,19 @@
<number>10</number>
</property>
</widget>
<widget class="QLabel" name="statusText">
<property name="geometry">
<rect>
<x>100</x>
<y>10</y>
<width>151</width>
<height>19</height>
</rect>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</widget>
</widget>
</widget>

View File

@ -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));
}
}
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<DATVModulation>& 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<DATVCodeRate>& 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);
}
}
}

View File

@ -21,6 +21,7 @@
#include <QByteArray>
#include <QString>
#include <stdint.h>
#include <vector>
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<DATVModulation>& modulations);
static void getAvailableCodeRates(dvb_version dvbStandard, DATVModulation modulation, std::vector<DATVCodeRate>& codeRates);
};
#endif // PLUGINS_CHANNELRX_DEMODATV_DATVDEMODSETTINGS_H_

View File

@ -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<SOFTSYMB, 256>(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<T> 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