mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-02-03 09:44:01 -05:00
SoapySDR support: input: auto correction GUIs (1)
This commit is contained in:
parent
98b79de593
commit
66f95bc0a6
@ -282,6 +282,24 @@ void SoapySDRInput::initGainSettings(SoapySDRInputSettings& settings)
|
|||||||
updateGains(m_deviceShared.m_device, m_deviceShared.m_channel, settings);
|
updateGains(m_deviceShared.m_device, m_deviceShared.m_channel, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SoapySDRInput::hasDCAutoCorrection()
|
||||||
|
{
|
||||||
|
const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel);
|
||||||
|
return channelSettings->m_hasDCAutoCorrection;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SoapySDRInput::hasDCCorrectionValue()
|
||||||
|
{
|
||||||
|
const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel);
|
||||||
|
return channelSettings->m_hasDCOffsetValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SoapySDRInput::hasIQCorrectionValue()
|
||||||
|
{
|
||||||
|
const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel);
|
||||||
|
return channelSettings->m_hasIQBalanceValue;
|
||||||
|
}
|
||||||
|
|
||||||
void SoapySDRInput::init()
|
void SoapySDRInput::init()
|
||||||
{
|
{
|
||||||
applySettings(m_settings, true);
|
applySettings(m_settings, true);
|
||||||
@ -753,10 +771,10 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo
|
|||||||
xlatedDeviceCenterFrequency -= settings.m_transverterMode ? settings.m_transverterDeltaFrequency : 0;
|
xlatedDeviceCenterFrequency -= settings.m_transverterMode ? settings.m_transverterDeltaFrequency : 0;
|
||||||
xlatedDeviceCenterFrequency = xlatedDeviceCenterFrequency < 0 ? 0 : xlatedDeviceCenterFrequency;
|
xlatedDeviceCenterFrequency = xlatedDeviceCenterFrequency < 0 ? 0 : xlatedDeviceCenterFrequency;
|
||||||
|
|
||||||
if ((m_settings.m_dcBlock != settings.m_dcBlock) ||
|
if ((m_settings.m_softDCCorrection != settings.m_softDCCorrection) ||
|
||||||
(m_settings.m_iqCorrection != settings.m_iqCorrection) || force)
|
(m_settings.m_softIQCorrection != settings.m_softIQCorrection) || force)
|
||||||
{
|
{
|
||||||
m_deviceAPI->configureCorrections(settings.m_dcBlock, settings.m_iqCorrection);
|
m_deviceAPI->configureCorrections(settings.m_softDCCorrection, settings.m_softIQCorrection);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force)
|
if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force)
|
||||||
@ -1015,8 +1033,8 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo
|
|||||||
<< " m_log2Decim: " << m_settings.m_log2Decim
|
<< " m_log2Decim: " << m_settings.m_log2Decim
|
||||||
<< " m_fcPos: " << m_settings.m_fcPos
|
<< " m_fcPos: " << m_settings.m_fcPos
|
||||||
<< " m_devSampleRate: " << m_settings.m_devSampleRate
|
<< " m_devSampleRate: " << m_settings.m_devSampleRate
|
||||||
<< " m_dcBlock: " << m_settings.m_dcBlock
|
<< " m_softDCCorrection: " << m_settings.m_softDCCorrection
|
||||||
<< " m_iqCorrection: " << m_settings.m_iqCorrection
|
<< " m_softIQCorrection: " << m_settings.m_softIQCorrection
|
||||||
<< " m_antenna: " << m_settings.m_antenna
|
<< " m_antenna: " << m_settings.m_antenna
|
||||||
<< " m_bandwidth: " << m_settings.m_bandwidth
|
<< " m_bandwidth: " << m_settings.m_bandwidth
|
||||||
<< " m_globalGain: " << m_settings.m_globalGain;
|
<< " m_globalGain: " << m_settings.m_globalGain;
|
||||||
|
@ -156,6 +156,10 @@ public:
|
|||||||
const std::vector<DeviceSoapySDRParams::FrequencySetting>& getTunableElements();
|
const std::vector<DeviceSoapySDRParams::FrequencySetting>& getTunableElements();
|
||||||
const std::vector<DeviceSoapySDRParams::GainSetting>& getIndividualGainsRanges();
|
const std::vector<DeviceSoapySDRParams::GainSetting>& getIndividualGainsRanges();
|
||||||
void initGainSettings(SoapySDRInputSettings& settings);
|
void initGainSettings(SoapySDRInputSettings& settings);
|
||||||
|
bool hasDCAutoCorrection();
|
||||||
|
bool hasDCCorrectionValue();
|
||||||
|
bool hasIQAutoCorrection() { return false; } // not in SoapySDR interface
|
||||||
|
bool hasIQCorrectionValue();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DeviceSourceAPI *m_deviceAPI;
|
DeviceSourceAPI *m_deviceAPI;
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "soapygui/stringrangegui.h"
|
#include "soapygui/stringrangegui.h"
|
||||||
#include "soapygui/dynamicitemsettinggui.h"
|
#include "soapygui/dynamicitemsettinggui.h"
|
||||||
#include "soapygui/intervalslidergui.h"
|
#include "soapygui/intervalslidergui.h"
|
||||||
|
#include "soapygui/complexfactorgui.h"
|
||||||
|
|
||||||
#include "ui_soapysdrinputgui.h"
|
#include "ui_soapysdrinputgui.h"
|
||||||
#include "soapysdrinputgui.h"
|
#include "soapysdrinputgui.h"
|
||||||
@ -46,7 +47,11 @@ SoapySDRInputGui::SoapySDRInputGui(DeviceUISet *deviceUISet, QWidget* parent) :
|
|||||||
m_sampleRateGUI(0),
|
m_sampleRateGUI(0),
|
||||||
m_bandwidthGUI(0),
|
m_bandwidthGUI(0),
|
||||||
m_gainSliderGUI(0),
|
m_gainSliderGUI(0),
|
||||||
m_autoGain(0)
|
m_autoGain(0),
|
||||||
|
m_dcCorrectionGUI(0),
|
||||||
|
m_iqCorrectionGUI(0),
|
||||||
|
m_autoDCCorrection(0),
|
||||||
|
m_autoIQCorrection(0)
|
||||||
{
|
{
|
||||||
m_sampleSource = (SoapySDRInput*) m_deviceUISet->m_deviceSourceAPI->getSampleSource();
|
m_sampleSource = (SoapySDRInput*) m_deviceUISet->m_deviceSourceAPI->getSampleSource();
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
@ -241,6 +246,57 @@ void SoapySDRInputGui::createIndividualGainsControl(const std::vector<DeviceSoap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoapySDRInputGui::createCorrectionsControl()
|
||||||
|
{
|
||||||
|
QVBoxLayout *layout = (QVBoxLayout *) ui->scrollAreaWidgetContents->layout();
|
||||||
|
|
||||||
|
if (m_sampleSource->hasDCCorrectionValue()) // complex GUI
|
||||||
|
{
|
||||||
|
m_dcCorrectionGUI = new ComplexFactorGUI(this);
|
||||||
|
m_dcCorrectionGUI->setLabel(QString("DC"));
|
||||||
|
m_dcCorrectionGUI->setAutomaticEnable(m_sampleSource->hasDCAutoCorrection());
|
||||||
|
layout->addWidget(m_dcCorrectionGUI);
|
||||||
|
|
||||||
|
connect(m_dcCorrectionGUI, SIGNAL(moduleChanged(double)), this, SLOT(dcCorrectionModuleChanged(double)));
|
||||||
|
connect(m_dcCorrectionGUI, SIGNAL(argumentChanged(double)), this, SLOT(dcCorrectionArgumentChanged(double)));
|
||||||
|
|
||||||
|
if (m_sampleSource->hasDCAutoCorrection()) {
|
||||||
|
connect(m_dcCorrectionGUI, SIGNAL(automaticChanged(bool)), this, SLOT(autoDCCorrectionChanged(bool)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_sampleSource->hasDCAutoCorrection()) // simple checkbox
|
||||||
|
{
|
||||||
|
m_autoDCCorrection = new QCheckBox(this);
|
||||||
|
m_autoDCCorrection->setText(QString("DC corr"));
|
||||||
|
layout->addWidget(m_autoDCCorrection);
|
||||||
|
|
||||||
|
connect(m_autoDCCorrection, SIGNAL(toggled(bool)), this, SLOT(autoDCCorrectionChanged(bool)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_sampleSource->hasIQCorrectionValue()) // complex GUI
|
||||||
|
{
|
||||||
|
m_iqCorrectionGUI = new ComplexFactorGUI(this);
|
||||||
|
m_iqCorrectionGUI->setLabel(QString("IQ"));
|
||||||
|
m_iqCorrectionGUI->setAutomaticEnable(m_sampleSource->hasIQAutoCorrection());
|
||||||
|
layout->addWidget(m_iqCorrectionGUI);
|
||||||
|
|
||||||
|
connect(m_iqCorrectionGUI, SIGNAL(moduleChanged(double)), this, SLOT(iqCorrectionModuleChanged(double)));
|
||||||
|
connect(m_iqCorrectionGUI, SIGNAL(argumentChanged(double)), this, SLOT(iqCorrectionArgumentChanged(double)));
|
||||||
|
|
||||||
|
if (m_sampleSource->hasIQAutoCorrection()) {
|
||||||
|
connect(m_iqCorrectionGUI, SIGNAL(automaticChanged(bool)), this, SLOT(autoIQCorrectionChanged(bool)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_sampleSource->hasIQAutoCorrection()) // simple checkbox
|
||||||
|
{
|
||||||
|
m_autoIQCorrection = new QCheckBox(this);
|
||||||
|
m_autoIQCorrection->setText(QString("IQ corr"));
|
||||||
|
layout->addWidget(m_autoIQCorrection);
|
||||||
|
|
||||||
|
connect(m_autoIQCorrection, SIGNAL(toggled(bool)), this, SLOT(autoIQCorrectionChanged(bool)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SoapySDRInputGui::setName(const QString& name)
|
void SoapySDRInputGui::setName(const QString& name)
|
||||||
{
|
{
|
||||||
setObjectName(name);
|
setObjectName(name);
|
||||||
@ -413,13 +469,13 @@ void SoapySDRInputGui::on_centerFrequency_changed(quint64 value)
|
|||||||
|
|
||||||
void SoapySDRInputGui::on_dcOffset_toggled(bool checked)
|
void SoapySDRInputGui::on_dcOffset_toggled(bool checked)
|
||||||
{
|
{
|
||||||
m_settings.m_dcBlock = checked;
|
m_settings.m_softDCCorrection = checked;
|
||||||
sendSettings();
|
sendSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoapySDRInputGui::on_iqImbalance_toggled(bool checked)
|
void SoapySDRInputGui::on_iqImbalance_toggled(bool checked)
|
||||||
{
|
{
|
||||||
m_settings.m_iqCorrection = checked;
|
m_settings.m_softIQCorrection = checked;
|
||||||
sendSettings();
|
sendSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,8 +562,8 @@ void SoapySDRInputGui::displaySettings()
|
|||||||
m_autoGain->setChecked(m_settings.m_autoGain);
|
m_autoGain->setChecked(m_settings.m_autoGain);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->dcOffset->setChecked(m_settings.m_dcBlock);
|
ui->dcOffset->setChecked(m_settings.m_softDCCorrection);
|
||||||
ui->iqImbalance->setChecked(m_settings.m_iqCorrection);
|
ui->iqImbalance->setChecked(m_settings.m_softIQCorrection);
|
||||||
|
|
||||||
ui->decim->setCurrentIndex(m_settings.m_log2Decim);
|
ui->decim->setCurrentIndex(m_settings.m_log2Decim);
|
||||||
ui->fcPos->setCurrentIndex((int) m_settings.m_fcPos);
|
ui->fcPos->setCurrentIndex((int) m_settings.m_fcPos);
|
||||||
|
@ -31,6 +31,7 @@ class StringRangeGUI;
|
|||||||
class DynamicItemSettingGUI;
|
class DynamicItemSettingGUI;
|
||||||
class IntervalSliderGUI;
|
class IntervalSliderGUI;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
|
class ComplexFactorGUI;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class SoapySDRInputGui;
|
class SoapySDRInputGui;
|
||||||
@ -65,6 +66,7 @@ private:
|
|||||||
void createTunableElementsControl(const std::vector<DeviceSoapySDRParams::FrequencySetting>& tunableElementsList);
|
void createTunableElementsControl(const std::vector<DeviceSoapySDRParams::FrequencySetting>& tunableElementsList);
|
||||||
void createGlobalGainControl();
|
void createGlobalGainControl();
|
||||||
void createIndividualGainsControl(const std::vector<DeviceSoapySDRParams::GainSetting>& individualGainsList);
|
void createIndividualGainsControl(const std::vector<DeviceSoapySDRParams::GainSetting>& individualGainsList);
|
||||||
|
void createCorrectionsControl();
|
||||||
|
|
||||||
Ui::SoapySDRInputGui* ui;
|
Ui::SoapySDRInputGui* ui;
|
||||||
|
|
||||||
@ -87,6 +89,10 @@ private:
|
|||||||
IntervalSliderGUI *m_gainSliderGUI;
|
IntervalSliderGUI *m_gainSliderGUI;
|
||||||
std::vector<DynamicItemSettingGUI*> m_individualGainsGUIs;
|
std::vector<DynamicItemSettingGUI*> m_individualGainsGUIs;
|
||||||
QCheckBox *m_autoGain;
|
QCheckBox *m_autoGain;
|
||||||
|
ComplexFactorGUI *m_dcCorrectionGUI;
|
||||||
|
ComplexFactorGUI *m_iqCorrectionGUI;
|
||||||
|
QCheckBox *m_autoDCCorrection;
|
||||||
|
QCheckBox *m_autoIQCorrection;
|
||||||
|
|
||||||
void displaySettings();
|
void displaySettings();
|
||||||
void displayTunableElementsControlSettings();
|
void displayTunableElementsControlSettings();
|
||||||
@ -106,6 +112,13 @@ private slots:
|
|||||||
void globalGainChanged(double gain);
|
void globalGainChanged(double gain);
|
||||||
void autoGainChanged(bool set);
|
void autoGainChanged(bool set);
|
||||||
void individualGainChanged(QString name, double value);
|
void individualGainChanged(QString name, double value);
|
||||||
|
void autoDCCorrectionChanged(bool set);
|
||||||
|
void autoIQCorrectionChanged(bool set);
|
||||||
|
void dcCorrectionModuleChanged(double value);
|
||||||
|
void dcCorrectionArgumentChanged(double value);
|
||||||
|
void iqCorrectionModuleChanged(double value);
|
||||||
|
void iqCorrectionArgumentChanged(double value);
|
||||||
|
|
||||||
void on_centerFrequency_changed(quint64 value);
|
void on_centerFrequency_changed(quint64 value);
|
||||||
void on_LOppm_valueChanged(int value);
|
void on_LOppm_valueChanged(int value);
|
||||||
void on_dcOffset_toggled(bool checked);
|
void on_dcOffset_toggled(bool checked);
|
||||||
|
@ -32,8 +32,8 @@ void SoapySDRInputSettings::resetToDefaults()
|
|||||||
m_devSampleRate = 1024000;
|
m_devSampleRate = 1024000;
|
||||||
m_log2Decim = 0;
|
m_log2Decim = 0;
|
||||||
m_fcPos = FC_POS_CENTER;
|
m_fcPos = FC_POS_CENTER;
|
||||||
m_dcBlock = false;
|
m_softDCCorrection = false;
|
||||||
m_iqCorrection = false;
|
m_softIQCorrection = false;
|
||||||
m_transverterMode = false;
|
m_transverterMode = false;
|
||||||
m_transverterDeltaFrequency = 0;
|
m_transverterDeltaFrequency = 0;
|
||||||
m_fileRecordName = "";
|
m_fileRecordName = "";
|
||||||
@ -41,6 +41,8 @@ void SoapySDRInputSettings::resetToDefaults()
|
|||||||
m_bandwidth = 1000000;
|
m_bandwidth = 1000000;
|
||||||
m_globalGain = 0;
|
m_globalGain = 0;
|
||||||
m_autoGain = false;
|
m_autoGain = false;
|
||||||
|
m_autoDCCorrection = false;
|
||||||
|
m_autoIQCorrection = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray SoapySDRInputSettings::serialize() const
|
QByteArray SoapySDRInputSettings::serialize() const
|
||||||
@ -50,8 +52,8 @@ QByteArray SoapySDRInputSettings::serialize() const
|
|||||||
s.writeS32(1, m_devSampleRate);
|
s.writeS32(1, m_devSampleRate);
|
||||||
s.writeU32(2, m_log2Decim);
|
s.writeU32(2, m_log2Decim);
|
||||||
s.writeS32(3, (int) m_fcPos);
|
s.writeS32(3, (int) m_fcPos);
|
||||||
s.writeBool(4, m_dcBlock);
|
s.writeBool(4, m_softDCCorrection);
|
||||||
s.writeBool(5, m_iqCorrection);
|
s.writeBool(5, m_softIQCorrection);
|
||||||
s.writeS32(6, m_LOppmTenths);
|
s.writeS32(6, m_LOppmTenths);
|
||||||
s.writeBool(7, m_transverterMode);
|
s.writeBool(7, m_transverterMode);
|
||||||
s.writeS64(8, m_transverterDeltaFrequency);
|
s.writeS64(8, m_transverterDeltaFrequency);
|
||||||
@ -61,6 +63,8 @@ QByteArray SoapySDRInputSettings::serialize() const
|
|||||||
s.writeS32(12, m_globalGain);
|
s.writeS32(12, m_globalGain);
|
||||||
s.writeBlob(13, serializeNamedElementMap(m_individualGains));
|
s.writeBlob(13, serializeNamedElementMap(m_individualGains));
|
||||||
s.writeBool(14, m_autoGain);
|
s.writeBool(14, m_autoGain);
|
||||||
|
s.writeBool(15, m_autoDCCorrection);
|
||||||
|
s.writeBool(16, m_autoIQCorrection);
|
||||||
|
|
||||||
return s.final();
|
return s.final();
|
||||||
}
|
}
|
||||||
@ -81,12 +85,12 @@ bool SoapySDRInputSettings::deserialize(const QByteArray& data)
|
|||||||
QByteArray blob;
|
QByteArray blob;
|
||||||
|
|
||||||
d.readS32(1, &m_devSampleRate, 1024000);
|
d.readS32(1, &m_devSampleRate, 1024000);
|
||||||
d.readU32(2, &m_log2Decim);
|
d.readU32(2, &m_log2Decim, 0);
|
||||||
d.readS32(3, &intval, (int) FC_POS_CENTER);
|
d.readS32(3, &intval, (int) FC_POS_CENTER);
|
||||||
m_fcPos = (fcPos_t) intval;
|
m_fcPos = (fcPos_t) intval;
|
||||||
d.readBool(4, &m_dcBlock);
|
d.readBool(4, &m_softDCCorrection, false);
|
||||||
d.readBool(5, &m_iqCorrection);
|
d.readBool(5, &m_softIQCorrection, false);
|
||||||
d.readS32(6, &m_LOppmTenths);
|
d.readS32(6, &m_LOppmTenths, 0);
|
||||||
d.readBool(7, &m_transverterMode, false);
|
d.readBool(7, &m_transverterMode, false);
|
||||||
d.readS64(8, &m_transverterDeltaFrequency, 0);
|
d.readS64(8, &m_transverterDeltaFrequency, 0);
|
||||||
d.readString(9, &m_antenna, "NONE");
|
d.readString(9, &m_antenna, "NONE");
|
||||||
@ -97,6 +101,8 @@ bool SoapySDRInputSettings::deserialize(const QByteArray& data)
|
|||||||
d.readBlob(13, &blob);
|
d.readBlob(13, &blob);
|
||||||
deserializeNamedElementMap(blob, m_individualGains);
|
deserializeNamedElementMap(blob, m_individualGains);
|
||||||
d.readBool(14, &m_autoGain, false);
|
d.readBool(14, &m_autoGain, false);
|
||||||
|
d.readBool(15, &m_autoDCCorrection, false);
|
||||||
|
d.readBool(16, &m_autoIQCorrection, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,8 @@ struct SoapySDRInputSettings {
|
|||||||
qint32 m_devSampleRate;
|
qint32 m_devSampleRate;
|
||||||
quint32 m_log2Decim;
|
quint32 m_log2Decim;
|
||||||
fcPos_t m_fcPos;
|
fcPos_t m_fcPos;
|
||||||
bool m_dcBlock;
|
bool m_softDCCorrection;
|
||||||
bool m_iqCorrection;
|
bool m_softIQCorrection;
|
||||||
bool m_transverterMode;
|
bool m_transverterMode;
|
||||||
qint64 m_transverterDeltaFrequency;
|
qint64 m_transverterDeltaFrequency;
|
||||||
QString m_fileRecordName;
|
QString m_fileRecordName;
|
||||||
@ -44,6 +44,10 @@ struct SoapySDRInputSettings {
|
|||||||
qint32 m_globalGain;
|
qint32 m_globalGain;
|
||||||
QMap<QString, double> m_individualGains;
|
QMap<QString, double> m_individualGains;
|
||||||
bool m_autoGain;
|
bool m_autoGain;
|
||||||
|
bool m_autoDCCorrection;
|
||||||
|
bool m_autoIQCorrection;
|
||||||
|
std::complex<float> m_dcCorrection;
|
||||||
|
std::complex<float> m_iqCorrection;
|
||||||
|
|
||||||
SoapySDRInputSettings();
|
SoapySDRInputSettings();
|
||||||
void resetToDefaults();
|
void resetToDefaults();
|
||||||
|
Loading…
Reference in New Issue
Block a user