Test Source: add phase imbalance control

This commit is contained in:
f4exb 2018-01-31 22:34:55 +01:00
parent 5cbfcccb85
commit 373aa6960f
11 changed files with 94 additions and 40 deletions

View File

@ -236,6 +236,13 @@ void TestSourceGui::on_qBias_valueChanged(int value)
sendSettings();
}
void TestSourceGui::on_phaseImbalance_valueChanged(int value)
{
ui->phaseImbalanceText->setText(QString(tr("%1 %").arg(value)));
m_settings.m_phaseImbalance = value / 100.0f;
sendSettings();
}
void TestSourceGui::on_record_toggled(bool checked)
{
if (checked) {

View File

@ -92,6 +92,7 @@ private slots:
void on_dcBias_valueChanged(int value);
void on_iBias_valueChanged(int value);
void on_qBias_valueChanged(int value);
void on_phaseImbalance_valueChanged(int value);
void on_record_toggled(bool checked);
void updateStatus();
void updateHardware();

View File

@ -624,12 +624,6 @@
</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>
@ -688,12 +682,6 @@
</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>
@ -745,6 +733,37 @@
</item>
<item row="0" column="4">
<widget class="QLabel" name="dcBiasText">
<property name="text">
<string>-100 %</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="phaseImbalanceLabel">
<property name="text">
<string>Phase</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="phaseImbalanceMinusLabel">
<property name="text">
<string>-</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLabel" name="phaseImbalancePlusLabel">
<property name="text">
<string>+</string>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QLabel" name="phaseImbalanceText">
<property name="minimumSize">
<size>
<width>45</width>
@ -759,24 +778,23 @@
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSlider" name="phaseImbalance">
<property name="minimum">
<number>-99</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="fillerLayout">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
<layout class="QHBoxLayout" name="fillerLayout"/>
</item>
</layout>
</widget>

View File

@ -316,6 +316,13 @@ bool TestSourceInput::applySettings(const TestSourceSettings& settings, bool for
}
}
if ((m_settings.m_phaseImbalance != settings.m_phaseImbalance) || force)
{
if (m_testSourceThread != 0) {
m_testSourceThread->setPhaseImbalance(settings.m_phaseImbalance);
}
}
if ((m_settings.m_sampleSizeIndex != settings.m_sampleSizeIndex) || force)
{
if (m_testSourceThread != 0) {

View File

@ -29,7 +29,7 @@
const PluginDescriptor TestSourcePlugin::m_pluginDescriptor = {
QString("Test Source input"),
QString("3.11.0"),
QString("3.12.0"),
QString("(c) Edouard Griffiths, F4EXB"),
QString("https://github.com/f4exb/sdrangel"),
true,

View File

@ -37,6 +37,7 @@ void TestSourceSettings::resetToDefaults()
m_dcFactor = 0.0f;
m_iFactor = 0.0f;
m_qFactor = 0.0f;
m_phaseImbalance = 0.0f;
}
QByteArray TestSourceSettings::serialize() const
@ -54,6 +55,7 @@ QByteArray TestSourceSettings::serialize() const
s.writeFloat(10, m_dcFactor);
s.writeFloat(11, m_iFactor);
s.writeFloat(12, m_qFactor);
s.writeFloat(13, m_phaseImbalance);
return s.final();
}
@ -84,6 +86,7 @@ bool TestSourceSettings::deserialize(const QByteArray& data)
d.readFloat(10, &m_dcFactor, 0.0f);
d.readFloat(11, &m_iFactor, 0.0f);
d.readFloat(12, &m_qFactor, 0.0f);
d.readFloat(13, &m_phaseImbalance, 0.0f);
return true;
}

View File

@ -33,9 +33,10 @@ struct TestSourceSettings {
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
float m_dcFactor; //!< -1.0 < x < 1.0
float m_iFactor; //!< -1.0 < x < 1.0
float m_qFactor; //!< -1.0 < x < 1.0
float m_phaseImbalance; //!< -1.0 < x < 1.0
TestSourceSettings();
void resetToDefaults();

View File

@ -40,6 +40,7 @@ TestSourceThread::TestSourceThread(SampleSinkFifo* sampleFifo, QObject* parent)
m_dcBias(0.0f),
m_iBias(0.0f),
m_qBias(0.0f),
m_phaseImbalance(0.0f),
m_amplitudeBitsDC(0),
m_amplitudeBitsI(127),
m_amplitudeBitsQ(127),
@ -138,6 +139,11 @@ void TestSourceThread::setQFactor(float iFactor)
m_amplitudeBitsQ = (1.0f + m_qBias) * m_amplitudeBits;
}
void TestSourceThread::setPhaseImbalance(float phaseImbalance)
{
m_phaseImbalance = phaseImbalance;
}
void TestSourceThread::setFrequencyShift(int shift)
{
m_nco.setFreq(shift, m_samplerate);
@ -189,7 +195,7 @@ void TestSourceThread::generate(quint32 chunksize)
for (int i = 0; i < n-1;)
{
Complex c = m_nco.nextIQ();
Complex c = m_nco.nextIQ(m_phaseImbalance);
m_buf[i++] = (int16_t) (c.real() * (float) m_amplitudeBitsI) + m_amplitudeBitsDC;
m_buf[i++] = (int16_t) (c.imag() * (float) m_amplitudeBitsQ);
}

View File

@ -47,6 +47,7 @@ public:
void setDCFactor(float iFactor);
void setIFactor(float iFactor);
void setQFactor(float qFactor);
void setPhaseImbalance(float phaseImbalance);
void setFrequencyShift(int shift);
void connectTimer(const QTimer& timer);
@ -73,6 +74,7 @@ private:
float m_dcBias;
float m_iBias;
float m_qBias;
float m_phaseImbalance;
int32_t m_amplitudeBitsDC;
int32_t m_amplitudeBitsI;
int32_t m_amplitudeBitsQ;

View File

@ -61,6 +61,14 @@ Complex NCOF::nextIQ()
return Complex(m_table[phase], -m_table[(phase + TableSize / 4) % TableSize]);
}
Complex NCOF::nextIQ(float imbalance)
{
int phase = nextPhase();
int phaseQ = imbalance < 0.0 ? phase + (int) (imbalance*TableSize) : phase;
int phaseI = imbalance < 0.0 ? phase : phase + (int) (imbalance*TableSize);
return Complex(m_table[phaseI % TableSize], -m_table[(phaseQ + TableSize / 4) % TableSize]);
}
Complex NCOF::nextQI()
{
int phase = nextPhase();

View File

@ -49,14 +49,15 @@ public:
return (int) m_phase;
}
Real next(); //!< Return next real sample
Complex nextIQ(); //!< Return next complex sample
Complex nextQI(); //!< Return next complex sample (reversed)
Real get(); //!< Return current real sample (no phase increment)
Complex getIQ(); //!< Return current complex sample (no phase increment)
void getIQ(Complex& c); //!< Sets to the current complex sample (no phase increment)
Complex getQI(); //!< Return current complex sample (no phase increment, reversed)
void getQI(Complex& c); //!< Sets to the current complex sample (no phase increment, reversed)
Real next(); //!< Return next real sample
Complex nextIQ(); //!< Return next complex sample
Complex nextIQ(float imbalance); //!< Return next complex sample with an imbalance factor on I
Complex nextQI(); //!< Return next complex sample (reversed)
Real get(); //!< Return current real sample (no phase increment)
Complex getIQ(); //!< Return current complex sample (no phase increment)
void getIQ(Complex& c); //!< Sets to the current complex sample (no phase increment)
Complex getQI(); //!< Return current complex sample (no phase increment, reversed)
void getQI(Complex& c); //!< Sets to the current complex sample (no phase increment, reversed)
};
#endif // INCLUDE_NCO_H