mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-11-08 23:30:29 -05:00
IQ swap: implementation in MIMO plugins
This commit is contained in:
parent
24aa55027c
commit
f9f1a1d99c
@ -42,6 +42,7 @@ void BladeRF2MIMOSettings::resetToDefaults()
|
||||
m_iqCorrection = false;
|
||||
m_rxTransverterMode = false;
|
||||
m_rxTransverterDeltaFrequency = 0;
|
||||
m_iqOrder = true;
|
||||
|
||||
m_txCenterFrequency = 435000*1000;
|
||||
m_log2Interp = 0;
|
||||
@ -80,6 +81,7 @@ QByteArray BladeRF2MIMOSettings::serialize() const
|
||||
s.writeBool(20, m_iqCorrection);
|
||||
s.writeBool(21, m_rxTransverterMode);
|
||||
s.writeS64(22, m_rxTransverterDeltaFrequency);
|
||||
s.writeBool(23, m_iqOrder);
|
||||
|
||||
s.writeU64(30, m_txCenterFrequency);
|
||||
s.writeU32(31, m_log2Interp);
|
||||
@ -132,6 +134,7 @@ bool BladeRF2MIMOSettings::deserialize(const QByteArray& data)
|
||||
d.readBool(20, &m_iqCorrection);
|
||||
d.readBool(21, &m_rxTransverterMode, false);
|
||||
d.readS64(22, &m_rxTransverterDeltaFrequency, 0);
|
||||
d.readBool(23, &m_iqOrder, true);
|
||||
|
||||
d.readU64(30, &m_txCenterFrequency, 435000*1000);
|
||||
d.readU32(31, &m_log2Interp);
|
||||
|
||||
@ -44,6 +44,7 @@ struct BladeRF2MIMOSettings {
|
||||
bool m_iqCorrection;
|
||||
bool m_rxTransverterMode;
|
||||
qint64 m_rxTransverterDeltaFrequency;
|
||||
bool m_iqOrder; //!< true: IQ - false: QI
|
||||
|
||||
quint64 m_txCenterFrequency;
|
||||
quint32 m_log2Interp;
|
||||
|
||||
@ -26,7 +26,8 @@ BladeRF2MIThread::BladeRF2MIThread(struct bladerf* dev, QObject* parent) :
|
||||
QThread(parent),
|
||||
m_running(false),
|
||||
m_dev(dev),
|
||||
m_sampleFifo(nullptr)
|
||||
m_sampleFifo(nullptr),
|
||||
m_iqOrder(true)
|
||||
{
|
||||
qDebug("BladeRF2MIThread::BladeRF2MIThread");
|
||||
m_buf = new qint16[2*DeviceBladeRF2::blockSize*2];
|
||||
@ -135,7 +136,12 @@ void BladeRF2MIThread::callback(const qint16* buf, qint32 samplesPerChannel)
|
||||
|
||||
for (unsigned int channel = 0; channel < 2; channel++)
|
||||
{
|
||||
lengths[channel] = channelCallback(&buf[2*samplesPerChannel*channel], 2*samplesPerChannel, channel);
|
||||
if (m_iqOrder) {
|
||||
lengths[channel] = channelCallbackIQ(&buf[2*samplesPerChannel*channel], 2*samplesPerChannel, channel);
|
||||
} else {
|
||||
lengths[channel] = channelCallbackQI(&buf[2*samplesPerChannel*channel], 2*samplesPerChannel, channel);
|
||||
}
|
||||
|
||||
vbegin.push_back(m_convertBuffer[channel].begin());
|
||||
}
|
||||
|
||||
@ -150,13 +156,13 @@ void BladeRF2MIThread::callback(const qint16* buf, qint32 samplesPerChannel)
|
||||
}
|
||||
}
|
||||
|
||||
int BladeRF2MIThread::channelCallback(const qint16* buf, qint32 len, int channel)
|
||||
int BladeRF2MIThread::channelCallbackIQ(const qint16* buf, qint32 len, int channel)
|
||||
{
|
||||
SampleVector::iterator it = m_convertBuffer[channel].begin();
|
||||
|
||||
if (m_log2Decim == 0)
|
||||
{
|
||||
m_decimators[channel].decimate1(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate1(&it, buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -165,22 +171,22 @@ int BladeRF2MIThread::channelCallback(const qint16* buf, qint32 len, int channel
|
||||
switch (m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
m_decimators[channel].decimate2_inf(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate2_inf(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_decimators[channel].decimate4_inf(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate4_inf(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_decimators[channel].decimate8_inf(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate8_inf(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_decimators[channel].decimate16_inf(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate16_inf(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_decimators[channel].decimate32_inf(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate32_inf(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_decimators[channel].decimate64_inf(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate64_inf(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -191,22 +197,22 @@ int BladeRF2MIThread::channelCallback(const qint16* buf, qint32 len, int channel
|
||||
switch (m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
m_decimators[channel].decimate2_sup(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate2_sup(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_decimators[channel].decimate4_sup(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate4_sup(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_decimators[channel].decimate8_sup(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate8_sup(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_decimators[channel].decimate16_sup(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate16_sup(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_decimators[channel].decimate32_sup(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate32_sup(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_decimators[channel].decimate64_sup(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate64_sup(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -217,22 +223,115 @@ int BladeRF2MIThread::channelCallback(const qint16* buf, qint32 len, int channel
|
||||
switch (m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
m_decimators[channel].decimate2_cen(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate2_cen(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_decimators[channel].decimate4_cen(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate4_cen(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_decimators[channel].decimate8_cen(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate8_cen(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_decimators[channel].decimate16_cen(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate16_cen(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_decimators[channel].decimate32_cen(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate32_cen(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_decimators[channel].decimate64_cen(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate64_cen(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return it - m_convertBuffer[channel].begin();
|
||||
}
|
||||
|
||||
int BladeRF2MIThread::channelCallbackQI(const qint16* buf, qint32 len, int channel)
|
||||
{
|
||||
SampleVector::iterator it = m_convertBuffer[channel].begin();
|
||||
|
||||
if (m_log2Decim == 0)
|
||||
{
|
||||
m_decimatorsQI[channel].decimate1(&it, buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_fcPos == 0) // Infra
|
||||
{
|
||||
switch (m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
m_decimatorsQI[channel].decimate2_inf(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_decimatorsQI[channel].decimate4_inf(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_decimatorsQI[channel].decimate8_inf(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_decimatorsQI[channel].decimate16_inf(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_decimatorsQI[channel].decimate32_inf(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_decimatorsQI[channel].decimate64_inf(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (m_fcPos == 1) // Supra
|
||||
{
|
||||
switch (m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
m_decimatorsQI[channel].decimate2_sup(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_decimatorsQI[channel].decimate4_sup(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_decimatorsQI[channel].decimate8_sup(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_decimatorsQI[channel].decimate16_sup(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_decimatorsQI[channel].decimate32_sup(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_decimatorsQI[channel].decimate64_sup(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (m_fcPos == 2) // Center
|
||||
{
|
||||
switch (m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
m_decimatorsQI[channel].decimate2_cen(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_decimatorsQI[channel].decimate4_cen(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_decimatorsQI[channel].decimate8_cen(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_decimatorsQI[channel].decimate16_cen(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_decimatorsQI[channel].decimate32_cen(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_decimatorsQI[channel].decimate64_cen(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -57,13 +57,16 @@ private:
|
||||
qint16 *m_buf;
|
||||
SampleVector m_convertBuffer[2];
|
||||
SampleMIFifo* m_sampleFifo;
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12> m_decimators[2];
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12, true> m_decimatorsIQ[2];
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12, false> m_decimatorsQI[2];
|
||||
unsigned int m_log2Decim;
|
||||
int m_fcPos;
|
||||
bool m_iqOrder;
|
||||
|
||||
void run();
|
||||
void callback(const qint16* buf, qint32 samplesPerChannel);
|
||||
int channelCallback(const qint16* buf, qint32 len, int channel);
|
||||
int channelCallbackIQ(const qint16* buf, qint32 len, int channel);
|
||||
int channelCallbackQI(const qint16* buf, qint32 len, int channel);
|
||||
};
|
||||
|
||||
#endif // PLUGINS_SAMPLEMIMO_BLADERF2MIMO_BLADERF2MITHREAD_H_
|
||||
|
||||
@ -296,6 +296,7 @@ bool LimeSDRMIMO::startRx()
|
||||
m_sampleMIFifo.reset();
|
||||
m_sourceThread->setFifo(&m_sampleMIFifo);
|
||||
m_sourceThread->setLog2Decimation(m_settings.m_log2SoftDecim);
|
||||
m_sourceThread->setIQOrder(m_settings.m_iqOrder);
|
||||
m_sourceThread->startWork();
|
||||
mutexLocker.unlock();
|
||||
m_runningRx = true;
|
||||
@ -951,6 +952,15 @@ bool LimeSDRMIMO::applySettings(const LimeSDRMIMOSettings& settings, bool force)
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
|
||||
{
|
||||
reverseAPIKeys.append("iqOrder");
|
||||
|
||||
if (m_sourceThread) {
|
||||
m_sourceThread->setIQOrder(settings.m_iqOrder);
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_antennaPathRx0 != settings.m_antennaPathRx0) || force)
|
||||
{
|
||||
reverseAPIKeys.append("antennaPathRx0");
|
||||
|
||||
@ -44,6 +44,7 @@ void LimeSDRMIMOSettings::resetToDefaults()
|
||||
m_iqCorrection = false;
|
||||
m_rxTransverterMode = false;
|
||||
m_rxTransverterDeltaFrequency = 0;
|
||||
m_iqOrder = true;
|
||||
m_ncoEnableRx = false;
|
||||
m_ncoFrequencyRx = 0;
|
||||
|
||||
@ -112,6 +113,7 @@ QByteArray LimeSDRMIMOSettings::serialize() const
|
||||
s.writeS64(26, m_rxTransverterDeltaFrequency);
|
||||
s.writeBool(27, m_ncoEnableRx);
|
||||
s.writeS32(28, m_ncoFrequencyRx);
|
||||
s.writeBool(29, m_iqOrder);
|
||||
|
||||
s.writeFloat(30, m_lpfBWRx0);
|
||||
s.writeBool(31, m_lpfFIREnableRx0);
|
||||
@ -201,6 +203,7 @@ bool LimeSDRMIMOSettings::deserialize(const QByteArray& data)
|
||||
d.readS64(26, &m_rxTransverterDeltaFrequency, 0);
|
||||
d.readBool(27, &m_ncoEnableRx, false);
|
||||
d.readS32(28, &m_ncoFrequencyRx, 0);
|
||||
d.readBool(29, &m_iqOrder, true);
|
||||
|
||||
d.readFloat(30, &m_lpfBWRx0, 1.5e6);
|
||||
d.readBool(31, &m_lpfFIREnableRx0, false);
|
||||
|
||||
@ -71,6 +71,7 @@ struct LimeSDRMIMOSettings
|
||||
bool m_iqCorrection;
|
||||
bool m_rxTransverterMode;
|
||||
qint64 m_rxTransverterDeltaFrequency;
|
||||
bool m_iqOrder;
|
||||
bool m_ncoEnableRx; //!< Rx Enable TSP NCO and mixing
|
||||
int m_ncoFrequencyRx; //!< Rx Actual NCO frequency (the resulting frequency with mixing is displayed)
|
||||
|
||||
|
||||
@ -24,7 +24,8 @@ LimeSDRMIThread::LimeSDRMIThread(lms_stream_t* stream0, lms_stream_t* stream1, Q
|
||||
m_running(false),
|
||||
m_stream0(stream0),
|
||||
m_stream1(stream1),
|
||||
m_sampleFifo(nullptr)
|
||||
m_sampleFifo(nullptr),
|
||||
m_iqOrder(true)
|
||||
{
|
||||
qDebug("LimeSDRMIThread::LimeSDRMIThread");
|
||||
|
||||
@ -168,8 +169,17 @@ void LimeSDRMIThread::run()
|
||||
res[1] = DeviceLimeSDR::blockSize;
|
||||
}
|
||||
|
||||
lengths[0] = channelCallback(m_buf0, 2*res[0], 0);
|
||||
lengths[1] = channelCallback(m_buf1, 2*res[1], 1);
|
||||
if (m_iqOrder)
|
||||
{
|
||||
lengths[0] = channelCallbackIQ(m_buf0, 2*res[0], 0);
|
||||
lengths[1] = channelCallbackIQ(m_buf1, 2*res[1], 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
lengths[0] = channelCallbackQI(m_buf0, 2*res[0], 0);
|
||||
lengths[1] = channelCallbackQI(m_buf1, 2*res[1], 1);
|
||||
}
|
||||
|
||||
|
||||
if (lengths[0] == lengths[1])
|
||||
{
|
||||
@ -186,35 +196,73 @@ void LimeSDRMIThread::run()
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
int LimeSDRMIThread::channelCallback(const qint16* buf, qint32 len, int channel)
|
||||
int LimeSDRMIThread::channelCallbackIQ(const qint16* buf, qint32 len, int channel)
|
||||
{
|
||||
SampleVector::iterator it = m_convertBuffer[channel].begin();
|
||||
|
||||
if (m_log2Decim == 0)
|
||||
{
|
||||
m_decimators[channel].decimate1(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate1(&it, buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
m_decimators[channel].decimate2_cen(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate2_cen(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_decimators[channel].decimate4_cen(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate4_cen(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_decimators[channel].decimate8_cen(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate8_cen(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_decimators[channel].decimate16_cen(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate16_cen(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_decimators[channel].decimate32_cen(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate32_cen(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_decimators[channel].decimate64_cen(&it, buf, len);
|
||||
m_decimatorsIQ[channel].decimate64_cen(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return it - m_convertBuffer[channel].begin();
|
||||
}
|
||||
|
||||
int LimeSDRMIThread::channelCallbackQI(const qint16* buf, qint32 len, int channel)
|
||||
{
|
||||
SampleVector::iterator it = m_convertBuffer[channel].begin();
|
||||
|
||||
if (m_log2Decim == 0)
|
||||
{
|
||||
m_decimatorsQI[channel].decimate1(&it, buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
m_decimatorsQI[channel].decimate2_cen(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_decimatorsQI[channel].decimate4_cen(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_decimatorsQI[channel].decimate8_cen(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_decimatorsQI[channel].decimate16_cen(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_decimatorsQI[channel].decimate32_cen(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_decimatorsQI[channel].decimate64_cen(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -46,6 +46,7 @@ public:
|
||||
unsigned int getLog2Decimation() const;
|
||||
void setFifo(SampleMIFifo *sampleFifo) { m_sampleFifo = sampleFifo; }
|
||||
SampleMIFifo *getFifo() { return m_sampleFifo; }
|
||||
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
|
||||
|
||||
private:
|
||||
QMutex m_startWaitMutex;
|
||||
@ -59,11 +60,14 @@ private:
|
||||
SampleVector m_convertBuffer[2];
|
||||
std::vector<SampleVector::const_iterator> m_vBegin;
|
||||
SampleMIFifo* m_sampleFifo;
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12> m_decimators[2];
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12, true> m_decimatorsIQ[2];
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12, false> m_decimatorsQI[2];
|
||||
unsigned int m_log2Decim;
|
||||
bool m_iqOrder;
|
||||
|
||||
void run();
|
||||
int channelCallback(const qint16* buf, qint32 len, int channel);
|
||||
int channelCallbackIQ(const qint16* buf, qint32 len, int channel);
|
||||
int channelCallbackQI(const qint16* buf, qint32 len, int channel);
|
||||
};
|
||||
|
||||
#endif // PLUGINS_SAMPLEMIMO_LIMESDRMIMO_LIMESDRMITHREAD_H_
|
||||
|
||||
@ -131,9 +131,9 @@ private:
|
||||
|
||||
MessageQueue m_inputMessageQueue;
|
||||
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 8> m_decimators_8;
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12> m_decimators_12;
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 16> m_decimators_16;
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 8, true> m_decimators_8;
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12, true> m_decimators_12;
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 16, true> m_decimators_16;
|
||||
|
||||
void startWork();
|
||||
void stopWork();
|
||||
|
||||
@ -137,6 +137,7 @@ bool XTRXMIMO::startRx()
|
||||
m_sampleMIFifo.reset();
|
||||
m_sourceThread->setFifo(&m_sampleMIFifo);
|
||||
m_sourceThread->setLog2Decimation(m_settings.m_log2SoftDecim);
|
||||
m_sourceThread->setIQOrder(m_settings.m_iqOrder);
|
||||
m_sourceThread->startWork();
|
||||
mutexLocker.unlock();
|
||||
m_runningRx = true;
|
||||
@ -585,6 +586,15 @@ bool XTRXMIMO::applySettings(const XTRXMIMOSettings& settings, bool force)
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
|
||||
{
|
||||
reverseAPIKeys.append("iqOrder");
|
||||
|
||||
if (m_sourceThread) {
|
||||
m_sourceThread->setIQOrder(settings.m_iqOrder);
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_ncoFrequencyRx != settings.m_ncoFrequencyRx) || force) {
|
||||
reverseAPIKeys.append("ncoFrequencyRx");
|
||||
}
|
||||
|
||||
@ -43,6 +43,7 @@ void XTRXMIMOSettings::resetToDefaults()
|
||||
m_ncoEnableRx = false;
|
||||
m_ncoFrequencyRx = 0;
|
||||
m_antennaPathRx = RXANT_LO;
|
||||
m_iqOrder = true;
|
||||
// Rx0
|
||||
m_lpfBWRx0 = 4.5e6f;
|
||||
m_gainRx0 = 50;
|
||||
@ -98,6 +99,7 @@ QByteArray XTRXMIMOSettings::serialize() const
|
||||
s.writeS32(25, m_ncoFrequencyRx);
|
||||
s.writeS32(26, (int) m_antennaPathRx);
|
||||
s.writeDouble(27, m_rxDevSampleRate);
|
||||
s.writeBool(28, m_iqOrder);
|
||||
// Rx0
|
||||
s.writeFloat(30, m_lpfBWRx0);
|
||||
s.writeU32(31, m_gainRx0);
|
||||
@ -172,6 +174,7 @@ bool XTRXMIMOSettings::deserialize(const QByteArray& data)
|
||||
d.readS32(26, &intval, 0);
|
||||
m_antennaPathRx = (RxAntenna) intval;
|
||||
d.readDouble(27, &m_rxDevSampleRate, 5e6);
|
||||
d.readBool(28, &m_iqOrder, true);
|
||||
// Rx0
|
||||
d.readFloat(30, &m_lpfBWRx0, 1.5e6);
|
||||
d.readU32(31, &m_gainRx0, 50);
|
||||
|
||||
@ -61,6 +61,7 @@ struct XTRXMIMOSettings
|
||||
bool m_ncoEnableRx; //!< Enable TSP NCO and mixing
|
||||
int m_ncoFrequencyRx; //!< Actual NCO frequency (the resulting frequency with mixing is displayed)
|
||||
RxAntenna m_antennaPathRx;
|
||||
bool m_iqOrder;
|
||||
// Rx0
|
||||
float m_lpfBWRx0; //!< LMS analog lowpass filter bandwidth (Hz)
|
||||
uint32_t m_gainRx0; //!< Optimally distributed gain (dB)
|
||||
|
||||
@ -27,7 +27,8 @@ XTRXMIThread::XTRXMIThread(struct xtrx_dev *dev, QObject* parent) :
|
||||
QThread(parent),
|
||||
m_running(false),
|
||||
m_dev(dev),
|
||||
m_sampleFifo(nullptr)
|
||||
m_sampleFifo(nullptr),
|
||||
m_iqOrder(true)
|
||||
{
|
||||
qDebug("XTRXMIThread::XTRXMIThread");
|
||||
|
||||
@ -134,8 +135,17 @@ void XTRXMIThread::run()
|
||||
qDebug("XTRXInputThread::run: overflow");
|
||||
}
|
||||
|
||||
lengths[0] = callbackSI(0, (const qint16*) buffs[0], 2*nfo.out_samples);
|
||||
lengths[1] = callbackSI(1, (const qint16*) buffs[1], 2*nfo.out_samples);
|
||||
if (m_iqOrder)
|
||||
{
|
||||
lengths[0] = callbackSIIQ(0, (const qint16*) buffs[0], 2*nfo.out_samples);
|
||||
lengths[1] = callbackSIIQ(1, (const qint16*) buffs[1], 2*nfo.out_samples);
|
||||
}
|
||||
else
|
||||
{
|
||||
lengths[0] = callbackSIQI(0, (const qint16*) buffs[0], 2*nfo.out_samples);
|
||||
lengths[1] = callbackSIQI(1, (const qint16*) buffs[1], 2*nfo.out_samples);
|
||||
}
|
||||
|
||||
|
||||
if (lengths[0] == lengths[1])
|
||||
{
|
||||
@ -173,35 +183,73 @@ unsigned int XTRXMIThread::getLog2Decimation() const
|
||||
return m_log2Decim;
|
||||
}
|
||||
|
||||
int XTRXMIThread::callbackSI(unsigned int channel, const qint16* buf, qint32 len)
|
||||
int XTRXMIThread::callbackSIIQ(unsigned int channel, const qint16* buf, qint32 len)
|
||||
{
|
||||
SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
|
||||
|
||||
if (m_log2Decim == 0)
|
||||
{
|
||||
m_channels[channel].m_decimators.decimate1(&it, buf, len);
|
||||
m_channels[channel].m_decimatorsIQ.decimate1(&it, buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
m_channels[channel].m_decimators.decimate2_cen(&it, buf, len);
|
||||
m_channels[channel].m_decimatorsIQ.decimate2_cen(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_channels[channel].m_decimators.decimate4_cen(&it, buf, len);
|
||||
m_channels[channel].m_decimatorsIQ.decimate4_cen(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_channels[channel].m_decimators.decimate8_cen(&it, buf, len);
|
||||
m_channels[channel].m_decimatorsIQ.decimate8_cen(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_channels[channel].m_decimators.decimate16_cen(&it, buf, len);
|
||||
m_channels[channel].m_decimatorsIQ.decimate16_cen(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_channels[channel].m_decimators.decimate32_cen(&it, buf, len);
|
||||
m_channels[channel].m_decimatorsIQ.decimate32_cen(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_channels[channel].m_decimators.decimate64_cen(&it, buf, len);
|
||||
m_channels[channel].m_decimatorsIQ.decimate64_cen(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return it - m_channels[channel].m_convertBuffer.begin();
|
||||
}
|
||||
|
||||
int XTRXMIThread::callbackSIQI(unsigned int channel, const qint16* buf, qint32 len)
|
||||
{
|
||||
SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
|
||||
|
||||
if (m_log2Decim == 0)
|
||||
{
|
||||
m_channels[channel].m_decimatorsQI.decimate1(&it, buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
m_channels[channel].m_decimatorsQI.decimate2_cen(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_channels[channel].m_decimatorsQI.decimate4_cen(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_channels[channel].m_decimatorsQI.decimate8_cen(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_channels[channel].m_decimatorsQI.decimate16_cen(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_channels[channel].m_decimatorsQI.decimate32_cen(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_channels[channel].m_decimatorsQI.decimate64_cen(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -43,12 +43,14 @@ public:
|
||||
unsigned int getLog2Decimation() const;
|
||||
void setFifo(SampleMIFifo *sampleFifo) { m_sampleFifo = sampleFifo; }
|
||||
SampleMIFifo *getFifo() { return m_sampleFifo; }
|
||||
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
|
||||
|
||||
private:
|
||||
struct Channel
|
||||
{
|
||||
SampleVector m_convertBuffer;
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12> m_decimators;
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12, true> m_decimatorsIQ;
|
||||
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12, false> m_decimatorsQI;
|
||||
};
|
||||
|
||||
QMutex m_startWaitMutex;
|
||||
@ -61,9 +63,11 @@ private:
|
||||
std::vector<SampleVector::const_iterator> m_vBegin;
|
||||
SampleMIFifo* m_sampleFifo;
|
||||
unsigned int m_log2Decim;
|
||||
bool m_iqOrder;
|
||||
|
||||
void run();
|
||||
int callbackSI(unsigned int channel, const qint16* buf, qint32 len);
|
||||
int callbackSIIQ(unsigned int channel, const qint16* buf, qint32 len);
|
||||
int callbackSIQI(unsigned int channel, const qint16* buf, qint32 len);
|
||||
};
|
||||
|
||||
#endif // PLUGINS_SAMPLEMIMO_XTRXMIMO_XTRXMITHREAD_H_
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user