mirror of https://github.com/f4exb/sdrangel.git
Test Source: add phase imbalance control
This commit is contained in:
parent
5cbfcccb85
commit
373aa6960f
|
@ -236,6 +236,13 @@ void TestSourceGui::on_qBias_valueChanged(int value)
|
||||||
sendSettings();
|
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)
|
void TestSourceGui::on_record_toggled(bool checked)
|
||||||
{
|
{
|
||||||
if (checked) {
|
if (checked) {
|
||||||
|
|
|
@ -92,6 +92,7 @@ private slots:
|
||||||
void on_dcBias_valueChanged(int value);
|
void on_dcBias_valueChanged(int value);
|
||||||
void on_iBias_valueChanged(int value);
|
void on_iBias_valueChanged(int value);
|
||||||
void on_qBias_valueChanged(int value);
|
void on_qBias_valueChanged(int value);
|
||||||
|
void on_phaseImbalance_valueChanged(int value);
|
||||||
void on_record_toggled(bool checked);
|
void on_record_toggled(bool checked);
|
||||||
void updateStatus();
|
void updateStatus();
|
||||||
void updateHardware();
|
void updateHardware();
|
||||||
|
|
|
@ -624,12 +624,6 @@
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="4">
|
<item row="2" column="4">
|
||||||
<widget class="QLabel" name="qBiasText">
|
<widget class="QLabel" name="qBiasText">
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>45</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>-100 %</string>
|
<string>-100 %</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -688,12 +682,6 @@
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="4">
|
<item row="1" column="4">
|
||||||
<widget class="QLabel" name="iBiasText">
|
<widget class="QLabel" name="iBiasText">
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>45</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>-100 %</string>
|
<string>-100 %</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -745,6 +733,37 @@
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="4">
|
<item row="0" column="4">
|
||||||
<widget class="QLabel" name="dcBiasText">
|
<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">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>45</width>
|
<width>45</width>
|
||||||
|
@ -759,24 +778,23 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="fillerLayout">
|
<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>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -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_settings.m_sampleSizeIndex != settings.m_sampleSizeIndex) || force)
|
||||||
{
|
{
|
||||||
if (m_testSourceThread != 0) {
|
if (m_testSourceThread != 0) {
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
const PluginDescriptor TestSourcePlugin::m_pluginDescriptor = {
|
const PluginDescriptor TestSourcePlugin::m_pluginDescriptor = {
|
||||||
QString("Test Source input"),
|
QString("Test Source input"),
|
||||||
QString("3.11.0"),
|
QString("3.12.0"),
|
||||||
QString("(c) Edouard Griffiths, F4EXB"),
|
QString("(c) Edouard Griffiths, F4EXB"),
|
||||||
QString("https://github.com/f4exb/sdrangel"),
|
QString("https://github.com/f4exb/sdrangel"),
|
||||||
true,
|
true,
|
||||||
|
|
|
@ -37,6 +37,7 @@ void TestSourceSettings::resetToDefaults()
|
||||||
m_dcFactor = 0.0f;
|
m_dcFactor = 0.0f;
|
||||||
m_iFactor = 0.0f;
|
m_iFactor = 0.0f;
|
||||||
m_qFactor = 0.0f;
|
m_qFactor = 0.0f;
|
||||||
|
m_phaseImbalance = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray TestSourceSettings::serialize() const
|
QByteArray TestSourceSettings::serialize() const
|
||||||
|
@ -54,6 +55,7 @@ QByteArray TestSourceSettings::serialize() const
|
||||||
s.writeFloat(10, m_dcFactor);
|
s.writeFloat(10, m_dcFactor);
|
||||||
s.writeFloat(11, m_iFactor);
|
s.writeFloat(11, m_iFactor);
|
||||||
s.writeFloat(12, m_qFactor);
|
s.writeFloat(12, m_qFactor);
|
||||||
|
s.writeFloat(13, m_phaseImbalance);
|
||||||
|
|
||||||
return s.final();
|
return s.final();
|
||||||
}
|
}
|
||||||
|
@ -84,6 +86,7 @@ bool TestSourceSettings::deserialize(const QByteArray& data)
|
||||||
d.readFloat(10, &m_dcFactor, 0.0f);
|
d.readFloat(10, &m_dcFactor, 0.0f);
|
||||||
d.readFloat(11, &m_iFactor, 0.0f);
|
d.readFloat(11, &m_iFactor, 0.0f);
|
||||||
d.readFloat(12, &m_qFactor, 0.0f);
|
d.readFloat(12, &m_qFactor, 0.0f);
|
||||||
|
d.readFloat(13, &m_phaseImbalance, 0.0f);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,10 @@ struct TestSourceSettings {
|
||||||
qint32 m_amplitudeBits;
|
qint32 m_amplitudeBits;
|
||||||
bool m_dcBlock;
|
bool m_dcBlock;
|
||||||
bool m_iqImbalance;
|
bool m_iqImbalance;
|
||||||
float m_dcFactor; //!< -1.0 < x < 1.0
|
float m_dcFactor; //!< -1.0 < x < 1.0
|
||||||
float m_iFactor; //!< -1.0 < x < 1.0
|
float m_iFactor; //!< -1.0 < x < 1.0
|
||||||
float m_qFactor; //!< -1.0 < x < 1.0
|
float m_qFactor; //!< -1.0 < x < 1.0
|
||||||
|
float m_phaseImbalance; //!< -1.0 < x < 1.0
|
||||||
|
|
||||||
TestSourceSettings();
|
TestSourceSettings();
|
||||||
void resetToDefaults();
|
void resetToDefaults();
|
||||||
|
|
|
@ -40,6 +40,7 @@ TestSourceThread::TestSourceThread(SampleSinkFifo* sampleFifo, QObject* parent)
|
||||||
m_dcBias(0.0f),
|
m_dcBias(0.0f),
|
||||||
m_iBias(0.0f),
|
m_iBias(0.0f),
|
||||||
m_qBias(0.0f),
|
m_qBias(0.0f),
|
||||||
|
m_phaseImbalance(0.0f),
|
||||||
m_amplitudeBitsDC(0),
|
m_amplitudeBitsDC(0),
|
||||||
m_amplitudeBitsI(127),
|
m_amplitudeBitsI(127),
|
||||||
m_amplitudeBitsQ(127),
|
m_amplitudeBitsQ(127),
|
||||||
|
@ -138,6 +139,11 @@ void TestSourceThread::setQFactor(float iFactor)
|
||||||
m_amplitudeBitsQ = (1.0f + m_qBias) * m_amplitudeBits;
|
m_amplitudeBitsQ = (1.0f + m_qBias) * m_amplitudeBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestSourceThread::setPhaseImbalance(float phaseImbalance)
|
||||||
|
{
|
||||||
|
m_phaseImbalance = phaseImbalance;
|
||||||
|
}
|
||||||
|
|
||||||
void TestSourceThread::setFrequencyShift(int shift)
|
void TestSourceThread::setFrequencyShift(int shift)
|
||||||
{
|
{
|
||||||
m_nco.setFreq(shift, m_samplerate);
|
m_nco.setFreq(shift, m_samplerate);
|
||||||
|
@ -189,7 +195,7 @@ void TestSourceThread::generate(quint32 chunksize)
|
||||||
|
|
||||||
for (int i = 0; i < n-1;)
|
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.real() * (float) m_amplitudeBitsI) + m_amplitudeBitsDC;
|
||||||
m_buf[i++] = (int16_t) (c.imag() * (float) m_amplitudeBitsQ);
|
m_buf[i++] = (int16_t) (c.imag() * (float) m_amplitudeBitsQ);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
void setDCFactor(float iFactor);
|
void setDCFactor(float iFactor);
|
||||||
void setIFactor(float iFactor);
|
void setIFactor(float iFactor);
|
||||||
void setQFactor(float qFactor);
|
void setQFactor(float qFactor);
|
||||||
|
void setPhaseImbalance(float phaseImbalance);
|
||||||
void setFrequencyShift(int shift);
|
void setFrequencyShift(int shift);
|
||||||
|
|
||||||
void connectTimer(const QTimer& timer);
|
void connectTimer(const QTimer& timer);
|
||||||
|
@ -73,6 +74,7 @@ private:
|
||||||
float m_dcBias;
|
float m_dcBias;
|
||||||
float m_iBias;
|
float m_iBias;
|
||||||
float m_qBias;
|
float m_qBias;
|
||||||
|
float m_phaseImbalance;
|
||||||
int32_t m_amplitudeBitsDC;
|
int32_t m_amplitudeBitsDC;
|
||||||
int32_t m_amplitudeBitsI;
|
int32_t m_amplitudeBitsI;
|
||||||
int32_t m_amplitudeBitsQ;
|
int32_t m_amplitudeBitsQ;
|
||||||
|
|
|
@ -61,6 +61,14 @@ Complex NCOF::nextIQ()
|
||||||
return Complex(m_table[phase], -m_table[(phase + TableSize / 4) % TableSize]);
|
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()
|
Complex NCOF::nextQI()
|
||||||
{
|
{
|
||||||
int phase = nextPhase();
|
int phase = nextPhase();
|
||||||
|
|
|
@ -49,14 +49,15 @@ public:
|
||||||
return (int) m_phase;
|
return (int) m_phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
Real next(); //!< Return next real sample
|
Real next(); //!< Return next real sample
|
||||||
Complex nextIQ(); //!< Return next complex sample
|
Complex nextIQ(); //!< Return next complex sample
|
||||||
Complex nextQI(); //!< Return next complex sample (reversed)
|
Complex nextIQ(float imbalance); //!< Return next complex sample with an imbalance factor on I
|
||||||
Real get(); //!< Return current real sample (no phase increment)
|
Complex nextQI(); //!< Return next complex sample (reversed)
|
||||||
Complex getIQ(); //!< Return current complex sample (no phase increment)
|
Real get(); //!< Return current real sample (no phase increment)
|
||||||
void getIQ(Complex& c); //!< Sets to the current complex sample (no phase increment)
|
Complex getIQ(); //!< Return current complex sample (no phase increment)
|
||||||
Complex getQI(); //!< Return current complex sample (no phase increment, reversed)
|
void getIQ(Complex& c); //!< Sets to the current complex sample (no phase increment)
|
||||||
void getQI(Complex& c); //!< Sets to the current complex sample (no phase increment, reversed)
|
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
|
#endif // INCLUDE_NCO_H
|
||||||
|
|
Loading…
Reference in New Issue