mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-23 01:55:48 -05:00
Support for Airspy: first working version
This commit is contained in:
parent
7e88cfcd48
commit
efa1a0c58a
@ -51,7 +51,7 @@ If you use your own location for libairspy install directory you need to specify
|
|||||||
|
|
||||||
`-DLIBAIRSPY_LIBRARIES=/opt/install/libairspy/lib/libairspy.so -DLIBAIRSPY_INCLUDE_DIR=/opt/install/libairspy/include`
|
`-DLIBAIRSPY_LIBRARIES=/opt/install/libairspy/lib/libairspy.so -DLIBAIRSPY_INCLUDE_DIR=/opt/install/libairspy/include`
|
||||||
|
|
||||||
Please note that if you are not using a recent version of libairspy (>= 1.0.6) the dynamic retrieval of sample rates is not supported. In this case you should modify the `plugins/samplesource/airspy/CMakeLists.txt` and change line `add_definitions(${QT_DEFINITIONS})` by `add_definitions("${QT_DEFINITIONS} -DLIBAIRSPY_OLD")`. In fact both lines are present with the former one commented out.
|
Please note that if you are using a recent version of libairspy (>= 1.0.6) the dynamic retrieval of sample rates is supported. To benefit from it you should modify the `plugins/samplesource/airspy/CMakeLists.txt` and change line `add_definitions(${QT_DEFINITIONS})` by `add_definitions("${QT_DEFINITIONS} -DLIBAIRSPY_DYN_RATES")`. In fact both lines are present with the last one commented out.
|
||||||
|
|
||||||
<h2>BladeRF</h2>
|
<h2>BladeRF</h2>
|
||||||
|
|
||||||
|
@ -29,8 +29,8 @@ include_directories(
|
|||||||
)
|
)
|
||||||
|
|
||||||
#include(${QT_USE_FILE})
|
#include(${QT_USE_FILE})
|
||||||
#add_definitions("${QT_DEFINITIONS} -DLIBAIRSPY_OLD")
|
#add_definitions(${QT_DEFINITIONS})
|
||||||
add_definitions(${QT_DEFINITIONS})
|
add_definitions("${QT_DEFINITIONS} -DLIBAIRSPY_DYN_RATES")
|
||||||
add_definitions(-DQT_PLUGIN)
|
add_definitions(-DQT_PLUGIN)
|
||||||
add_definitions(-DQT_SHARED)
|
add_definitions(-DQT_SHARED)
|
||||||
|
|
||||||
|
@ -37,6 +37,9 @@ AirspyGui::AirspyGui(PluginAPI* pluginAPI, QWidget* parent) :
|
|||||||
displaySettings();
|
displaySettings();
|
||||||
|
|
||||||
m_sampleSource = new AirspyInput();
|
m_sampleSource = new AirspyInput();
|
||||||
|
m_rates = ((AirspyInput*) m_sampleSource)->getSampleRates();
|
||||||
|
displaySampleRates();
|
||||||
|
connect(m_sampleSource->getOutputMessageQueueToGUI(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages()));
|
||||||
DSPEngine::instance()->setSource(m_sampleSource);
|
DSPEngine::instance()->setSource(m_sampleSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +97,9 @@ bool AirspyGui::handleMessage(const Message& message)
|
|||||||
{
|
{
|
||||||
if (AirspyInput::MsgReportAirspy::match(message))
|
if (AirspyInput::MsgReportAirspy::match(message))
|
||||||
{
|
{
|
||||||
displaySettings();
|
qDebug() << "AirspyGui::handleMessage: MsgReportAirspy";
|
||||||
|
m_rates = ((AirspyInput::MsgReportAirspy&) message).getSampleRates();
|
||||||
|
displaySampleRates();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -103,6 +108,21 @@ bool AirspyGui::handleMessage(const Message& message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AirspyGui::handleSourceMessages()
|
||||||
|
{
|
||||||
|
Message* message;
|
||||||
|
|
||||||
|
while ((message = m_sampleSource->getOutputMessageQueueToGUI()->pop()) != 0)
|
||||||
|
{
|
||||||
|
qDebug("AirspyGui::HandleSourceMessages: message: %s", message->getIdentifier());
|
||||||
|
|
||||||
|
if (handleMessage(*message))
|
||||||
|
{
|
||||||
|
delete message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AirspyGui::displaySettings()
|
void AirspyGui::displaySettings()
|
||||||
{
|
{
|
||||||
ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000);
|
ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000);
|
||||||
@ -129,6 +149,33 @@ void AirspyGui::displaySettings()
|
|||||||
ui->vga->setValue(m_settings.m_vgaGain);
|
ui->vga->setValue(m_settings.m_vgaGain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AirspyGui::displaySampleRates()
|
||||||
|
{
|
||||||
|
int savedIndex = m_settings.m_devSampleRateIndex;
|
||||||
|
ui->sampleRate->blockSignals(true);
|
||||||
|
|
||||||
|
if (m_rates.size() > 0)
|
||||||
|
{
|
||||||
|
ui->sampleRate->clear();
|
||||||
|
|
||||||
|
for (int i = 0; i < m_rates.size(); i++)
|
||||||
|
{
|
||||||
|
ui->sampleRate->addItem(QString("%1M").arg(QString::number(m_rates[i]/1000000.0, 'f', 3)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->sampleRate->blockSignals(false);
|
||||||
|
|
||||||
|
if (savedIndex < m_rates.size())
|
||||||
|
{
|
||||||
|
ui->sampleRate->setCurrentIndex(savedIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->sampleRate->setCurrentIndex((int) m_rates.size()-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AirspyGui::sendSettings()
|
void AirspyGui::sendSettings()
|
||||||
{
|
{
|
||||||
if(!m_updateTimer.isActive())
|
if(!m_updateTimer.isActive())
|
||||||
@ -188,7 +235,7 @@ void AirspyGui::on_lna_valueChanged(int value)
|
|||||||
if ((value < 0) || (value > 14))
|
if ((value < 0) || (value > 14))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ui->lnaGainText->setText(tr("%1dB").arg(value*3));
|
ui->lnaGainText->setText(tr("%1dB").arg(value));
|
||||||
m_settings.m_lnaGain = value;
|
m_settings.m_lnaGain = value;
|
||||||
sendSettings();
|
sendSettings();
|
||||||
}
|
}
|
||||||
@ -198,7 +245,7 @@ void AirspyGui::on_mix_valueChanged(int value)
|
|||||||
if ((value < 0) || (value > 15))
|
if ((value < 0) || (value > 15))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ui->mixText->setText(tr("%1dB").arg(value*3));
|
ui->mixText->setText(tr("%1dB").arg(value));
|
||||||
m_settings.m_lnaGain = value;
|
m_settings.m_lnaGain = value;
|
||||||
sendSettings();
|
sendSettings();
|
||||||
}
|
}
|
||||||
@ -208,7 +255,7 @@ void AirspyGui::on_vga_valueChanged(int value)
|
|||||||
if ((value < 0) || (value > 15))
|
if ((value < 0) || (value > 15))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ui->vgaText->setText(tr("%1dB").arg(value*3));
|
ui->vgaText->setText(tr("%1dB").arg(value));
|
||||||
m_settings.m_lnaGain = value;
|
m_settings.m_lnaGain = value;
|
||||||
sendSettings();
|
sendSettings();
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@ private:
|
|||||||
SampleSource* m_sampleSource;
|
SampleSource* m_sampleSource;
|
||||||
|
|
||||||
void displaySettings();
|
void displaySettings();
|
||||||
|
void displaySampleRates();
|
||||||
void sendSettings();
|
void sendSettings();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
@ -73,6 +74,7 @@ private slots:
|
|||||||
void on_mix_valueChanged(int value);
|
void on_mix_valueChanged(int value);
|
||||||
void on_vga_valueChanged(int value);
|
void on_vga_valueChanged(int value);
|
||||||
void updateHardware();
|
void updateHardware();
|
||||||
|
void handleSourceMessages();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INCLUDE_AIRSPYGUI_H
|
#endif // INCLUDE_AIRSPYGUI_H
|
||||||
|
@ -351,7 +351,7 @@
|
|||||||
<number>1</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="value">
|
<property name="value">
|
||||||
<number>15</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
@ -410,7 +410,7 @@
|
|||||||
<number>1</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="value">
|
<property name="value">
|
||||||
<number>9</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
|
@ -100,6 +100,8 @@ AirspyInput::AirspyInput() :
|
|||||||
m_airspyThread(0),
|
m_airspyThread(0),
|
||||||
m_deviceDescription("Airspy")
|
m_deviceDescription("Airspy")
|
||||||
{
|
{
|
||||||
|
m_sampleRates.push_back(10000000);
|
||||||
|
m_sampleRates.push_back(2500000);
|
||||||
}
|
}
|
||||||
|
|
||||||
AirspyInput::~AirspyInput()
|
AirspyInput::~AirspyInput()
|
||||||
@ -135,16 +137,13 @@ bool AirspyInput::start(int device)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_dev = open_airspy_from_sequence(device)) == 0) // TODO: fix; Open first available device as there is no proper handling for multiple devices
|
if ((m_dev = open_airspy_from_sequence(device)) == 0)
|
||||||
{
|
{
|
||||||
qCritical("AirspyInput::start: could not open Airspy");
|
qCritical("AirspyInput::start: could not open Airspy #%d", device);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LIBAIRSPY_OLD
|
#ifdef LIBAIRSPY_DYN_RATES
|
||||||
m_sampleRates.push_back(2500000);
|
|
||||||
m_sampleRates.push_back(10000000);
|
|
||||||
#else
|
|
||||||
uint32_t nbSampleRates;
|
uint32_t nbSampleRates;
|
||||||
uint32_t *sampleRates;
|
uint32_t *sampleRates;
|
||||||
|
|
||||||
@ -160,14 +159,20 @@ bool AirspyInput::start(int device)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_sampleRates.clear();
|
||||||
|
|
||||||
for (int i=0; i<nbSampleRates; i++)
|
for (int i=0; i<nbSampleRates; i++)
|
||||||
{
|
{
|
||||||
m_sampleRates.push_back(sampleRates[i]);
|
m_sampleRates.push_back(sampleRates[i]);
|
||||||
|
qDebug("AirspyInput::start: sampleRates[%d] = %u Hz", i, sampleRates[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] sampleRates;
|
delete[] sampleRates;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
MsgReportAirspy *message = MsgReportAirspy::create(m_sampleRates);
|
||||||
|
getOutputMessageQueueToGUI()->push(message);
|
||||||
|
|
||||||
rc = (airspy_error) airspy_set_sample_type(m_dev, AIRSPY_SAMPLE_INT16_IQ);
|
rc = (airspy_error) airspy_set_sample_type(m_dev, AIRSPY_SAMPLE_INT16_IQ);
|
||||||
|
|
||||||
if (rc != AIRSPY_SUCCESS)
|
if (rc != AIRSPY_SUCCESS)
|
||||||
@ -176,31 +181,27 @@ bool AirspyInput::start(int device)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
applySettings(m_settings, true);
|
if((m_airspyThread = new AirspyThread(m_dev, &m_sampleFifo)) == 0)
|
||||||
|
{
|
||||||
MsgReportAirspy *message = MsgReportAirspy::create(m_sampleRates);
|
qFatal("AirspyInput::start: out of memory");
|
||||||
getOutputMessageQueueToGUI()->push(message);
|
stop();
|
||||||
|
return false;
|
||||||
if((m_airspyThread = new AirspyThread(m_dev, &m_sampleFifo)) == NULL) {
|
|
||||||
qFatal("out of memory");
|
|
||||||
goto failed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_airspyThread->startWork();
|
m_airspyThread->startWork();
|
||||||
|
|
||||||
mutexLocker.unlock();
|
mutexLocker.unlock();
|
||||||
|
|
||||||
|
applySettings(m_settings, true);
|
||||||
|
|
||||||
qDebug("AirspyInput::startInput: started");
|
qDebug("AirspyInput::startInput: started");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
failed:
|
|
||||||
stop();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AirspyInput::stop()
|
void AirspyInput::stop()
|
||||||
{
|
{
|
||||||
|
qDebug("AirspyInput::stop");
|
||||||
QMutexLocker mutexLocker(&m_mutex);
|
QMutexLocker mutexLocker(&m_mutex);
|
||||||
|
|
||||||
if(m_airspyThread != 0)
|
if(m_airspyThread != 0)
|
||||||
@ -243,7 +244,9 @@ bool AirspyInput::handleMessage(const Message& message)
|
|||||||
MsgConfigureAirspy& conf = (MsgConfigureAirspy&) message;
|
MsgConfigureAirspy& conf = (MsgConfigureAirspy&) message;
|
||||||
qDebug() << "AirspyInput::handleMessage: MsgConfigureAirspy";
|
qDebug() << "AirspyInput::handleMessage: MsgConfigureAirspy";
|
||||||
|
|
||||||
if (!applySettings(conf.getSettings(), false))
|
bool success = applySettings(conf.getSettings(), false);
|
||||||
|
|
||||||
|
if (!success)
|
||||||
{
|
{
|
||||||
qDebug("Airspy config error");
|
qDebug("Airspy config error");
|
||||||
}
|
}
|
||||||
@ -274,32 +277,29 @@ void AirspyInput::setCenterFrequency(quint64 freq_hz)
|
|||||||
|
|
||||||
bool AirspyInput::applySettings(const Settings& settings, bool force)
|
bool AirspyInput::applySettings(const Settings& settings, bool force)
|
||||||
{
|
{
|
||||||
bool forwardChange = false;
|
|
||||||
airspy_error rc;
|
|
||||||
qint64 deviceCenterFrequency = m_settings.m_centerFrequency;
|
|
||||||
qint64 f_img = deviceCenterFrequency;
|
|
||||||
quint32 devSampleRate = m_sampleRates[m_settings.m_devSampleRateIndex];
|
|
||||||
|
|
||||||
QMutexLocker mutexLocker(&m_mutex);
|
QMutexLocker mutexLocker(&m_mutex);
|
||||||
|
|
||||||
qDebug() << "AirspyInput::applySettings: m_dev: " << m_dev;
|
bool forwardChange = false;
|
||||||
|
airspy_error rc;
|
||||||
|
|
||||||
|
qDebug() << "AirspyInput::applySettings";
|
||||||
|
|
||||||
if ((m_settings.m_devSampleRateIndex != settings.m_devSampleRateIndex) || force)
|
if ((m_settings.m_devSampleRateIndex != settings.m_devSampleRateIndex) || force)
|
||||||
{
|
{
|
||||||
|
forwardChange = true;
|
||||||
|
|
||||||
if (settings.m_devSampleRateIndex < m_sampleRates.size())
|
if (settings.m_devSampleRateIndex < m_sampleRates.size())
|
||||||
{
|
{
|
||||||
m_settings.m_devSampleRateIndex = settings.m_devSampleRateIndex;
|
m_settings.m_devSampleRateIndex = settings.m_devSampleRateIndex;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_settings.m_devSampleRateIndex = m_sampleRates.size() - 1;
|
m_settings.m_devSampleRateIndex = m_sampleRates.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
forwardChange = true;
|
|
||||||
|
|
||||||
if (m_dev != 0)
|
if (m_dev != 0)
|
||||||
{
|
{
|
||||||
rc = (airspy_error) airspy_set_samplerate(m_dev, static_cast<airspy_samplerate_t>(m_sampleRates[m_settings.m_devSampleRateIndex]));
|
rc = (airspy_error) airspy_set_samplerate(m_dev, static_cast<airspy_samplerate_t>(m_settings.m_devSampleRateIndex));
|
||||||
|
|
||||||
if (rc != AIRSPY_SUCCESS)
|
if (rc != AIRSPY_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -336,6 +336,10 @@ bool AirspyInput::applySettings(const Settings& settings, bool force)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qint64 deviceCenterFrequency = m_settings.m_centerFrequency;
|
||||||
|
qint64 f_img = deviceCenterFrequency;
|
||||||
|
quint32 devSampleRate = m_sampleRates[m_settings.m_devSampleRateIndex];
|
||||||
|
|
||||||
if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force)
|
if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force)
|
||||||
{
|
{
|
||||||
m_settings.m_centerFrequency = settings.m_centerFrequency;
|
m_settings.m_centerFrequency = settings.m_centerFrequency;
|
||||||
@ -461,12 +465,16 @@ bool AirspyInput::applySettings(const Settings& settings, bool force)
|
|||||||
|
|
||||||
struct airspy_device *AirspyInput::open_airspy_from_sequence(int sequence)
|
struct airspy_device *AirspyInput::open_airspy_from_sequence(int sequence)
|
||||||
{
|
{
|
||||||
struct airspy_device *devinfo;
|
airspy_read_partid_serialno_t read_partid_serialno;
|
||||||
int rc;
|
struct airspy_device *devinfo, *retdev = 0;
|
||||||
|
uint32_t serial_msb = 0;
|
||||||
|
uint32_t serial_lsb = 0;
|
||||||
|
airspy_error rc;
|
||||||
|
int i;
|
||||||
|
|
||||||
for (int i=0; i < AIRSPY_MAX_DEVICE; i++)
|
for (int i = 0; i < AIRSPY_MAX_DEVICE; i++)
|
||||||
{
|
{
|
||||||
rc = airspy_open(&devinfo);
|
rc = (airspy_error) airspy_open(&devinfo);
|
||||||
|
|
||||||
if (rc == AIRSPY_SUCCESS)
|
if (rc == AIRSPY_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -474,10 +482,14 @@ struct airspy_device *AirspyInput::open_airspy_from_sequence(int sequence)
|
|||||||
{
|
{
|
||||||
return devinfo;
|
return devinfo;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
airspy_close(devinfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break; // finished
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +98,7 @@ public:
|
|||||||
virtual const QString& getDeviceDescription() const;
|
virtual const QString& getDeviceDescription() const;
|
||||||
virtual int getSampleRate() const;
|
virtual int getSampleRate() const;
|
||||||
virtual quint64 getCenterFrequency() const;
|
virtual quint64 getCenterFrequency() const;
|
||||||
|
const std::vector<uint32_t>& getSampleRates() const { return m_sampleRates; }
|
||||||
|
|
||||||
virtual bool handleMessage(const Message& message);
|
virtual bool handleMessage(const Message& message);
|
||||||
|
|
||||||
|
@ -53,8 +53,11 @@ PluginInterface::SampleSourceDevices AirspyPlugin::enumSampleSources()
|
|||||||
{
|
{
|
||||||
SampleSourceDevices result;
|
SampleSourceDevices result;
|
||||||
airspy_read_partid_serialno_t read_partid_serialno;
|
airspy_read_partid_serialno_t read_partid_serialno;
|
||||||
struct airspy_device *devinfo = 0;
|
struct airspy_device *devinfo;
|
||||||
|
uint32_t serial_msb = 0;
|
||||||
|
uint32_t serial_lsb = 0;
|
||||||
airspy_error rc;
|
airspy_error rc;
|
||||||
|
int i;
|
||||||
|
|
||||||
rc = (airspy_error) airspy_init();
|
rc = (airspy_error) airspy_init();
|
||||||
|
|
||||||
@ -63,29 +66,40 @@ PluginInterface::SampleSourceDevices AirspyPlugin::enumSampleSources()
|
|||||||
qCritical("AirspyPlugin::enumSampleSources: failed to initiate Airspy library: %s", airspy_error_name(rc));
|
qCritical("AirspyPlugin::enumSampleSources: failed to initiate Airspy library: %s", airspy_error_name(rc));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i < AIRSPY_MAX_DEVICE; i++)
|
for (i=0; i < AIRSPY_MAX_DEVICE; i++)
|
||||||
{
|
{
|
||||||
rc = (airspy_error) airspy_open(&devinfo);
|
rc = (airspy_error) airspy_open(&devinfo);
|
||||||
|
|
||||||
if (rc == AIRSPY_SUCCESS)
|
if (rc == AIRSPY_SUCCESS)
|
||||||
{
|
{
|
||||||
|
qDebug("AirspyPlugin::enumSampleSources: try to enumerate Airspy device #%d", i);
|
||||||
|
|
||||||
rc = (airspy_error) airspy_board_partid_serialno_read(devinfo, &read_partid_serialno);
|
rc = (airspy_error) airspy_board_partid_serialno_read(devinfo, &read_partid_serialno);
|
||||||
|
|
||||||
if (rc != AIRSPY_SUCCESS)
|
if (rc != AIRSPY_SUCCESS)
|
||||||
{
|
{
|
||||||
qDebug("AirspyPlugin::enumSampleSources: failed to read serial no: %s", airspy_error_name(rc));
|
qDebug("AirspyPlugin::enumSampleSources: failed to read serial no: %s", airspy_error_name(rc));
|
||||||
|
airspy_close(devinfo);
|
||||||
continue; // next
|
continue; // next
|
||||||
}
|
}
|
||||||
|
|
||||||
QString serial_str = QString::number(read_partid_serialno.serial_no[2], 16) + QString::number(read_partid_serialno.serial_no[3], 16);
|
if ((read_partid_serialno.serial_no[2] != serial_msb) && (read_partid_serialno.serial_no[3] != serial_lsb))
|
||||||
uint64_t serial_num = (((uint64_t) read_partid_serialno.serial_no[2])<<32) + read_partid_serialno.serial_no[3];
|
{
|
||||||
QString displayedName(QString("Airspy #%1 0x%2").arg(i+1).arg(serial_str));
|
serial_msb = read_partid_serialno.serial_no[2];
|
||||||
SimpleSerializer s(1);
|
serial_lsb = read_partid_serialno.serial_no[3];
|
||||||
s.writeS32(1, i);
|
|
||||||
s.writeString(2, serial_str);
|
|
||||||
s.writeU64(3, serial_num);
|
|
||||||
|
|
||||||
result.append(SampleSourceDevice(displayedName, "org.osmocom.sdr.samplesource.airspy", s.final()));
|
QString serial_str = QString::number(serial_msb, 16) + QString::number(serial_lsb, 16);
|
||||||
|
uint64_t serial_num = (((uint64_t) serial_msb)<<32) + serial_lsb;
|
||||||
|
QString displayedName(QString("Airspy #%1 0x%2").arg(i).arg(serial_str));
|
||||||
|
SimpleSerializer s(1);
|
||||||
|
s.writeS32(1, i);
|
||||||
|
s.writeString(2, serial_str);
|
||||||
|
s.writeU64(3, serial_num);
|
||||||
|
result.append(SampleSourceDevice(displayedName, "org.osmocom.sdr.samplesource.airspy", s.final()));
|
||||||
|
qDebug("AirspyPlugin::enumSampleSources: enumerated Airspy device #%d", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
airspy_close(devinfo);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -94,7 +108,8 @@ PluginInterface::SampleSourceDevices AirspyPlugin::enumSampleSources()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
airspy_exit();
|
rc = (airspy_error) airspy_exit();
|
||||||
|
qDebug("AirspyPlugin::enumSampleSources: airspy_exit: %s", airspy_error_name(rc));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@ void AirspyThread::startWork()
|
|||||||
|
|
||||||
void AirspyThread::stopWork()
|
void AirspyThread::stopWork()
|
||||||
{
|
{
|
||||||
|
qDebug("AirspyThread::stopWork");
|
||||||
m_running = false;
|
m_running = false;
|
||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
@ -92,6 +93,17 @@ void AirspyThread::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = (airspy_error) airspy_stop_rx(m_dev);
|
||||||
|
|
||||||
|
if (rc == AIRSPY_SUCCESS)
|
||||||
|
{
|
||||||
|
qDebug("AirspyInput::run: stopped Airspy Rx");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug("AirspyInput::run: failed to stop Airspy Rx: %s", airspy_error_name(rc));
|
||||||
|
}
|
||||||
|
|
||||||
m_running = false;
|
m_running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,13 +189,13 @@ void AirspyThread::callback(const qint16* buf, qint32 len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
m_sampleFifo->write(m_convertBuffer.begin(), it);
|
m_sampleFifo->write(m_convertBuffer.begin(), it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int AirspyThread::rx_callback(airspy_transfer_t* transfer)
|
int AirspyThread::rx_callback(airspy_transfer_t* transfer)
|
||||||
{
|
{
|
||||||
qint32 bytes_to_write = transfer->sample_count * sizeof(qint16) * 2;
|
qint32 bytes_to_write = transfer->sample_count * sizeof(qint16);
|
||||||
m_this->callback((qint16 *) transfer->samples, bytes_to_write);
|
m_this->callback((qint16 *) transfer->samples, bytes_to_write);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include "dsp/samplefifo.h"
|
#include "dsp/samplefifo.h"
|
||||||
#include "dsp/decimators.h"
|
#include "dsp/decimators.h"
|
||||||
|
|
||||||
#define AIRSPY_BLOCKSIZE (1<<14)
|
#define AIRSPY_BLOCKSIZE (1<<17)
|
||||||
|
|
||||||
class AirspyThread : public QThread {
|
class AirspyThread : public QThread {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Loading…
Reference in New Issue
Block a user