diff --git a/plugins/samplemimo/metismiso/metismiso.cpp b/plugins/samplemimo/metismiso/metismiso.cpp index 8844a349e0..3ad802c5d0 100644 --- a/plugins/samplemimo/metismiso/metismiso.cpp +++ b/plugins/samplemimo/metismiso/metismiso.cpp @@ -66,6 +66,7 @@ MetisMISO::MetisMISO(DeviceAPI *deviceAPI) : MetisMISO::~MetisMISO() { + qDebug("MetisMISO::~MetisMISO"); QObject::disconnect( m_networkManager, &QNetworkAccessManager::finished, @@ -77,6 +78,7 @@ MetisMISO::~MetisMISO() if (m_running) { stopRx(); } + qDebug("MetisMISO::~MetisMISO: end"); } void MetisMISO::destroy() @@ -155,6 +157,7 @@ void MetisMISO::startMetis() void MetisMISO::stopMetis() { + qDebug("MetisMISO::stopMetis"); MetisMISOUDPHandler::MsgStartStop *message = MetisMISOUDPHandler::MsgStartStop::create(false); m_udpHandler.getInputMessageQueue()->push(message); } diff --git a/sdrbase/dsp/dspdevicemimoengine.cpp b/sdrbase/dsp/dspdevicemimoengine.cpp index 386c234b82..7fd4997ae1 100644 --- a/sdrbase/dsp/dspdevicemimoengine.cpp +++ b/sdrbase/dsp/dspdevicemimoengine.cpp @@ -41,7 +41,7 @@ MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::ConfigureCorrection, Message) MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::SetSpectrumSinkInput, Message) DSPDeviceMIMOEngine::DSPDeviceMIMOEngine(uint32_t uid, QObject* parent) : - QThread(parent), + QObject(parent), m_uid(uid), m_stateRx(StNotStarted), m_stateTx(StNotStarted), @@ -49,15 +49,14 @@ DSPDeviceMIMOEngine::DSPDeviceMIMOEngine(uint32_t uid, QObject* parent) : m_spectrumInputSourceElseSink(true), m_spectrumInputIndex(0) { + setStateRx(StIdle); + setStateTx(StIdle); connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection); - - moveToThread(this); } DSPDeviceMIMOEngine::~DSPDeviceMIMOEngine() { - stop(); - wait(); + qDebug("DSPDeviceMIMOEngine::~DSPDeviceMIMOEngine"); } void DSPDeviceMIMOEngine::setStateRx(State state) @@ -78,30 +77,6 @@ void DSPDeviceMIMOEngine::setStateTx(State state) } } -void DSPDeviceMIMOEngine::run() -{ - qDebug() << "DSPDeviceMIMOEngine::run"; - setStateRx(StIdle); - setStateTx(StIdle); - exec(); -} - -void DSPDeviceMIMOEngine::start() -{ - qDebug() << "DSPDeviceMIMOEngine::start"; - QThread::start(); -} - -void DSPDeviceMIMOEngine::stop() -{ - qDebug() << "DSPDeviceMIMOEngine::stop"; - gotoIdle(0); // Rx - gotoIdle(1); // Tx - setStateRx(StNotStarted); - setStateTx(StNotStarted); - QThread::exit(); -} - bool DSPDeviceMIMOEngine::initProcess(int subsystemIndex) { qDebug() << "DSPDeviceMIMOEngine::initProcess: subsystemIndex: " << subsystemIndex; diff --git a/sdrbase/dsp/dspdevicemimoengine.h b/sdrbase/dsp/dspdevicemimoengine.h index b765aecb7e..57968680cb 100644 --- a/sdrbase/dsp/dspdevicemimoengine.h +++ b/sdrbase/dsp/dspdevicemimoengine.h @@ -19,7 +19,7 @@ #ifndef SDRBASE_DSP_DSPDEVICEMIMOENGINE_H_ #define SDRBASE_DSP_DSPDEVICEMIMOENGINE_H_ -#include +#include #include "dsp/dsptypes.h" #include "util/message.h" @@ -33,7 +33,7 @@ class BasebandSampleSink; class BasebandSampleSource; class MIMOChannel; -class SDRBASE_API DSPDeviceMIMOEngine : public QThread { +class SDRBASE_API DSPDeviceMIMOEngine : public QObject { Q_OBJECT public: @@ -213,13 +213,10 @@ class SDRBASE_API DSPDeviceMIMOEngine : public QThread { }; DSPDeviceMIMOEngine(uint32_t uid, QObject* parent = nullptr); - ~DSPDeviceMIMOEngine(); + ~DSPDeviceMIMOEngine() override; MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; } - void start(); //!< This thread start - void stop(); //!< This thread stop - bool initProcess(int subsystemIndex); //!< Initialize process sequence bool startProcess(int subsystemIndex); //!< Start process sequence void stopProcess(int subsystemIndex); //!< Stop process sequence @@ -339,7 +336,6 @@ class SDRBASE_API DSPDeviceMIMOEngine : public QThread { bool m_spectrumInputSourceElseSink; //!< Source else sink stream to be used as spectrum sink input unsigned int m_spectrumInputIndex; //!< Index of the stream to be used as spectrum sink input - void run(); void workSampleSinkFifos(); //!< transfer samples of all sink streams (sync mode) void workSampleSinkFifo(unsigned int streamIndex); //!< transfer samples of one sink stream (async mode) void workSamplesSink(const SampleVector::const_iterator& vbegin, const SampleVector::const_iterator& vend, unsigned int streamIndex); diff --git a/sdrbase/dsp/dspdevicesourceengine.cpp b/sdrbase/dsp/dspdevicesourceengine.cpp index 27869762a7..afaf18ee74 100644 --- a/sdrbase/dsp/dspdevicesourceengine.cpp +++ b/sdrbase/dsp/dspdevicesourceengine.cpp @@ -52,6 +52,7 @@ DSPDeviceSourceEngine::DSPDeviceSourceEngine(uint uid, QObject* parent) : DSPDeviceSourceEngine::~DSPDeviceSourceEngine() { + qDebug("DSPDeviceSourceEngine::~DSPDeviceSourceEngine"); } void DSPDeviceSourceEngine::setState(State state) diff --git a/sdrbase/dsp/dspengine.cpp b/sdrbase/dsp/dspengine.cpp index b6d688ba74..43e7be763d 100644 --- a/sdrbase/dsp/dspengine.cpp +++ b/sdrbase/dsp/dspengine.cpp @@ -138,24 +138,45 @@ void DSPEngine::removeLastDeviceSinkEngine() DSPDeviceMIMOEngine *DSPEngine::addDeviceMIMOEngine() { - m_deviceMIMOEngines.push_back(new DSPDeviceMIMOEngine(m_deviceMIMOEnginesUIDSequence)); + auto *deviceMIMOEngine = new DSPDeviceMIMOEngine(m_deviceMIMOEnginesUIDSequence); + auto *deviceThread = new QThread(); m_deviceMIMOEnginesUIDSequence++; - m_deviceEngineReferences.push_back(DeviceEngineReference{2, nullptr, nullptr, m_deviceMIMOEngines.back(), nullptr}); - return m_deviceMIMOEngines.back(); + m_deviceMIMOEngines.push_back(deviceMIMOEngine); + m_deviceEngineReferences.push_back(DeviceEngineReference{2, nullptr, nullptr, m_deviceMIMOEngines.back(), deviceThread}); + deviceMIMOEngine->moveToThread(deviceThread); + + QObject::connect( + deviceThread, + &QThread::finished, + deviceMIMOEngine, + &QObject::deleteLater + ); + QObject::connect( + deviceThread, + &QThread::finished, + deviceThread, + &QThread::deleteLater + ); + + deviceThread->start(); + + return deviceMIMOEngine; } void DSPEngine::removeLastDeviceMIMOEngine() { - if (m_deviceMIMOEngines.size() > 0) + if (!m_deviceMIMOEngines.empty()) { - DSPDeviceMIMOEngine *lastDeviceEngine = m_deviceMIMOEngines.back(); - delete lastDeviceEngine; + const DSPDeviceMIMOEngine *lastDeviceEngine = m_deviceMIMOEngines.back(); m_deviceMIMOEngines.pop_back(); for (int i = 0; i < m_deviceEngineReferences.size(); i++) { if (m_deviceEngineReferences[i].m_deviceMIMOEngine == lastDeviceEngine) { + QThread* deviceThread = m_deviceEngineReferences[i].m_thread; + deviceThread->exit(); + deviceThread->wait(); m_deviceEngineReferences.removeAt(i); break; } @@ -186,7 +207,9 @@ void DSPEngine::removeDeviceEngineAt(int deviceIndex) else if (m_deviceEngineReferences[deviceIndex].m_deviceEngineType == 2) // MIMO { DSPDeviceMIMOEngine *deviceEngine = m_deviceEngineReferences[deviceIndex].m_deviceMIMOEngine; - delete deviceEngine; + QThread *deviceThread = m_deviceEngineReferences[deviceIndex].m_thread; + deviceThread->exit(); + deviceThread->wait(); m_deviceMIMOEngines.removeAll(deviceEngine); } diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index 3c3cef8168..5d29360ad8 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -783,7 +783,6 @@ void MainWindow::sampleSinkCreate( void MainWindow::sampleMIMOAdd(Workspace *deviceWorkspace, Workspace *spectrumWorkspace, int deviceIndex) { DSPDeviceMIMOEngine *dspDeviceMIMOEngine = m_dspEngine->addDeviceMIMOEngine(); - dspDeviceMIMOEngine->start(); uint dspDeviceMIMOEngineUID = dspDeviceMIMOEngine->getUID(); char uidCStr[16]; @@ -1002,65 +1001,62 @@ void MainWindow::removeDeviceSet(int deviceSetIndex) deviceUISet->m_deviceAPI->getSampleSource()->setMessageQueueToGUI(nullptr); // have source stop sending messages to the GUI deviceUISet->m_deviceGUI->destroy(); deviceUISet->m_deviceAPI->resetSamplingDeviceId(); - deviceUISet->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceInput( - deviceUISet->m_deviceAPI->getSampleSource()); deviceUISet->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists - DeviceAPI *sourceAPI = deviceUISet->m_deviceAPI; - delete deviceUISet; - m_dspEngine->removeDeviceEngineAt(deviceSetIndex); + m_dspEngine->removeDeviceEngineAt(deviceSetIndex); DeviceEnumerator::instance()->removeRxSelection(deviceSetIndex); - delete sourceAPI; + DeviceAPI *sourceAPI = deviceUISet->m_deviceAPI; + delete deviceUISet; + delete sourceAPI->getSampleSource(); + delete sourceAPI; } else if (deviceUISet->m_deviceSinkEngine) // sink device { DSPDeviceSinkEngine *deviceEngine = deviceUISet->m_deviceSinkEngine; - deviceEngine->stopGeneration(); - deviceEngine->removeSpectrumSink(deviceUISet->m_spectrumVis); + deviceEngine->stopGeneration(); + deviceEngine->removeSpectrumSink(deviceUISet->m_spectrumVis); // deletes old UI and output object deviceUISet->freeChannels(); deviceUISet->m_deviceAPI->getSampleSink()->setMessageQueueToGUI(nullptr); // have sink stop sending messages to the GUI deviceUISet->m_deviceGUI->destroy(); - deviceUISet->m_deviceAPI->resetSamplingDeviceId(); - deviceUISet->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput( - deviceUISet->m_deviceAPI->getSampleSink()); + deviceUISet->m_deviceAPI->resetSamplingDeviceId(); + deviceUISet->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput( + deviceUISet->m_deviceAPI->getSampleSink()); deviceUISet->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists DeviceAPI *sinkAPI = deviceUISet->m_deviceAPI; - delete deviceUISet; + delete deviceUISet; - deviceEngine->stop(); - m_dspEngine->removeDeviceEngineAt(deviceSetIndex); + deviceEngine->stop(); + m_dspEngine->removeDeviceEngineAt(deviceSetIndex); DeviceEnumerator::instance()->removeTxSelection(deviceSetIndex); - delete sinkAPI; + delete sinkAPI; } else if (deviceUISet->m_deviceMIMOEngine) // MIMO device { DSPDeviceMIMOEngine *deviceEngine = deviceUISet->m_deviceMIMOEngine; deviceEngine->stopProcess(1); // Tx side deviceEngine->stopProcess(0); // Rx side - deviceEngine->removeSpectrumSink(deviceUISet->m_spectrumVis); + deviceEngine->removeSpectrumSink(deviceUISet->m_spectrumVis); // deletes old UI and output object deviceUISet->freeChannels(); deviceUISet->m_deviceAPI->getSampleMIMO()->setMessageQueueToGUI(nullptr); // have sink stop sending messages to the GUI deviceUISet->m_deviceGUI->destroy(); - deviceUISet->m_deviceAPI->resetSamplingDeviceId(); - deviceUISet->m_deviceAPI->getPluginInterface()->deleteSampleMIMOPluginInstanceMIMO( - deviceUISet->m_deviceAPI->getSampleMIMO()); + deviceUISet->m_deviceAPI->resetSamplingDeviceId(); - DeviceAPI *mimoAPI = deviceUISet->m_deviceAPI; - delete deviceUISet; - deviceEngine->stop(); - m_dspEngine->removeDeviceEngineAt(deviceSetIndex); + m_dspEngine->removeDeviceEngineAt(deviceSetIndex); DeviceEnumerator::instance()->removeMIMOSelection(deviceSetIndex); - delete mimoAPI; + DeviceAPI *mimoAPI = deviceUISet->m_deviceAPI; + delete deviceUISet; + delete mimoAPI->getSampleMIMO(); + delete mimoAPI; } m_deviceUIs.erase(m_deviceUIs.begin() + deviceSetIndex); @@ -1094,75 +1090,72 @@ void MainWindow::removeDeviceSet(int deviceSetIndex) void MainWindow::removeLastDeviceSet() { + qDebug("MainWindow::removeLastDeviceSet: %s", qPrintable(m_deviceUIs.back()->m_deviceAPI->getHardwareId())); int removedDeviceSetIndex = m_deviceUIs.size() - 1; if (m_deviceUIs.back()->m_deviceSourceEngine) // source tab { DSPDeviceSourceEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSourceEngine; - lastDeviceEngine->stopAcquistion(); - lastDeviceEngine->removeSink(m_deviceUIs.back()->m_spectrumVis); + lastDeviceEngine->stopAcquistion(); + lastDeviceEngine->removeSink(m_deviceUIs.back()->m_spectrumVis); // deletes old UI and input object m_deviceUIs.back()->freeChannels(); // destroys the channel instances m_deviceUIs.back()->m_deviceAPI->getSampleSource()->setMessageQueueToGUI(nullptr); // have source stop sending messages to the GUI m_deviceUIs.back()->m_deviceGUI->destroy(); m_deviceUIs.back()->m_deviceAPI->resetSamplingDeviceId(); - m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceInput( - m_deviceUIs.back()->m_deviceAPI->getSampleSource()); m_deviceUIs.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists - DeviceAPI *sourceAPI = m_deviceUIs.back()->m_deviceAPI; - delete m_deviceUIs.back(); - m_dspEngine->removeLastDeviceSourceEngine(); + m_dspEngine->removeLastDeviceSourceEngine(); - delete sourceAPI; + DeviceAPI *sourceAPI = m_deviceUIs.back()->m_deviceAPI; + delete m_deviceUIs.back(); + delete sourceAPI->getSampleSource(); + delete sourceAPI; } else if (m_deviceUIs.back()->m_deviceSinkEngine) // sink tab { DSPDeviceSinkEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSinkEngine; - lastDeviceEngine->stopGeneration(); - lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis); + lastDeviceEngine->stopGeneration(); + lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis); // deletes old UI and output object m_deviceUIs.back()->freeChannels(); m_deviceUIs.back()->m_deviceAPI->getSampleSink()->setMessageQueueToGUI(nullptr); // have sink stop sending messages to the GUI m_deviceUIs.back()->m_deviceGUI->destroy(); - m_deviceUIs.back()->m_deviceAPI->resetSamplingDeviceId(); - m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput( - m_deviceUIs.back()->m_deviceAPI->getSampleSink()); + m_deviceUIs.back()->m_deviceAPI->resetSamplingDeviceId(); + m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput( + m_deviceUIs.back()->m_deviceAPI->getSampleSink()); m_deviceUIs.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists DeviceAPI *sinkAPI = m_deviceUIs.back()->m_deviceAPI; - delete m_deviceUIs.back(); + delete m_deviceUIs.back(); - lastDeviceEngine->stop(); - m_dspEngine->removeLastDeviceSinkEngine(); + lastDeviceEngine->stop(); + m_dspEngine->removeLastDeviceSinkEngine(); - delete sinkAPI; + delete sinkAPI; } else if (m_deviceUIs.back()->m_deviceMIMOEngine) // MIMO tab { DSPDeviceMIMOEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceMIMOEngine; lastDeviceEngine->stopProcess(1); // Tx side lastDeviceEngine->stopProcess(0); // Rx side - lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis); + lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis); // deletes old UI and output object m_deviceUIs.back()->freeChannels(); m_deviceUIs.back()->m_deviceAPI->getSampleMIMO()->setMessageQueueToGUI(nullptr); // have sink stop sending messages to the GUI m_deviceUIs.back()->m_deviceGUI->destroy(); - m_deviceUIs.back()->m_deviceAPI->resetSamplingDeviceId(); - m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleMIMOPluginInstanceMIMO( - m_deviceUIs.back()->m_deviceAPI->getSampleMIMO()); - - DeviceAPI *mimoAPI = m_deviceUIs.back()->m_deviceAPI; - delete m_deviceUIs.back(); + m_deviceUIs.back()->m_deviceAPI->resetSamplingDeviceId(); - lastDeviceEngine->stop(); - m_dspEngine->removeLastDeviceMIMOEngine(); + m_dspEngine->removeLastDeviceMIMOEngine(); - delete mimoAPI; + DeviceAPI *mimoAPI = m_deviceUIs.back()->m_deviceAPI; + delete m_deviceUIs.back(); + delete mimoAPI->getSampleMIMO(); + delete mimoAPI; } m_deviceUIs.pop_back(); diff --git a/sdrsrv/mainserver.cpp b/sdrsrv/mainserver.cpp index 7f66b948ed..c98f5decd5 100644 --- a/sdrsrv/mainserver.cpp +++ b/sdrsrv/mainserver.cpp @@ -27,6 +27,9 @@ #include "dsp/dspdevicesourceengine.h" #include "dsp/dspdevicesinkengine.h" #include "dsp/dspdevicemimoengine.h" +#include "dsp/devicesamplesource.h" +#include "dsp/devicesamplesink.h" +#include "dsp/devicesamplemimo.h" #include "dsp/spectrumvis.h" #include "device/deviceapi.h" #include "device/deviceset.h" @@ -316,10 +319,6 @@ void MainServer::addSourceDevice() { DSPDeviceSourceEngine *dspDeviceSourceEngine = m_dspEngine->addDeviceSourceEngine(); - uint dspDeviceSourceEngineUID = dspDeviceSourceEngine->getUID(); - char uidCStr[16]; - sprintf(uidCStr, "UID:%d", dspDeviceSourceEngineUID); - int deviceTabIndex = m_mainCore->m_deviceSets.size(); m_mainCore->m_deviceSets.push_back(new DeviceSet(deviceTabIndex, 0)); m_mainCore->m_deviceSets.back()->m_deviceSourceEngine = dspDeviceSourceEngine; @@ -327,9 +326,6 @@ void MainServer::addSourceDevice() m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine = nullptr; dspDeviceSourceEngine->addSink(m_mainCore->m_deviceSets.back()->m_spectrumVis); - char tabNameCStr[16]; - sprintf(tabNameCStr, "R%d", deviceTabIndex); - DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamSingleRx, deviceTabIndex, dspDeviceSourceEngine, nullptr, nullptr); m_mainCore->m_deviceSets.back()->m_deviceAPI = deviceAPI; @@ -361,11 +357,6 @@ void MainServer::addSourceDevice() void MainServer::addMIMODevice() { DSPDeviceMIMOEngine *dspDeviceMIMOEngine = m_dspEngine->addDeviceMIMOEngine(); - dspDeviceMIMOEngine->start(); - - uint dspDeviceMIMOEngineUID = dspDeviceMIMOEngine->getUID(); - char uidCStr[16]; - sprintf(uidCStr, "UID:%d", dspDeviceMIMOEngineUID); int deviceTabIndex = m_mainCore->m_deviceSets.size(); m_mainCore->m_deviceSets.push_back(new DeviceSet(deviceTabIndex, 2)); @@ -374,9 +365,6 @@ void MainServer::addMIMODevice() m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine = dspDeviceMIMOEngine; dspDeviceMIMOEngine->addSpectrumSink(m_mainCore->m_deviceSets.back()->m_spectrumVis); - char tabNameCStr[16]; - sprintf(tabNameCStr, "M%d", deviceTabIndex); - DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamMIMO, deviceTabIndex, nullptr, nullptr, dspDeviceMIMOEngine); // create a test MIMO by default @@ -415,15 +403,13 @@ void MainServer::removeLastDevice() // deletes old UI and input object m_mainCore->m_deviceSets.back()->freeChannels(); // destroys the channel instances m_mainCore->m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId(); - m_mainCore->m_deviceSets.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceInput( - m_mainCore->m_deviceSets.back()->m_deviceAPI->getSampleSource()); m_mainCore->m_deviceSets.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists - DeviceAPI *sourceAPI = m_mainCore->m_deviceSets.back()->m_deviceAPI; - delete m_mainCore->m_deviceSets.back(); - m_dspEngine->removeLastDeviceSourceEngine(); + DeviceAPI *sourceAPI = m_mainCore->m_deviceSets.back()->m_deviceAPI; + delete m_mainCore->m_deviceSets.back(); + delete sourceAPI->getSampleSource(); delete sourceAPI; } else if (m_mainCore->m_deviceSets.back()->m_deviceSinkEngine) // sink set @@ -446,6 +432,22 @@ void MainServer::removeLastDevice() delete sinkAPI; } + else if (m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine) // MIMO set + { + DSPDeviceMIMOEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine; + lastDeviceEngine->stopProcess(1); // Tx side + lastDeviceEngine->stopProcess(0); // Rx side + + m_mainCore->m_deviceSets.back()->freeChannels(); + m_mainCore->m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId(); + + m_dspEngine->removeLastDeviceSourceEngine(); + + DeviceAPI *mimoAPI = m_mainCore->m_deviceSets.back()->m_deviceAPI; + delete m_mainCore->m_deviceSets.back(); + delete mimoAPI->getSampleMIMO(); + delete mimoAPI; + } m_mainCore->m_deviceSets.pop_back(); emit m_mainCore->deviceSetRemoved(removedTabIndex);