diff --git a/ft8/ft8.cpp b/ft8/ft8.cpp index 2fab2399c..d0f33327d 100644 --- a/ft8/ft8.cpp +++ b/ft8/ft8.cpp @@ -3269,10 +3269,11 @@ void FT8::subtract( // ??? while (fabs(target - actual) > M_PI) { - if (target < actual) - target += 2 * M_PI; - else - target -= 2 * M_PI; + if (target < actual) { + target += (2 * M_PI) - 1e-3; // plus epsilonn to break possible infinite loop + } else { + target -= (2 * M_PI) + 1e-3; // plus epsilonn to break possible infinite loop + } } // adj is to be spread evenly over the off-ramp and on-ramp samples. diff --git a/plugins/channelrx/demodft8/CMakeLists.txt b/plugins/channelrx/demodft8/CMakeLists.txt index 1117c9925..b5734b004 100644 --- a/plugins/channelrx/demodft8/CMakeLists.txt +++ b/plugins/channelrx/demodft8/CMakeLists.txt @@ -32,10 +32,13 @@ if(NOT SERVER_MODE) ${demodft8_SOURCES} ft8demodgui.cpp ft8demodgui.ui + ft8demodsettingsdialog.cpp + ft8demodsettingsdialog.ui ) set(demodft8_HEADERS ${demodft8_HEADERS} ft8demodgui.h + ft8demodsettingsdialog.h ) set(TARGET_NAME demodft8) set(TARGET_LIB "Qt::Widgets") diff --git a/plugins/channelrx/demodft8/ft8demod.cpp b/plugins/channelrx/demodft8/ft8demod.cpp index 163b1f043..727efef32 100644 --- a/plugins/channelrx/demodft8/ft8demod.cpp +++ b/plugins/channelrx/demodft8/ft8demod.cpp @@ -32,6 +32,10 @@ #include "SWGFT8DemodReport.h" #include "dsp/dspengine.h" +#include "dsp/dspdevicesourceengine.h" +#include "dsp/dspdevicemimoengine.h" +#include "dsp/devicesamplesource.h" +#include "dsp/devicesamplemimo.h" #include "dsp/dspcommands.h" #include "dsp/devicesamplemimo.h" #include "device/deviceapi.h" @@ -104,6 +108,18 @@ void FT8Demod::setDeviceAPI(DeviceAPI *deviceAPI) } } +void FT8Demod::setDeviceCenterFrequency(qint64 centerFrequency, int index) +{ + DSPDeviceSourceEngine *deviceSourceEngine = m_deviceAPI->getDeviceSourceEngine(); + DSPDeviceMIMOEngine *deviceMIMOEngine = m_deviceAPI->getDeviceMIMOEngine(); + + if (deviceSourceEngine) { + deviceSourceEngine->getSource()->setCenterFrequency(centerFrequency); + } else if (deviceMIMOEngine) { + deviceMIMOEngine->getMIMO()->setSourceCenterFrequency(centerFrequency, index); + } +} + void FT8Demod::setMessageQueueToGUI(MessageQueue *queue) { ChannelAPI::setMessageQueueToGUI(queue); diff --git a/plugins/channelrx/demodft8/ft8demod.h b/plugins/channelrx/demodft8/ft8demod.h index 2bb711e2b..7af6ec211 100644 --- a/plugins/channelrx/demodft8/ft8demod.h +++ b/plugins/channelrx/demodft8/ft8demod.h @@ -95,6 +95,7 @@ public: return m_settings.m_inputFrequencyOffset; } + void setDeviceCenterFrequency(qint64 centerFrequency, int index); void setMessageQueueToGUI(MessageQueue* queue) override; uint32_t getChannelSampleRate() const { return m_running ? m_basebandSink->getChannelSampleRate() : 0; } double getMagSq() const { return m_running ? m_basebandSink->getMagSq() : 0.0; } diff --git a/plugins/channelrx/demodft8/ft8demodgui.cpp b/plugins/channelrx/demodft8/ft8demodgui.cpp index f870c9537..bc53a1bfd 100644 --- a/plugins/channelrx/demodft8/ft8demodgui.cpp +++ b/plugins/channelrx/demodft8/ft8demodgui.cpp @@ -36,6 +36,7 @@ #include "ui_ft8demodgui.h" #include "ft8demodgui.h" #include "ft8demod.h" +#include "ft8demodsettingsdialog.h" FT8DemodGUI* FT8DemodGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel) { @@ -68,6 +69,7 @@ bool FT8DemodGUI::deserialize(const QByteArray& data) ui->lowCut->setMinimum(-480); displaySettings(); applyBandwidths(m_settings.m_filterBank[m_settings.m_filterIndex].m_spanLog2, true); // does applySettings(true) + populateBandPresets(); return true; } else @@ -79,6 +81,7 @@ bool FT8DemodGUI::deserialize(const QByteArray& data) ui->lowCut->setMinimum(-480); displaySettings(); applyBandwidths(m_settings.m_filterBank[m_settings.m_filterIndex].m_spanLog2, true); // does applySettings(true) + populateBandPresets(); return false; } } @@ -211,6 +214,22 @@ void FT8DemodGUI::on_filterIndex_valueChanged(int value) applyBandwidths(m_settings.m_filterBank[m_settings.m_filterIndex].m_spanLog2, true); // does applySettings(true) } +void FT8DemodGUI::on_applyBandPreset_clicked() +{ + int bandPresetIndex = ui->bandPreset->currentIndex(); + int channelShift = m_settings.m_bandPresets[bandPresetIndex].m_channelOffset; // kHz + int baseFrequency = m_settings.m_bandPresets[bandPresetIndex].m_baseFrequency; // kHz + quint64 deviceFrequency = (baseFrequency - channelShift)*1000; // Hz + m_ft8Demod->setDeviceCenterFrequency(deviceFrequency, m_settings.m_streamIndex); + + if (channelShift * 1000 != m_settings.m_inputFrequencyOffset) + { + m_settings.m_inputFrequencyOffset = channelShift * 1000; // Hz + displaySettings(); + applySettings(); + } +} + void FT8DemodGUI::on_clearMessages_clicked() { ui->messages->setRowCount(0); @@ -229,18 +248,38 @@ void FT8DemodGUI::on_logMessages_toggled(bool checked) applySettings(); } -void FT8DemodGUI::on_nbThreads_valueChanged(int value) +void FT8DemodGUI::on_settings_clicked() { - ui->nbThreadsText->setText(tr("%1").arg(value)); - m_settings.m_nbDecoderThreads = value; - applySettings(); -} + FT8DemodSettings settings = m_settings; + QStringList settingsKeys; + FT8DemodSettingsDialog dialog(settings, settingsKeys); -void FT8DemodGUI::on_timeBudget_valueChanged(int value) -{ - m_settings.m_decoderTimeBudget = value / 10.0f; - ui->timeBudgetText->setText(tr("%1").arg(m_settings.m_decoderTimeBudget, 0, 'f', 1)); - applySettings(); + if (dialog.exec() == QDialog::Accepted) + { + bool changed = false; + + if (settingsKeys.contains("nbDecoderThreads")) + { + m_settings.m_nbDecoderThreads = settings.m_nbDecoderThreads; + changed = true; + } + + if (settingsKeys.contains("decoderTimeBudget")) + { + m_settings.m_decoderTimeBudget = settings.m_decoderTimeBudget; + changed = true; + } + + if (settingsKeys.contains("bandPresets")) + { + m_settings.m_bandPresets = settings.m_bandPresets; + populateBandPresets(); + } + + if (changed) { + applySettings(); + } + } } void FT8DemodGUI::onMenuDialogCalled(const QPoint &p) @@ -377,6 +416,7 @@ FT8DemodGUI::FT8DemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban // Resize the table using dummy data resizeMessageTable(); + populateBandPresets(); } FT8DemodGUI::~FT8DemodGUI() @@ -544,10 +584,6 @@ void FT8DemodGUI::displaySettings() ui->recordWav->setChecked(m_settings.m_recordWav); ui->logMessages->setChecked(m_settings.m_logMessages); - ui->nbThreads->setValue(m_settings.m_nbDecoderThreads); - ui->nbThreadsText->setText(tr("%1").arg(m_settings.m_nbDecoderThreads)); - ui->timeBudget->setValue(m_settings.m_decoderTimeBudget*10); - ui->timeBudgetText->setText(tr("%1").arg(m_settings.m_decoderTimeBudget, 0, 'f', 1)); updateIndexLabel(); @@ -598,11 +634,11 @@ void FT8DemodGUI::makeUIConnections() QObject::connect(ui->spanLog2, &QSlider::valueChanged, this, &FT8DemodGUI::on_spanLog2_valueChanged); QObject::connect(ui->fftWindow, QOverload::of(&QComboBox::currentIndexChanged), this, &FT8DemodGUI::on_fftWindow_currentIndexChanged); QObject::connect(ui->filterIndex, &QDial::valueChanged, this, &FT8DemodGUI::on_filterIndex_valueChanged); + QObject::connect(ui->applyBandPreset, &QPushButton::clicked, this, &FT8DemodGUI::on_applyBandPreset_clicked); QObject::connect(ui->clearMessages, &QPushButton::clicked, this, &FT8DemodGUI::on_clearMessages_clicked); QObject::connect(ui->recordWav, &ButtonSwitch::toggled, this, &FT8DemodGUI::on_recordWav_toggled); QObject::connect(ui->logMessages, &ButtonSwitch::toggled, this, &FT8DemodGUI::on_logMessages_toggled); - QObject::connect(ui->nbThreads, &QDial::valueChanged, this, &FT8DemodGUI::on_nbThreads_valueChanged); - QObject::connect(ui->timeBudget, &QDial::valueChanged, this, &FT8DemodGUI::on_timeBudget_valueChanged); + QObject::connect(ui->settings, &QPushButton::clicked, this, &FT8DemodGUI::on_settings_clicked); } void FT8DemodGUI::updateAbsoluteCenterFrequency() @@ -687,3 +723,15 @@ void FT8DemodGUI::messagesReceived(const QList& messages) ui->messages->scrollToBottom(); } } + +void FT8DemodGUI::populateBandPresets() +{ + ui->bandPreset->blockSignals(true); + ui->bandPreset->clear(); + + for (const auto& bandPreset : m_settings.m_bandPresets) { + ui->bandPreset->addItem(bandPreset.m_name); + } + + ui->bandPreset->blockSignals(false); +} diff --git a/plugins/channelrx/demodft8/ft8demodgui.h b/plugins/channelrx/demodft8/ft8demodgui.h index d63aa9003..7861c11e6 100644 --- a/plugins/channelrx/demodft8/ft8demodgui.h +++ b/plugins/channelrx/demodft8/ft8demodgui.h @@ -103,6 +103,7 @@ private: void resizeMessageTable(); void messagesReceived(const QList& messages); + void populateBandPresets(); enum MessageCol { MESSAGE_COL_UTC, @@ -126,11 +127,11 @@ private slots: void on_spanLog2_valueChanged(int value); void on_fftWindow_currentIndexChanged(int index); void on_filterIndex_valueChanged(int value); + void on_applyBandPreset_clicked(); void on_clearMessages_clicked(); void on_recordWav_toggled(bool checked); void on_logMessages_toggled(bool checked); - void on_nbThreads_valueChanged(int value); - void on_timeBudget_valueChanged(int value); + void on_settings_clicked(); void onWidgetRolled(QWidget* widget, bool rollDown); void onMenuDialogCalled(const QPoint& p); void handleInputMessages(); diff --git a/plugins/channelrx/demodft8/ft8demodgui.ui b/plugins/channelrx/demodft8/ft8demodgui.ui index fbae3b061..3423953ba 100644 --- a/plugins/channelrx/demodft8/ft8demodgui.ui +++ b/plugins/channelrx/demodft8/ft8demodgui.ui @@ -780,93 +780,22 @@ - - - Th - - - - - + - 24 - 24 + 32 + 16777215 - Number of decoder threads + Open settings dialog - - 2 - - - 12 - - - 1 - - - 1 - - - 6 - - - - - - 6 + - - - - - - Qt::Vertical - - - - - - - TB - - - - - - - - 24 - 24 - - - - Decoder time budget (seconds) - - - 5 - - - 50 - - - 1 - - - 1 - - - 25 - - - - - - - 2.5 + + + :/tool.png:/tool.png @@ -904,7 +833,7 @@ - + / @@ -918,6 +847,9 @@ 0 + + Total number of decodes displayed + 0 @@ -926,6 +858,43 @@ + + + + Band + + + + + + + + 80 + 0 + + + + + + + + + 32 + 16777215 + + + + Apply selected band presets + + + + + + + :/arrow_left.png:/arrow_left.png + + + diff --git a/plugins/channelrx/demodft8/ft8demodsettings.cpp b/plugins/channelrx/demodft8/ft8demodsettings.cpp index 6e3640c1f..b5df03de1 100644 --- a/plugins/channelrx/demodft8/ft8demodsettings.cpp +++ b/plugins/channelrx/demodft8/ft8demodsettings.cpp @@ -60,11 +60,54 @@ void FT8DemodSettings::resetToDefaults() m_workspaceIndex = 0; m_hidden = false; m_filterIndex = 0; + m_bandPresets.push_back(FT8DemodBandPreset{"160m", 1840, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "80m", 3573, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "60m", 5357, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "40m", 7074, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "30m", 10136, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "20m", 14074, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "17m", 18100, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "15m", 21074, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "12m", 24915, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "10m", 28074, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "6m", 50313, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "4m", 70100, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "2m", 144120, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{"1.2m", 222065, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{"70cm", 432065, 0}); +} + +void FT8DemodSettings::resetBandPresets() +{ + m_bandPresets.clear(); + m_bandPresets.push_back(FT8DemodBandPreset{"160m", 1840, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "80m", 3573, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "60m", 5357, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "40m", 7074, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "30m", 10136, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "20m", 14074, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "17m", 18100, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "15m", 21074, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "12m", 24915, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "10m", 28074, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "6m", 50313, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "4m", 70100, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{ "2m", 144120, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{"1.2m", 222065, 0}); + m_bandPresets.push_back(FT8DemodBandPreset{"70cm", 432065, 0}); } QByteArray FT8DemodSettings::serialize() const { SimpleSerializer s(1); + QByteArray bytetmp; + + QDataStream *stream = new QDataStream(&bytetmp, QIODevice::WriteOnly); + *stream << m_bandPresets; + delete stream; + s.writeBlob(2, bytetmp); + + s.writeS32(1, m_inputFrequencyOffset); s.writeS32(3, m_volume * 10.0); @@ -123,6 +166,10 @@ bool FT8DemodSettings::deserialize(const QByteArray& data) uint32_t utmp; QString strtmp; + d.readBlob(2, &bytetmp); + QDataStream readStream(&bytetmp, QIODevice::ReadOnly); + readStream >> m_bandPresets; + d.readS32(1, &m_inputFrequencyOffset, 0); d.readS32(3, &tmp, 30); m_volume = tmp / 10.0; @@ -188,3 +235,19 @@ bool FT8DemodSettings::deserialize(const QByteArray& data) return false; } } + +QDataStream& operator<<(QDataStream& out, const FT8DemodBandPreset& bandPreset) +{ + out << bandPreset.m_name; + out << bandPreset.m_baseFrequency; + out << bandPreset.m_channelOffset; + return out; +} + +QDataStream& operator>>(QDataStream& in, FT8DemodBandPreset& bandPreset) +{ + in >> bandPreset.m_name; + in >> bandPreset.m_baseFrequency; + in >> bandPreset.m_channelOffset; + return in; +} diff --git a/plugins/channelrx/demodft8/ft8demodsettings.h b/plugins/channelrx/demodft8/ft8demodsettings.h index 481de9335..214365f1f 100644 --- a/plugins/channelrx/demodft8/ft8demodsettings.h +++ b/plugins/channelrx/demodft8/ft8demodsettings.h @@ -20,6 +20,7 @@ #include #include +#include #include "dsp/fftwindow.h" @@ -40,6 +41,13 @@ struct FT8DemodFilterSettings {} }; +struct FT8DemodBandPreset +{ + QString m_name; + int m_baseFrequency; + int m_channelOffset; +}; + struct FT8DemodSettings { qint32 m_inputFrequencyOffset; @@ -65,6 +73,7 @@ struct FT8DemodSettings // FFTWindow::Function m_fftWindow; std::vector m_filterBank; unsigned int m_filterIndex; + QList m_bandPresets; Serializable *m_channelMarker; Serializable *m_spectrumGUI; @@ -77,11 +86,14 @@ struct FT8DemodSettings void setRollupState(Serializable *rollupState) { m_rollupState = rollupState; } QByteArray serialize() const; bool deserialize(const QByteArray& data); + void resetBandPresets(); static const int m_ft8SampleRate; static const int m_minPowerThresholdDB; static const float m_mminPowerThresholdDBf; }; +QDataStream& operator<<(QDataStream& out, const FT8DemodBandPreset& bandPreset); +QDataStream& operator>>(QDataStream& in, FT8DemodBandPreset& bandPreset); #endif /* PLUGINS_CHANNELRX_DEMODFT8_FT8DEMODSETTINGS_H_ */ diff --git a/plugins/channelrx/demodft8/ft8demodsettingsdialog.cpp b/plugins/channelrx/demodft8/ft8demodsettingsdialog.cpp new file mode 100644 index 000000000..db51c95a5 --- /dev/null +++ b/plugins/channelrx/demodft8/ft8demodsettingsdialog.cpp @@ -0,0 +1,290 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 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 . // +/////////////////////////////////////////////////////////////////////////////////// +#include +#include + +#include "ft8demodsettings.h" +#include "ft8demodsettingsdialog.h" + +FT8DemodSettingsDialog::FT8DemodSettingsDialog(FT8DemodSettings& settings, QStringList& settingsKeys, QWidget* parent ) : + QDialog(parent), + ui(new Ui::FT8DemodSettingsDialog), + m_settings(settings), + m_settingsKeys(settingsKeys) +{ + ui->setupUi(this); + ui->decoderNbThreads->setValue(m_settings.m_nbDecoderThreads); + ui->decoderTimeBudget->setValue(m_settings.m_decoderTimeBudget); + resizeBandsTable(); + populateBandsTable(); + connect(ui->bands, &QTableWidget::cellChanged, this, &FT8DemodSettingsDialog::textCellChanged); +} + +FT8DemodSettingsDialog::~FT8DemodSettingsDialog() +{ +} + +void FT8DemodSettingsDialog::resizeBandsTable() +{ + // Fill table with a row of dummy data that will size the columns nicely + // Trailing spaces are for sort arrow + int row = ui->bands->rowCount(); + ui->bands->setRowCount(row + 1); + ui->bands->setItem(row, BAND_NAME, new QTableWidgetItem("123456789012345")); + ui->bands->setItem(row, BAND_BASE_FREQUENCY, new QTableWidgetItem("10000000")); + ui->bands->setItem(row, BAND_OFFSET_FREQUENCY, new QTableWidgetItem("-1000")); + ui->bands->resizeColumnsToContents(); + ui->bands->removeRow(row); +} + +void FT8DemodSettingsDialog::populateBandsTable() +{ + // Add to messages table + int row = ui->bands->rowCount(); + + for (const auto& band : m_settings.m_bandPresets) + { + ui->bands->setRowCount(row + 1); + + QTableWidgetItem *nameItem = new QTableWidgetItem(); + QTableWidgetItem *baseFrequencyItem = new QTableWidgetItem(); + QTableWidgetItem *offsetFrequencyItem = new QTableWidgetItem(); + + ui->bands->setItem(row, BAND_NAME, nameItem); + ui->bands->setItem(row, BAND_BASE_FREQUENCY, baseFrequencyItem); + ui->bands->setItem(row, BAND_OFFSET_FREQUENCY, offsetFrequencyItem); + + nameItem->setText(band.m_name); + QLineEdit *editBaseFrequency = new QLineEdit(ui->bands); + editBaseFrequency->setValidator(new QIntValidator()); + editBaseFrequency->setText(tr("%1").arg(band.m_baseFrequency)); + editBaseFrequency->setAlignment(Qt::AlignRight); + editBaseFrequency->setProperty("row", row); + ui->bands->setCellWidget(row, BAND_BASE_FREQUENCY, editBaseFrequency); + QLineEdit *editOffsetFrequency = new QLineEdit(ui->bands); + editOffsetFrequency->setValidator(new QIntValidator()); + editOffsetFrequency->setText(tr("%1").arg(band.m_channelOffset)); + editOffsetFrequency->setAlignment(Qt::AlignRight); + editOffsetFrequency->setProperty("row", row); + ui->bands->setCellWidget(row, BAND_OFFSET_FREQUENCY, editOffsetFrequency); + + connect(editBaseFrequency, &QLineEdit::editingFinished, this, &FT8DemodSettingsDialog::baseFrequencyCellChanged); + connect(editOffsetFrequency, &QLineEdit::editingFinished, this, &FT8DemodSettingsDialog::offsetFrequencyCellChanged); + + row++; + } +} + +void FT8DemodSettingsDialog::accept() +{ + QDialog::accept(); +} + +void FT8DemodSettingsDialog::reject() +{ + m_settingsKeys.clear(); + QDialog::reject(); +} + +void FT8DemodSettingsDialog::on_decoderNbThreads_valueChanged(int value) +{ + m_settings.m_nbDecoderThreads = value; + + if (!m_settingsKeys.contains("nbDecoderThreads")) { + m_settingsKeys.append("nbDecoderThreads"); + } +} + +void FT8DemodSettingsDialog::on_decoderTimeBudget_valueChanged(double value) +{ + m_settings.m_decoderTimeBudget = value; + + if (!m_settingsKeys.contains("decoderTimeBudget")) { + m_settingsKeys.append("decoderTimeBudget"); + } +} + +void FT8DemodSettingsDialog::on_addBand_clicked() +{ + int currentRow = ui->bands->currentRow(); + const QTableWidgetItem *currentNameItem = ui->bands->item(currentRow, BAND_NAME); + FT8DemodBandPreset newPreset({"", 0, 0}); + + if (currentNameItem) { + newPreset.m_name = currentNameItem->text(); + } + + QLineEdit *currentEditBaseFrequency = qobject_cast(ui->bands->cellWidget(currentRow, BAND_BASE_FREQUENCY)); + + if (currentEditBaseFrequency) { + newPreset.m_baseFrequency = currentEditBaseFrequency->text().toInt(); + } + + QLineEdit *currentEditOffsetFrequency = qobject_cast(ui->bands->cellWidget(currentRow, BAND_OFFSET_FREQUENCY)); + + if (currentEditOffsetFrequency) { + newPreset.m_channelOffset = currentEditOffsetFrequency->text().toInt(); + } + + m_settings.m_bandPresets.push_back(newPreset); + ui->bands->blockSignals(true); + ui->bands->setRowCount(0); + populateBandsTable(); + ui->bands->blockSignals(false); + + if (!m_settingsKeys.contains("bandPresets")) { + m_settingsKeys.append("bandPresets"); + } +} + +void FT8DemodSettingsDialog::on_deleteBand_clicked() +{ + int currentRow = ui->bands->currentRow(); + + if (currentRow < 0) { + return; + } + + m_settings.m_bandPresets.removeAt(currentRow); + ui->bands->removeRow(currentRow); + + if (!m_settingsKeys.contains("bandPresets")) { + m_settingsKeys.append("bandPresets"); + } +} + +void FT8DemodSettingsDialog::on_moveBandUp_clicked() +{ + int currentRow = ui->bands->currentRow(); + + if (currentRow < 1) { + return; + } + + ui->bands->blockSignals(true); + QList sourceItems = takeRow(currentRow); + QList destItems = takeRow(currentRow-1); + setRow(currentRow, destItems); + setRow(currentRow-1, sourceItems); + ui->bands->blockSignals(false); + + const auto sourceBandPreset = m_settings.m_bandPresets[currentRow]; + const auto destBandPreset = m_settings.m_bandPresets[currentRow-1]; + m_settings.m_bandPresets[currentRow] = destBandPreset; + m_settings.m_bandPresets[currentRow-1] = sourceBandPreset; + + if (!m_settingsKeys.contains("bandPresets")) { + m_settingsKeys.append("bandPresets"); + } +} + +void FT8DemodSettingsDialog::on_moveBandDown_clicked() +{ + int currentRow = ui->bands->currentRow(); + + if (currentRow > ui->bands->rowCount()-2) { + return; + } + + ui->bands->blockSignals(true); + QList sourceItems = takeRow(currentRow); + QList destItems = takeRow(currentRow+1); + setRow(currentRow, destItems); + setRow(currentRow+1, sourceItems); + ui->bands->blockSignals(false); + + const auto sourceBandPreset = m_settings.m_bandPresets[currentRow]; + const auto destBandPreset = m_settings.m_bandPresets[currentRow+1]; + m_settings.m_bandPresets[currentRow] = destBandPreset; + m_settings.m_bandPresets[currentRow+1] = sourceBandPreset; + + if (!m_settingsKeys.contains("bandPresets")) { + m_settingsKeys.append("bandPresets"); + } +} + +void FT8DemodSettingsDialog::on_restoreBandPresets_clicked() +{ + m_settings.resetBandPresets(); + ui->bands->blockSignals(true); + ui->bands->setRowCount(0); + populateBandsTable(); + ui->bands->blockSignals(false); + + if (!m_settingsKeys.contains("bandPresets")) { + m_settingsKeys.append("bandPresets"); + } +} + +void FT8DemodSettingsDialog::textCellChanged(int row, int col) +{ + if (col == BAND_NAME) { + m_settings.m_bandPresets[row].m_name = ui->bands->item(row, col)->text(); + } + + if (!m_settingsKeys.contains("bandPresets")) { + m_settingsKeys.append("bandPresets"); + } +} + +void FT8DemodSettingsDialog::baseFrequencyCellChanged() +{ + QLineEdit *editBaseFrequency = qobject_cast(sender()); + + if (editBaseFrequency) + { + int row = editBaseFrequency->property("row").toInt(); + m_settings.m_bandPresets[row].m_baseFrequency = editBaseFrequency->text().toInt(); + } + + if (!m_settingsKeys.contains("bandPresets")) { + m_settingsKeys.append("bandPresets"); + } +} + +void FT8DemodSettingsDialog::offsetFrequencyCellChanged() +{ + QLineEdit *editOffsetFrequency = qobject_cast(sender()); + + if (editOffsetFrequency) + { + int row = editOffsetFrequency->property("row").toInt(); + m_settings.m_bandPresets[row].m_channelOffset = editOffsetFrequency->text().toInt(); + } + + if (!m_settingsKeys.contains("bandPresets")) { + m_settingsKeys.append("bandPresets"); + } +} + +QList FT8DemodSettingsDialog::takeRow(int row) +{ + QList rowItems; + + for (int col = 0; col < ui->bands->columnCount(); ++col) { + rowItems << ui->bands->takeItem(row, col); + } + + return rowItems; +} + +void FT8DemodSettingsDialog::setRow(int row, const QList& rowItems) +{ + for (int col = 0; col < ui->bands->columnCount(); ++col) { + ui->bands->setItem(row, col, rowItems.at(col)); + } +} diff --git a/plugins/channelrx/demodft8/ft8demodsettingsdialog.h b/plugins/channelrx/demodft8/ft8demodsettingsdialog.h new file mode 100644 index 000000000..c59ac0b6f --- /dev/null +++ b/plugins/channelrx/demodft8/ft8demodsettingsdialog.h @@ -0,0 +1,65 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 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 PLUGINS_CHANNELRX_DEMODFT8_FT8DEMODSETTINGSDIALOG_H_ +#define PLUGINS_CHANNELRX_DEMODFT8_FT8DEMODSETTINGSDIALOG_H_ + +#include "ui_ft8demodsettingsdialog.h" + +class FT8DemodSettings; +class QStringList; +class QTableWidgetItem; + +class FT8DemodSettingsDialog : public QDialog { + Q_OBJECT +public: + FT8DemodSettingsDialog(FT8DemodSettings& settings, QStringList& settingsKeys, QWidget* parent = nullptr); + ~FT8DemodSettingsDialog(); + +private: + Ui::FT8DemodSettingsDialog* ui; + FT8DemodSettings& m_settings; + QStringList& m_settingsKeys; + + enum BandCol { + BAND_NAME, + BAND_BASE_FREQUENCY, + BAND_OFFSET_FREQUENCY, + }; + + void resizeBandsTable(); + void populateBandsTable(); + QList takeRow(int row); + void setRow(int row, const QList& rowItems); + +private slots: + void accept(); + void reject(); + void on_decoderNbThreads_valueChanged(int value); + void on_decoderTimeBudget_valueChanged(double value); + void on_addBand_clicked(); + void on_deleteBand_clicked(); + void on_moveBandUp_clicked(); + void on_moveBandDown_clicked(); + void on_restoreBandPresets_clicked(); + void textCellChanged(int row, int col); + void baseFrequencyCellChanged(); + void offsetFrequencyCellChanged(); +}; + + +#endif // PLUGINS_CHANNELRX_DEMODFT8_FT8DEMODSETTINGSDIALOG_H_ diff --git a/plugins/channelrx/demodft8/ft8demodsettingsdialog.ui b/plugins/channelrx/demodft8/ft8demodsettingsdialog.ui new file mode 100644 index 000000000..d3a83db7e --- /dev/null +++ b/plugins/channelrx/demodft8/ft8demodsettingsdialog.ui @@ -0,0 +1,322 @@ + + + FT8DemodSettingsDialog + + + + 0 + 0 + 349 + 316 + + + + + Liberation Sans + 9 + + + + FT8 demod settings + + + + + + Decoder + + + + 2 + + + + + + + Number of threads + + + + + + + Number of decoding threads + + + 2 + + + 12 + + + 3 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Time budget (s) + + + + + + + Time limit for the decoder (s) + + + 1 + + + 0.500000000000000 + + + 5.000000000000000 + + + 0.100000000000000 + + + 0.500000000000000 + + + + + + + + + + + + Band presets + + + + 2 + + + + + Predefined frequencies + + + false + + + 15 + + + 15 + + + + Name + + + Band displayed name + + + + + F (kHz) + + + Base frequency (kHz) + + + + + off (kHz) + + + Channel offset frequency (kHz) + + + + + + + + + + + 32 + 16777215 + + + + Add band + + + + + + + :/create.png:/create.png + + + + + + + + 32 + 16777215 + + + + Remove selected band + + + + + + + :/bin.png:/bin.png + + + + + + + + 32 + 16777215 + + + + Move up selected band + + + + + + + :/arrow_up.png:/arrow_up.png + + + + + + + + 32 + 16777215 + + + + Move down selected band + + + + + + + :/arrow_down.png:/arrow_down.png + + + + + + + + 32 + 16777215 + + + + Restore default band presets + + + + + + + :/recycle.png:/recycle.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + FT8DemodSettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + FT8DemodSettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/plugins/channelrx/demodft8/ft8demodworker.cpp b/plugins/channelrx/demodft8/ft8demodworker.cpp index 53822aa83..a6a801419 100644 --- a/plugins/channelrx/demodft8/ft8demodworker.cpp +++ b/plugins/channelrx/demodft8/ft8demodworker.cpp @@ -213,7 +213,7 @@ void FT8DemodWorker::processBuffer(int16_t *buffer, QDateTime periodTS) } QString logMessage = QString("%1 %2 Rx FT8 %3 %4 %5 %6 %7 %8") - .arg(ft8Message.ts.toString("yyyyMMdd_HHmmss")) + .arg(periodTS.toString("yyyyMMdd_HHmmss")) .arg(baseFrequencyMHz, 9, 'f', 3) .arg(ft8Message.snr, 6) .arg(ft8Message.dt, 4, 'f', 1) diff --git a/sdrbase/dsp/dspdevicemimoengine.h b/sdrbase/dsp/dspdevicemimoengine.h index d076b0440..e2de68a3c 100644 --- a/sdrbase/dsp/dspdevicemimoengine.h +++ b/sdrbase/dsp/dspdevicemimoengine.h @@ -31,6 +31,7 @@ class DeviceSampleMIMO; class BasebandSampleSink; +class BasebandSampleSource; class MIMOChannel; class SDRBASE_API DSPDeviceMIMOEngine : public QThread {