mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-25 09:18:54 -05:00
SoapySDR support: input: settings and thread output: settings
This commit is contained in:
parent
6cede7a667
commit
0d09958483
@ -33,6 +33,8 @@ public:
|
||||
uint32_t getNbDevices() const { return m_scanner.getNbDevices(); }
|
||||
const std::vector<DeviceSoapySDRScan::SoapySDRDeviceEnum>& getDevicesEnumeration() const { return m_scanner.getDevicesEnumeration(); }
|
||||
|
||||
static const unsigned int blockSize = (1<<14);
|
||||
|
||||
protected:
|
||||
DeviceSoapySDR();
|
||||
DeviceSoapySDR(const DeviceSoapySDR&) {}
|
||||
|
27
devices/soapysdr/devicesoapysdrshared.cpp
Normal file
27
devices/soapysdr/devicesoapysdrshared.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "devicesoapysdrshared.h"
|
||||
|
||||
DeviceSoapySDRShared::DeviceSoapySDRShared() :
|
||||
m_device(0),
|
||||
m_channel(-1),
|
||||
m_source(0),
|
||||
m_sink(0)
|
||||
{}
|
||||
|
||||
DeviceSoapySDRShared::~DeviceSoapySDRShared()
|
||||
{}
|
43
devices/soapysdr/devicesoapysdrshared.h
Normal file
43
devices/soapysdr/devicesoapysdrshared.h
Normal file
@ -0,0 +1,43 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef DEVICES_SOAPYSDR_DEVICESOAPYSDRSHARED_H_
|
||||
#define DEVICES_SOAPYSDR_DEVICESOAPYSDRSHARED_H_
|
||||
|
||||
#include <SoapySDR/Device.hpp>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
class SoapySDRInput;
|
||||
class SoapySDROutput;
|
||||
|
||||
/**
|
||||
* Structure shared by a buddy with other buddies
|
||||
*/
|
||||
class DEVICES_API DeviceSoapySDRShared
|
||||
{
|
||||
public:
|
||||
DeviceSoapySDRShared();
|
||||
~DeviceSoapySDRShared();
|
||||
|
||||
SoapySDR::Device *m_device;
|
||||
int m_channel; //!< allocated channel (-1 if none)
|
||||
SoapySDRInput *m_source;
|
||||
SoapySDROutput *m_sink;
|
||||
};
|
||||
|
||||
|
||||
#endif /* DEVICES_SOAPYSDR_DEVICESOAPYSDRSHARED_H_ */
|
@ -18,7 +18,6 @@
|
||||
#define PLUGINS_SAMPLESINK_BLADERF2OUTPUT_BLADERF2OUTPUTSETTINGS_H_
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <libbladeRF.h>
|
||||
|
||||
struct BladeRF2OutputSettings {
|
||||
quint64 m_centerFrequency;
|
||||
|
@ -6,7 +6,7 @@ set(soapysdroutput_SOURCES
|
||||
soapysdroutputgui.cpp
|
||||
soapysdroutput.cpp
|
||||
soapysdroutputplugin.cpp
|
||||
# soapysdroutputsettings.cpp
|
||||
soapysdroutputsettings.cpp
|
||||
# soapysdroutputthread.cpp
|
||||
)
|
||||
|
||||
@ -14,7 +14,7 @@ set(soapysdroutput_HEADERS
|
||||
soapysdroutputgui.h
|
||||
soapysdroutput.h
|
||||
soapysdroutputplugin.h
|
||||
# soapysdroutputsettings.h
|
||||
soapysdroutputsettings.h
|
||||
# soapysdroutputthread.h
|
||||
)
|
||||
|
||||
|
@ -41,7 +41,7 @@ void SoapySDROutput::destroy()
|
||||
|
||||
bool SoapySDROutput::openDevice()
|
||||
{
|
||||
m_sampleSourceFifo.resize(96000 * 4);
|
||||
m_sampleSourceFifo.resize(m_settings.m_devSampleRate/(1<<(m_settings.m_log2Interp <= 4 ? m_settings.m_log2Interp : 4)));
|
||||
|
||||
// look for Tx buddies and get reference to the device object
|
||||
if (m_deviceAPI->getSinkBuddies().size() > 0) // look sink sibling first
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "dsp/devicesamplesink.h"
|
||||
#include "soapysdr/devicesoapysdrshared.h"
|
||||
|
||||
#include "soapysdroutputsettings.h"
|
||||
|
||||
class DeviceSinkAPI;
|
||||
|
||||
class SoapySDROutput : public DeviceSampleSink {
|
||||
@ -47,6 +49,7 @@ public:
|
||||
|
||||
private:
|
||||
DeviceSinkAPI *m_deviceAPI;
|
||||
SoapySDROutputSettings m_settings;
|
||||
QString m_deviceDescription;
|
||||
DeviceSoapySDRShared m_deviceShared;
|
||||
bool m_running;
|
||||
|
75
plugins/samplesink/soapysdroutput/soapysdroutputsettings.cpp
Normal file
75
plugins/samplesink/soapysdroutput/soapysdroutputsettings.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QtGlobal>
|
||||
#include "util/simpleserializer.h"
|
||||
|
||||
#include "soapysdroutputsettings.h"
|
||||
|
||||
SoapySDROutputSettings::SoapySDROutputSettings()
|
||||
{
|
||||
resetToDefaults();
|
||||
}
|
||||
|
||||
void SoapySDROutputSettings::resetToDefaults()
|
||||
{
|
||||
m_centerFrequency = 435000*1000;
|
||||
m_LOppmTenths = 0;
|
||||
m_devSampleRate = 1024000;
|
||||
m_log2Interp = 0;
|
||||
m_transverterMode = false;
|
||||
m_transverterDeltaFrequency = 0;
|
||||
}
|
||||
|
||||
QByteArray SoapySDROutputSettings::serialize() const
|
||||
{
|
||||
SimpleSerializer s(1);
|
||||
|
||||
s.writeS32(1, m_devSampleRate);
|
||||
s.writeS32(2, m_LOppmTenths);
|
||||
s.writeU32(3, m_log2Interp);
|
||||
s.writeBool(4, m_transverterMode);
|
||||
s.writeS64(5, m_transverterDeltaFrequency);
|
||||
|
||||
return s.final();
|
||||
}
|
||||
|
||||
bool SoapySDROutputSettings::deserialize(const QByteArray& data)
|
||||
{
|
||||
SimpleDeserializer d(data);
|
||||
|
||||
if (!d.isValid())
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d.getVersion() == 1)
|
||||
{
|
||||
d.readS32(1, &m_devSampleRate);
|
||||
d.readS32(2, &m_LOppmTenths);
|
||||
d.readU32(3, &m_log2Interp);
|
||||
d.readBool(4, &m_transverterMode, false);
|
||||
d.readS64(5, &m_transverterDeltaFrequency, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
}
|
36
plugins/samplesink/soapysdroutput/soapysdroutputsettings.h
Normal file
36
plugins/samplesink/soapysdroutput/soapysdroutputsettings.h
Normal file
@ -0,0 +1,36 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PLUGINS_SAMPLESINK_SOAPYSDROUTPUT_SOAPYSDROUTPUTSETTINGS_H_
|
||||
#define PLUGINS_SAMPLESINK_SOAPYSDROUTPUT_SOAPYSDROUTPUTSETTINGS_H_
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
struct SoapySDROutputSettings {
|
||||
quint64 m_centerFrequency;
|
||||
int m_LOppmTenths;
|
||||
qint32 m_devSampleRate;
|
||||
quint32 m_log2Interp;
|
||||
bool m_transverterMode;
|
||||
qint64 m_transverterDeltaFrequency;
|
||||
|
||||
SoapySDROutputSettings();
|
||||
void resetToDefaults();
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
};
|
||||
|
||||
#endif /* PLUGINS_SAMPLESINK_SOAPYSDROUTPUT_SOAPYSDROUTPUTSETTINGS_H_ */
|
@ -19,7 +19,6 @@
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QString>
|
||||
#include <libbladeRF.h>
|
||||
|
||||
struct BladeRF2InputSettings {
|
||||
typedef enum {
|
||||
|
@ -6,16 +6,16 @@ set(soapysdrinput_SOURCES
|
||||
soapysdrinputgui.cpp
|
||||
soapysdrinput.cpp
|
||||
soapysdrinputplugin.cpp
|
||||
# soapysdrinputsettings.cpp
|
||||
# soapysdrinputthread.cpp
|
||||
soapysdrinputsettings.cpp
|
||||
soapysdrinputthread.cpp
|
||||
)
|
||||
|
||||
set(soapysdrinput_HEADERS
|
||||
soapysdrinputgui.h
|
||||
soapysdrinput.h
|
||||
soapysdrinputplugin.h
|
||||
# soapysdrinputsettings.h
|
||||
# soapysdrinputthread.h
|
||||
soapysdrinputsettings.h
|
||||
soapysdrinputthread.h
|
||||
)
|
||||
|
||||
set(soapysdrinput_FORMS
|
||||
|
@ -23,10 +23,12 @@
|
||||
#include "dsp/dspengine.h"
|
||||
#include "soapysdr/devicesoapysdr.h"
|
||||
|
||||
#include "soapysdrinputthread.h"
|
||||
#include "soapysdrinput.h"
|
||||
|
||||
SoapySDRInput::SoapySDRInput(DeviceSourceAPI *deviceAPI) :
|
||||
m_deviceAPI(deviceAPI),
|
||||
m_thread(0),
|
||||
m_deviceDescription("SoapySDRInput"),
|
||||
m_running(false)
|
||||
{
|
||||
@ -131,9 +133,9 @@ void SoapySDRInput::closeDevice()
|
||||
stop();
|
||||
}
|
||||
|
||||
// if (m_thread) { // stills own the thread => transfer to a buddy
|
||||
// moveThreadToBuddy();
|
||||
// }
|
||||
if (m_thread) { // stills own the thread => transfer to a buddy
|
||||
moveThreadToBuddy();
|
||||
}
|
||||
|
||||
m_deviceShared.m_channel = -1; // publicly release channel
|
||||
m_deviceShared.m_source = 0;
|
||||
@ -152,6 +154,23 @@ void SoapySDRInput::init()
|
||||
{
|
||||
}
|
||||
|
||||
void SoapySDRInput::moveThreadToBuddy()
|
||||
{
|
||||
const std::vector<DeviceSourceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
|
||||
std::vector<DeviceSourceAPI*>::const_iterator it = sourceBuddies.begin();
|
||||
|
||||
for (; it != sourceBuddies.end(); ++it)
|
||||
{
|
||||
SoapySDRInput *buddySource = ((DeviceSoapySDRShared*) (*it)->getBuddySharedPtr())->m_source;
|
||||
|
||||
if (buddySource)
|
||||
{
|
||||
buddySource->setThread(m_thread);
|
||||
m_thread = 0; // zero for others
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SoapySDRInput::start()
|
||||
{
|
||||
return false;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "dsp/devicesamplesource.h"
|
||||
|
||||
class DeviceSourceAPI;
|
||||
class SoapySDRInputThread;
|
||||
|
||||
class SoapySDRInput : public DeviceSampleSource
|
||||
{
|
||||
@ -36,6 +37,8 @@ public:
|
||||
virtual void init();
|
||||
virtual bool start();
|
||||
virtual void stop();
|
||||
SoapySDRInputThread *getThread() { return m_thread; }
|
||||
void setThread(SoapySDRInputThread *thread) { m_thread = thread; }
|
||||
|
||||
virtual QByteArray serialize() const;
|
||||
virtual bool deserialize(const QByteArray& data);
|
||||
@ -51,11 +54,13 @@ public:
|
||||
private:
|
||||
DeviceSourceAPI *m_deviceAPI;
|
||||
DeviceSoapySDRShared m_deviceShared;
|
||||
SoapySDRInputThread *m_thread;
|
||||
QString m_deviceDescription;
|
||||
bool m_running;
|
||||
|
||||
bool openDevice();
|
||||
void closeDevice();
|
||||
void moveThreadToBuddy();
|
||||
};
|
||||
|
||||
|
||||
|
87
plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp
Normal file
87
plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "util/simpleserializer.h"
|
||||
|
||||
#include "soapysdrinputsettings.h"
|
||||
|
||||
SoapySDRInputSettings::SoapySDRInputSettings()
|
||||
{
|
||||
resetToDefaults();
|
||||
}
|
||||
|
||||
void SoapySDRInputSettings::resetToDefaults()
|
||||
{
|
||||
m_centerFrequency = 435000*1000;
|
||||
m_LOppmTenths = 0;
|
||||
m_devSampleRate = 1024000;
|
||||
m_log2Decim = 0;
|
||||
m_fcPos = FC_POS_CENTER;
|
||||
m_dcBlock = false;
|
||||
m_iqCorrection = false;
|
||||
m_transverterMode = false;
|
||||
m_transverterDeltaFrequency = 0;
|
||||
m_fileRecordName = "";
|
||||
}
|
||||
|
||||
QByteArray SoapySDRInputSettings::serialize() const
|
||||
{
|
||||
SimpleSerializer s(1);
|
||||
|
||||
s.writeS32(1, m_devSampleRate);
|
||||
s.writeU32(2, m_log2Decim);
|
||||
s.writeS32(3, (int) m_fcPos);
|
||||
s.writeBool(4, m_dcBlock);
|
||||
s.writeBool(5, m_iqCorrection);
|
||||
s.writeS32(6, m_LOppmTenths);
|
||||
s.writeBool(7, m_transverterMode);
|
||||
s.writeS64(8, m_transverterDeltaFrequency);
|
||||
|
||||
return s.final();
|
||||
}
|
||||
|
||||
bool SoapySDRInputSettings::deserialize(const QByteArray& data)
|
||||
{
|
||||
SimpleDeserializer d(data);
|
||||
|
||||
if (!d.isValid())
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d.getVersion() == 1)
|
||||
{
|
||||
int intval;
|
||||
|
||||
d.readS32(1, &m_devSampleRate, 1024000);
|
||||
d.readU32(2, &m_log2Decim);
|
||||
d.readS32(3, &intval, (int) FC_POS_CENTER);
|
||||
m_fcPos = (fcPos_t) intval;
|
||||
d.readBool(4, &m_dcBlock);
|
||||
d.readBool(5, &m_iqCorrection);
|
||||
d.readS32(6, &m_LOppmTenths);
|
||||
d.readBool(7, &m_transverterMode, false);
|
||||
d.readS64(8, &m_transverterDeltaFrequency, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
}
|
47
plugins/samplesource/soapysdrinput/soapysdrinputsettings.h
Normal file
47
plugins/samplesource/soapysdrinput/soapysdrinputsettings.h
Normal file
@ -0,0 +1,47 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PLUGINS_SAMPLESOURCE_SOAPYSDRINPUT_SOAPYSDRINPUTSETTINGS_H_
|
||||
#define PLUGINS_SAMPLESOURCE_SOAPYSDRINPUT_SOAPYSDRINPUTSETTINGS_H_
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QString>
|
||||
|
||||
struct SoapySDRInputSettings {
|
||||
typedef enum {
|
||||
FC_POS_INFRA = 0,
|
||||
FC_POS_SUPRA,
|
||||
FC_POS_CENTER
|
||||
} fcPos_t;
|
||||
|
||||
quint64 m_centerFrequency;
|
||||
qint32 m_LOppmTenths;
|
||||
qint32 m_devSampleRate;
|
||||
quint32 m_log2Decim;
|
||||
fcPos_t m_fcPos;
|
||||
bool m_dcBlock;
|
||||
bool m_iqCorrection;
|
||||
bool m_transverterMode;
|
||||
qint64 m_transverterDeltaFrequency;
|
||||
QString m_fileRecordName;
|
||||
|
||||
SoapySDRInputSettings();
|
||||
void resetToDefaults();
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
};
|
||||
|
||||
#endif /* PLUGINS_SAMPLESOURCE_SOAPYSDRINPUT_SOAPYSDRINPUTSETTINGS_H_ */
|
532
plugins/samplesource/soapysdrinput/soapysdrinputthread.cpp
Normal file
532
plugins/samplesource/soapysdrinput/soapysdrinputthread.cpp
Normal file
@ -0,0 +1,532 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <SoapySDR/Formats.hpp>
|
||||
#include <SoapySDR/Errors.hpp>
|
||||
|
||||
#include "dsp/samplesinkfifo.h"
|
||||
#include "soapysdr/devicesoapysdr.h"
|
||||
|
||||
#include "soapysdrinputthread.h"
|
||||
|
||||
SoapySDRInputThread::SoapySDRInputThread(SoapySDR::Device* dev, unsigned int nbRxChannels, QObject* parent) :
|
||||
QThread(parent),
|
||||
m_running(false),
|
||||
m_dev(dev),
|
||||
m_sampleRate(0),
|
||||
m_nbChannels(nbRxChannels),
|
||||
m_decimatorType(DecimatorFloat)
|
||||
{
|
||||
qDebug("SoapySDRInputThread::SoapySDRInputThread");
|
||||
m_channels = new Channel[nbRxChannels];
|
||||
|
||||
for (unsigned int i = 0; i < nbRxChannels; i++) {
|
||||
m_channels[i].m_convertBuffer.resize(DeviceSoapySDR::blockSize, Sample{0,0});
|
||||
}
|
||||
|
||||
m_buf = new qint16[2*DeviceSoapySDR::blockSize*nbRxChannels];
|
||||
}
|
||||
|
||||
SoapySDRInputThread::~SoapySDRInputThread()
|
||||
{
|
||||
qDebug("SoapySDRInputThread::~SoapySDRInputThread");
|
||||
|
||||
if (m_running) {
|
||||
stopWork();
|
||||
}
|
||||
|
||||
delete[] m_buf;
|
||||
delete[] m_channels;
|
||||
}
|
||||
|
||||
void SoapySDRInputThread::startWork()
|
||||
{
|
||||
m_startWaitMutex.lock();
|
||||
start();
|
||||
|
||||
while(!m_running) {
|
||||
m_startWaiter.wait(&m_startWaitMutex, 100);
|
||||
}
|
||||
|
||||
m_startWaitMutex.unlock();
|
||||
}
|
||||
|
||||
void SoapySDRInputThread::stopWork()
|
||||
{
|
||||
m_running = false;
|
||||
wait();
|
||||
}
|
||||
|
||||
void SoapySDRInputThread::run()
|
||||
{
|
||||
m_running = true;
|
||||
m_startWaiter.wakeAll();
|
||||
|
||||
unsigned int nbFifos = getNbFifos();
|
||||
|
||||
if ((m_nbChannels > 0) && (nbFifos > 0))
|
||||
{
|
||||
// build channels list
|
||||
std::vector<std::size_t> channels(m_nbChannels);
|
||||
std::iota(channels.begin(), channels.end(), 0); // Fill with 0, 1, ..., m_nbChannels-1.
|
||||
|
||||
//initialize the sample rate for all channels
|
||||
for (const auto &it : channels) {
|
||||
m_dev->setSampleRate(SOAPY_SDR_RX, it, m_sampleRate);
|
||||
}
|
||||
|
||||
// Determine sample format to be used
|
||||
double fullScale(0.0);
|
||||
std::string format = m_dev->getNativeStreamFormat(SOAPY_SDR_RX, channels.front(), fullScale);
|
||||
|
||||
if ((format == "CF8") && (fullScale == 128.0)) { // 8 bit signed - native
|
||||
m_decimatorType = Decimator8;
|
||||
} else if ((format == "CF16") && (fullScale == 2048.0)) { // 12 bit signed - native
|
||||
m_decimatorType = Decimator12;
|
||||
} else if ((format == "CF16") && (fullScale == 32768.0)) { // 16 bit signed - native
|
||||
m_decimatorType = Decimator16;
|
||||
} else { // for other types make a conversion to float
|
||||
m_decimatorType = DecimatorFloat;
|
||||
format = "CF32";
|
||||
}
|
||||
|
||||
unsigned int elemSize = SoapySDR::formatToSize(format); // sample (I+Q) size in bytes
|
||||
SoapySDR::Stream *stream = m_dev->setupStream(SOAPY_SDR_RX, format, channels);
|
||||
|
||||
//allocate buffers for the stream read/write
|
||||
const unsigned int numElems = m_dev->getStreamMTU(stream); // number of samples (I+Q)
|
||||
std::vector<std::vector<char>> buffMem(m_nbChannels, std::vector<char>(elemSize*numElems));
|
||||
std::vector<void *> buffs(m_nbChannels);
|
||||
|
||||
for (std::size_t i = 0; i < m_nbChannels; i++) {
|
||||
buffs[i] = buffMem[i].data();
|
||||
}
|
||||
|
||||
qDebug("SoapySDRInputThread::run: start running loop");
|
||||
m_dev->activateStream(stream);
|
||||
int flags(0);
|
||||
long long timeNs(0);
|
||||
|
||||
while (m_running)
|
||||
{
|
||||
int ret = m_dev->readStream(stream, buffs.data(), numElems, flags, timeNs);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
qCritical("SoapySDRInputThread::run: Unexpected read stream error: %s", SoapySDR::errToStr(ret));
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_nbChannels > 1)
|
||||
{
|
||||
callbackMI(buffs, (elemSize/2)*numElems);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_decimatorType)
|
||||
{
|
||||
case Decimator8:
|
||||
callbackSI8((const qint8*) buffs[0], (elemSize/2)*numElems);
|
||||
break;
|
||||
case Decimator12:
|
||||
callbackSI12((const qint16*) buffs[0], (elemSize/2)*numElems);
|
||||
break;
|
||||
case Decimator16:
|
||||
callbackSI16((const qint16*) buffs[0], (elemSize/2)*numElems);
|
||||
break;
|
||||
case DecimatorFloat:
|
||||
default:
|
||||
callbackSIF((const float*) buffs[0], (elemSize/2)*numElems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qDebug("SoapySDRInputThread::run: stop running loop");
|
||||
m_dev->deactivateStream(stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning("SoapySDRInputThread::run: no channels or FIFO allocated. Aborting");
|
||||
}
|
||||
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
unsigned int SoapySDRInputThread::getNbFifos()
|
||||
{
|
||||
unsigned int fifoCount = 0;
|
||||
|
||||
for (unsigned int i = 0; i < m_nbChannels; i++)
|
||||
{
|
||||
if (m_channels[i].m_sampleFifo) {
|
||||
fifoCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return fifoCount;
|
||||
}
|
||||
|
||||
void SoapySDRInputThread::setLog2Decimation(unsigned int channel, unsigned int log2_decim)
|
||||
{
|
||||
if (channel < m_nbChannels) {
|
||||
m_channels[channel].m_log2Decim = log2_decim;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int SoapySDRInputThread::getLog2Decimation(unsigned int channel) const
|
||||
{
|
||||
if (channel < m_nbChannels) {
|
||||
return m_channels[channel].m_log2Decim;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SoapySDRInputThread::setFcPos(unsigned int channel, int fcPos)
|
||||
{
|
||||
if (channel < m_nbChannels) {
|
||||
m_channels[channel].m_fcPos = fcPos;
|
||||
}
|
||||
}
|
||||
|
||||
int SoapySDRInputThread::getFcPos(unsigned int channel) const
|
||||
{
|
||||
if (channel < m_nbChannels) {
|
||||
return m_channels[channel].m_fcPos;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SoapySDRInputThread::setFifo(unsigned int channel, SampleSinkFifo *sampleFifo)
|
||||
{
|
||||
if (channel < m_nbChannels) {
|
||||
m_channels[channel].m_sampleFifo = sampleFifo;
|
||||
}
|
||||
}
|
||||
|
||||
SampleSinkFifo *SoapySDRInputThread::getFifo(unsigned int channel)
|
||||
{
|
||||
if (channel < m_nbChannels) {
|
||||
return m_channels[channel].m_sampleFifo;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SoapySDRInputThread::callbackMI(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);
|
||||
break;
|
||||
case Decimator12:
|
||||
callbackSI12((const qint16*) buffs[ichan], samplesPerChannel, ichan);
|
||||
break;
|
||||
case Decimator16:
|
||||
callbackSI16((const qint16*) buffs[ichan], samplesPerChannel, ichan);
|
||||
break;
|
||||
case DecimatorFloat:
|
||||
default:
|
||||
callbackSIF((const float*) buffs[ichan], samplesPerChannel, ichan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SoapySDRInputThread::callbackSI8(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);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_channels[channel].m_fcPos == 0) // Infra
|
||||
{
|
||||
switch (m_channels[channel].m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
m_channels[channel].m_decimators8.decimate2_inf(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_channels[channel].m_decimators8.decimate4_inf(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_channels[channel].m_decimators8.decimate8_inf(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_channels[channel].m_decimators8.decimate16_inf(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_channels[channel].m_decimators8.decimate32_inf(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_channels[channel].m_decimators8.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_decimators8.decimate2_sup(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_channels[channel].m_decimators8.decimate4_sup(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_channels[channel].m_decimators8.decimate8_sup(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_channels[channel].m_decimators8.decimate16_sup(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_channels[channel].m_decimators8.decimate32_sup(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_channels[channel].m_decimators8.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_decimators8.decimate2_cen(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_channels[channel].m_decimators8.decimate4_cen(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_channels[channel].m_decimators8.decimate8_cen(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_channels[channel].m_decimators8.decimate16_cen(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_channels[channel].m_decimators8.decimate32_cen(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_channels[channel].m_decimators8.decimate64_cen(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
|
||||
}
|
||||
|
||||
void SoapySDRInputThread::callbackSI12(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_decimators12.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_decimators12.decimate2_inf(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_channels[channel].m_decimators12.decimate4_inf(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_channels[channel].m_decimators12.decimate8_inf(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_channels[channel].m_decimators12.decimate16_inf(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_channels[channel].m_decimators12.decimate32_inf(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_channels[channel].m_decimators12.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_decimators12.decimate2_sup(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_channels[channel].m_decimators12.decimate4_sup(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_channels[channel].m_decimators12.decimate8_sup(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_channels[channel].m_decimators12.decimate16_sup(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_channels[channel].m_decimators12.decimate32_sup(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_channels[channel].m_decimators12.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_decimators12.decimate2_cen(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_channels[channel].m_decimators12.decimate4_cen(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_channels[channel].m_decimators12.decimate8_cen(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_channels[channel].m_decimators12.decimate16_cen(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_channels[channel].m_decimators12.decimate32_cen(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_channels[channel].m_decimators12.decimate64_cen(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
|
||||
}
|
||||
|
||||
void SoapySDRInputThread::callbackSI16(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);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_channels[channel].m_fcPos == 0) // Infra
|
||||
{
|
||||
switch (m_channels[channel].m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
m_channels[channel].m_decimators16.decimate2_inf(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_channels[channel].m_decimators16.decimate4_inf(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_channels[channel].m_decimators16.decimate8_inf(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_channels[channel].m_decimators16.decimate16_inf(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_channels[channel].m_decimators16.decimate32_inf(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_channels[channel].m_decimators16.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_decimators16.decimate2_sup(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_channels[channel].m_decimators16.decimate4_sup(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_channels[channel].m_decimators16.decimate8_sup(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_channels[channel].m_decimators16.decimate16_sup(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_channels[channel].m_decimators16.decimate32_sup(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_channels[channel].m_decimators16.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_decimators16.decimate2_cen(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
m_channels[channel].m_decimators16.decimate4_cen(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
m_channels[channel].m_decimators16.decimate8_cen(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
m_channels[channel].m_decimators16.decimate16_cen(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
m_channels[channel].m_decimators16.decimate32_cen(&it, buf, len);
|
||||
break;
|
||||
case 6:
|
||||
m_channels[channel].m_decimators16.decimate64_cen(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
|
||||
}
|
108
plugins/samplesource/soapysdrinput/soapysdrinputthread.h
Normal file
108
plugins/samplesource/soapysdrinput/soapysdrinputthread.h
Normal file
@ -0,0 +1,108 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2018 Edouard Griffiths, F4EXB //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PLUGINS_SAMPLESOURCE_SOAPYSDRINPUT_SOAPYSDRINPUTTHREAD_H_
|
||||
#define PLUGINS_SAMPLESOURCE_SOAPYSDRINPUT_SOAPYSDRINPUTTHREAD_H_
|
||||
|
||||
// SoapySDR is a device wrapper with a single stream supporting one or many Rx
|
||||
// Therefore only one thread can be allocated for the Rx side
|
||||
// All FIFOs must be registered before calling startWork()
|
||||
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
|
||||
#include <SoapySDR/Device.hpp>
|
||||
|
||||
#include "soapysdr/devicesoapysdrshared.h"
|
||||
#include "dsp/decimators.h"
|
||||
#include "dsp/decimatorsfi.h"
|
||||
|
||||
class SampleSinkFifo;
|
||||
|
||||
class SoapySDRInputThread : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SoapySDRInputThread(SoapySDR::Device* dev, unsigned int nbRxChannels, QObject* parent = NULL);
|
||||
~SoapySDRInputThread();
|
||||
|
||||
void startWork();
|
||||
void stopWork();
|
||||
bool isRunning() const { return m_running; }
|
||||
unsigned int getNbChannels() const { return m_nbChannels; }
|
||||
void setLog2Decimation(unsigned int channel, unsigned int log2_decim);
|
||||
unsigned int getLog2Decimation(unsigned int channel) const;
|
||||
void setSampleRate(unsigned int sampleRate) { m_sampleRate = sampleRate; }
|
||||
unsigned int getSampleRate() const { return m_sampleRate; }
|
||||
void setFcPos(unsigned int channel, int fcPos);
|
||||
int getFcPos(unsigned int channel) const;
|
||||
void setFifo(unsigned int channel, SampleSinkFifo *sampleFifo);
|
||||
SampleSinkFifo *getFifo(unsigned int channel);
|
||||
|
||||
private:
|
||||
struct Channel
|
||||
{
|
||||
SampleVector m_convertBuffer;
|
||||
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;
|
||||
|
||||
Channel() :
|
||||
m_sampleFifo(0),
|
||||
m_log2Decim(0),
|
||||
m_fcPos(0)
|
||||
{}
|
||||
|
||||
~Channel()
|
||||
{}
|
||||
};
|
||||
|
||||
enum DecimatorType
|
||||
{
|
||||
Decimator8,
|
||||
Decimator12,
|
||||
Decimator16,
|
||||
DecimatorFloat
|
||||
};
|
||||
|
||||
QMutex m_startWaitMutex;
|
||||
QWaitCondition m_startWaiter;
|
||||
bool m_running;
|
||||
SoapySDR::Device* m_dev;
|
||||
|
||||
Channel *m_channels; //!< Array of channels dynamically allocated for the given number of Rx channels
|
||||
unsigned int m_sampleRate;
|
||||
qint16 *m_buf; //!< Full buffer for SISO or MIMO operation
|
||||
unsigned int m_nbChannels;
|
||||
DecimatorType m_decimatorType;
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* PLUGINS_SAMPLESOURCE_SOAPYSDRINPUT_SOAPYSDRINPUTTHREAD_H_ */
|
Loading…
Reference in New Issue
Block a user