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