mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-26 09:48:45 -05:00
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();
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -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();
|
||||
|
@ -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>
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user