TestSource: implemente DC and IQ bias and corrections

This commit is contained in:
f4exb 2018-01-14 11:58:36 +01:00
parent 45e04f06ae
commit bd8c916dd4
8 changed files with 326 additions and 4 deletions

View File

@ -141,6 +141,19 @@ void TestSourceGui::on_centerFrequency_changed(quint64 value)
sendSettings();
}
void TestSourceGui::on_dcOffset_toggled(bool checked)
{
m_settings.m_dcBlock = checked;
sendSettings();
}
void TestSourceGui::on_iqImbalance_toggled(bool checked)
{
m_settings.m_iqImbalance = checked;
sendSettings();
}
void TestSourceGui::on_frequencyShift_changed(qint64 value)
{
m_settings.m_frequencyShift = value;
@ -204,6 +217,27 @@ void TestSourceGui::on_amplitudeFine_valueChanged(int value __attribute__((unuse
sendSettings();
}
void TestSourceGui::on_dcBias_valueChanged(int value)
{
ui->dcBiasText->setText(QString(tr("%1 %").arg(value)));
m_settings.m_dcFactor = value / 100.0f;
sendSettings();
}
void TestSourceGui::on_iBias_valueChanged(int value)
{
ui->iBiasText->setText(QString(tr("%1 %").arg(value)));
m_settings.m_iFactor = value / 100.0f;
sendSettings();
}
void TestSourceGui::on_qBias_valueChanged(int value)
{
ui->qBiasText->setText(QString(tr("%1 %").arg(value)));
m_settings.m_qFactor = value / 100.0f;
sendSettings();
}
void TestSourceGui::on_record_toggled(bool checked)
{
if (checked) {
@ -309,6 +343,12 @@ void TestSourceGui::displaySettings()
updateAmpFineLimit();
ui->amplitudeFine->setValue(amplitudeBits%100);
displayAmplitude();
int dcBiasPercent = roundf(m_settings.m_dcFactor * 100.0f);
ui->dcBiasText->setText(QString(tr("%1 %").arg(dcBiasPercent)));
int iBiasPercent = roundf(m_settings.m_iFactor * 100.0f);
ui->iBiasText->setText(QString(tr("%1 %").arg(iBiasPercent)));
int qBiasPercent = roundf(m_settings.m_qFactor * 100.0f);
ui->qBiasText->setText(QString(tr("%1 %").arg(qBiasPercent)));
blockApplySettings(false);
}

View File

@ -82,6 +82,8 @@ private slots:
void handleInputMessages();
void on_startStop_toggled(bool checked);
void on_centerFrequency_changed(quint64 value);
void on_dcOffset_toggled(bool checked);
void on_iqImbalance_toggled(bool checked);
void on_frequencyShift_changed(qint64 value);
void on_decimation_currentIndexChanged(int index);
void on_fcPos_currentIndexChanged(int index);
@ -89,6 +91,9 @@ private slots:
void on_sampleSize_currentIndexChanged(int index);
void on_amplitudeCoarse_valueChanged(int value);
void on_amplitudeFine_valueChanged(int value);
void on_dcBias_valueChanged(int value);
void on_iBias_valueChanged(int value);
void on_qBias_valueChanged(int value);
void on_record_toggled(bool checked);
void updateStatus();
void updateHardware();

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>360</width>
<height>220</height>
<height>300</height>
</rect>
</property>
<property name="sizePolicy">
@ -19,7 +19,7 @@
<property name="minimumSize">
<size>
<width>360</width>
<height>220</height>
<height>300</height>
</size>
</property>
<property name="font">
@ -185,6 +185,44 @@
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="autoCorrectionsLayout">
<item>
<widget class="QLabel" name="autoCorrLabel">
<property name="text">
<string>Auto</string>
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="dcOffset">
<property name="text">
<string>DC</string>
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="iqImbalance">
<property name="text">
<string>IQ</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="frequencyShiftLayout">
<item>
@ -569,6 +607,160 @@
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="iqBiasLayout">
<item row="2" column="2">
<widget class="QSlider" name="qBias">
<property name="minimum">
<number>-99</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QLabel" name="qBiasText">
<property name="minimumSize">
<size>
<width>45</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>-100 %</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="qBiasLabel">
<property name="text">
<string>Q bias</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLabel" name="qBiasPlusQLabel">
<property name="text">
<string>+</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="qBiasMinusLabel">
<property name="text">
<string>-</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="iBiasLabel">
<property name="text">
<string>I bias</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="iBiasMinusLabel">
<property name="text">
<string>-</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSlider" name="iBias">
<property name="minimum">
<number>-99</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLabel" name="iBiasText">
<property name="minimumSize">
<size>
<width>45</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>-100 %</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="iBiasPlusLabel">
<property name="text">
<string>+</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="dcBiasLabel">
<property name="text">
<string>DC bias</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="dcBiasMinusLabel">
<property name="text">
<string>-</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QSlider" name="dcBias">
<property name="minimum">
<number>-99</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="dcBiasPlusLabel">
<property name="text">
<string>+</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="dcBiasText">
<property name="minimumSize">
<size>
<width>45</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>-100 %</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="fillerLayout">
<item>

View File

@ -222,6 +222,14 @@ bool TestSourceInput::handleMessage(const Message& message)
bool TestSourceInput::applySettings(const TestSourceSettings& settings, bool force)
{
if ((m_settings.m_dcBlock != settings.m_dcBlock) || (m_settings.m_iqImbalance != settings.m_iqImbalance) || force)
{
m_deviceAPI->configureCorrections(settings.m_dcBlock, settings.m_iqImbalance);
qDebug("TestSourceInput::applySettings: corrections: DC block: %s IQ imbalance: %s",
settings.m_dcBlock ? "true" : "false",
settings.m_iqImbalance ? "true" : "false");
}
if ((m_settings.m_sampleRate != settings.m_sampleRate) || force)
{
if (m_testSourceThread != 0)
@ -287,6 +295,27 @@ bool TestSourceInput::applySettings(const TestSourceSettings& settings, bool for
}
}
if ((m_settings.m_dcFactor != settings.m_dcFactor) || force)
{
if (m_testSourceThread != 0) {
m_testSourceThread->setDCFactor(settings.m_dcFactor);
}
}
if ((m_settings.m_iFactor != settings.m_iFactor) || force)
{
if (m_testSourceThread != 0) {
m_testSourceThread->setIFactor(settings.m_iFactor);
}
}
if ((m_settings.m_qFactor != settings.m_qFactor) || force)
{
if (m_testSourceThread != 0) {
m_testSourceThread->setQFactor(settings.m_qFactor);
}
}
if ((m_settings.m_sampleSizeIndex != settings.m_sampleSizeIndex) || force)
{
if (m_testSourceThread != 0) {

View File

@ -32,6 +32,11 @@ void TestSourceSettings::resetToDefaults()
m_fcPos = FC_POS_CENTER;
m_sampleSizeIndex = 0;
m_amplitudeBits = 127;
m_dcBlock = false;
m_iqImbalance = false;
m_dcFactor = 0.0f;
m_iFactor = 0.0f;
m_qFactor = 0.0f;
}
QByteArray TestSourceSettings::serialize() const
@ -44,6 +49,11 @@ QByteArray TestSourceSettings::serialize() const
s.writeS32(5, (int) m_fcPos);
s.writeU32(6, m_sampleSizeIndex);
s.writeS32(7, m_amplitudeBits);
s.writeBool(8, m_dcBlock);
s.writeBool(9, m_iqImbalance);
s.writeFloat(10, m_dcFactor);
s.writeFloat(11, m_iFactor);
s.writeFloat(12, m_qFactor);
return s.final();
}
@ -69,6 +79,11 @@ bool TestSourceSettings::deserialize(const QByteArray& data)
m_fcPos = (fcPos_t) intval;
d.readU32(6, &m_sampleSizeIndex, 0);
d.readS32(7, &m_amplitudeBits, 128);
d.readBool(8, &m_dcBlock, false);
d.readBool(9, &m_iqImbalance, false);
d.readFloat(10, &m_dcFactor, 0.0f);
d.readFloat(11, &m_iFactor, 0.0f);
d.readFloat(12, &m_qFactor, 0.0f);
return true;
}

View File

@ -31,6 +31,11 @@ struct TestSourceSettings {
fcPos_t m_fcPos;
quint32 m_sampleSizeIndex;
qint32 m_amplitudeBits;
bool m_dcBlock;
bool m_iqImbalance;
float m_dcFactor; //!< -1.0 < x < 1.0
float m_iFactor; //!< -1.0 < x < 1.0
float m_qFactor; //!< -1.0 < x < 1.0
TestSourceSettings();
void resetToDefaults();

View File

@ -37,6 +37,12 @@ TestSourceThread::TestSourceThread(SampleSinkFifo* sampleFifo, QObject* parent)
m_bitSizeIndex(0),
m_bitShift(8),
m_amplitudeBits(127),
m_dcBias(0.0f),
m_iBias(0.0f),
m_qBias(0.0f),
m_amplitudeBitsDC(0),
m_amplitudeBitsI(127),
m_amplitudeBitsQ(127),
m_frequency(435*1000),
m_fcPosShift(0),
m_throttlems(TESTSOURCE_THROTTLE_MS),
@ -109,6 +115,27 @@ void TestSourceThread::setBitSize(quint32 bitSizeIndex)
void TestSourceThread::setAmplitudeBits(int32_t amplitudeBits)
{
m_amplitudeBits = amplitudeBits;
m_amplitudeBitsDC = m_dcBias * amplitudeBits;
m_amplitudeBitsI = (1.0f + m_iBias) * amplitudeBits;
m_amplitudeBitsQ = (1.0f + m_qBias) * amplitudeBits;
}
void TestSourceThread::setDCFactor(float dcFactor)
{
m_dcBias = dcFactor;
m_amplitudeBitsDC = m_dcBias * m_amplitudeBits;
}
void TestSourceThread::setIFactor(float iFactor)
{
m_iBias = iFactor;
m_amplitudeBitsI = (1.0f + m_iBias) * m_amplitudeBits;
}
void TestSourceThread::setQFactor(float iFactor)
{
m_qBias = iFactor;
m_amplitudeBitsQ = (1.0f + m_qBias) * m_amplitudeBits;
}
void TestSourceThread::setFrequencyShift(int shift)
@ -163,8 +190,8 @@ void TestSourceThread::generate(quint32 chunksize)
for (int i = 0; i < n-1;)
{
Complex c = m_nco.nextIQ();
m_buf[i++] = (int16_t) (c.real() * (float) m_amplitudeBits);
m_buf[i++] = (int16_t) (c.imag() * (float) m_amplitudeBits);
m_buf[i++] = (int16_t) (c.real() * (float) m_amplitudeBitsI) + m_amplitudeBitsDC;
m_buf[i++] = (int16_t) (c.imag() * (float) m_amplitudeBitsQ);
}
callback(m_buf, n);

View File

@ -44,6 +44,9 @@ public:
void setFcPos(int fcPos);
void setBitSize(uint32_t bitSizeIndex);
void setAmplitudeBits(int32_t amplitudeBits);
void setDCFactor(float iFactor);
void setIFactor(float iFactor);
void setQFactor(float qFactor);
void setFrequencyShift(int shift);
void connectTimer(const QTimer& timer);
@ -67,6 +70,12 @@ private:
uint32_t m_bitSizeIndex;
uint32_t m_bitShift;
int32_t m_amplitudeBits;
float m_dcBias;
float m_iBias;
float m_qBias;
int32_t m_amplitudeBitsDC;
int32_t m_amplitudeBitsI;
int32_t m_amplitudeBitsQ;
uint64_t m_frequency;
int m_fcPosShift;