1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-08-14 23:43:43 -04:00

IQ swap: initial implementation in non MIMO plugins

This commit is contained in:
f4exb
2020-06-21 11:46:08 +02:00
parent ed5ebd6361
commit 24aa55027c
83 changed files with 4845 additions and 2834 deletions
+16 -6
View File
@@ -52,7 +52,7 @@ AirspyInput::AirspyInput(DeviceAPI *deviceAPI) :
m_fileSink(nullptr),
m_settings(),
m_dev(nullptr),
m_airspyThread(0),
m_airspyThread(nullptr),
m_deviceDescription("Airspy"),
m_running(false)
{
@@ -183,6 +183,7 @@ bool AirspyInput::start()
m_airspyThread = new AirspyThread(m_dev, &m_sampleFifo);
m_airspyThread->setSamplerate(m_sampleRates[m_settings.m_devSampleRateIndex]);
m_airspyThread->setLog2Decimation(m_settings.m_log2Decim);
m_airspyThread->setIQOrder(m_settings.m_iqOrder);
m_airspyThread->setFcPos((int) m_settings.m_fcPos);
m_airspyThread->startWork();
@@ -215,11 +216,11 @@ void AirspyInput::stop()
qDebug("AirspyInput::stop");
QMutexLocker mutexLocker(&m_mutex);
if (m_airspyThread != 0)
if (m_airspyThread)
{
m_airspyThread->stopWork();
delete m_airspyThread;
m_airspyThread = 0;
m_airspyThread = nullptr;
}
m_running = false;
@@ -413,7 +414,7 @@ bool AirspyInput::applySettings(const AirspySettings& settings, bool force)
{
qCritical("AirspyInput::applySettings: could not set sample rate index %u (%d S/s): %s", settings.m_devSampleRateIndex, m_sampleRates[settings.m_devSampleRateIndex], airspy_error_name(rc));
}
else if (m_airspyThread != 0)
else if (m_airspyThread)
{
qDebug("AirspyInput::applySettings: sample rate set to index: %u (%d S/s)", settings.m_devSampleRateIndex, m_sampleRates[settings.m_devSampleRateIndex]);
m_airspyThread->setSamplerate(m_sampleRates[settings.m_devSampleRateIndex]);
@@ -426,13 +427,22 @@ bool AirspyInput::applySettings(const AirspySettings& settings, bool force)
reverseAPIKeys.append("log2Decim");
forwardChange = true;
if (m_airspyThread != 0)
if (m_airspyThread)
{
m_airspyThread->setLog2Decimation(settings.m_log2Decim);
qDebug() << "AirspyInput: set decimation to " << (1<<settings.m_log2Decim);
}
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
reverseAPIKeys.append("iqOrder");
if (m_airspyThread) {
m_airspyThread->setIQOrder(settings.m_iqOrder);
}
}
if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) {
reverseAPIKeys.append("centerFrequency");
}
@@ -474,7 +484,7 @@ bool AirspyInput::applySettings(const AirspySettings& settings, bool force)
if ((m_settings.m_fcPos != settings.m_fcPos) || force)
{
if (m_airspyThread != 0)
if (m_airspyThread)
{
m_airspyThread->setFcPos((int) settings.m_fcPos);
qDebug() << "AirspyInput: set fc pos (enum) to " << (int) settings.m_fcPos;
@@ -41,6 +41,7 @@ void AirspySettings::resetToDefaults()
m_iqCorrection = false;
m_transverterMode = false;
m_transverterDeltaFrequency = 0;
m_iqOrder = true;
m_fileRecordName = "";
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
@@ -70,6 +71,7 @@ QByteArray AirspySettings::serialize() const
s.writeString(16, m_reverseAPIAddress);
s.writeU32(17, m_reverseAPIPort);
s.writeU32(18, m_reverseAPIDeviceIndex);
s.writeBool(19, m_iqOrder);
return s.final();
}
@@ -116,6 +118,7 @@ bool AirspySettings::deserialize(const QByteArray& data)
d.readU32(18, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
d.readBool(19, &m_iqOrder, true);
return true;
}
@@ -42,6 +42,7 @@ struct AirspySettings {
bool m_iqCorrection;
bool m_transverterMode;
qint64 m_transverterDeltaFrequency;
bool m_iqOrder;
QString m_fileRecordName;
bool m_useReverseAPI;
QString m_reverseAPIAddress;
+122 -23
View File
@@ -33,7 +33,8 @@ AirspyThread::AirspyThread(struct airspy_device* dev, SampleSinkFifo* sampleFifo
m_sampleFifo(sampleFifo),
m_samplerate(10),
m_log2Decim(0),
m_fcPos(0)
m_fcPos(0),
m_iqOrder(true)
{
m_this = this;
std::fill(m_buf, m_buf + 2*AIRSPY_BLOCKSIZE, 0);
@@ -112,13 +113,13 @@ void AirspyThread::run()
}
// Decimate according to specified log2 (ex: log2=4 => decim=16)
void AirspyThread::callback(const qint16* buf, qint32 len)
void AirspyThread::callbackIQ(const qint16* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimators.decimate1(&it, buf, len);
m_decimatorsIQ.decimate1(&it, buf, len);
}
else
{
@@ -127,22 +128,22 @@ void AirspyThread::callback(const qint16* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_inf(&it, buf, len);
m_decimatorsIQ.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimators.decimate4_inf(&it, buf, len);
m_decimatorsIQ.decimate4_inf(&it, buf, len);
break;
case 3:
m_decimators.decimate8_inf(&it, buf, len);
m_decimatorsIQ.decimate8_inf(&it, buf, len);
break;
case 4:
m_decimators.decimate16_inf(&it, buf, len);
m_decimatorsIQ.decimate16_inf(&it, buf, len);
break;
case 5:
m_decimators.decimate32_inf(&it, buf, len);
m_decimatorsIQ.decimate32_inf(&it, buf, len);
break;
case 6:
m_decimators.decimate64_inf(&it, buf, len);
m_decimatorsIQ.decimate64_inf(&it, buf, len);
break;
default:
break;
@@ -153,22 +154,22 @@ void AirspyThread::callback(const qint16* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_sup(&it, buf, len);
m_decimatorsIQ.decimate2_sup(&it, buf, len);
break;
case 2:
m_decimators.decimate4_sup(&it, buf, len);
m_decimatorsIQ.decimate4_sup(&it, buf, len);
break;
case 3:
m_decimators.decimate8_sup(&it, buf, len);
m_decimatorsIQ.decimate8_sup(&it, buf, len);
break;
case 4:
m_decimators.decimate16_sup(&it, buf, len);
m_decimatorsIQ.decimate16_sup(&it, buf, len);
break;
case 5:
m_decimators.decimate32_sup(&it, buf, len);
m_decimatorsIQ.decimate32_sup(&it, buf, len);
break;
case 6:
m_decimators.decimate64_sup(&it, buf, len);
m_decimatorsIQ.decimate64_sup(&it, buf, len);
break;
default:
break;
@@ -179,22 +180,22 @@ void AirspyThread::callback(const qint16* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_cen(&it, buf, len);
m_decimatorsIQ.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimators.decimate4_cen(&it, buf, len);
m_decimatorsIQ.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimators.decimate8_cen(&it, buf, len);
m_decimatorsIQ.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimators.decimate16_cen(&it, buf, len);
m_decimatorsIQ.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimators.decimate32_cen(&it, buf, len);
m_decimatorsIQ.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimators.decimate64_cen(&it, buf, len);
m_decimatorsIQ.decimate64_cen(&it, buf, len);
break;
default:
break;
@@ -205,10 +206,108 @@ void AirspyThread::callback(const qint16* buf, qint32 len)
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
void AirspyThread::callbackQI(const qint16* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimatorsQI.decimate1(&it, buf, len);
}
else
{
if (m_fcPos == 0) // Infra
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_inf(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_inf(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_inf(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_inf(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_inf(&it, buf, len);
break;
default:
break;
}
}
else if (m_fcPos == 1) // Supra
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_sup(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_sup(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_sup(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_sup(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_sup(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_sup(&it, buf, len);
break;
default:
break;
}
}
else if (m_fcPos == 2) // Center
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_cen(&it, buf, len);
break;
default:
break;
}
}
}
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
int AirspyThread::rx_callback(airspy_transfer_t* transfer)
{
qint32 bytes_to_write = transfer->sample_count * sizeof(qint16);
m_this->callback((qint16 *) transfer->samples, bytes_to_write);
return 0;
if (m_this->m_iqOrder) {
m_this->callbackIQ((qint16 *) transfer->samples, bytes_to_write);
} else {
m_this->callbackQI((qint16 *) transfer->samples, bytes_to_write);
}
return 0;
}
+6 -2
View File
@@ -40,6 +40,7 @@ public:
void setSamplerate(uint32_t samplerate);
void setLog2Decimation(unsigned int log2_decim);
void setFcPos(int fcPos);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
QMutex m_startWaitMutex;
@@ -54,12 +55,15 @@ private:
int m_samplerate;
unsigned int m_log2Decim;
int m_fcPos;
bool m_iqOrder;
static AirspyThread *m_this;
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;
void run();
void callback(const qint16* buf, qint32 len);
void callbackIQ(const qint16* buf, qint32 len);
void callbackQI(const qint16* buf, qint32 len);
static int rx_callback(airspy_transfer_t* transfer);
};
@@ -54,7 +54,7 @@ AirspyHFInput::AirspyHFInput(DeviceAPI *deviceAPI) :
m_fileSink(nullptr),
m_settings(),
m_dev(0),
m_airspyHFThread(0),
m_airspyHFThread(nullptr),
m_deviceDescription("AirspyHF"),
m_running(false)
{
@@ -186,6 +186,7 @@ bool AirspyHFInput::start()
}
m_airspyHFThread->setLog2Decimation(m_settings.m_log2Decim);
m_airspyHFThread->setIQOrder(m_settings.m_iqOrder);
m_airspyHFThread->startWork();
mutexLocker.unlock();
@@ -215,11 +216,11 @@ void AirspyHFInput::stop()
qDebug("AirspyHFInput::stop");
QMutexLocker mutexLocker(&m_mutex);
if (m_airspyHFThread != 0)
if (m_airspyHFThread)
{
m_airspyHFThread->stopWork();
delete m_airspyHFThread;
m_airspyHFThread = 0;
m_airspyHFThread = nullptr;
}
m_running = false;
@@ -460,7 +461,7 @@ bool AirspyHFInput::applySettings(const AirspyHFSettings& settings, bool force)
{
qCritical("AirspyHFInput::applySettings: could not set sample rate index %u (%d S/s)", sampleRateIndex, m_sampleRates[sampleRateIndex]);
}
else if (m_airspyHFThread != 0)
else if (m_airspyHFThread)
{
qDebug("AirspyHFInput::applySettings: sample rate set to index: %u (%d S/s)", sampleRateIndex, m_sampleRates[sampleRateIndex]);
m_airspyHFThread->setSamplerate(m_sampleRates[sampleRateIndex]);
@@ -473,13 +474,22 @@ bool AirspyHFInput::applySettings(const AirspyHFSettings& settings, bool force)
reverseAPIKeys.append("log2Decim");
forwardChange = true;
if (m_airspyHFThread != 0)
if (m_airspyHFThread)
{
m_airspyHFThread->setLog2Decimation(settings.m_log2Decim);
qDebug() << "AirspyInput: set decimation to " << (1<<settings.m_log2Decim);
}
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
reverseAPIKeys.append("iqOrder");
if (m_airspyHFThread) {
m_airspyHFThread->setIQOrder(settings.m_iqOrder);
}
}
if ((m_settings.m_LOppmTenths != settings.m_LOppmTenths) || force)
{
reverseAPIKeys.append("LOppmTenths");
@@ -492,7 +502,7 @@ bool AirspyHFInput::applySettings(const AirspyHFSettings& settings, bool force)
{
qCritical("AirspyHFInput::applySettings: could not set LO ppm correction to %f", settings.m_LOppmTenths / 10.0f);
}
else if (m_airspyHFThread != 0)
else if (m_airspyHFThread)
{
qDebug("AirspyHFInput::applySettings: LO ppm correction set to %f", settings.m_LOppmTenths / 10.0f);
}
@@ -33,6 +33,7 @@ void AirspyHFSettings::resetToDefaults()
m_log2Decim = 0;
m_transverterMode = false;
m_transverterDeltaFrequency = 0;
m_iqOrder = true;
m_bandIndex = 0;
m_fileRecordName = "";
m_useReverseAPI = false;
@@ -69,6 +70,7 @@ QByteArray AirspyHFSettings::serialize() const
s.writeU32(18, m_attenuatorSteps);
s.writeBool(19, m_dcBlock);
s.writeBool(20, m_iqCorrection);
s.writeBool(21, m_iqOrder);
return s.final();
}
@@ -115,6 +117,7 @@ bool AirspyHFSettings::deserialize(const QByteArray& data)
d.readU32(18, &m_attenuatorSteps, 0);
d.readBool(19, &m_dcBlock, false);
d.readBool(20, &m_iqCorrection, false);
d.readBool(21, &m_iqOrder, true);
return true;
}
@@ -28,6 +28,7 @@ struct AirspyHFSettings
quint32 m_log2Decim;
bool m_transverterMode;
qint64 m_transverterDeltaFrequency;
bool m_iqOrder;
quint32 m_bandIndex;
QString m_fileRecordName;
bool m_useReverseAPI;
@@ -31,7 +31,8 @@ AirspyHFThread::AirspyHFThread(airspyhf_device_t* dev, SampleSinkFifo* sampleFif
m_convertBuffer(AIRSPYHF_BLOCKSIZE),
m_sampleFifo(sampleFifo),
m_samplerate(10),
m_log2Decim(0)
m_log2Decim(0),
m_iqOrder(true)
{
memset((char*) m_buf, 0, 2*AIRSPYHF_BLOCKSIZE*sizeof(qint16));
m_this = this;
@@ -102,32 +103,32 @@ void AirspyHFThread::run()
}
// Decimate according to specified log2 (ex: log2=4 => decim=16)
void AirspyHFThread::callback(const float* buf, qint32 len)
void AirspyHFThread::callbackIQ(const float* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
switch (m_log2Decim)
{
case 0:
m_decimators.decimate1(&it, buf, len);
m_decimatorsIQ.decimate1(&it, buf, len);
break;
case 1:
m_decimators.decimate2_cen(&it, buf, len);
m_decimatorsIQ.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimators.decimate4_cen(&it, buf, len);
m_decimatorsIQ.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimators.decimate8_cen(&it, buf, len);
m_decimatorsIQ.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimators.decimate16_cen(&it, buf, len);
m_decimatorsIQ.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimators.decimate32_cen(&it, buf, len);
m_decimatorsIQ.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimators.decimate64_cen(&it, buf, len);
m_decimatorsIQ.decimate64_cen(&it, buf, len);
break;
default:
break;
@@ -136,10 +137,49 @@ void AirspyHFThread::callback(const float* buf, qint32 len)
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
void AirspyHFThread::callbackQI(const float* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
switch (m_log2Decim)
{
case 0:
m_decimatorsQI.decimate1(&it, buf, len);
break;
case 1:
m_decimatorsQI.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_cen(&it, buf, len);
break;
default:
break;
}
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
int AirspyHFThread::rx_callback(airspyhf_transfer_t* transfer)
{
qint32 nbIAndQ = transfer->sample_count * 2;
m_this->callback((float *) transfer->samples, nbIAndQ);
return 0;
if (m_this->m_iqOrder) {
m_this->callbackIQ((float *) transfer->samples, nbIAndQ);
} else {
m_this->callbackQI((float *) transfer->samples, nbIAndQ);
}
return 0;
}
@@ -39,6 +39,7 @@ public:
void stopWork();
void setSamplerate(uint32_t samplerate);
void setLog2Decimation(unsigned int log2_decim);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
QMutex m_startWaitMutex;
@@ -52,12 +53,15 @@ private:
int m_samplerate;
unsigned int m_log2Decim;
bool m_iqOrder;
static AirspyHFThread *m_this;
DecimatorsFI m_decimators;
DecimatorsFI<true> m_decimatorsIQ;
DecimatorsFI<false> m_decimatorsQI;
void run();
void callback(const float* buf, qint32 len);
void callbackIQ(const float* buf, qint32 len);
void callbackQI(const float* buf, qint32 len);
static int rx_callback(airspyhf_transfer_t* transfer);
};
@@ -47,7 +47,7 @@ Bladerf1Input::Bladerf1Input(DeviceAPI *deviceAPI) :
m_fileSink(nullptr),
m_settings(),
m_dev(0),
m_bladerfThread(0),
m_bladerfThread(nullptr),
m_deviceDescription("BladeRFInput"),
m_running(false)
{
@@ -168,6 +168,7 @@ bool Bladerf1Input::start()
m_bladerfThread = new Bladerf1InputThread(m_dev, &m_sampleFifo);
m_bladerfThread->setLog2Decimation(m_settings.m_log2Decim);
m_bladerfThread->setFcPos((int) m_settings.m_fcPos);
m_bladerfThread->setIQOrder(m_settings.m_iqOrder);
m_bladerfThread->startWork();
@@ -211,11 +212,11 @@ void Bladerf1Input::stop()
{
// QMutexLocker mutexLocker(&m_mutex);
if(m_bladerfThread != 0)
if(m_bladerfThread)
{
m_bladerfThread->stopWork();
delete m_bladerfThread;
m_bladerfThread = 0;
m_bladerfThread = nullptr;
}
m_running = false;
@@ -529,7 +530,7 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, bool fo
{
reverseAPIKeys.append("fcPos");
if (m_bladerfThread != 0)
if (m_bladerfThread)
{
m_bladerfThread->setFcPos((int) settings.m_fcPos);
qDebug() << "BladerfInput::applySettings: set fc pos (enum) to " << (int) settings.m_fcPos;
@@ -541,13 +542,22 @@ bool Bladerf1Input::applySettings(const BladeRF1InputSettings& settings, bool fo
reverseAPIKeys.append("log2Decim");
forwardChange = true;
if (m_bladerfThread != 0)
if (m_bladerfThread)
{
m_bladerfThread->setLog2Decimation(settings.m_log2Decim);
qDebug() << "BladerfInput::applySettings: set decimation to " << (1<<settings.m_log2Decim);
}
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
reverseAPIKeys.append("iqOrder");
if (m_bladerfThread) {
m_bladerfThread->setIQOrder(settings.m_iqOrder);
}
}
if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) {
reverseAPIKeys.append("centerFrequency");
}
@@ -41,6 +41,7 @@ void BladeRF1InputSettings::resetToDefaults()
m_xb200Filter = BLADERF_XB200_AUTO_1DB;
m_dcBlock = false;
m_iqCorrection = false;
m_iqOrder = true;
m_fileRecordName = "";
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
@@ -68,6 +69,7 @@ QByteArray BladeRF1InputSettings::serialize() const
s.writeString(14, m_reverseAPIAddress);
s.writeU32(15, m_reverseAPIPort);
s.writeU32(16, m_reverseAPIDeviceIndex);
s.writeBool(17, m_iqOrder);
return s.final();
}
@@ -114,6 +116,7 @@ bool BladeRF1InputSettings::deserialize(const QByteArray& data)
d.readU32(16, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
d.readBool(17, &m_iqOrder);
return true;
}
@@ -42,6 +42,7 @@ struct BladeRF1InputSettings {
bladerf_xb200_filter m_xb200Filter;
bool m_dcBlock;
bool m_iqCorrection;
bool m_iqOrder;
QString m_fileRecordName;
bool m_useReverseAPI;
QString m_reverseAPIAddress;
@@ -31,7 +31,8 @@ Bladerf1InputThread::Bladerf1InputThread(struct bladerf* dev, SampleSinkFifo* sa
m_convertBuffer(BLADERF_BLOCKSIZE),
m_sampleFifo(sampleFifo),
m_log2Decim(0),
m_fcPos(0)
m_fcPos(0),
m_iqOrder(true)
{
std::fill(m_buf, m_buf + 2*BLADERF_BLOCKSIZE, 0);
}
@@ -79,20 +80,24 @@ void Bladerf1InputThread::run()
break;
}
callback(m_buf, 2 * BLADERF_BLOCKSIZE);
if (m_iqOrder) {
callbackIQ(m_buf, 2 * BLADERF_BLOCKSIZE);
} else {
callbackQI(m_buf, 2 * BLADERF_BLOCKSIZE);
}
}
m_running = false;
}
// Decimate according to specified log2 (ex: log2=4 => decim=16)
void Bladerf1InputThread::callback(const qint16* buf, qint32 len)
void Bladerf1InputThread::callbackIQ(const qint16* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimators.decimate1(&it, buf, len);
m_decimatorsIQ.decimate1(&it, buf, len);
}
else
{
@@ -101,22 +106,22 @@ void Bladerf1InputThread::callback(const qint16* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_inf(&it, buf, len);
m_decimatorsIQ.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimators.decimate4_inf(&it, buf, len);
m_decimatorsIQ.decimate4_inf(&it, buf, len);
break;
case 3:
m_decimators.decimate8_inf(&it, buf, len);
m_decimatorsIQ.decimate8_inf(&it, buf, len);
break;
case 4:
m_decimators.decimate16_inf(&it, buf, len);
m_decimatorsIQ.decimate16_inf(&it, buf, len);
break;
case 5:
m_decimators.decimate32_inf(&it, buf, len);
m_decimatorsIQ.decimate32_inf(&it, buf, len);
break;
case 6:
m_decimators.decimate64_inf(&it, buf, len);
m_decimatorsIQ.decimate64_inf(&it, buf, len);
break;
default:
break;
@@ -127,22 +132,22 @@ void Bladerf1InputThread::callback(const qint16* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_sup(&it, buf, len);
m_decimatorsIQ.decimate2_sup(&it, buf, len);
break;
case 2:
m_decimators.decimate4_sup(&it, buf, len);
m_decimatorsIQ.decimate4_sup(&it, buf, len);
break;
case 3:
m_decimators.decimate8_sup(&it, buf, len);
m_decimatorsIQ.decimate8_sup(&it, buf, len);
break;
case 4:
m_decimators.decimate16_sup(&it, buf, len);
m_decimatorsIQ.decimate16_sup(&it, buf, len);
break;
case 5:
m_decimators.decimate32_sup(&it, buf, len);
m_decimatorsIQ.decimate32_sup(&it, buf, len);
break;
case 6:
m_decimators.decimate64_sup(&it, buf, len);
m_decimatorsIQ.decimate64_sup(&it, buf, len);
break;
default:
break;
@@ -153,22 +158,116 @@ void Bladerf1InputThread::callback(const qint16* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_cen(&it, buf, len);
m_decimatorsIQ.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimators.decimate4_cen(&it, buf, len);
m_decimatorsIQ.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimators.decimate8_cen(&it, buf, len);
m_decimatorsIQ.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimators.decimate16_cen(&it, buf, len);
m_decimatorsIQ.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimators.decimate32_cen(&it, buf, len);
m_decimatorsIQ.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimators.decimate64_cen(&it, buf, len);
m_decimatorsIQ.decimate64_cen(&it, buf, len);
break;
default:
break;
}
}
}
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
void Bladerf1InputThread::callbackQI(const qint16* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimatorsQI.decimate1(&it, buf, len);
}
else
{
if (m_fcPos == 0) // Infra
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_inf(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_inf(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_inf(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_inf(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_inf(&it, buf, len);
break;
default:
break;
}
}
else if (m_fcPos == 1) // Supra
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_sup(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_sup(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_sup(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_sup(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_sup(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_sup(&it, buf, len);
break;
default:
break;
}
}
else if (m_fcPos == 2) // Center
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_cen(&it, buf, len);
break;
default:
break;
@@ -38,6 +38,7 @@ public:
void stopWork();
void setLog2Decimation(unsigned int log2_decim);
void setFcPos(int fcPos);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
QMutex m_startWaitMutex;
@@ -51,11 +52,14 @@ private:
unsigned int m_log2Decim;
int m_fcPos;
bool m_iqOrder;
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;
void run();
void callback(const qint16* buf, qint32 len);
void callbackIQ(const qint16* buf, qint32 len);
void callbackQI(const qint16* buf, qint32 len);
};
#endif // INCLUDE_BLADERFINPUTTHREAD_H
@@ -51,7 +51,7 @@ BladeRF2Input::BladeRF2Input(DeviceAPI *deviceAPI) :
m_settings(),
m_deviceDescription("BladeRF2Input"),
m_running(false),
m_thread(0)
m_thread(nullptr)
{
openDevice();
@@ -212,7 +212,7 @@ void BladeRF2Input::init()
BladeRF2InputThread *BladeRF2Input::findThread()
{
if (m_thread == 0) // this does not own the thread
if (!m_thread) // this does not own the thread
{
BladeRF2InputThread *bladerf2InputThread = 0;
@@ -254,7 +254,7 @@ void BladeRF2Input::moveThreadToBuddy()
if (buddySource)
{
buddySource->setThread(m_thread);
m_thread = 0; // zero for others
m_thread = nullptr; // zero for others
}
}
}
@@ -326,6 +326,7 @@ bool BladeRF2Input::start()
delete bladerf2InputThread;
bladerf2InputThread = new BladeRF2InputThread(m_deviceShared.m_dev->getDev(), requestedChannel+1);
m_thread = bladerf2InputThread; // take ownership
bladerf2InputThread->setIQOrder(m_settings.m_iqOrder);
for (int i = 0; i < nbOriginalChannels; i++) // restore original FIFO references
{
@@ -426,7 +427,7 @@ void BladeRF2Input::stop()
qDebug("BladeRF2Input::stop: SI mode. Just stop and delete the thread");
bladerf2InputThread->stopWork();
delete bladerf2InputThread;
m_thread = 0;
m_thread = nullptr;
// remove old thread address from buddies (reset in all buddies)
const std::vector<DeviceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
@@ -456,7 +457,7 @@ void BladeRF2Input::stop()
}
delete bladerf2InputThread;
m_thread = 0;
m_thread = nullptr;
if (stillActiveFIFO)
{
@@ -861,7 +862,7 @@ bool BladeRF2Input::applySettings(const BladeRF2InputSettings& settings, bool fo
reverseAPIKeys.append("fcPos");
BladeRF2InputThread *inputThread = findThread();
if (inputThread != 0)
if (inputThread)
{
inputThread->setFcPos(requestedChannel, (int) settings.m_fcPos);
qDebug() << "BladeRF2Input::applySettings: set fc pos (enum) to " << (int) settings.m_fcPos;
@@ -874,13 +875,23 @@ bool BladeRF2Input::applySettings(const BladeRF2InputSettings& settings, bool fo
forwardChangeOwnDSP = true;
BladeRF2InputThread *inputThread = findThread();
if (inputThread != 0)
if (inputThread)
{
inputThread->setLog2Decimation(requestedChannel, settings.m_log2Decim);
qDebug() << "BladeRF2Input::applySettings: set decimation to " << (1<<settings.m_log2Decim);
}
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
reverseAPIKeys.append("iqOrder");
BladeRF2InputThread *inputThread = findThread();
if (inputThread) {
inputThread->setIQOrder(settings.m_iqOrder);
}
}
if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) {
reverseAPIKeys.append("centerFrequency");
}
@@ -39,6 +39,7 @@ void BladeRF2InputSettings::resetToDefaults()
m_iqCorrection = false;
m_transverterMode = false;
m_transverterDeltaFrequency = 0;
m_iqOrder = true;
m_fileRecordName = "";
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
@@ -66,6 +67,7 @@ QByteArray BladeRF2InputSettings::serialize() const
s.writeString(14, m_reverseAPIAddress);
s.writeU32(15, m_reverseAPIPort);
s.writeU32(16, m_reverseAPIDeviceIndex);
s.writeBool(17, m_iqOrder);
return s.final();
}
@@ -110,6 +112,7 @@ bool BladeRF2InputSettings::deserialize(const QByteArray& data)
d.readU32(16, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
d.readBool(17, &m_iqOrder, true);
return true;
}
@@ -41,6 +41,7 @@ struct BladeRF2InputSettings {
bool m_iqCorrection;
bool m_transverterMode;
qint64 m_transverterDeltaFrequency;
bool m_iqOrder;
QString m_fileRecordName;
bool m_useReverseAPI;
QString m_reverseAPIAddress;
@@ -23,7 +23,8 @@ BladeRF2InputThread::BladeRF2InputThread(struct bladerf* dev, unsigned int nbRxC
QThread(parent),
m_running(false),
m_dev(dev),
m_nbChannels(nbRxChannels)
m_nbChannels(nbRxChannels),
m_iqOrder(true)
{
qDebug("BladeRF2InputThread::BladeRF2InputThread");
m_channels = new Channel[nbRxChannels];
@@ -105,10 +106,17 @@ void BladeRF2InputThread::run()
break;
}
if (m_nbChannels > 1) {
if (m_nbChannels > 1)
{
callbackMI(m_buf, DeviceBladeRF2::blockSize);
} else {
callbackSI(m_buf, 2*DeviceBladeRF2::blockSize);
}
else
{
if (m_iqOrder) {
callbackSIIQ(m_buf, 2*DeviceBladeRF2::blockSize);
} else {
callbackSIQI(m_buf, 2*DeviceBladeRF2::blockSize);
}
}
}
qDebug("BladeRF2InputThread::run: stop running loop");
@@ -198,19 +206,24 @@ void BladeRF2InputThread::callbackMI(const qint16* buf, qint32 samplesPerChannel
for (unsigned int channel = 0; channel < m_nbChannels; channel++)
{
if (m_channels[channel].m_sampleFifo) {
callbackSI(&buf[2*samplesPerChannel*channel], 2*samplesPerChannel, channel);
if (m_channels[channel].m_sampleFifo)
{
if (m_iqOrder) {
callbackSIIQ(&buf[2*samplesPerChannel*channel], 2*samplesPerChannel, channel);
} else {
callbackSIQI(&buf[2*samplesPerChannel*channel], 2*samplesPerChannel, channel);
}
}
}
}
void BladeRF2InputThread::callbackSI(const qint16* buf, qint32 len, unsigned int channel)
void BladeRF2InputThread::callbackSIIQ(const qint16* buf, qint32 len, unsigned int channel)
{
SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
if (m_channels[channel].m_log2Decim == 0)
{
m_channels[channel].m_decimators.decimate1(&it, buf, len);
m_channels[channel].m_decimatorsIQ.decimate1(&it, buf, len);
}
else
{
@@ -219,22 +232,22 @@ void BladeRF2InputThread::callbackSI(const qint16* buf, qint32 len, unsigned int
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators.decimate2_inf(&it, buf, len);
m_channels[channel].m_decimatorsIQ.decimate2_inf(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators.decimate4_inf(&it, buf, len);
m_channels[channel].m_decimatorsIQ.decimate4_inf(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators.decimate8_inf(&it, buf, len);
m_channels[channel].m_decimatorsIQ.decimate8_inf(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators.decimate16_inf(&it, buf, len);
m_channels[channel].m_decimatorsIQ.decimate16_inf(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators.decimate32_inf(&it, buf, len);
m_channels[channel].m_decimatorsIQ.decimate32_inf(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators.decimate64_inf(&it, buf, len);
m_channels[channel].m_decimatorsIQ.decimate64_inf(&it, buf, len);
break;
default:
break;
@@ -245,22 +258,22 @@ void BladeRF2InputThread::callbackSI(const qint16* buf, qint32 len, unsigned int
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators.decimate2_sup(&it, buf, len);
m_channels[channel].m_decimatorsIQ.decimate2_sup(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators.decimate4_sup(&it, buf, len);
m_channels[channel].m_decimatorsIQ.decimate4_sup(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators.decimate8_sup(&it, buf, len);
m_channels[channel].m_decimatorsIQ.decimate8_sup(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators.decimate16_sup(&it, buf, len);
m_channels[channel].m_decimatorsIQ.decimate16_sup(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators.decimate32_sup(&it, buf, len);
m_channels[channel].m_decimatorsIQ.decimate32_sup(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators.decimate64_sup(&it, buf, len);
m_channels[channel].m_decimatorsIQ.decimate64_sup(&it, buf, len);
break;
default:
break;
@@ -271,22 +284,22 @@ void BladeRF2InputThread::callbackSI(const qint16* buf, qint32 len, unsigned int
switch (m_channels[channel].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;
@@ -297,3 +310,95 @@ void BladeRF2InputThread::callbackSI(const qint16* buf, qint32 len, unsigned int
m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
}
void BladeRF2InputThread::callbackSIQI(const qint16* buf, qint32 len, unsigned int channel)
{
SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
if (m_channels[channel].m_log2Decim == 0)
{
m_channels[channel].m_decimatorsQI.decimate1(&it, buf, len);
}
else
{
if (m_channels[channel].m_fcPos == 0) // Infra
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimatorsQI.decimate2_inf(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimatorsQI.decimate4_inf(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimatorsQI.decimate8_inf(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimatorsQI.decimate16_inf(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimatorsQI.decimate32_inf(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimatorsQI.decimate64_inf(&it, buf, len);
break;
default:
break;
}
}
else if (m_channels[channel].m_fcPos == 1) // Supra
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimatorsQI.decimate2_sup(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimatorsQI.decimate4_sup(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimatorsQI.decimate8_sup(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimatorsQI.decimate16_sup(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimatorsQI.decimate32_sup(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimatorsQI.decimate64_sup(&it, buf, len);
break;
default:
break;
}
}
else if (m_channels[channel].m_fcPos == 2) // Center
{
switch (m_channels[channel].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;
}
}
}
m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
}
@@ -51,6 +51,7 @@ public:
int getFcPos(unsigned int channel) const;
void setFifo(unsigned int channel, SampleSinkFifo *sampleFifo);
SampleSinkFifo *getFifo(unsigned int channel);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
struct Channel
@@ -59,7 +60,8 @@ private:
SampleSinkFifo* m_sampleFifo;
unsigned int m_log2Decim;
int m_fcPos;
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;
Channel() :
m_sampleFifo(0),
@@ -79,10 +81,12 @@ private:
Channel *m_channels; //!< Array of channels dynamically allocated for the given number of Rx channels
qint16 *m_buf; //!< Full buffer for SISO or MIMO operation
unsigned int m_nbChannels;
bool m_iqOrder;
void run();
unsigned int getNbFifos();
void callbackSI(const qint16* buf, qint32 len, unsigned int channel = 0);
void callbackSIIQ(const qint16* buf, qint32 len, unsigned int channel = 0);
void callbackSIQI(const qint16* buf, qint32 len, unsigned int channel = 0);
void callbackMI(const qint16* buf, qint32 samplesPerChannel);
};
+17 -3
View File
@@ -46,7 +46,7 @@ FCDProInput::FCDProInput(DeviceAPI *deviceAPI) :
m_fileSink(nullptr),
m_dev(0),
m_settings(),
m_FCDThread(0),
m_FCDThread(nullptr),
m_deviceDescription(fcd_traits<Pro>::displayedName),
m_running(false)
{
@@ -140,6 +140,9 @@ bool FCDProInput::start()
}
m_FCDThread = new FCDProThread(&m_sampleFifo, &m_fcdFIFO);
m_FCDThread->setLog2Decimation(m_settings.m_log2Decim);
m_FCDThread->setFcPos(m_settings.m_fcPos);
m_FCDThread->setIQOrder(m_settings.m_iqOrder);
m_FCDThread->startWork();
// mutexLocker.unlock();
@@ -386,7 +389,7 @@ void FCDProInput::applySettings(const FCDProSettings& settings, bool force)
reverseAPIKeys.append("log2Decim");
forwardChange = true;
if (m_FCDThread != 0)
if (m_FCDThread)
{
m_FCDThread->setLog2Decimation(settings.m_log2Decim);
qDebug() << "FCDProInput::applySettings: set decimation to " << (1<<settings.m_log2Decim);
@@ -397,13 +400,24 @@ void FCDProInput::applySettings(const FCDProSettings& settings, bool force)
{
reverseAPIKeys.append("fcPos");
if (m_FCDThread != 0) {
if (m_FCDThread) {
m_FCDThread->setFcPos((int) settings.m_fcPos);
}
qDebug() << "FCDProInput::applySettings: set fc pos (enum) to " << (int) settings.m_fcPos;
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
reverseAPIKeys.append("iqOrder");
if (m_FCDThread) {
m_FCDThread->setIQOrder((int) settings.m_iqOrder);
}
qDebug() << "FCDProInput::applySettings: set IQ order to %s" << (settings.m_iqOrder ? "IQ" : "QI");
}
if ((m_settings.m_lnaGainIndex != settings.m_lnaGainIndex) || force)
{
reverseAPIKeys.append("lnaGainIndex");
@@ -50,6 +50,7 @@ void FCDProSettings::resetToDefaults()
m_fcPos = FC_POS_CENTER;
m_transverterMode = false;
m_transverterDeltaFrequency = 0;
m_iqOrder = true;
m_fileRecordName = "";
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
@@ -88,6 +89,7 @@ QByteArray FCDProSettings::serialize() const
s.writeString(25, m_reverseAPIAddress);
s.writeU32(26, m_reverseAPIPort);
s.writeU32(27, m_reverseAPIDeviceIndex);
s.writeBool(28, m_iqOrder);
return s.final();
}
@@ -143,6 +145,7 @@ bool FCDProSettings::deserialize(const QByteArray& data)
d.readU32(27, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
d.readBool(28, &m_iqOrder, true);
return true;
}
@@ -51,6 +51,7 @@ struct FCDProSettings {
bool m_iqCorrection;
bool m_transverterMode;
qint64 m_transverterDeltaFrequency;
bool m_iqOrder;
QString m_fileRecordName;
bool m_useReverseAPI;
QString m_reverseAPIAddress;
+122 -22
View File
@@ -34,7 +34,8 @@ FCDProThread::FCDProThread(SampleSinkFifo* sampleFifo, AudioFifo *fcdFIFO, QObje
m_log2Decim(0),
m_fcPos(2),
m_convertBuffer(fcd_traits<Pro>::convBufSize), // nb samples
m_sampleFifo(sampleFifo)
m_sampleFifo(sampleFifo),
m_iqOrder(true)
{
start();
}
@@ -80,7 +81,12 @@ void FCDProThread::run()
while (m_running)
{
work(fcd_traits<Pro>::convBufSize);
if (m_iqOrder) {
workIQ(fcd_traits<Pro>::convBufSize);
} else {
workQI(fcd_traits<Pro>::convBufSize);
}
std::this_thread::sleep_for(std::chrono::microseconds(200));
}
@@ -88,14 +94,14 @@ void FCDProThread::run()
m_running = false;
}
void FCDProThread::work(unsigned int n_items)
void FCDProThread::workIQ(unsigned int n_items)
{
uint32_t nbRead = m_fcdFIFO->read((unsigned char *) m_buf, n_items); // number of samples
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimators.decimate1(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate1(&it, m_buf, 2*nbRead);
}
else
{
@@ -104,22 +110,22 @@ void FCDProThread::work(unsigned int n_items)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_inf(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate2_inf(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimators.decimate4_inf(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate4_inf(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimators.decimate8_inf(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate8_inf(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimators.decimate16_inf(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate16_inf(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimators.decimate32_inf(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate32_inf(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimators.decimate64_inf(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate64_inf(&it, m_buf, 2*nbRead);
break;
default:
break;
@@ -130,22 +136,22 @@ void FCDProThread::work(unsigned int n_items)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_sup(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate2_sup(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimators.decimate4_sup(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate4_sup(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimators.decimate8_sup(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate8_sup(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimators.decimate16_sup(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate16_sup(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimators.decimate32_sup(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate32_sup(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimators.decimate64_sup(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate64_sup(&it, m_buf, 2*nbRead);
break;
default:
break;
@@ -156,22 +162,116 @@ void FCDProThread::work(unsigned int n_items)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_cen(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate2_cen(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimators.decimate4_cen(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate4_cen(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimators.decimate8_cen(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate8_cen(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimators.decimate16_cen(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate16_cen(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimators.decimate32_cen(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate32_cen(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimators.decimate64_cen(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate64_cen(&it, m_buf, 2*nbRead);
break;
default:
break;
}
}
}
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
void FCDProThread::workQI(unsigned int n_items)
{
uint32_t nbRead = m_fcdFIFO->read((unsigned char *) m_buf, n_items); // number of samples
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimatorsQI.decimate1(&it, m_buf, 2*nbRead);
}
else
{
if (m_fcPos == 0) // Infradyne
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_inf(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimatorsQI.decimate4_inf(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimatorsQI.decimate8_inf(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimatorsQI.decimate16_inf(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimatorsQI.decimate32_inf(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimatorsQI.decimate64_inf(&it, m_buf, 2*nbRead);
break;
default:
break;
}
}
else if (m_fcPos == 1) // Supradyne
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_sup(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimatorsQI.decimate4_sup(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimatorsQI.decimate8_sup(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimatorsQI.decimate16_sup(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimatorsQI.decimate32_sup(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimatorsQI.decimate64_sup(&it, m_buf, 2*nbRead);
break;
default:
break;
}
}
else // Centered
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_cen(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimatorsQI.decimate4_cen(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimatorsQI.decimate8_cen(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimatorsQI.decimate16_cen(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimatorsQI.decimate32_cen(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimatorsQI.decimate64_cen(&it, m_buf, 2*nbRead);
break;
default:
break;
+7 -2
View File
@@ -39,6 +39,7 @@ public:
void stopWork();
void setLog2Decimation(unsigned int log2_decim);
void setFcPos(int fcPos);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
AudioFifo* m_fcdFIFO;
@@ -48,14 +49,18 @@ private:
bool m_running;
unsigned int m_log2Decim;
int m_fcPos;
bool m_iqOrder;
qint16 m_buf[fcd_traits<Pro>::convBufSize*2]; // stereo (I, Q)
SampleVector m_convertBuffer;
SampleSinkFifo* m_sampleFifo;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 16> m_decimators;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 16, true> m_decimatorsIQ;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 16, false> m_decimatorsQI;
void run();
void work(unsigned int n_items);
void workIQ(unsigned int n_items);
void workQI(unsigned int n_items);
};
#endif // INCLUDE_FCDPROTHREAD_H
@@ -46,7 +46,7 @@ FCDProPlusInput::FCDProPlusInput(DeviceAPI *deviceAPI) :
m_fileSink(nullptr),
m_dev(0),
m_settings(),
m_FCDThread(0),
m_FCDThread(nullptr),
m_deviceDescription(fcd_traits<ProPlus>::displayedName),
m_running(false)
{
@@ -142,6 +142,9 @@ bool FCDProPlusInput::start()
}
m_FCDThread = new FCDProPlusThread(&m_sampleFifo, &m_fcdFIFO);
m_FCDThread->setLog2Decimation(m_settings.m_log2Decim);
m_FCDThread->setFcPos(m_settings.m_fcPos);
m_FCDThread->setIQOrder(m_settings.m_iqOrder);
m_FCDThread->startWork();
// mutexLocker.unlock();
@@ -387,7 +390,7 @@ void FCDProPlusInput::applySettings(const FCDProPlusSettings& settings, bool for
reverseAPIKeys.append("log2Decim");
forwardChange = true;
if (m_FCDThread != 0)
if (m_FCDThread)
{
m_FCDThread->setLog2Decimation(settings.m_log2Decim);
qDebug() << "FCDProPlusInput::applySettings: set decimation to " << (1<<settings.m_log2Decim);
@@ -398,13 +401,24 @@ void FCDProPlusInput::applySettings(const FCDProPlusSettings& settings, bool for
{
reverseAPIKeys.append("fcPos");
if (m_FCDThread != 0) {
if (m_FCDThread) {
m_FCDThread->setFcPos((int) settings.m_fcPos);
}
qDebug() << "FCDProPlusInput::applySettings: set fc pos (enum) to " << (int) settings.m_fcPos;
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
reverseAPIKeys.append("iqOrder");
if (m_FCDThread) {
m_FCDThread->setIQOrder((int) settings.m_iqOrder);
}
qDebug() << "FCDProPlusInput::applySettings: set IQ order to %s" << (settings.m_iqOrder ? "IQ" : "QI");
}
if ((m_settings.m_lnaGain != settings.m_lnaGain) || force)
{
reverseAPIKeys.append("lnaGain");
@@ -41,6 +41,7 @@ void FCDProPlusSettings::resetToDefaults()
m_iqImbalance = false;
m_transverterMode = false;
m_transverterDeltaFrequency = 0;
m_iqOrder = true;
m_fileRecordName = "";
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
@@ -69,6 +70,7 @@ QByteArray FCDProPlusSettings::serialize() const
s.writeString(15, m_reverseAPIAddress);
s.writeU32(16, m_reverseAPIPort);
s.writeU32(17, m_reverseAPIDeviceIndex);
s.writeBool(18, m_iqOrder);
return s.final();
}
@@ -114,6 +116,8 @@ bool FCDProPlusSettings::deserialize(const QByteArray& data)
d.readU32(17, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
d.readBool(18, &m_iqOrder, true);
return true;
}
else
@@ -42,6 +42,7 @@ struct FCDProPlusSettings {
bool m_iqImbalance;
bool m_transverterMode;
qint64 m_transverterDeltaFrequency;
bool m_iqOrder;
QString m_fileRecordName;
bool m_useReverseAPI;
QString m_reverseAPIAddress;
@@ -33,7 +33,8 @@ FCDProPlusThread::FCDProPlusThread(SampleSinkFifo* sampleFifo, AudioFifo *fcdFIF
m_log2Decim(0),
m_fcPos(2),
m_convertBuffer(fcd_traits<ProPlus>::convBufSize), // nb samples
m_sampleFifo(sampleFifo)
m_sampleFifo(sampleFifo),
m_iqOrder(true)
{
start();
}
@@ -79,7 +80,12 @@ void FCDProPlusThread::run()
while (m_running)
{
work(fcd_traits<ProPlus>::convBufSize);
if (m_iqOrder) {
workIQ(fcd_traits<ProPlus>::convBufSize);
} else {
workQI(fcd_traits<ProPlus>::convBufSize);
}
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
@@ -87,14 +93,14 @@ void FCDProPlusThread::run()
m_running = false;
}
void FCDProPlusThread::work(unsigned int n_items)
void FCDProPlusThread::workIQ(unsigned int n_items)
{
uint32_t nbRead = m_fcdFIFO->read((unsigned char *) m_buf, n_items); // number of samples
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimators.decimate1(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate1(&it, m_buf, 2*nbRead);
}
else
{
@@ -103,22 +109,22 @@ void FCDProPlusThread::work(unsigned int n_items)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_inf(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate2_inf(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimators.decimate4_inf(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate4_inf(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimators.decimate8_inf(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate8_inf(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimators.decimate16_inf(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate16_inf(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimators.decimate32_inf(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate32_inf(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimators.decimate64_inf(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate64_inf(&it, m_buf, 2*nbRead);
break;
default:
break;
@@ -129,22 +135,22 @@ void FCDProPlusThread::work(unsigned int n_items)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_sup(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate2_sup(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimators.decimate4_sup(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate4_sup(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimators.decimate8_sup(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate8_sup(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimators.decimate16_sup(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate16_sup(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimators.decimate32_sup(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate32_sup(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimators.decimate64_sup(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate64_sup(&it, m_buf, 2*nbRead);
break;
default:
break;
@@ -155,22 +161,116 @@ void FCDProPlusThread::work(unsigned int n_items)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_cen(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate2_cen(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimators.decimate4_cen(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate4_cen(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimators.decimate8_cen(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate8_cen(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimators.decimate16_cen(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate16_cen(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimators.decimate32_cen(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate32_cen(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimators.decimate64_cen(&it, m_buf, 2*nbRead);
m_decimatorsIQ.decimate64_cen(&it, m_buf, 2*nbRead);
break;
default:
break;
}
}
}
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
void FCDProPlusThread::workQI(unsigned int n_items)
{
uint32_t nbRead = m_fcdFIFO->read((unsigned char *) m_buf, n_items); // number of samples
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimatorsQI.decimate1(&it, m_buf, 2*nbRead);
}
else
{
if (m_fcPos == 0) // Infradyne
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_inf(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimatorsQI.decimate4_inf(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimatorsQI.decimate8_inf(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimatorsQI.decimate16_inf(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimatorsQI.decimate32_inf(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimatorsQI.decimate64_inf(&it, m_buf, 2*nbRead);
break;
default:
break;
}
}
else if (m_fcPos == 1) // Supradyne
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_sup(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimatorsQI.decimate4_sup(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimatorsQI.decimate8_sup(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimatorsQI.decimate16_sup(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimatorsQI.decimate32_sup(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimatorsQI.decimate64_sup(&it, m_buf, 2*nbRead);
break;
default:
break;
}
}
else // Centered
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_cen(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimatorsQI.decimate4_cen(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimatorsQI.decimate8_cen(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimatorsQI.decimate16_cen(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimatorsQI.decimate32_cen(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimatorsQI.decimate64_cen(&it, m_buf, 2*nbRead);
break;
default:
break;
@@ -40,6 +40,7 @@ public:
void stopWork();
void setLog2Decimation(unsigned int log2_decim);
void setFcPos(int fcPos);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
AudioFifo* m_fcdFIFO;
@@ -49,13 +50,16 @@ private:
bool m_running;
unsigned int m_log2Decim;
int m_fcPos;
bool m_iqOrder;
qint16 m_buf[fcd_traits<ProPlus>::convBufSize*2]; // stereo (I, Q)
SampleVector m_convertBuffer;
SampleSinkFifo* m_sampleFifo;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 16> m_decimators;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 16, true> m_decimatorsIQ;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 16, false> m_decimatorsQI;
void run();
void work(unsigned int n_items);
void workIQ(unsigned int n_items);
void workQI(unsigned int n_items);
};
#endif // INCLUDE_FCDTHREAD_H
@@ -47,8 +47,8 @@ HackRFInput::HackRFInput(DeviceAPI *deviceAPI) :
m_deviceAPI(deviceAPI),
m_fileSink(nullptr),
m_settings(),
m_dev(0),
m_hackRFThread(0),
m_dev(nullptr),
m_hackRFThread(nullptr),
m_deviceDescription("HackRF"),
m_running(false)
{
@@ -157,7 +157,7 @@ bool HackRFInput::start()
m_hackRFThread->setSamplerate(m_settings.m_devSampleRate);
m_hackRFThread->setLog2Decimation(m_settings.m_log2Decim);
m_hackRFThread->setFcPos((int) m_settings.m_fcPos);
m_hackRFThread->setIQOrder(m_settings.m_iqOrder);
m_hackRFThread->startWork();
qDebug("HackRFInput::startInput: started");
@@ -188,11 +188,11 @@ void HackRFInput::stop()
qDebug("HackRFInput::stop");
// QMutexLocker mutexLocker(&m_mutex);
if (m_hackRFThread != 0)
if (m_hackRFThread)
{
m_hackRFThread->stopWork();
delete m_hackRFThread;
m_hackRFThread = 0;
m_hackRFThread = nullptr;
}
m_running = false;
@@ -418,7 +418,7 @@ bool HackRFInput::applySettings(const HackRFInputSettings& settings, bool force)
}
else
{
if (m_hackRFThread != 0)
if (m_hackRFThread)
{
qDebug("HackRFInput::applySettings: sample rate set to %llu S/s", settings.m_devSampleRate);
m_hackRFThread->setSamplerate(settings.m_devSampleRate);
@@ -432,13 +432,22 @@ bool HackRFInput::applySettings(const HackRFInputSettings& settings, bool force)
reverseAPIKeys.append("log2Decim");
forwardChange = true;
if (m_hackRFThread != 0)
if (m_hackRFThread)
{
m_hackRFThread->setLog2Decimation(settings.m_log2Decim);
qDebug() << "HackRFInput: set decimation to " << (1<<settings.m_log2Decim);
}
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
reverseAPIKeys.append("iqOrder");
if (m_hackRFThread) {
m_hackRFThread->setIQOrder(settings.m_iqOrder);
}
}
if (force || (m_settings.m_centerFrequency != settings.m_centerFrequency)) {
reverseAPIKeys.append("centerFrequency");
}
@@ -486,7 +495,7 @@ bool HackRFInput::applySettings(const HackRFInputSettings& settings, bool force)
if ((m_settings.m_fcPos != settings.m_fcPos) || force)
{
if (m_hackRFThread != 0)
if (m_hackRFThread)
{
m_hackRFThread->setFcPos((int) settings.m_fcPos);
qDebug() << "HackRFInput: set fc pos (enum) to " << (int) settings.m_fcPos;
@@ -43,6 +43,7 @@ void HackRFInputSettings::resetToDefaults()
m_fileRecordName = "";
m_transverterMode = false;
m_transverterDeltaFrequency = 0;
m_iqOrder = true;
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
m_reverseAPIPort = 8888;
@@ -70,6 +71,7 @@ QByteArray HackRFInputSettings::serialize() const
s.writeU32(17, m_reverseAPIDeviceIndex);
s.writeBool(18, m_transverterMode);
s.writeS64(19, m_transverterDeltaFrequency);
s.writeBool(20, m_iqOrder);
return s.final();
}
@@ -115,6 +117,7 @@ bool HackRFInputSettings::deserialize(const QByteArray& data)
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
d.readBool(18, &m_transverterMode, false);
d.readS64(19, &m_transverterDeltaFrequency, 0);
d.readBool(20, &m_iqOrder, true);
return true;
}
@@ -43,6 +43,7 @@ struct HackRFInputSettings {
QString m_fileRecordName;
bool m_transverterMode;
qint64 m_transverterDeltaFrequency;
bool m_iqOrder;
bool m_useReverseAPI;
QString m_reverseAPIAddress;
uint16_t m_reverseAPIPort;
@@ -31,7 +31,8 @@ HackRFInputThread::HackRFInputThread(hackrf_device* dev, SampleSinkFifo* sampleF
m_sampleFifo(sampleFifo),
m_samplerate(10),
m_log2Decim(0),
m_fcPos(0)
m_fcPos(0),
m_iqOrder(true)
{
std::fill(m_buf, m_buf + 2*HACKRF_BLOCKSIZE, 0);
}
@@ -122,13 +123,13 @@ void HackRFInputThread::run()
}
// Decimate according to specified log2 (ex: log2=4 => decim=16)
void HackRFInputThread::callback(const qint8* buf, qint32 len)
void HackRFInputThread::callbackIQ(const qint8* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimators.decimate1(&it, buf, len);
m_decimatorsIQ.decimate1(&it, buf, len);
}
else
{
@@ -137,22 +138,22 @@ void HackRFInputThread::callback(const qint8* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_inf(&it, buf, len);
m_decimatorsIQ.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimators.decimate4_inf_txsync(&it, buf, len);
m_decimatorsIQ.decimate4_inf_txsync(&it, buf, len);
break;
case 3:
m_decimators.decimate8_inf_txsync(&it, buf, len);
m_decimatorsIQ.decimate8_inf_txsync(&it, buf, len);
break;
case 4:
m_decimators.decimate16_inf_txsync(&it, buf, len);
m_decimatorsIQ.decimate16_inf_txsync(&it, buf, len);
break;
case 5:
m_decimators.decimate32_inf_txsync(&it, buf, len);
m_decimatorsIQ.decimate32_inf_txsync(&it, buf, len);
break;
case 6:
m_decimators.decimate64_inf_txsync(&it, buf, len);
m_decimatorsIQ.decimate64_inf_txsync(&it, buf, len);
break;
default:
break;
@@ -163,22 +164,22 @@ void HackRFInputThread::callback(const qint8* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_sup(&it, buf, len);
m_decimatorsIQ.decimate2_sup(&it, buf, len);
break;
case 2:
m_decimators.decimate4_sup_txsync(&it, buf, len);
m_decimatorsIQ.decimate4_sup_txsync(&it, buf, len);
break;
case 3:
m_decimators.decimate8_sup_txsync(&it, buf, len);
m_decimatorsIQ.decimate8_sup_txsync(&it, buf, len);
break;
case 4:
m_decimators.decimate16_sup_txsync(&it, buf, len);
m_decimatorsIQ.decimate16_sup_txsync(&it, buf, len);
break;
case 5:
m_decimators.decimate32_sup_txsync(&it, buf, len);
m_decimatorsIQ.decimate32_sup_txsync(&it, buf, len);
break;
case 6:
m_decimators.decimate64_sup_txsync(&it, buf, len);
m_decimatorsIQ.decimate64_sup_txsync(&it, buf, len);
break;
default:
break;
@@ -189,22 +190,22 @@ void HackRFInputThread::callback(const qint8* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_cen(&it, buf, len);
m_decimatorsIQ.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimators.decimate4_cen(&it, buf, len);
m_decimatorsIQ.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimators.decimate8_cen(&it, buf, len);
m_decimatorsIQ.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimators.decimate16_cen(&it, buf, len);
m_decimatorsIQ.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimators.decimate32_cen(&it, buf, len);
m_decimatorsIQ.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimators.decimate64_cen(&it, buf, len);
m_decimatorsIQ.decimate64_cen(&it, buf, len);
break;
default:
break;
@@ -215,11 +216,109 @@ void HackRFInputThread::callback(const qint8* buf, qint32 len)
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
void HackRFInputThread::callbackQI(const qint8* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimatorsQI.decimate1(&it, buf, len);
}
else
{
if (m_fcPos == 0) // Infra
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_inf_txsync(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_inf_txsync(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_inf_txsync(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_inf_txsync(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_inf_txsync(&it, buf, len);
break;
default:
break;
}
}
else if (m_fcPos == 1) // Supra
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_sup(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_sup_txsync(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_sup_txsync(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_sup_txsync(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_sup_txsync(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_sup_txsync(&it, buf, len);
break;
default:
break;
}
}
else if (m_fcPos == 2) // Center
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_cen(&it, buf, len);
break;
default:
break;
}
}
}
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
int HackRFInputThread::rx_callback(hackrf_transfer* transfer)
{
HackRFInputThread *thread = (HackRFInputThread *) transfer->rx_ctx;
qint32 bytes_to_write = transfer->valid_length;
thread->callback((qint8 *) transfer->buffer, bytes_to_write);
return 0;
if (thread->m_iqOrder) {
thread->callbackIQ((qint8 *) transfer->buffer, bytes_to_write);
} else {
thread->callbackQI((qint8 *) transfer->buffer, bytes_to_write);
}
return 0;
}
@@ -40,6 +40,7 @@ public:
void setSamplerate(uint32_t samplerate);
void setLog2Decimation(unsigned int log2_decim);
void setFcPos(int fcPos);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
QMutex m_startWaitMutex;
@@ -54,11 +55,14 @@ private:
int m_samplerate;
unsigned int m_log2Decim;
int m_fcPos;
bool m_iqOrder;
Decimators<qint32, qint8, SDR_RX_SAMP_SZ, 8> m_decimators;
Decimators<qint32, qint8, SDR_RX_SAMP_SZ, 8, true> m_decimatorsIQ;
Decimators<qint32, qint8, SDR_RX_SAMP_SZ, 8, false> m_decimatorsQI;
void run();
void callback(const qint8* buf, qint32 len);
void callbackIQ(const qint8* buf, qint32 len);
void callbackQI(const qint8* buf, qint32 len);
static int rx_callback(hackrf_transfer* transfer);
};
@@ -54,7 +54,7 @@ LimeSDRInput::LimeSDRInput(DeviceAPI *deviceAPI) :
m_deviceAPI(deviceAPI),
m_fileSink(nullptr),
m_settings(),
m_limeSDRInputThread(0),
m_limeSDRInputThread(nullptr),
m_deviceDescription("LimeSDRInput"),
m_running(false),
m_channelAcquired(false)
@@ -425,7 +425,7 @@ bool LimeSDRInput::start()
applySettings(m_settings, true);
m_limeSDRInputThread->setLog2Decimation(m_settings.m_log2SoftDecim);
m_limeSDRInputThread->setIQOrder(m_settings.m_iqOrder);
m_limeSDRInputThread->startWork();
m_deviceShared.m_thread = m_limeSDRInputThread;
@@ -442,7 +442,7 @@ void LimeSDRInput::stop()
{
m_limeSDRInputThread->stopWork();
delete m_limeSDRInputThread;
m_limeSDRInputThread = 0;
m_limeSDRInputThread = nullptr;
}
m_deviceShared.m_thread = 0;
@@ -1109,6 +1109,15 @@ bool LimeSDRInput::applySettings(const LimeSDRInputSettings& settings, bool forc
}
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
reverseAPIKeys.append("iqOrder");
if (m_limeSDRInputThread) {
m_limeSDRInputThread->setIQOrder(settings.m_iqOrder);
}
}
if ((m_settings.m_antennaPath != settings.m_antennaPath) || force)
{
reverseAPIKeys.append("antennaPath");
@@ -46,6 +46,7 @@ void LimeSDRInputSettings::resetToDefaults()
m_extClockFreq = 10000000; // 10 MHz
m_transverterMode = false;
m_transverterDeltaFrequency = 0;
m_iqOrder = true;
m_fileRecordName = "";
m_gpioDir = 0;
m_gpioPins = 0;
@@ -85,6 +86,7 @@ QByteArray LimeSDRInputSettings::serialize() const
s.writeString(25, m_reverseAPIAddress);
s.writeU32(26, m_reverseAPIPort);
s.writeU32(27, m_reverseAPIDeviceIndex);
s.writeBool(28, m_iqOrder);
return s.final();
}
@@ -141,6 +143,7 @@ bool LimeSDRInputSettings::deserialize(const QByteArray& data)
d.readU32(27, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
d.readBool(28, &m_iqOrder, true);
return true;
}
@@ -66,6 +66,7 @@ struct LimeSDRInputSettings
uint32_t m_extClockFreq; //!< Frequency (Hz) of external clock source
bool m_transverterMode;
qint64 m_transverterDeltaFrequency;
bool m_iqOrder;
QString m_fileRecordName;
uint8_t m_gpioDir; //!< GPIO pin direction LSB first; 0 input, 1 output
uint8_t m_gpioPins; //!< GPIO pins to write; LSB first
@@ -27,7 +27,8 @@ LimeSDRInputThread::LimeSDRInputThread(lms_stream_t* stream, SampleSinkFifo* sam
m_stream(stream),
m_convertBuffer(DeviceLimeSDR::blockSize),
m_sampleFifo(sampleFifo),
m_log2Decim(0)
m_log2Decim(0),
m_iqOrder(true)
{
std::fill(m_buf, m_buf + 2*DeviceLimeSDR::blockSize, 0);
}
@@ -94,39 +95,43 @@ void LimeSDRInputThread::run()
break;
}
callback(m_buf, 2 * res);
if (m_iqOrder) {
callbackIQ(m_buf, 2 * res);
} else {
callbackQI(m_buf, 2 * res);
}
}
m_running = false;
}
// Decimate according to specified log2 (ex: log2=4 => decim=16)
void LimeSDRInputThread::callback(const qint16* buf, qint32 len)
void LimeSDRInputThread::callbackIQ(const qint16* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
switch (m_log2Decim)
{
case 0:
m_decimators.decimate1(&it, buf, len);
m_decimatorsIQ.decimate1(&it, buf, len);
break;
case 1:
m_decimators.decimate2_cen(&it, buf, len);
m_decimatorsIQ.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimators.decimate4_cen(&it, buf, len);
m_decimatorsIQ.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimators.decimate8_cen(&it, buf, len);
m_decimatorsIQ.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimators.decimate16_cen(&it, buf, len);
m_decimatorsIQ.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimators.decimate32_cen(&it, buf, len);
m_decimatorsIQ.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimators.decimate64_cen(&it, buf, len);
m_decimatorsIQ.decimate64_cen(&it, buf, len);
break;
default:
break;
@@ -135,3 +140,36 @@ void LimeSDRInputThread::callback(const qint16* buf, qint32 len)
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
void LimeSDRInputThread::callbackQI(const qint16* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
switch (m_log2Decim)
{
case 0:
m_decimatorsQI.decimate1(&it, buf, len);
break;
case 1:
m_decimatorsQI.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_cen(&it, buf, len);
break;
default:
break;
}
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
@@ -42,6 +42,7 @@ public:
virtual void setDeviceSampleRate(int sampleRate) { (void) sampleRate; }
virtual bool isRunning() { return m_running; }
void setLog2Decimation(unsigned int log2_decim);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
QMutex m_startWaitMutex;
@@ -54,11 +55,14 @@ private:
SampleSinkFifo* m_sampleFifo;
unsigned int m_log2Decim; // soft decimation
bool m_iqOrder;
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;
void run();
void callback(const qint16* buf, qint32 len);
void callbackIQ(const qint16* buf, qint32 len);
void callbackQI(const qint16* buf, qint32 len);
};
+14 -4
View File
@@ -44,7 +44,7 @@ PerseusInput::PerseusInput(DeviceAPI *deviceAPI) :
m_fileSink(nullptr),
m_deviceDescription("PerseusInput"),
m_running(false),
m_perseusThread(0),
m_perseusThread(nullptr),
m_perseusDescriptor(0)
{
openDevice();
@@ -88,6 +88,7 @@ bool PerseusInput::start()
applySettings(m_settings, true);
m_perseusThread->setIQOrder(m_settings.m_iqOrder);
m_perseusThread->setLog2Decimation(m_settings.m_log2Decim);
m_perseusThread->startWork();
@@ -98,11 +99,11 @@ bool PerseusInput::start()
void PerseusInput::stop()
{
if (m_perseusThread != 0)
if (m_perseusThread)
{
m_perseusThread->stopWork();
delete m_perseusThread;
m_perseusThread = 0;
m_perseusThread = nullptr;
}
m_running = false;
@@ -353,13 +354,22 @@ bool PerseusInput::applySettings(const PerseusSettings& settings, bool force)
reverseAPIKeys.append("log2Decim");
forwardChange = true;
if (m_perseusThread != 0)
if (m_perseusThread)
{
m_perseusThread->setLog2Decimation(settings.m_log2Decim);
qDebug("PerseusInput: set decimation to %d", (1<<settings.m_log2Decim));
}
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
reverseAPIKeys.append("iqOrder");
if (m_perseusThread) {
m_perseusThread->setIQOrder(settings.m_iqOrder);
}
}
if (force || (m_settings.m_centerFrequency != settings.m_centerFrequency)) {
reverseAPIKeys.append("centerFrequency");
}
@@ -32,6 +32,7 @@ void PerseusSettings::resetToDefaults()
m_log2Decim = 0;
m_transverterMode = false;
m_transverterDeltaFrequency = 0;
m_iqOrder = true;
m_adcDither = false;
m_adcPreamp = false;
m_wideBand = false;
@@ -60,6 +61,7 @@ QByteArray PerseusSettings::serialize() const
s.writeString(11, m_reverseAPIAddress);
s.writeU32(12, m_reverseAPIPort);
s.writeU32(13, m_reverseAPIDeviceIndex);
s.writeBool(14, m_iqOrder);
return s.final();
}
@@ -107,6 +109,7 @@ bool PerseusSettings::deserialize(const QByteArray& data)
d.readU32(13, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
d.readBool(14, &m_iqOrder, true);
return true;
}
@@ -38,6 +38,7 @@ struct PerseusSettings
quint32 m_log2Decim;
bool m_transverterMode;
qint64 m_transverterDeltaFrequency;
bool m_iqOrder;
bool m_adcDither;
bool m_adcPreamp;
bool m_wideBand;
+36 -7
View File
@@ -27,7 +27,8 @@ PerseusThread::PerseusThread(perseus_descr* dev, SampleSinkFifo* sampleFifo, QOb
m_dev(dev),
m_convertBuffer(PERSEUS_NBSAMPLES),
m_sampleFifo(sampleFifo),
m_log2Decim(0)
m_log2Decim(0),
m_iqOrder(true)
{
m_this = this;
std::fill(m_buf, m_buf + 2*PERSEUS_NBSAMPLES, 0);
@@ -90,20 +91,42 @@ void PerseusThread::run()
m_running = false;
}
void PerseusThread::callback(const uint8_t* buf, qint32 len)
void PerseusThread::callbackIQ(const uint8_t* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
switch (m_log2Decim)
{
case 0:
m_decimators32.decimate1(&it, (TripleByteLE<qint32>*) buf, len);
m_decimators32IQ.decimate1(&it, (TripleByteLE<qint32>*) buf, len);
break;
case 1:
m_decimators64.decimate2_cen(&it, (TripleByteLE<qint64>*) buf, len);
m_decimators64IQ.decimate2_cen(&it, (TripleByteLE<qint64>*) buf, len);
break;
case 2:
m_decimators64.decimate4_cen(&it, (TripleByteLE<qint64>*) buf, len);
m_decimators64IQ.decimate4_cen(&it, (TripleByteLE<qint64>*) buf, len);
break;
default:
break;
}
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
void PerseusThread::callbackQI(const uint8_t* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
switch (m_log2Decim)
{
case 0:
m_decimators32QI.decimate1(&it, (TripleByteLE<qint32>*) buf, len);
break;
case 1:
m_decimators64QI.decimate2_cen(&it, (TripleByteLE<qint64>*) buf, len);
break;
case 2:
m_decimators64QI.decimate4_cen(&it, (TripleByteLE<qint64>*) buf, len);
break;
default:
break;
@@ -116,7 +139,13 @@ int PerseusThread::rx_callback(void *buf, int buf_size, void *extra)
{
(void) extra;
qint32 nbIAndQ = buf_size / 3; // 3 bytes per I or Q
m_this->callback((uint8_t*) buf, nbIAndQ);
return 0;
if (m_this->m_iqOrder) {
m_this->callbackIQ((uint8_t*) buf, nbIAndQ);
} else {
m_this->callbackQI((uint8_t*) buf, nbIAndQ);
}
return 0;
}
+8 -3
View File
@@ -39,6 +39,7 @@ public:
void startWork();
void stopWork();
void setLog2Decimation(unsigned int log2_decim);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
QMutex m_startWaitMutex;
@@ -51,13 +52,17 @@ private:
SampleSinkFifo* m_sampleFifo;
unsigned int m_log2Decim;
bool m_iqOrder;
static PerseusThread *m_this;
Decimators<qint32, TripleByteLE<qint32>, SDR_RX_SAMP_SZ, 24> m_decimators32; // for no decimation (accumulator is int32)
Decimators<qint32, TripleByteLE<qint64>, SDR_RX_SAMP_SZ, 24> m_decimators64; // for actual decimation (accumulator is int64)
Decimators<qint32, TripleByteLE<qint32>, SDR_RX_SAMP_SZ, 24, true> m_decimators32IQ; // for no decimation (accumulator is int32)
Decimators<qint32, TripleByteLE<qint64>, SDR_RX_SAMP_SZ, 24, true> m_decimators64IQ; // for actual decimation (accumulator is int64)
Decimators<qint32, TripleByteLE<qint32>, SDR_RX_SAMP_SZ, 24, false> m_decimators32QI; // for no decimation (accumulator is int32)
Decimators<qint32, TripleByteLE<qint64>, SDR_RX_SAMP_SZ, 24, false> m_decimators64QI; // for actual decimation (accumulator is int64)
void run();
void callback(const uint8_t* buf, qint32 len); // inner call back
void callbackIQ(const uint8_t* buf, qint32 len); // inner call back
void callbackQI(const uint8_t* buf, qint32 len);
static int rx_callback(void *buf, int buf_size, void *extra); // call back from Perseus
};
@@ -48,7 +48,7 @@ PlutoSDRInput::PlutoSDRInput(DeviceAPI *deviceAPI) :
m_deviceDescription("PlutoSDRInput"),
m_running(false),
m_plutoRxBuffer(0),
m_plutoSDRInputThread(0)
m_plutoSDRInputThread(nullptr)
{
m_deviceSampleRates.m_addaConnvRate = 0;
m_deviceSampleRates.m_bbRateHz = 0;
@@ -118,6 +118,7 @@ bool PlutoSDRInput::start()
applySettings(m_settings, true);
m_plutoSDRInputThread->setLog2Decimation(m_settings.m_log2Decim);
m_plutoSDRInputThread->setIQOrder(m_settings.m_iqOrder);
m_plutoSDRInputThread->startWork();
m_deviceShared.m_thread = m_plutoSDRInputThread;
@@ -128,14 +129,14 @@ bool PlutoSDRInput::start()
void PlutoSDRInput::stop()
{
if (m_plutoSDRInputThread != 0)
if (m_plutoSDRInputThread)
{
m_plutoSDRInputThread->stopWork();
delete m_plutoSDRInputThread;
m_plutoSDRInputThread = 0;
m_plutoSDRInputThread = nullptr;
}
m_deviceShared.m_thread = 0;
m_deviceShared.m_thread = nullptr;
m_running = false;
}
@@ -598,7 +599,7 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo
if ((m_settings.m_log2Decim != settings.m_log2Decim) || force)
{
if (m_plutoSDRInputThread != 0)
if (m_plutoSDRInputThread)
{
m_plutoSDRInputThread->setLog2Decimation(settings.m_log2Decim);
qDebug() << "PlutoSDRInput::applySettings: set soft decimation to " << (1<<settings.m_log2Decim);
@@ -607,6 +608,13 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo
forwardChangeOwnDSP = true;
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
if (m_plutoSDRInputThread) {
m_plutoSDRInputThread->setIQOrder(settings.m_iqOrder);
}
}
if ((m_settings.m_LOppmTenths != settings.m_LOppmTenths) || force)
{
plutoBox->setLOPPMTenths(settings.m_LOppmTenths);
@@ -638,7 +646,7 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo
if ((m_settings.m_fcPos != settings.m_fcPos) || force)
{
if (m_plutoSDRInputThread != 0)
if (m_plutoSDRInputThread)
{
m_plutoSDRInputThread->setFcPos(settings.m_fcPos);
qDebug() << "PlutoSDRInput::applySettings: set fcPos to " << settings.m_fcPos;
@@ -48,6 +48,7 @@ void PlutoSDRInputSettings::resetToDefaults()
m_gainMode = GAIN_MANUAL;
m_transverterMode = false;
m_transverterDeltaFrequency = 0;
m_iqOrder = true;
m_fileRecordName = "";
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
@@ -82,6 +83,7 @@ QByteArray PlutoSDRInputSettings::serialize() const
s.writeBool(22, m_hwBBDCBlock);
s.writeBool(23, m_hwRFDCBlock);
s.writeBool(24, m_hwIQCorrection);
s.writeBool(25, m_iqOrder);
return s.final();
}
@@ -153,6 +155,7 @@ bool PlutoSDRInputSettings::deserialize(const QByteArray& data)
d.readBool(22, &m_hwBBDCBlock, true);
d.readBool(23, &m_hwRFDCBlock, true);
d.readBool(24, &m_hwIQCorrection, true);
d.readBool(25, &m_iqOrder, true);
return true;
}
@@ -78,6 +78,7 @@ struct PlutoSDRInputSettings {
GainMode m_gainMode;
bool m_transverterMode;
qint64 m_transverterDeltaFrequency;
bool m_iqOrder;
QString m_fileRecordName;
bool m_useReverseAPI;
QString m_reverseAPIAddress;
@@ -31,7 +31,8 @@ PlutoSDRInputThread::PlutoSDRInputThread(uint32_t blocksizeSamples, DevicePlutoS
m_sampleFifo(sampleFifo),
m_log2Decim(0),
m_fcPos(PlutoSDRInputSettings::FC_POS_CENTER),
m_phasor(0)
m_phasor(0),
m_iqOrder(true)
{
m_buf = new qint16[blocksizeSamples*2]; // (I,Q) -> 2 * int16_t
m_bufConv = new qint16[blocksizeSamples*2]; // (I,Q) -> 2 * int16_t
@@ -139,21 +140,24 @@ void PlutoSDRInputThread::run()
ihs++;
}
//m_sampleFifo->write((unsigned char *) m_buf, ihs*sizeof(int16_t));
convert(m_buf, 2*m_blockSizeSamples); // size given in number of int16_t (I and Q interleaved)
if (m_iqOrder) {
convertIQ(m_buf, 2*m_blockSizeSamples); // size given in number of int16_t (I and Q interleaved)
} else {
convertQI(m_buf, 2*m_blockSizeSamples);
}
}
m_running = false;
}
// Decimate according to specified log2 (ex: log2=4 => decim=16)
void PlutoSDRInputThread::convert(const qint16* buf, qint32 len)
void PlutoSDRInputThread::convertIQ(const qint16* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimators.decimate1(&it, buf, len);
m_decimatorsIQ.decimate1(&it, buf, len);
}
else
{
@@ -162,22 +166,22 @@ void PlutoSDRInputThread::convert(const qint16* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_inf(&it, buf, len);
m_decimatorsIQ.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimators.decimate4_inf(&it, buf, len);
m_decimatorsIQ.decimate4_inf(&it, buf, len);
break;
case 3:
m_decimators.decimate8_inf(&it, buf, len);
m_decimatorsIQ.decimate8_inf(&it, buf, len);
break;
case 4:
m_decimators.decimate16_inf(&it, buf, len);
m_decimatorsIQ.decimate16_inf(&it, buf, len);
break;
case 5:
m_decimators.decimate32_inf(&it, buf, len);
m_decimatorsIQ.decimate32_inf(&it, buf, len);
break;
case 6:
m_decimators.decimate64_inf(&it, buf, len);
m_decimatorsIQ.decimate64_inf(&it, buf, len);
break;
default:
break;
@@ -188,22 +192,22 @@ void PlutoSDRInputThread::convert(const qint16* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_sup(&it, buf, len);
m_decimatorsIQ.decimate2_sup(&it, buf, len);
break;
case 2:
m_decimators.decimate4_sup(&it, buf, len);
m_decimatorsIQ.decimate4_sup(&it, buf, len);
break;
case 3:
m_decimators.decimate8_sup(&it, buf, len);
m_decimatorsIQ.decimate8_sup(&it, buf, len);
break;
case 4:
m_decimators.decimate16_sup(&it, buf, len);
m_decimatorsIQ.decimate16_sup(&it, buf, len);
break;
case 5:
m_decimators.decimate32_sup(&it, buf, len);
m_decimatorsIQ.decimate32_sup(&it, buf, len);
break;
case 6:
m_decimators.decimate64_sup(&it, buf, len);
m_decimatorsIQ.decimate64_sup(&it, buf, len);
break;
default:
break;
@@ -214,22 +218,22 @@ void PlutoSDRInputThread::convert(const qint16* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_cen(&it, buf, len);
m_decimatorsIQ.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimators.decimate4_cen(&it, buf, len);
m_decimatorsIQ.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimators.decimate8_cen(&it, buf, len);
m_decimatorsIQ.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimators.decimate16_cen(&it, buf, len);
m_decimatorsIQ.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimators.decimate32_cen(&it, buf, len);
m_decimatorsIQ.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimators.decimate64_cen(&it, buf, len);
m_decimatorsIQ.decimate64_cen(&it, buf, len);
break;
default:
break;
@@ -240,3 +244,95 @@ void PlutoSDRInputThread::convert(const qint16* buf, qint32 len)
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
void PlutoSDRInputThread::convertQI(const qint16* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimatorsQI.decimate1(&it, buf, len);
}
else
{
if (m_fcPos == 0) // Infra
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_inf(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_inf(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_inf(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_inf(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_inf(&it, buf, len);
break;
default:
break;
}
}
else if (m_fcPos == 1) // Supra
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_sup(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_sup(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_sup(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_sup(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_sup(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_sup(&it, buf, len);
break;
default:
break;
}
}
else if (m_fcPos == 2) // Center
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_cen(&it, buf, len);
break;
default:
break;
}
}
}
m_sampleFifo->write(m_convertBuffer.begin(), it);
}
@@ -42,6 +42,7 @@ public:
virtual bool isRunning() { return m_running; }
void setLog2Decimation(unsigned int log2_decim);
void setFcPos(int fcPos);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
QMutex m_startWaitMutex;
@@ -59,12 +60,14 @@ private:
unsigned int m_log2Decim; // soft decimation
int m_fcPos;
float m_phasor;
bool m_iqOrder;
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;
void run();
void convert(const qint16* buf, qint32 len);
void convertIQ(const qint16* buf, qint32 len);
void convertQI(const qint16* buf, qint32 len);
};
+15 -6
View File
@@ -58,7 +58,7 @@ RTLSDRInput::RTLSDRInput(DeviceAPI *deviceAPI) :
m_fileSink(nullptr),
m_settings(),
m_dev(0),
m_rtlSDRThread(0),
m_rtlSDRThread(nullptr),
m_deviceDescription(),
m_running(false)
{
@@ -210,7 +210,7 @@ bool RTLSDRInput::start()
m_rtlSDRThread->setSamplerate(m_settings.m_devSampleRate);
m_rtlSDRThread->setLog2Decimation(m_settings.m_log2Decim);
m_rtlSDRThread->setFcPos((int) m_settings.m_fcPos);
m_rtlSDRThread->setIQOrder(m_settings.m_iqOrder);
m_rtlSDRThread->startWork();
mutexLocker.unlock();
@@ -236,11 +236,11 @@ void RTLSDRInput::stop()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_rtlSDRThread != 0)
if (m_rtlSDRThread)
{
m_rtlSDRThread->stopWork();
delete m_rtlSDRThread;
m_rtlSDRThread = 0;
m_rtlSDRThread = nullptr;
}
m_running = false;
@@ -473,7 +473,7 @@ bool RTLSDRInput::applySettings(const RTLSDRSettings& settings, bool force)
reverseAPIKeys.append("log2Decim");
forwardChange = true;
if (m_rtlSDRThread != 0) {
if (m_rtlSDRThread) {
m_rtlSDRThread->setLog2Decimation(settings.m_log2Decim);
}
@@ -484,7 +484,7 @@ bool RTLSDRInput::applySettings(const RTLSDRSettings& settings, bool force)
{
reverseAPIKeys.append("fcPos");
if (m_rtlSDRThread != 0) {
if (m_rtlSDRThread) {
m_rtlSDRThread->setFcPos((int) settings.m_fcPos);
}
@@ -504,6 +504,15 @@ bool RTLSDRInput::applySettings(const RTLSDRSettings& settings, bool force)
reverseAPIKeys.append("transverterDeltaFrequency");
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
reverseAPIKeys.append("iqOrder");
if (m_rtlSDRThread) {
m_rtlSDRThread->setIQOrder(settings.m_iqOrder);
}
}
if ((m_settings.m_centerFrequency != settings.m_centerFrequency)
|| (m_settings.m_fcPos != settings.m_fcPos)
|| (m_settings.m_log2Decim != settings.m_log2Decim)
@@ -38,6 +38,7 @@ void RTLSDRSettings::resetToDefaults()
m_agc = false;
m_noModMode = false;
m_transverterMode = false;
m_iqOrder = true;
m_transverterDeltaFrequency = 0;
m_rfBandwidth = 2500 * 1000; // Hz
m_fileRecordName = "";
@@ -70,6 +71,7 @@ QByteArray RTLSDRSettings::serialize() const
s.writeString(17, m_reverseAPIAddress);
s.writeU32(18, m_reverseAPIPort);
s.writeU32(19, m_reverseAPIDeviceIndex);
s.writeBool(20, m_iqOrder);
return s.final();
}
@@ -116,6 +118,7 @@ bool RTLSDRSettings::deserialize(const QByteArray& data)
d.readU32(19, &utmp, 0);
m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp;
d.readBool(20, &m_iqOrder, true);
return true;
}
@@ -39,6 +39,7 @@ struct RTLSDRSettings {
bool m_agc;
bool m_noModMode;
bool m_transverterMode;
bool m_iqOrder;
qint64 m_transverterDeltaFrequency;
quint32 m_rfBandwidth; //!< RF filter bandwidth in Hz
QString m_fileRecordName;
+125 -23
View File
@@ -32,7 +32,8 @@ RTLSDRThread::RTLSDRThread(rtlsdr_dev_t* dev, SampleSinkFifo* sampleFifo, QObjec
m_sampleFifo(sampleFifo),
m_samplerate(288000),
m_log2Decim(4),
m_fcPos(0)
m_fcPos(0),
m_iqOrder(true)
{
}
@@ -89,13 +90,13 @@ void RTLSDRThread::run()
}
// Decimate according to specified log2 (ex: log2=4 => decim=16)
void RTLSDRThread::callback(const quint8* buf, qint32 len)
void RTLSDRThread::callbackIQ(const quint8* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimators.decimate1(&it, buf, len);
m_decimatorsIQ.decimate1(&it, buf, len);
}
else
{
@@ -104,22 +105,22 @@ void RTLSDRThread::callback(const quint8* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_inf(&it, buf, len);
m_decimatorsIQ.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimators.decimate4_inf(&it, buf, len);
m_decimatorsIQ.decimate4_inf(&it, buf, len);
break;
case 3:
m_decimators.decimate8_inf(&it, buf, len);
m_decimatorsIQ.decimate8_inf(&it, buf, len);
break;
case 4:
m_decimators.decimate16_inf(&it, buf, len);
m_decimatorsIQ.decimate16_inf(&it, buf, len);
break;
case 5:
m_decimators.decimate32_inf(&it, buf, len);
m_decimatorsIQ.decimate32_inf(&it, buf, len);
break;
case 6:
m_decimators.decimate64_inf(&it, buf, len);
m_decimatorsIQ.decimate64_inf(&it, buf, len);
break;
default:
break;
@@ -130,22 +131,22 @@ void RTLSDRThread::callback(const quint8* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_sup(&it, buf, len);
m_decimatorsIQ.decimate2_sup(&it, buf, len);
break;
case 2:
m_decimators.decimate4_sup(&it, buf, len);
m_decimatorsIQ.decimate4_sup(&it, buf, len);
break;
case 3:
m_decimators.decimate8_sup(&it, buf, len);
m_decimatorsIQ.decimate8_sup(&it, buf, len);
break;
case 4:
m_decimators.decimate16_sup(&it, buf, len);
m_decimatorsIQ.decimate16_sup(&it, buf, len);
break;
case 5:
m_decimators.decimate32_sup(&it, buf, len);
m_decimatorsIQ.decimate32_sup(&it, buf, len);
break;
case 6:
m_decimators.decimate64_sup(&it, buf, len);
m_decimatorsIQ.decimate64_sup(&it, buf, len);
break;
default:
break;
@@ -156,22 +157,118 @@ void RTLSDRThread::callback(const quint8* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_cen(&it, buf, len);
m_decimatorsIQ.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimators.decimate4_cen(&it, buf, len);
m_decimatorsIQ.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimators.decimate8_cen(&it, buf, len);
m_decimatorsIQ.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimators.decimate16_cen(&it, buf, len);
m_decimatorsIQ.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimators.decimate32_cen(&it, buf, len);
m_decimatorsIQ.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimators.decimate64_cen(&it, buf, len);
m_decimatorsIQ.decimate64_cen(&it, buf, len);
break;
default:
break;
}
}
}
m_sampleFifo->write(m_convertBuffer.begin(), it);
if(!m_running)
rtlsdr_cancel_async(m_dev);
}
void RTLSDRThread::callbackQI(const quint8* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimatorsQI.decimate1(&it, buf, len);
}
else
{
if (m_fcPos == 0) // Infradyne
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_inf(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_inf(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_inf(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_inf(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_inf(&it, buf, len);
break;
default:
break;
}
}
else if (m_fcPos == 1) // Supradyne
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_sup(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_sup(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_sup(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_sup(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_sup(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_sup(&it, buf, len);
break;
default:
break;
}
}
else // Centered
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_cen(&it, buf, len);
break;
default:
break;
@@ -187,7 +284,12 @@ void RTLSDRThread::callback(const quint8* buf, qint32 len)
void RTLSDRThread::callbackHelper(unsigned char* buf, uint32_t len, void* ctx)
{
RTLSDRThread* thread = (RTLSDRThread*)ctx;
thread->callback(buf, len);
RTLSDRThread* thread = (RTLSDRThread*) ctx;
if (thread->m_iqOrder) {
thread->callbackIQ(buf, len);
} else {
thread->callbackQI(buf, len);
}
}
+6 -2
View File
@@ -39,6 +39,7 @@ public:
void setSamplerate(int samplerate);
void setLog2Decimation(unsigned int log2_decim);
void setFcPos(int fcPos);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
QMutex m_startWaitMutex;
@@ -52,11 +53,14 @@ private:
int m_samplerate;
unsigned int m_log2Decim;
int m_fcPos;
bool m_iqOrder;
DecimatorsU<qint32, quint8, SDR_RX_SAMP_SZ, 8, 127> m_decimators;
DecimatorsU<qint32, quint8, SDR_RX_SAMP_SZ, 8, 127, true> m_decimatorsIQ;
DecimatorsU<qint32, quint8, SDR_RX_SAMP_SZ, 8, 127, false> m_decimatorsQI;
void run();
void callback(const quint8* buf, qint32 len);
void callbackIQ(const quint8* buf, qint32 len);
void callbackQI(const quint8* buf, qint32 len);
static void callbackHelper(unsigned char* buf, uint32_t len, void* ctx);
};
+17 -6
View File
@@ -50,7 +50,7 @@ SDRPlayInput::SDRPlayInput(DeviceAPI *deviceAPI) :
m_variant(SDRPlayUndef),
m_settings(),
m_dev(0),
m_sdrPlayThread(0),
m_sdrPlayThread(nullptr),
m_deviceDescription("SDRPlay"),
m_devNumber(0),
m_running(false)
@@ -188,7 +188,7 @@ bool SDRPlayInput::start()
m_sdrPlayThread = new SDRPlayThread(m_dev, &m_sampleFifo);
m_sdrPlayThread->setLog2Decimation(m_settings.m_log2Decim);
m_sdrPlayThread->setFcPos((int) m_settings.m_fcPos);
m_sdrPlayThread->setIQOrder(m_settings.m_iqOrder);
m_sdrPlayThread->startWork();
// mutexLocker.unlock();
@@ -219,11 +219,11 @@ void SDRPlayInput::stop()
{
// QMutexLocker mutexLocker(&m_mutex);
if(m_sdrPlayThread != 0)
if(m_sdrPlayThread)
{
m_sdrPlayThread->stopWork();
delete m_sdrPlayThread;
m_sdrPlayThread = 0;
m_sdrPlayThread = nullptr;
}
m_running = false;
@@ -537,7 +537,7 @@ bool SDRPlayInput::applySettings(const SDRPlaySettings& settings, bool forwardCh
{
reverseAPIKeys.append("log2Decim");
if (m_sdrPlayThread != 0)
if (m_sdrPlayThread)
{
m_sdrPlayThread->setLog2Decimation(settings.m_log2Decim);
qDebug() << "SDRPlayInput::applySettings: set decimation to " << (1<<settings.m_log2Decim);
@@ -548,13 +548,24 @@ bool SDRPlayInput::applySettings(const SDRPlaySettings& settings, bool forwardCh
{
reverseAPIKeys.append("fcPos");
if (m_sdrPlayThread != 0)
if (m_sdrPlayThread)
{
m_sdrPlayThread->setFcPos((int) settings.m_fcPos);
qDebug() << "SDRPlayInput: set fc pos (enum) to " << (int) settings.m_fcPos;
}
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
reverseAPIKeys.append("iqOrder");
if (m_sdrPlayThread)
{
m_sdrPlayThread->setIQOrder((int) settings.m_iqOrder);
qDebug() << "SDRPlayInput: set IQ order to " << (settings.m_iqOrder ? "IQ" : "QI");
}
}
if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) {
reverseAPIKeys.append("centerFrequency");
}
@@ -42,6 +42,7 @@ void SDRPlaySettings::resetToDefaults()
m_lnaOn = false;
m_mixerAmpOn = false;
m_basebandGain = 29;
m_iqOrder = true;
m_fileRecordName = "";
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
@@ -71,6 +72,7 @@ QByteArray SDRPlaySettings::serialize() const
s.writeString(16, m_reverseAPIAddress);
s.writeU32(17, m_reverseAPIPort);
s.writeU32(18, m_reverseAPIDeviceIndex);
s.writeBool(19, m_iqOrder);
return s.final();
}
@@ -117,6 +119,7 @@ bool SDRPlaySettings::deserialize(const QByteArray& data)
d.readU32(18, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
d.readBool(19, &m_iqOrder, true);
return true;
}
@@ -45,6 +45,7 @@ struct SDRPlaySettings {
bool m_lnaOn;
bool m_mixerAmpOn;
int m_basebandGain;
bool m_iqOrder;
QString m_fileRecordName;
bool m_useReverseAPI;
QString m_reverseAPIAddress;
+126 -22
View File
@@ -28,7 +28,8 @@ SDRPlayThread::SDRPlayThread(mirisdr_dev_t* dev, SampleSinkFifo* sampleFifo, QOb
m_sampleFifo(sampleFifo),
m_samplerate(288000),
m_log2Decim(0),
m_fcPos(0)
m_fcPos(0),
m_iqOrder(true)
{
}
@@ -89,16 +90,22 @@ void SDRPlayThread::run()
void SDRPlayThread::callbackHelper(unsigned char* buf, uint32_t len, void* ctx)
{
SDRPlayThread* thread = (SDRPlayThread*) ctx;
thread->callback((const qint16*) buf, len/2);
if (thread->m_iqOrder) {
thread->callbackIQ((const qint16*) buf, len/2);
} else {
thread->callbackQI((const qint16*) buf, len/2);
}
}
void SDRPlayThread::callback(const qint16* buf, qint32 len)
void SDRPlayThread::callbackIQ(const qint16* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimators.decimate1(&it, buf, len);
m_decimatorsIQ.decimate1(&it, buf, len);
}
else
{
@@ -107,22 +114,22 @@ void SDRPlayThread::callback(const qint16* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_inf(&it, buf, len);
m_decimatorsIQ.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimators.decimate4_inf(&it, buf, len);
m_decimatorsIQ.decimate4_inf(&it, buf, len);
break;
case 3:
m_decimators.decimate8_inf(&it, buf, len);
m_decimatorsIQ.decimate8_inf(&it, buf, len);
break;
case 4:
m_decimators.decimate16_inf(&it, buf, len);
m_decimatorsIQ.decimate16_inf(&it, buf, len);
break;
case 5:
m_decimators.decimate32_inf(&it, buf, len);
m_decimatorsIQ.decimate32_inf(&it, buf, len);
break;
case 6:
m_decimators.decimate64_inf(&it, buf, len);
m_decimatorsIQ.decimate64_inf(&it, buf, len);
break;
default:
break;
@@ -133,22 +140,22 @@ void SDRPlayThread::callback(const qint16* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_sup(&it, buf, len);
m_decimatorsIQ.decimate2_sup(&it, buf, len);
break;
case 2:
m_decimators.decimate4_sup(&it, buf, len);
m_decimatorsIQ.decimate4_sup(&it, buf, len);
break;
case 3:
m_decimators.decimate8_sup(&it, buf, len);
m_decimatorsIQ.decimate8_sup(&it, buf, len);
break;
case 4:
m_decimators.decimate16_sup(&it, buf, len);
m_decimatorsIQ.decimate16_sup(&it, buf, len);
break;
case 5:
m_decimators.decimate32_sup(&it, buf, len);
m_decimatorsIQ.decimate32_sup(&it, buf, len);
break;
case 6:
m_decimators.decimate64_sup(&it, buf, len);
m_decimatorsIQ.decimate64_sup(&it, buf, len);
break;
default:
break;
@@ -159,22 +166,22 @@ void SDRPlayThread::callback(const qint16* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_cen(&it, buf, len);
m_decimatorsIQ.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimators.decimate4_cen(&it, buf, len);
m_decimatorsIQ.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimators.decimate8_cen(&it, buf, len);
m_decimatorsIQ.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimators.decimate16_cen(&it, buf, len);
m_decimatorsIQ.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimators.decimate32_cen(&it, buf, len);
m_decimatorsIQ.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimators.decimate64_cen(&it, buf, len);
m_decimatorsIQ.decimate64_cen(&it, buf, len);
break;
default:
break;
@@ -190,3 +197,100 @@ void SDRPlayThread::callback(const qint16* buf, qint32 len)
}
}
void SDRPlayThread::callbackQI(const qint16* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
if (m_log2Decim == 0)
{
m_decimatorsQI.decimate1(&it, buf, len);
}
else
{
if (m_fcPos == 0) // Infradyne
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_inf(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_inf(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_inf(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_inf(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_inf(&it, buf, len);
break;
default:
break;
}
}
else if (m_fcPos == 1) // Supradyne
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_sup(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_sup(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_sup(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_sup(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_sup(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_sup(&it, buf, len);
break;
default:
break;
}
}
else // Centered
{
switch (m_log2Decim)
{
case 1:
m_decimatorsQI.decimate2_cen(&it, buf, len);
break;
case 2:
m_decimatorsQI.decimate4_cen(&it, buf, len);
break;
case 3:
m_decimatorsQI.decimate8_cen(&it, buf, len);
break;
case 4:
m_decimatorsQI.decimate16_cen(&it, buf, len);
break;
case 5:
m_decimatorsQI.decimate32_cen(&it, buf, len);
break;
case 6:
m_decimatorsQI.decimate64_cen(&it, buf, len);
break;
default:
break;
}
}
}
m_sampleFifo->write(m_convertBuffer.begin(), it);
if(!m_running)
{
mirisdr_cancel_async(m_dev);
}
}
+6 -2
View File
@@ -39,6 +39,7 @@ public:
void setSamplerate(int samplerate);
void setLog2Decimation(unsigned int log2_decim);
void setFcPos(int fcPos);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
QMutex m_startWaitMutex;
@@ -52,11 +53,14 @@ private:
int m_samplerate;
unsigned int m_log2Decim;
int m_fcPos;
bool m_iqOrder;
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;
void run();
void callback(const qint16* buf, qint32 len);
void callbackIQ(const qint16* buf, qint32 len);
void callbackQI(const qint16* buf, qint32 len);
static void callbackHelper(unsigned char* buf, uint32_t len, void* ctx);
};
@@ -49,7 +49,7 @@ SoapySDRInput::SoapySDRInput(DeviceAPI *deviceAPI) :
m_settings(),
m_deviceDescription("SoapySDRInput"),
m_running(false),
m_thread(0)
m_thread(nullptr)
{
openDevice();
initGainSettings(m_settings);
@@ -397,7 +397,7 @@ void SoapySDRInput::init()
SoapySDRInputThread *SoapySDRInput::findThread()
{
if (m_thread == 0) // this does not own the thread
if (!m_thread) // this does not own the thread
{
SoapySDRInputThread *soapySDRInputThread = 0;
@@ -439,7 +439,7 @@ void SoapySDRInput::moveThreadToBuddy()
if (buddySource)
{
buddySource->setThread(m_thread);
m_thread = 0; // zero for others
m_thread = nullptr; // zero for others
}
}
}
@@ -606,7 +606,7 @@ void SoapySDRInput::stop()
qDebug("SoapySDRInput::stop: SI mode. Just stop and delete the thread");
soapySDRInputThread->stopWork();
delete soapySDRInputThread;
m_thread = 0;
m_thread = nullptr;
// remove old thread address from buddies (reset in all buddies)
const std::vector<DeviceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
@@ -638,7 +638,7 @@ void SoapySDRInput::stop()
}
delete soapySDRInputThread;
m_thread = 0;
m_thread = nullptr;
if (highestActiveChannelIndex >= 0) // there is at least one channel still active
{
@@ -987,7 +987,7 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo
{
reverseAPIKeys.append("fcPos");
if (inputThread != 0)
if (inputThread)
{
inputThread->setFcPos(requestedChannel, (int) settings.m_fcPos);
qDebug() << "SoapySDRInput::applySettings: set fc pos (enum) to " << (int) settings.m_fcPos;
@@ -1000,13 +1000,25 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo
forwardChangeOwnDSP = true;
SoapySDRInputThread *inputThread = findThread();
if (inputThread != 0)
if (inputThread)
{
inputThread->setLog2Decimation(requestedChannel, settings.m_log2Decim);
qDebug() << "SoapySDRInput::applySettings: set decimation to " << (1<<settings.m_log2Decim);
}
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
reverseAPIKeys.append("iqOrder");
SoapySDRInputThread *inputThread = findThread();
if (inputThread)
{
inputThread->setIQOrder(settings.m_iqOrder);
qDebug() << "SoapySDRInput::applySettings: set IQ order to " << (settings.m_iqOrder ? "IQ" : "QI");
}
}
if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) {
reverseAPIKeys.append("centerFrequency");
}
@@ -37,6 +37,7 @@ void SoapySDRInputSettings::resetToDefaults()
m_softIQCorrection = false;
m_transverterMode = false;
m_transverterDeltaFrequency = 0;
m_iqOrder = true;
m_fileRecordName = "";
m_antenna = "NONE";
m_bandwidth = 1000000;
@@ -82,6 +83,7 @@ QByteArray SoapySDRInputSettings::serialize() const
s.writeString(24, m_reverseAPIAddress);
s.writeU32(25, m_reverseAPIPort);
s.writeU32(26, m_reverseAPIDeviceIndex);
s.writeBool(27, m_iqOrder);
return s.final();
}
@@ -144,6 +146,7 @@ bool SoapySDRInputSettings::deserialize(const QByteArray& data)
d.readU32(26, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
d.readBool(27, &m_iqOrder, true);
return true;
}
@@ -39,6 +39,7 @@ struct SoapySDRInputSettings {
bool m_softIQCorrection;
bool m_transverterMode;
qint64 m_transverterDeltaFrequency;
bool m_iqOrder;
QString m_fileRecordName;
QString m_antenna;
quint32 m_bandwidth;
@@ -32,7 +32,8 @@ SoapySDRInputThread::SoapySDRInputThread(SoapySDR::Device* dev, unsigned int nbR
m_dev(dev),
m_sampleRate(0),
m_nbChannels(nbRxChannels),
m_decimatorType(DecimatorFloat)
m_decimatorType(DecimatorFloat),
m_iqOrder(true)
{
qDebug("SoapySDRInputThread::SoapySDRInputThread");
m_channels = new Channel[nbRxChannels];
@@ -155,28 +156,57 @@ void SoapySDRInputThread::run()
break;
}
if (m_nbChannels > 1)
if (m_iqOrder)
{
callbackMI(buffs, numElems*2); // size given in number of I or Q samples (2 items per sample)
if (m_nbChannels > 1)
{
callbackMIIQ(buffs, numElems*2); // size given in number of I or Q samples (2 items per sample)
}
else
{
switch (m_decimatorType)
{
case Decimator8:
callbackSI8IQ((const qint8*) buffs[0], numElems*2);
break;
case Decimator12:
callbackSI12IQ((const qint16*) buffs[0], numElems*2);
break;
case Decimator16:
callbackSI16IQ((const qint16*) buffs[0], numElems*2);
break;
case DecimatorFloat:
default:
callbackSIFIQ((const float*) buffs[0], numElems*2);
}
}
}
else
{
switch (m_decimatorType)
if (m_nbChannels > 1)
{
case Decimator8:
callbackSI8((const qint8*) buffs[0], numElems*2);
break;
case Decimator12:
callbackSI12((const qint16*) buffs[0], numElems*2);
break;
case Decimator16:
callbackSI16((const qint16*) buffs[0], numElems*2);
break;
case DecimatorFloat:
default:
callbackSIF((const float*) buffs[0], numElems*2);
callbackMIQI(buffs, numElems*2); // size given in number of I or Q samples (2 items per sample)
}
else
{
switch (m_decimatorType)
{
case Decimator8:
callbackSI8QI((const qint8*) buffs[0], numElems*2);
break;
case Decimator12:
callbackSI12QI((const qint16*) buffs[0], numElems*2);
break;
case Decimator16:
callbackSI16QI((const qint16*) buffs[0], numElems*2);
break;
case DecimatorFloat:
default:
callbackSIFQI((const float*) buffs[0], numElems*2);
}
}
}
}
qDebug("SoapySDRInputThread::run: stop running loop");
@@ -253,35 +283,57 @@ SampleSinkFifo *SoapySDRInputThread::getFifo(unsigned int channel)
}
}
void SoapySDRInputThread::callbackMI(std::vector<void *>& buffs, qint32 samplesPerChannel)
void SoapySDRInputThread::callbackMIIQ(std::vector<void *>& buffs, qint32 samplesPerChannel)
{
for(unsigned int ichan = 0; ichan < m_nbChannels; ichan++)
{
switch (m_decimatorType)
{
case Decimator8:
callbackSI8((const qint8*) buffs[ichan], samplesPerChannel, ichan);
callbackSI8IQ((const qint8*) buffs[ichan], samplesPerChannel, ichan);
break;
case Decimator12:
callbackSI12((const qint16*) buffs[ichan], samplesPerChannel, ichan);
callbackSI12IQ((const qint16*) buffs[ichan], samplesPerChannel, ichan);
break;
case Decimator16:
callbackSI16((const qint16*) buffs[ichan], samplesPerChannel, ichan);
callbackSI16IQ((const qint16*) buffs[ichan], samplesPerChannel, ichan);
break;
case DecimatorFloat:
default:
callbackSIF((const float*) buffs[ichan], samplesPerChannel, ichan);
callbackSIFIQ((const float*) buffs[ichan], samplesPerChannel, ichan);
}
}
}
void SoapySDRInputThread::callbackSI8(const qint8* buf, qint32 len, unsigned int channel)
void SoapySDRInputThread::callbackMIQI(std::vector<void *>& buffs, qint32 samplesPerChannel)
{
for(unsigned int ichan = 0; ichan < m_nbChannels; ichan++)
{
switch (m_decimatorType)
{
case Decimator8:
callbackSI8QI((const qint8*) buffs[ichan], samplesPerChannel, ichan);
break;
case Decimator12:
callbackSI12QI((const qint16*) buffs[ichan], samplesPerChannel, ichan);
break;
case Decimator16:
callbackSI16QI((const qint16*) buffs[ichan], samplesPerChannel, ichan);
break;
case DecimatorFloat:
default:
callbackSIFQI((const float*) buffs[ichan], samplesPerChannel, ichan);
}
}
}
void SoapySDRInputThread::callbackSI8IQ(const qint8* buf, qint32 len, unsigned int channel)
{
SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
if (m_channels[channel].m_log2Decim == 0)
{
m_channels[channel].m_decimators8.decimate1(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate1(&it, buf, len);
}
else
{
@@ -290,22 +342,22 @@ void SoapySDRInputThread::callbackSI8(const qint8* buf, qint32 len, unsigned int
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators8.decimate2_inf(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate2_inf(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators8.decimate4_inf(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate4_inf(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators8.decimate8_inf(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate8_inf(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators8.decimate16_inf(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate16_inf(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators8.decimate32_inf(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate32_inf(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators8.decimate64_inf(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate64_inf(&it, buf, len);
break;
default:
break;
@@ -316,22 +368,22 @@ void SoapySDRInputThread::callbackSI8(const qint8* buf, qint32 len, unsigned int
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators8.decimate2_sup(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate2_sup(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators8.decimate4_sup(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate4_sup(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators8.decimate8_sup(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate8_sup(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators8.decimate16_sup(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate16_sup(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators8.decimate32_sup(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate32_sup(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators8.decimate64_sup(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate64_sup(&it, buf, len);
break;
default:
break;
@@ -342,22 +394,22 @@ void SoapySDRInputThread::callbackSI8(const qint8* buf, qint32 len, unsigned int
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators8.decimate2_cen(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate2_cen(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators8.decimate4_cen(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate4_cen(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators8.decimate8_cen(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate8_cen(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators8.decimate16_cen(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate16_cen(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators8.decimate32_cen(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate32_cen(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators8.decimate64_cen(&it, buf, len);
m_channels[channel].m_decimators8IQ.decimate64_cen(&it, buf, len);
break;
default:
break;
@@ -368,13 +420,13 @@ void SoapySDRInputThread::callbackSI8(const qint8* buf, qint32 len, unsigned int
m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
}
void SoapySDRInputThread::callbackSI12(const qint16* buf, qint32 len, unsigned int channel)
void SoapySDRInputThread::callbackSI8QI(const qint8* buf, qint32 len, unsigned int channel)
{
SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
if (m_channels[channel].m_log2Decim == 0)
{
m_channels[channel].m_decimators12.decimate1(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate1(&it, buf, len);
}
else
{
@@ -383,22 +435,22 @@ void SoapySDRInputThread::callbackSI12(const qint16* buf, qint32 len, unsigned i
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators12.decimate2_inf(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate2_inf(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators12.decimate4_inf(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate4_inf(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators12.decimate8_inf(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate8_inf(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators12.decimate16_inf(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate16_inf(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators12.decimate32_inf(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate32_inf(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators12.decimate64_inf(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate64_inf(&it, buf, len);
break;
default:
break;
@@ -409,22 +461,22 @@ void SoapySDRInputThread::callbackSI12(const qint16* buf, qint32 len, unsigned i
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators12.decimate2_sup(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate2_sup(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators12.decimate4_sup(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate4_sup(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators12.decimate8_sup(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate8_sup(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators12.decimate16_sup(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate16_sup(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators12.decimate32_sup(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate32_sup(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators12.decimate64_sup(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate64_sup(&it, buf, len);
break;
default:
break;
@@ -435,22 +487,22 @@ void SoapySDRInputThread::callbackSI12(const qint16* buf, qint32 len, unsigned i
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators12.decimate2_cen(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate2_cen(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators12.decimate4_cen(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate4_cen(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators12.decimate8_cen(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate8_cen(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators12.decimate16_cen(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate16_cen(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators12.decimate32_cen(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate32_cen(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators12.decimate64_cen(&it, buf, len);
m_channels[channel].m_decimators8QI.decimate64_cen(&it, buf, len);
break;
default:
break;
@@ -461,13 +513,13 @@ void SoapySDRInputThread::callbackSI12(const qint16* buf, qint32 len, unsigned i
m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
}
void SoapySDRInputThread::callbackSI16(const qint16* buf, qint32 len, unsigned int channel)
void SoapySDRInputThread::callbackSI12IQ(const qint16* buf, qint32 len, unsigned int channel)
{
SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
if (m_channels[channel].m_log2Decim == 0)
{
m_channels[channel].m_decimators16.decimate1(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate1(&it, buf, len);
}
else
{
@@ -476,22 +528,22 @@ void SoapySDRInputThread::callbackSI16(const qint16* buf, qint32 len, unsigned i
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators16.decimate2_inf(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate2_inf(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators16.decimate4_inf(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate4_inf(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators16.decimate8_inf(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate8_inf(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators16.decimate16_inf(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate16_inf(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators16.decimate32_inf(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate32_inf(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators16.decimate64_inf(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate64_inf(&it, buf, len);
break;
default:
break;
@@ -502,22 +554,22 @@ void SoapySDRInputThread::callbackSI16(const qint16* buf, qint32 len, unsigned i
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators16.decimate2_sup(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate2_sup(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators16.decimate4_sup(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate4_sup(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators16.decimate8_sup(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate8_sup(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators16.decimate16_sup(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate16_sup(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators16.decimate32_sup(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate32_sup(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators16.decimate64_sup(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate64_sup(&it, buf, len);
break;
default:
break;
@@ -528,22 +580,22 @@ void SoapySDRInputThread::callbackSI16(const qint16* buf, qint32 len, unsigned i
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators16.decimate2_cen(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate2_cen(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators16.decimate4_cen(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate4_cen(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators16.decimate8_cen(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate8_cen(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators16.decimate16_cen(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate16_cen(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators16.decimate32_cen(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate32_cen(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators16.decimate64_cen(&it, buf, len);
m_channels[channel].m_decimators12IQ.decimate64_cen(&it, buf, len);
break;
default:
break;
@@ -554,13 +606,13 @@ void SoapySDRInputThread::callbackSI16(const qint16* buf, qint32 len, unsigned i
m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
}
void SoapySDRInputThread::callbackSIF(const float* buf, qint32 len, unsigned int channel)
void SoapySDRInputThread::callbackSI12QI(const qint16* buf, qint32 len, unsigned int channel)
{
SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
if (m_channels[channel].m_log2Decim == 0)
{
m_channels[channel].m_decimatorsFloat.decimate1(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate1(&it, buf, len);
}
else
{
@@ -569,22 +621,22 @@ void SoapySDRInputThread::callbackSIF(const float* buf, qint32 len, unsigned int
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimatorsFloat.decimate2_inf(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate2_inf(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimatorsFloat.decimate4_inf(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate4_inf(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimatorsFloat.decimate8_inf(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate8_inf(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimatorsFloat.decimate16_inf(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate16_inf(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimatorsFloat.decimate32_inf(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate32_inf(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimatorsFloat.decimate64_inf(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate64_inf(&it, buf, len);
break;
default:
break;
@@ -595,22 +647,22 @@ void SoapySDRInputThread::callbackSIF(const float* buf, qint32 len, unsigned int
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimatorsFloat.decimate2_sup(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate2_sup(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimatorsFloat.decimate4_sup(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate4_sup(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimatorsFloat.decimate8_sup(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate8_sup(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimatorsFloat.decimate16_sup(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate16_sup(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimatorsFloat.decimate32_sup(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate32_sup(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimatorsFloat.decimate64_sup(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate64_sup(&it, buf, len);
break;
default:
break;
@@ -621,22 +673,394 @@ void SoapySDRInputThread::callbackSIF(const float* buf, qint32 len, unsigned int
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimatorsFloat.decimate2_cen(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate2_cen(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimatorsFloat.decimate4_cen(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate4_cen(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimatorsFloat.decimate8_cen(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate8_cen(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimatorsFloat.decimate16_cen(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate16_cen(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimatorsFloat.decimate32_cen(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate32_cen(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimatorsFloat.decimate64_cen(&it, buf, len);
m_channels[channel].m_decimators12QI.decimate64_cen(&it, buf, len);
break;
default:
break;
}
}
}
m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
}
void SoapySDRInputThread::callbackSI16IQ(const qint16* buf, qint32 len, unsigned int channel)
{
SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
if (m_channels[channel].m_log2Decim == 0)
{
m_channels[channel].m_decimators16IQ.decimate1(&it, buf, len);
}
else
{
if (m_channels[channel].m_fcPos == 0) // Infra
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators16IQ.decimate2_inf(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators16IQ.decimate4_inf(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators16IQ.decimate8_inf(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators16IQ.decimate16_inf(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators16IQ.decimate32_inf(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators16IQ.decimate64_inf(&it, buf, len);
break;
default:
break;
}
}
else if (m_channels[channel].m_fcPos == 1) // Supra
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators16IQ.decimate2_sup(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators16IQ.decimate4_sup(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators16IQ.decimate8_sup(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators16IQ.decimate16_sup(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators16IQ.decimate32_sup(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators16IQ.decimate64_sup(&it, buf, len);
break;
default:
break;
}
}
else if (m_channels[channel].m_fcPos == 2) // Center
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators16IQ.decimate2_cen(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators16IQ.decimate4_cen(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators16IQ.decimate8_cen(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators16IQ.decimate16_cen(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators16IQ.decimate32_cen(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators16IQ.decimate64_cen(&it, buf, len);
break;
default:
break;
}
}
}
m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
}
void SoapySDRInputThread::callbackSI16QI(const qint16* buf, qint32 len, unsigned int channel)
{
SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
if (m_channels[channel].m_log2Decim == 0)
{
m_channels[channel].m_decimators16QI.decimate1(&it, buf, len);
}
else
{
if (m_channels[channel].m_fcPos == 0) // Infra
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators16QI.decimate2_inf(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators16QI.decimate4_inf(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators16QI.decimate8_inf(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators16QI.decimate16_inf(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators16QI.decimate32_inf(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators16QI.decimate64_inf(&it, buf, len);
break;
default:
break;
}
}
else if (m_channels[channel].m_fcPos == 1) // Supra
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators16QI.decimate2_sup(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators16QI.decimate4_sup(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators16QI.decimate8_sup(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators16QI.decimate16_sup(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators16QI.decimate32_sup(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators16QI.decimate64_sup(&it, buf, len);
break;
default:
break;
}
}
else if (m_channels[channel].m_fcPos == 2) // Center
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimators16QI.decimate2_cen(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimators16QI.decimate4_cen(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimators16QI.decimate8_cen(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimators16QI.decimate16_cen(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimators16QI.decimate32_cen(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimators16QI.decimate64_cen(&it, buf, len);
break;
default:
break;
}
}
}
m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
}
void SoapySDRInputThread::callbackSIFIQ(const float* buf, qint32 len, unsigned int channel)
{
SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
if (m_channels[channel].m_log2Decim == 0)
{
m_channels[channel].m_decimatorsFloatIQ.decimate1(&it, buf, len);
}
else
{
if (m_channels[channel].m_fcPos == 0) // Infra
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimatorsFloatIQ.decimate2_inf(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimatorsFloatIQ.decimate4_inf(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimatorsFloatIQ.decimate8_inf(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimatorsFloatIQ.decimate16_inf(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimatorsFloatIQ.decimate32_inf(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimatorsFloatIQ.decimate64_inf(&it, buf, len);
break;
default:
break;
}
}
else if (m_channels[channel].m_fcPos == 1) // Supra
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimatorsFloatIQ.decimate2_sup(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimatorsFloatIQ.decimate4_sup(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimatorsFloatIQ.decimate8_sup(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimatorsFloatIQ.decimate16_sup(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimatorsFloatIQ.decimate32_sup(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimatorsFloatIQ.decimate64_sup(&it, buf, len);
break;
default:
break;
}
}
else if (m_channels[channel].m_fcPos == 2) // Center
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimatorsFloatIQ.decimate2_cen(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimatorsFloatIQ.decimate4_cen(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimatorsFloatIQ.decimate8_cen(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimatorsFloatIQ.decimate16_cen(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimatorsFloatIQ.decimate32_cen(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimatorsFloatIQ.decimate64_cen(&it, buf, len);
break;
default:
break;
}
}
}
m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
}
void SoapySDRInputThread::callbackSIFQI(const float* buf, qint32 len, unsigned int channel)
{
SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
if (m_channels[channel].m_log2Decim == 0)
{
m_channels[channel].m_decimatorsFloatQI.decimate1(&it, buf, len);
}
else
{
if (m_channels[channel].m_fcPos == 0) // Infra
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimatorsFloatQI.decimate2_inf(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimatorsFloatQI.decimate4_inf(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimatorsFloatQI.decimate8_inf(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimatorsFloatQI.decimate16_inf(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimatorsFloatQI.decimate32_inf(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimatorsFloatQI.decimate64_inf(&it, buf, len);
break;
default:
break;
}
}
else if (m_channels[channel].m_fcPos == 1) // Supra
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimatorsFloatQI.decimate2_sup(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimatorsFloatQI.decimate4_sup(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimatorsFloatQI.decimate8_sup(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimatorsFloatQI.decimate16_sup(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimatorsFloatQI.decimate32_sup(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimatorsFloatQI.decimate64_sup(&it, buf, len);
break;
default:
break;
}
}
else if (m_channels[channel].m_fcPos == 2) // Center
{
switch (m_channels[channel].m_log2Decim)
{
case 1:
m_channels[channel].m_decimatorsFloatQI.decimate2_cen(&it, buf, len);
break;
case 2:
m_channels[channel].m_decimatorsFloatQI.decimate4_cen(&it, buf, len);
break;
case 3:
m_channels[channel].m_decimatorsFloatQI.decimate8_cen(&it, buf, len);
break;
case 4:
m_channels[channel].m_decimatorsFloatQI.decimate16_cen(&it, buf, len);
break;
case 5:
m_channels[channel].m_decimatorsFloatQI.decimate32_cen(&it, buf, len);
break;
case 6:
m_channels[channel].m_decimatorsFloatQI.decimate64_cen(&it, buf, len);
break;
default:
break;
@@ -53,6 +53,7 @@ public:
int getFcPos(unsigned int channel) const;
void setFifo(unsigned int channel, SampleSinkFifo *sampleFifo);
SampleSinkFifo *getFifo(unsigned int channel);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
struct Channel
@@ -61,10 +62,14 @@ private:
SampleSinkFifo* m_sampleFifo;
unsigned int m_log2Decim;
int m_fcPos;
Decimators<qint32, qint8, SDR_RX_SAMP_SZ, 8> m_decimators8;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12> m_decimators12;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 16> m_decimators16;
DecimatorsFI m_decimatorsFloat;
Decimators<qint32, qint8, SDR_RX_SAMP_SZ, 8, true> m_decimators8IQ;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12, true> m_decimators12IQ;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 16, true> m_decimators16IQ;
Decimators<qint32, qint8, SDR_RX_SAMP_SZ, 8, false> m_decimators8QI;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12, false> m_decimators12QI;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 16, false> m_decimators16QI;
DecimatorsFI<true> m_decimatorsFloatIQ;
DecimatorsFI<false> m_decimatorsFloatQI;
Channel() :
m_sampleFifo(0),
@@ -93,14 +98,23 @@ private:
unsigned int m_sampleRate;
unsigned int m_nbChannels;
DecimatorType m_decimatorType;
bool m_iqOrder;
void run();
unsigned int getNbFifos();
void callbackSI8(const qint8* buf, qint32 len, unsigned int channel = 0);
void callbackSI12(const qint16* buf, qint32 len, unsigned int channel = 0);
void callbackSI16(const qint16* buf, qint32 len, unsigned int channel = 0);
void callbackSIF(const float* buf, qint32 len, unsigned int channel = 0);
void callbackMI(std::vector<void *>& buffs, qint32 samplesPerChannel);
void callbackSI8IQ(const qint8* buf, qint32 len, unsigned int channel = 0);
void callbackSI12IQ(const qint16* buf, qint32 len, unsigned int channel = 0);
void callbackSI16IQ(const qint16* buf, qint32 len, unsigned int channel = 0);
void callbackSIFIQ(const float* buf, qint32 len, unsigned int channel = 0);
void callbackSI8QI(const qint8* buf, qint32 len, unsigned int channel = 0);
void callbackSI12QI(const qint16* buf, qint32 len, unsigned int channel = 0);
void callbackSI16QI(const qint16* buf, qint32 len, unsigned int channel = 0);
void callbackSIFQI(const float* buf, qint32 len, unsigned int channel = 0);
void callbackMIIQ(std::vector<void *>& buffs, qint32 samplesPerChannel);
void callbackMIQI(std::vector<void *>& buffs, qint32 samplesPerChannel);
};
@@ -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;
std::map<int, int> m_timerHistogram;
uint32_t m_histoCounter;
+20 -7
View File
@@ -52,7 +52,7 @@ MESSAGE_CLASS_DEFINITION(XTRXInput::MsgStartStop, Message)
XTRXInput::XTRXInput(DeviceAPI *deviceAPI) :
m_deviceAPI(deviceAPI),
m_settings(),
m_XTRXInputThread(0),
m_XTRXInputThread(nullptr),
m_deviceDescription("XTRXInput"),
m_running(false)
{
@@ -201,9 +201,9 @@ void XTRXInput::init()
XTRXInputThread *XTRXInput::findThread()
{
if (m_XTRXInputThread == 0) // this does not own the thread
if (!m_XTRXInputThread) // this does not own the thread
{
XTRXInputThread *xtrxInputThread = 0;
XTRXInputThread *xtrxInputThread = nullptr;
// find a buddy that has allocated the thread
const std::vector<DeviceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
@@ -243,7 +243,7 @@ void XTRXInput::moveThreadToBuddy()
if (buddySource)
{
buddySource->setThread(m_XTRXInputThread);
m_XTRXInputThread = 0; // zero for others
m_XTRXInputThread = nullptr; // zero for others
}
}
}
@@ -308,8 +308,9 @@ bool XTRXInput::start()
xtrxInputThread->stopWork();
delete xtrxInputThread;
xtrxInputThread = new XTRXInputThread(m_deviceShared.m_dev->getDevice(), 2); // MI mode (2 channels)
m_XTRXInputThread = xtrxInputThread; // take ownership
xtrxInputThread->setIQOrder(m_settings.m_iqOrder);
m_deviceShared.m_thread = xtrxInputThread;
m_XTRXInputThread = xtrxInputThread; // take ownership
for (int i = 0; i < 2; i++) // restore original FIFO references
{
@@ -394,8 +395,8 @@ void XTRXInput::stop()
qDebug("XTRXInput::stop: SI mode. Just stop and delete the thread");
xtrxInputThread->stopWork();
delete xtrxInputThread;
m_XTRXInputThread = 0;
m_deviceShared.m_thread = 0;
m_XTRXInputThread = nullptr;
m_deviceShared.m_thread = nullptr;
// remove old thread address from buddies (reset in all buddies)
const std::vector<DeviceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
@@ -410,6 +411,7 @@ void XTRXInput::stop()
m_XTRXInputThread = xtrxInputThread; // take ownership
m_deviceShared.m_thread = xtrxInputThread;
xtrxInputThread->setIQOrder(m_settings.m_iqOrder);
xtrxInputThread->setFifo(requestedChannel, &m_sampleFifo);
xtrxInputThread->setLog2Decimation(requestedChannel, m_settings.m_log2SoftDecim);
@@ -1040,6 +1042,17 @@ bool XTRXInput::applySettings(const XTRXInputSettings& settings, bool force, boo
}
}
if ((m_settings.m_iqOrder != settings.m_iqOrder) || force)
{
reverseAPIKeys.append("iqOrder");
if (inputThread)
{
inputThread->setIQOrder(settings.m_iqOrder);
qDebug() << "XTRXInput::applySettings: set IQ order to " << (settings.m_iqOrder ? "IQ" : "QI");
}
}
if ((m_settings.m_antennaPath != settings.m_antennaPath) || force)
{
reverseAPIKeys.append("antennaPath");
@@ -43,6 +43,7 @@ void XTRXInputSettings::resetToDefaults()
m_extClock = false;
m_extClockFreq = 0; // Auto
m_pwrmode = 1;
m_iqOrder = true;
m_fileRecordName = "";
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
@@ -76,6 +77,7 @@ QByteArray XTRXInputSettings::serialize() const
s.writeString(23, m_reverseAPIAddress);
s.writeU32(24, m_reverseAPIPort);
s.writeU32(25, m_reverseAPIDeviceIndex);
s.writeBool(26, m_iqOrder);
return s.final();
}
@@ -127,6 +129,7 @@ bool XTRXInputSettings::deserialize(const QByteArray& data)
d.readU32(25, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
d.readBool(26, &m_iqOrder, true);
return true;
}
@@ -56,6 +56,7 @@ struct XTRXInputSettings
bool m_extClock; //!< True if external clock source
uint32_t m_extClockFreq; //!< Frequency (Hz) of external clock source
uint32_t m_pwrmode;
bool m_iqOrder;
QString m_fileRecordName;
bool m_useReverseAPI;
QString m_reverseAPIAddress;
@@ -29,7 +29,8 @@ XTRXInputThread::XTRXInputThread(struct xtrx_dev *dev, unsigned int nbChannels,
m_running(false),
m_dev(dev),
m_nbChannels(nbChannels),
m_uniqueChannelIndex(uniqueChannelIndex)
m_uniqueChannelIndex(uniqueChannelIndex),
m_iqOrder(true)
{
qDebug("XTRXInputThread::XTRXInputThread: nbChannels: %u uniqueChannelIndex: %u", nbChannels, uniqueChannelIndex);
m_channels = new Channel[2];
@@ -150,10 +151,17 @@ void XTRXInputThread::run()
qDebug("XTRXInputThread::run: overflow");
}
if (m_nbChannels > 1) {
if (m_nbChannels > 1)
{
callbackMI((const qint16*) buffs[0], (const qint16*) buffs[1], 2 * nfo.out_samples);
} else {
callbackSI((const qint16*) buffs[0], 2 * nfo.out_samples);
}
else
{
if (m_iqOrder) {
callbackSIIQ((const qint16*) buffs[0], 2 * nfo.out_samples);
} else {
callbackSIQI((const qint16*) buffs[0], 2 * nfo.out_samples);
}
}
}
@@ -223,35 +231,73 @@ SampleSinkFifo *XTRXInputThread::getFifo(unsigned int channel)
}
}
void XTRXInputThread::callbackSI(const qint16* buf, qint32 len)
void XTRXInputThread::callbackSIIQ(const qint16* buf, qint32 len)
{
SampleVector::iterator it = m_channels[m_uniqueChannelIndex].m_convertBuffer.begin();
if (m_channels[m_uniqueChannelIndex].m_log2Decim == 0)
{
m_channels[m_uniqueChannelIndex].m_decimators.decimate1(&it, buf, len);
m_channels[m_uniqueChannelIndex].m_decimatorsIQ.decimate1(&it, buf, len);
}
else
{
switch (m_channels[m_uniqueChannelIndex].m_log2Decim)
{
case 1:
m_channels[m_uniqueChannelIndex].m_decimators.decimate2_cen(&it, buf, len);
m_channels[m_uniqueChannelIndex].m_decimatorsIQ.decimate2_cen(&it, buf, len);
break;
case 2:
m_channels[m_uniqueChannelIndex].m_decimators.decimate4_cen(&it, buf, len);
m_channels[m_uniqueChannelIndex].m_decimatorsIQ.decimate4_cen(&it, buf, len);
break;
case 3:
m_channels[m_uniqueChannelIndex].m_decimators.decimate8_cen(&it, buf, len);
m_channels[m_uniqueChannelIndex].m_decimatorsIQ.decimate8_cen(&it, buf, len);
break;
case 4:
m_channels[m_uniqueChannelIndex].m_decimators.decimate16_cen(&it, buf, len);
m_channels[m_uniqueChannelIndex].m_decimatorsIQ.decimate16_cen(&it, buf, len);
break;
case 5:
m_channels[m_uniqueChannelIndex].m_decimators.decimate32_cen(&it, buf, len);
m_channels[m_uniqueChannelIndex].m_decimatorsIQ.decimate32_cen(&it, buf, len);
break;
case 6:
m_channels[m_uniqueChannelIndex].m_decimators.decimate64_cen(&it, buf, len);
m_channels[m_uniqueChannelIndex].m_decimatorsIQ.decimate64_cen(&it, buf, len);
break;
default:
break;
}
}
m_channels[m_uniqueChannelIndex].m_sampleFifo->write(m_channels[m_uniqueChannelIndex].m_convertBuffer.begin(), it);
}
void XTRXInputThread::callbackSIQI(const qint16* buf, qint32 len)
{
SampleVector::iterator it = m_channels[m_uniqueChannelIndex].m_convertBuffer.begin();
if (m_channels[m_uniqueChannelIndex].m_log2Decim == 0)
{
m_channels[m_uniqueChannelIndex].m_decimatorsQI.decimate1(&it, buf, len);
}
else
{
switch (m_channels[m_uniqueChannelIndex].m_log2Decim)
{
case 1:
m_channels[m_uniqueChannelIndex].m_decimatorsQI.decimate2_cen(&it, buf, len);
break;
case 2:
m_channels[m_uniqueChannelIndex].m_decimatorsQI.decimate4_cen(&it, buf, len);
break;
case 3:
m_channels[m_uniqueChannelIndex].m_decimatorsQI.decimate8_cen(&it, buf, len);
break;
case 4:
m_channels[m_uniqueChannelIndex].m_decimatorsQI.decimate16_cen(&it, buf, len);
break;
case 5:
m_channels[m_uniqueChannelIndex].m_decimatorsQI.decimate32_cen(&it, buf, len);
break;
case 6:
m_channels[m_uniqueChannelIndex].m_decimatorsQI.decimate64_cen(&it, buf, len);
break;
default:
break;
@@ -267,10 +313,21 @@ void XTRXInputThread::callbackMI(const qint16* buf0, const qint16* buf1, qint32
// channel 0
m_uniqueChannelIndex = 0;
callbackSI(buf0, len);
if (m_iqOrder) {
callbackSIIQ(buf0, len);
} else {
callbackSIQI(buf0, len);
}
// channel 1
m_uniqueChannelIndex = 1;
callbackSI(buf1, len);
if (m_iqOrder) {
callbackSIIQ(buf1, len);
} else {
callbackSIQI(buf1, len);
}
m_uniqueChannelIndex = uniqueChannelIndex;
}
@@ -47,6 +47,7 @@ public:
unsigned int getLog2Decimation(unsigned int channel) const;
void setFifo(unsigned int channel, SampleSinkFifo *sampleFifo);
SampleSinkFifo *getFifo(unsigned int channel);
void setIQOrder(bool iqOrder) { m_iqOrder = iqOrder; }
private:
struct Channel
@@ -54,7 +55,8 @@ private:
SampleVector m_convertBuffer;
SampleSinkFifo* m_sampleFifo;
unsigned int m_log2Decim;
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;
Channel() :
m_sampleFifo(0),
@@ -73,10 +75,12 @@ private:
Channel *m_channels; //!< Array of channels dynamically allocated for the given number of Rx channels
unsigned int m_nbChannels;
unsigned int m_uniqueChannelIndex;
bool m_iqOrder;
void run();
unsigned int getNbFifos();
void callbackSI(const qint16* buf, qint32 len);
void callbackSIQI(const qint16* buf, qint32 len);
void callbackSIIQ(const qint16* buf, qint32 len);
void callbackMI(const qint16* buf0, const qint16* buf1, qint32 len);
};