1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-12-23 01:55:48 -05:00

Local Sink: auto detect Local Input devices and fix crashes in most situations. Part of #871

This commit is contained in:
f4exb 2022-12-03 13:33:38 +01:00
parent 6cc15442e2
commit b1ba80b847
14 changed files with 218 additions and 169 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

View File

@ -34,6 +34,7 @@
#include "dsp/hbfilterchainconverter.h" #include "dsp/hbfilterchainconverter.h"
#include "dsp/devicesamplemimo.h" #include "dsp/devicesamplemimo.h"
#include "device/deviceapi.h" #include "device/deviceapi.h"
#include "device/deviceset.h"
#include "feature/feature.h" #include "feature/feature.h"
#include "settings/serializable.h" #include "settings/serializable.h"
#include "maincore.h" #include "maincore.h"
@ -42,6 +43,7 @@
#include "localsink.h" #include "localsink.h"
MESSAGE_CLASS_DEFINITION(LocalSink::MsgConfigureLocalSink, Message) MESSAGE_CLASS_DEFINITION(LocalSink::MsgConfigureLocalSink, Message)
MESSAGE_CLASS_DEFINITION(LocalSink::MsgReportDevices, Message)
const char* const LocalSink::m_channelIdURI = "sdrangel.channel.localsink"; const char* const LocalSink::m_channelIdURI = "sdrangel.channel.localsink";
const char* const LocalSink::m_channelId = "LocalSink"; const char* const LocalSink::m_channelId = "LocalSink";
@ -75,7 +77,19 @@ LocalSink::LocalSink(DeviceAPI *deviceAPI) :
this, this,
&LocalSink::handleIndexInDeviceSetChanged &LocalSink::handleIndexInDeviceSetChanged
); );
start(); // Update device list when devices are added or removed
QObject::connect(
MainCore::instance(),
&MainCore::deviceSetAdded,
this,
&LocalSink::updateDeviceSetList
);
QObject::connect(
MainCore::instance(),
&MainCore::deviceSetRemoved,
this,
&LocalSink::updateDeviceSetList
);
} }
LocalSink::~LocalSink() LocalSink::~LocalSink()
@ -89,7 +103,7 @@ LocalSink::~LocalSink()
delete m_networkManager; delete m_networkManager;
m_deviceAPI->removeChannelSinkAPI(this); m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this); m_deviceAPI->removeChannelSink(this);
stop(); stopProcessing();
} }
void LocalSink::setDeviceAPI(DeviceAPI *deviceAPI) void LocalSink::setDeviceAPI(DeviceAPI *deviceAPI)
@ -119,12 +133,18 @@ void LocalSink::feed(const SampleVector::const_iterator& begin, const SampleVect
} }
void LocalSink::start() void LocalSink::start()
{ }
void LocalSink::stop()
{ }
void LocalSink::startProcessing()
{ {
if (m_running) { if (m_running) {
return; return;
} }
qDebug("LocalSink::start"); qDebug("LocalSink::startProcessing");
m_thread = new QThread(this); m_thread = new QThread(this);
m_basebandSink = new LocalSinkBaseband(); m_basebandSink = new LocalSinkBaseband();
m_basebandSink->moveToThread(m_thread); m_basebandSink->moveToThread(m_thread);
@ -135,19 +155,24 @@ void LocalSink::start()
m_basebandSink->reset(); m_basebandSink->reset();
m_thread->start(); m_thread->start();
LocalSinkBaseband::MsgConfigureLocalSinkBaseband *msg = LocalSinkBaseband::MsgConfigureLocalSinkBaseband::create(m_settings, true); DeviceSampleSource *deviceSource = getLocalDevice(m_settings.m_localDeviceIndex);
m_basebandSink->getInputMessageQueue()->push(msg); LocalSinkBaseband::MsgConfigureLocalDeviceSampleSource *msgDevice =
LocalSinkBaseband::MsgConfigureLocalDeviceSampleSource::create(deviceSource);
m_basebandSink->getInputMessageQueue()->push(msgDevice);
LocalSinkBaseband::MsgConfigureLocalSinkBaseband *msgConfig = LocalSinkBaseband::MsgConfigureLocalSinkBaseband::create(m_settings, true);
m_basebandSink->getInputMessageQueue()->push(msgConfig);
m_running = true; m_running = true;
} }
void LocalSink::stop() void LocalSink::stopProcessing()
{ {
if (!m_running) { if (!m_running) {
return; return;
} }
qDebug("LocalSink::stop"); qDebug("LocalSink::stopProcessing");
m_running = false; m_running = false;
m_thread->exit(); m_thread->exit();
m_thread->wait(); m_thread->wait();
@ -218,27 +243,15 @@ bool LocalSink::deserialize(const QByteArray& data)
} }
} }
void LocalSink::getLocalDevices(std::vector<uint32_t>& indexes) DeviceSampleSource *LocalSink::getLocalDevice(int index)
{ {
indexes.clear(); if (index < 0) {
return nullptr;
}
DSPEngine *dspEngine = DSPEngine::instance(); DSPEngine *dspEngine = DSPEngine::instance();
for (uint32_t i = 0; i < dspEngine->getDeviceSourceEnginesNumber(); i++) if (index < (int) dspEngine->getDeviceSourceEnginesNumber())
{
DSPDeviceSourceEngine *deviceSourceEngine = dspEngine->getDeviceSourceEngineByIndex(i);
DeviceSampleSource *deviceSource = deviceSourceEngine->getSource();
if (deviceSource->getDeviceDescription() == "LocalInput") {
indexes.push_back(i);
}
}
}
DeviceSampleSource *LocalSink::getLocalDevice(uint32_t index)
{
DSPEngine *dspEngine = DSPEngine::instance();
if (index < dspEngine->getDeviceSourceEnginesNumber())
{ {
DSPDeviceSourceEngine *deviceSourceEngine = dspEngine->getDeviceSourceEngineByIndex(index); DSPDeviceSourceEngine *deviceSourceEngine = dspEngine->getDeviceSourceEngineByIndex(index);
DeviceSampleSource *deviceSource = deviceSourceEngine->getSource(); DeviceSampleSource *deviceSource = deviceSourceEngine->getSource();
@ -266,7 +279,7 @@ DeviceSampleSource *LocalSink::getLocalDevice(uint32_t index)
return nullptr; return nullptr;
} }
void LocalSink::propagateSampleRateAndFrequency(uint32_t index, uint32_t log2Decim) void LocalSink::propagateSampleRateAndFrequency(int index, uint32_t log2Decim)
{ {
qDebug() << "LocalSink::propagateSampleRateAndFrequency:" qDebug() << "LocalSink::propagateSampleRateAndFrequency:"
<< " index: " << index << " index: " << index
@ -329,10 +342,10 @@ void LocalSink::applySettings(const LocalSinkSettings& settings, bool force)
{ {
reverseAPIKeys.append("play"); reverseAPIKeys.append("play");
if (m_running) if (settings.m_play) {
{ startProcessing();
LocalSinkBaseband::MsgConfigureLocalSinkWork *msg = LocalSinkBaseband::MsgConfigureLocalSinkWork::create(settings.m_play); } else {
m_basebandSink->getInputMessageQueue()->push(msg); stopProcessing();
} }
} }
@ -682,3 +695,67 @@ void LocalSink::handleIndexInDeviceSetChanged(int index)
.arg(index); .arg(index);
m_basebandSink->setFifoLabel(fifoLabel); m_basebandSink->setFifoLabel(fifoLabel);
} }
void LocalSink::updateDeviceSetList()
{
MainCore *mainCore = MainCore::instance();
std::vector<DeviceSet*>& deviceSets = mainCore->getDeviceSets();
std::vector<DeviceSet*>::const_iterator it = deviceSets.begin();
m_localInputDeviceIndexes.clear();
unsigned int deviceIndex = 0;
for (; it != deviceSets.end(); ++it, deviceIndex++)
{
DSPDeviceSourceEngine *deviceSourceEngine = (*it)->m_deviceSourceEngine;
if (deviceSourceEngine)
{
DeviceSampleSource *deviceSource = deviceSourceEngine->getSource();
if (deviceSource->getDeviceDescription() == "LocalInput") {
m_localInputDeviceIndexes.append(deviceIndex);
}
}
}
if (m_guiMessageQueue)
{
MsgReportDevices *msg = MsgReportDevices::create();
msg->getDeviceSetIndexes() = m_localInputDeviceIndexes;
m_guiMessageQueue->push(msg);
}
LocalSinkSettings settings = m_settings;
int newIndexInList;
if (it != deviceSets.begin())
{
if (m_settings.m_localDeviceIndex < 0) {
newIndexInList = 0;
} else if (m_settings.m_localDeviceIndex >= m_localInputDeviceIndexes.size()) {
newIndexInList = m_localInputDeviceIndexes.size() - 1;
} else {
newIndexInList = m_settings.m_localDeviceIndex;
}
}
else
{
newIndexInList = -1;
}
if (newIndexInList < 0) {
settings.m_localDeviceIndex = -1; // means no device
} else {
settings.m_localDeviceIndex = m_localInputDeviceIndexes[newIndexInList];
}
qDebug("LocalSink::updateDeviceSetLists: new device index: %d device: %d", newIndexInList, settings.m_localDeviceIndex);
applySettings(settings);
if (m_guiMessageQueue)
{
MsgConfigureLocalSink *msg = MsgConfigureLocalSink::create(m_settings, false);
m_guiMessageQueue->push(msg);
}
}

View File

@ -45,8 +45,7 @@ public:
const LocalSinkSettings& getSettings() const { return m_settings; } const LocalSinkSettings& getSettings() const { return m_settings; }
bool getForce() const { return m_force; } bool getForce() const { return m_force; }
static MsgConfigureLocalSink* create(const LocalSinkSettings& settings, bool force) static MsgConfigureLocalSink* create(const LocalSinkSettings& settings, bool force) {
{
return new MsgConfigureLocalSink(settings, force); return new MsgConfigureLocalSink(settings, force);
} }
@ -61,6 +60,24 @@ public:
{ } { }
}; };
class MsgReportDevices : public Message {
MESSAGE_CLASS_DECLARATION
public:
QList<int>& getDeviceSetIndexes() { return m_deviceSetIndexes; }
static MsgReportDevices* create() {
return new MsgReportDevices();
}
private:
QList<int> m_deviceSetIndexes;
MsgReportDevices() :
Message()
{ }
};
LocalSink(DeviceAPI *deviceAPI); LocalSink(DeviceAPI *deviceAPI);
virtual ~LocalSink(); virtual ~LocalSink();
virtual void destroy() { delete this; } virtual void destroy() { delete this; }
@ -116,8 +133,8 @@ public:
const QStringList& channelSettingsKeys, const QStringList& channelSettingsKeys,
SWGSDRangel::SWGChannelSettings& response); SWGSDRangel::SWGChannelSettings& response);
void getLocalDevices(std::vector<uint32_t>& indexes);
uint32_t getNumberOfDeviceStreams() const; uint32_t getNumberOfDeviceStreams() const;
const QList<int>& getDeviceSetList() { return m_localInputDeviceIndexes; }
static const char* const m_channelIdURI; static const char* const m_channelIdURI;
static const char* const m_channelId; static const char* const m_channelId;
@ -128,6 +145,7 @@ private:
LocalSinkBaseband *m_basebandSink; LocalSinkBaseband *m_basebandSink;
bool m_running; bool m_running;
LocalSinkSettings m_settings; LocalSinkSettings m_settings;
QList<int> m_localInputDeviceIndexes;
uint64_t m_centerFrequency; uint64_t m_centerFrequency;
int64_t m_frequencyOffset; int64_t m_frequencyOffset;
@ -138,10 +156,13 @@ private:
virtual bool handleMessage(const Message& cmd); virtual bool handleMessage(const Message& cmd);
void applySettings(const LocalSinkSettings& settings, bool force = false); void applySettings(const LocalSinkSettings& settings, bool force = false);
void propagateSampleRateAndFrequency(uint32_t index, uint32_t log2Decim); void propagateSampleRateAndFrequency(int index, uint32_t log2Decim);
static void validateFilterChainHash(LocalSinkSettings& settings); static void validateFilterChainHash(LocalSinkSettings& settings);
void calculateFrequencyOffset(uint32_t log2Decim, uint32_t filterChainHash); void calculateFrequencyOffset(uint32_t log2Decim, uint32_t filterChainHash);
DeviceSampleSource *getLocalDevice(uint32_t index); void updateDeviceSetList();
DeviceSampleSource *getLocalDevice(int index);
void startProcessing();
void stopProcessing();
void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const LocalSinkSettings& settings, bool force); void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const LocalSinkSettings& settings, bool force);
void sendChannelSettings( void sendChannelSettings(

View File

@ -24,7 +24,6 @@
#include "localsinkbaseband.h" #include "localsinkbaseband.h"
MESSAGE_CLASS_DEFINITION(LocalSinkBaseband::MsgConfigureLocalSinkBaseband, Message) MESSAGE_CLASS_DEFINITION(LocalSinkBaseband::MsgConfigureLocalSinkBaseband, Message)
MESSAGE_CLASS_DEFINITION(LocalSinkBaseband::MsgConfigureLocalSinkWork, Message)
MESSAGE_CLASS_DEFINITION(LocalSinkBaseband::MsgConfigureLocalDeviceSampleSource, Message) MESSAGE_CLASS_DEFINITION(LocalSinkBaseband::MsgConfigureLocalDeviceSampleSource, Message)
LocalSinkBaseband::LocalSinkBaseband() : LocalSinkBaseband::LocalSinkBaseband() :
@ -43,10 +42,12 @@ LocalSinkBaseband::LocalSinkBaseband() :
); );
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
m_sink.start(m_localSampleSource);
} }
LocalSinkBaseband::~LocalSinkBaseband() LocalSinkBaseband::~LocalSinkBaseband()
{ {
m_sink.stop();
delete m_channelizer; delete m_channelizer;
} }
@ -123,20 +124,6 @@ bool LocalSinkBaseband::handleMessage(const Message& cmd)
return true; return true;
} }
else if (MsgConfigureLocalSinkWork::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureLocalSinkWork& conf = (MsgConfigureLocalSinkWork&) cmd;
qDebug() << "LocalSinkBaseband::handleMessage: MsgConfigureLocalSinkWork: " << conf.isWorking();
if (conf.isWorking()) {
m_sink.start(m_localSampleSource);
} else {
m_sink.stop();
}
return true;
}
else if (MsgConfigureLocalDeviceSampleSource::match(cmd)) else if (MsgConfigureLocalDeviceSampleSource::match(cmd))
{ {
QMutexLocker mutexLocker(&m_mutex); QMutexLocker mutexLocker(&m_mutex);

View File

@ -57,26 +57,6 @@ public:
{ } { }
}; };
class MsgConfigureLocalSinkWork : public Message {
MESSAGE_CLASS_DECLARATION
public:
bool isWorking() const { return m_working; }
static MsgConfigureLocalSinkWork* create(bool working)
{
return new MsgConfigureLocalSinkWork(working);
}
private:
bool m_working;
MsgConfigureLocalSinkWork(bool working) :
Message(),
m_working(working)
{ }
};
class MsgConfigureLocalDeviceSampleSource : public Message { class MsgConfigureLocalDeviceSampleSource : public Message {
MESSAGE_CLASS_DECLARATION MESSAGE_CLASS_DECLARATION

View File

@ -22,7 +22,6 @@
#include "gui/devicestreamselectiondialog.h" #include "gui/devicestreamselectiondialog.h"
#include "dsp/hbfilterchainconverter.h" #include "dsp/hbfilterchainconverter.h"
#include "dsp/dspcommands.h" #include "dsp/dspcommands.h"
#include "mainwindow.h"
#include "localsinkgui.h" #include "localsinkgui.h"
#include "localsink.h" #include "localsink.h"
@ -53,7 +52,6 @@ QByteArray LocalSinkGUI::serialize() const
bool LocalSinkGUI::deserialize(const QByteArray& data) bool LocalSinkGUI::deserialize(const QByteArray& data)
{ {
updateLocalDevices();
if (m_settings.deserialize(data)) if (m_settings.deserialize(data))
{ {
@ -90,6 +88,12 @@ bool LocalSinkGUI::handleMessage(const Message& message)
blockApplySettings(false); blockApplySettings(false);
return true; return true;
} }
else if (LocalSink::MsgReportDevices::match(message))
{
LocalSink::MsgReportDevices& report = (LocalSink::MsgReportDevices&) message;
updateDeviceSetList(report.getDeviceSetIndexes());
return true;
}
else else
{ {
return false; return false;
@ -131,7 +135,7 @@ LocalSinkGUI::LocalSinkGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseb
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages())); connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages()));
updateLocalDevices(); updateDeviceSetList(m_localSink->getDeviceSetList());
displaySettings(); displaySettings();
makeUIConnections(); makeUIConnections();
applySettings(true); applySettings(true);
@ -199,18 +203,6 @@ void LocalSinkGUI::displayRateAndShift()
m_channelMarker.setBandwidth(channelSampleRate); m_channelMarker.setBandwidth(channelSampleRate);
} }
void LocalSinkGUI::updateLocalDevices()
{
std::vector<uint32_t> localDevicesIndexes;
m_localSink->getLocalDevices(localDevicesIndexes);
ui->localDevice->clear();
std::vector<uint32_t>::const_iterator it = localDevicesIndexes.begin();
for (; it != localDevicesIndexes.end(); ++it) {
ui->localDevice->addItem(tr("%1").arg(*it), QVariant(*it));
}
}
int LocalSinkGUI::getLocalDeviceIndexInCombo(int localDeviceIndex) int LocalSinkGUI::getLocalDeviceIndexInCombo(int localDeviceIndex)
{ {
int index = 0; int index = 0;
@ -224,7 +216,6 @@ int LocalSinkGUI::getLocalDeviceIndexInCombo(int localDeviceIndex)
return -1; return -1;
} }
void LocalSinkGUI::leaveEvent(QEvent* event) void LocalSinkGUI::leaveEvent(QEvent* event)
{ {
m_channelMarker.setHighlighted(false); m_channelMarker.setHighlighted(false);
@ -243,8 +234,7 @@ void LocalSinkGUI::handleSourceMessages()
while ((message = getInputMessageQueue()->pop()) != 0) while ((message = getInputMessageQueue()->pop()) != 0)
{ {
if (handleMessage(*message)) if (handleMessage(*message)) {
{
delete message; delete message;
} }
} }
@ -306,6 +296,21 @@ void LocalSinkGUI::onMenuDialogCalled(const QPoint &p)
resetContextMenuType(); resetContextMenuType();
} }
void LocalSinkGUI::updateDeviceSetList(const QList<int>& deviceSetIndexes)
{
QList<int>::const_iterator it = deviceSetIndexes.begin();
ui->localDevice->blockSignals(true);
ui->localDevice->clear();
for (; it != deviceSetIndexes.end(); ++it) {
ui->localDevice->addItem(QString("R%1").arg(*it), *it);
}
ui->localDevice->blockSignals(false);
}
void LocalSinkGUI::on_decimationFactor_currentIndexChanged(int index) void LocalSinkGUI::on_decimationFactor_currentIndexChanged(int index)
{ {
m_settings.m_log2Decim = index; m_settings.m_log2Decim = index;
@ -320,18 +325,10 @@ void LocalSinkGUI::on_position_valueChanged(int value)
void LocalSinkGUI::on_localDevice_currentIndexChanged(int index) void LocalSinkGUI::on_localDevice_currentIndexChanged(int index)
{ {
m_settings.m_localDeviceIndex = ui->localDevice->itemData(index).toInt(); if (index >= 0)
{
m_settings.m_localDeviceIndex = ui->localDevice->currentData().toInt();
applySettings(); applySettings();
}
void LocalSinkGUI::on_localDevicesRefresh_clicked(bool checked)
{
(void) checked;
updateLocalDevices();
int index = getLocalDeviceIndexInCombo(m_settings.m_localDeviceIndex);
if (index >= 0) {
ui->localDevice->setCurrentIndex(index);
} }
} }
@ -379,7 +376,6 @@ void LocalSinkGUI::makeUIConnections()
QObject::connect(ui->decimationFactor, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LocalSinkGUI::on_decimationFactor_currentIndexChanged); QObject::connect(ui->decimationFactor, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LocalSinkGUI::on_decimationFactor_currentIndexChanged);
QObject::connect(ui->position, &QSlider::valueChanged, this, &LocalSinkGUI::on_position_valueChanged); QObject::connect(ui->position, &QSlider::valueChanged, this, &LocalSinkGUI::on_position_valueChanged);
QObject::connect(ui->localDevice, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LocalSinkGUI::on_localDevice_currentIndexChanged); QObject::connect(ui->localDevice, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LocalSinkGUI::on_localDevice_currentIndexChanged);
QObject::connect(ui->localDevicesRefresh, &QPushButton::clicked, this, &LocalSinkGUI::on_localDevicesRefresh_clicked);
QObject::connect(ui->localDevicePlay, &ButtonSwitch::toggled, this, &LocalSinkGUI::on_localDevicePlay_toggled); QObject::connect(ui->localDevicePlay, &ButtonSwitch::toggled, this, &LocalSinkGUI::on_localDevicePlay_toggled);
} }

View File

@ -84,11 +84,11 @@ private:
void applySettings(bool force = false); void applySettings(bool force = false);
void displaySettings(); void displaySettings();
void displayRateAndShift(); void displayRateAndShift();
void updateLocalDevices();
int getLocalDeviceIndexInCombo(int localDeviceIndex);
bool handleMessage(const Message& message); bool handleMessage(const Message& message);
void makeUIConnections(); void makeUIConnections();
void updateAbsoluteCenterFrequency(); void updateAbsoluteCenterFrequency();
void updateDeviceSetList(const QList<int>& deviceSetIndexes);
int getLocalDeviceIndexInCombo(int localDeviceIndex);
void leaveEvent(QEvent*); void leaveEvent(QEvent*);
void enterEvent(EnterEventType*); void enterEvent(EnterEventType*);
@ -101,7 +101,6 @@ private slots:
void on_decimationFactor_currentIndexChanged(int index); void on_decimationFactor_currentIndexChanged(int index);
void on_position_valueChanged(int value); void on_position_valueChanged(int value);
void on_localDevice_currentIndexChanged(int index); void on_localDevice_currentIndexChanged(int index);
void on_localDevicesRefresh_clicked(bool checked);
void on_localDevicePlay_toggled(bool checked); void on_localDevicePlay_toggled(bool checked);
void onWidgetRolled(QWidget* widget, bool rollDown); void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDialogCalled(const QPoint& p); void onMenuDialogCalled(const QPoint& p);

View File

@ -281,30 +281,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="localDevicesRefresh">
<property name="maximumSize">
<size>
<width>24</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Refresh indexes of available local devices</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/recycle.png</normaloff>:/recycle.png</iconset>
</property>
</widget>
</item>
<item> <item>
<widget class="ButtonSwitch" name="localDevicePlay"> <widget class="ButtonSwitch" name="localDevicePlay">
<property name="toolTip"> <property name="toolTip">
<string>Start/Stop sink</string> <string>Start/Stop processing</string>
</property> </property>
<property name="text"> <property name="text">
<string/> <string/>
@ -335,17 +315,17 @@
</widget> </widget>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget>
<class>ButtonSwitch</class>
<extends>QToolButton</extends>
<header>gui/buttonswitch.h</header>
</customwidget>
<customwidget> <customwidget>
<class>RollupContents</class> <class>RollupContents</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>gui/rollupcontents.h</header> <header>gui/rollupcontents.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>ButtonSwitch</class>
<extends>QToolButton</extends>
<header>gui/buttonswitch.h</header>
</customwidget>
</customwidgets> </customwidgets>
<resources> <resources>
<include location="../../../sdrgui/resources/res.qrc"/> <include location="../../../sdrgui/resources/res.qrc"/>

View File

@ -30,7 +30,7 @@ LocalSinkSettings::LocalSinkSettings()
void LocalSinkSettings::resetToDefaults() void LocalSinkSettings::resetToDefaults()
{ {
m_localDeviceIndex = 0; m_localDeviceIndex = -1;
m_rgbColor = QColor(140, 4, 4).rgb(); m_rgbColor = QColor(140, 4, 4).rgb();
m_title = "Local sink"; m_title = "Local sink";
m_log2Decim = 0; m_log2Decim = 0;
@ -51,7 +51,7 @@ void LocalSinkSettings::resetToDefaults()
QByteArray LocalSinkSettings::serialize() const QByteArray LocalSinkSettings::serialize() const
{ {
SimpleSerializer s(1); SimpleSerializer s(1);
s.writeU32(1, m_localDeviceIndex); s.writeS32(1, m_localDeviceIndex);
if (m_channelMarker) { if (m_channelMarker) {
s.writeBlob(2, m_channelMarker->serialize()); s.writeBlob(2, m_channelMarker->serialize());
@ -95,7 +95,7 @@ bool LocalSinkSettings::deserialize(const QByteArray& data)
QString strtmp; QString strtmp;
QByteArray bytetmp; QByteArray bytetmp;
d.readU32(1, &m_localDeviceIndex, 0); d.readS32(1, &m_localDeviceIndex, -1);
if (m_channelMarker) if (m_channelMarker)
{ {

View File

@ -25,7 +25,7 @@ class Serializable;
struct LocalSinkSettings struct LocalSinkSettings
{ {
uint32_t m_localDeviceIndex; int m_localDeviceIndex;
quint32 m_rgbColor; quint32 m_rgbColor;
QString m_title; QString m_title;
uint32_t m_log2Decim; uint32_t m_log2Decim;

View File

@ -26,6 +26,7 @@
#include "localsinksink.h" #include "localsinksink.h"
LocalSinkSink::LocalSinkSink() : LocalSinkSink::LocalSinkSink() :
m_deviceSource(nullptr),
m_sinkWorker(nullptr), m_sinkWorker(nullptr),
m_running(false), m_running(false),
m_centerFrequency(0), m_centerFrequency(0),
@ -43,34 +44,39 @@ LocalSinkSink::~LocalSinkSink()
void LocalSinkSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end) void LocalSinkSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
{ {
m_sampleFifo.write(begin, end); if (m_running && m_deviceSource) {
m_deviceSource->getSampleFifo()->write(begin, end);
}
// m_sampleFifo.write(begin, end);
} }
void LocalSinkSink::start(DeviceSampleSource *deviceSource) void LocalSinkSink::start(DeviceSampleSource *deviceSource)
{ {
qDebug("LocalSinkSink::start"); qDebug("LocalSinkSink::start: deviceSource: %p", deviceSource);
if (m_running) { if (m_running) {
stop(); stop();
} }
m_sinkWorker = new LocalSinkWorker(); m_deviceSource = deviceSource;
m_sinkWorker->moveToThread(&m_sinkWorkerThread); // TODO: We'll see later if a worker is really needed
m_sinkWorker->setSampleFifo(&m_sampleFifo); // m_sinkWorker = new LocalSinkWorker();
// m_sinkWorker->moveToThread(&m_sinkWorkerThread);
// m_sinkWorker->setSampleFifo(&m_sampleFifo);
if (deviceSource) { // if (deviceSource) {
m_sinkWorker->setDeviceSampleFifo(deviceSource->getSampleFifo()); // m_sinkWorker->setDeviceSampleFifo(deviceSource->getSampleFifo());
} // }
QObject::connect( // QObject::connect(
&m_sampleFifo, // &m_sampleFifo,
&SampleSinkFifo::dataReady, // &SampleSinkFifo::dataReady,
m_sinkWorker, // m_sinkWorker,
&LocalSinkWorker::handleData, // &LocalSinkWorker::handleData,
Qt::QueuedConnection // Qt::QueuedConnection
); // );
startWorker(); // startWorker();
m_running = true; m_running = true;
} }
@ -78,21 +84,23 @@ void LocalSinkSink::stop()
{ {
qDebug("LocalSinkSink::stop"); qDebug("LocalSinkSink::stop");
QObject::disconnect( // TODO: We'll see later if a worker is really needed
&m_sampleFifo, // QObject::disconnect(
&SampleSinkFifo::dataReady, // &m_sampleFifo,
m_sinkWorker, // &SampleSinkFifo::dataReady,
&LocalSinkWorker::handleData // m_sinkWorker,
); // &LocalSinkWorker::handleData
// );
if (m_sinkWorker != 0) // if (m_sinkWorker != 0)
{ // {
stopWorker(); // stopWorker();
m_sinkWorker->deleteLater(); // m_sinkWorker->deleteLater();
m_sinkWorker = nullptr; // m_sinkWorker = nullptr;
} // }
m_running = false; m_running = false;
m_deviceSource = nullptr;
} }
void LocalSinkSink::startWorker() void LocalSinkSink::startWorker()

View File

@ -43,6 +43,7 @@ public:
void setSampleRate(int sampleRate); void setSampleRate(int sampleRate);
private: private:
DeviceSampleSource *m_deviceSource;
SampleSinkFifo m_sampleFifo; SampleSinkFifo m_sampleFifo;
LocalSinkSettings m_settings; LocalSinkSettings m_settings;
LocalSinkWorker *m_sinkWorker; LocalSinkWorker *m_sinkWorker;

View File

@ -12,7 +12,7 @@ These Local Sinks can then be coupled with two Local Input device source plugins
Note that because it uses only the channelizer half band filter chain to achieve decimation and center frequency shift you have a limited choice on the center frequencies that may be used (similarly to the Remote Sink). The available center frequencies depend on the baseband sample rate, the channel decimation and the filter chain that is used so you have to play with these parameters to obtain a suitable center frequency and pass band. Note that because it uses only the channelizer half band filter chain to achieve decimation and center frequency shift you have a limited choice on the center frequencies that may be used (similarly to the Remote Sink). The available center frequencies depend on the baseband sample rate, the channel decimation and the filter chain that is used so you have to play with these parameters to obtain a suitable center frequency and pass band.
<b>&#9888; Important warning</b> When closing the application or before closing the local input device the local sink is connected to you have to stop the device where the local sink operates. This is because there is no reverse link for the local input to notify the local sink that it closes. Therefore closing the local input while the local sink runs will crash the program. <b>&#9888; Important warning</b> When closing the application or before closing the local input device the local sink is connected it is recommended to stop processing on the local sink (7). Depending on the sequence by which the devices have been created closing the local input while the local sink runs may crash the program.
<h2>Interface</h2> <h2>Interface</h2>
@ -52,6 +52,6 @@ The slider moves the channel center frequency roughly from the lower to the high
This selects the index of the Local Input source where to send the I/Q samples. The list can be refreshed with the next button (7) This selects the index of the Local Input source where to send the I/Q samples. The list can be refreshed with the next button (7)
<h3>7: Refresh local input devices list</h2> <h3>7: Start/stop processing</h2>
Use this button to refresh the list of Local Input sources indexes. Use this button to start or stop processing.