From 966767a44a230a608d4adbb3dddad9912c175cdc Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 14 Dec 2017 18:02:49 +0100 Subject: [PATCH] Web API: use message passing to start/stop device for all the rest of device plugins --- .../bladerfoutput/bladerfoutput.cpp | 4 +- .../bladerfoutput/bladerfoutputgui.cpp | 8 + .../samplesink/hackrfoutput/hackrfoutput.cpp | 40 +- .../samplesink/hackrfoutput/hackrfoutput.h | 19 + .../hackrfoutput/hackrfoutputgui.cpp | 29 +- .../limesdroutput/limesdroutput.cpp | 40 +- .../samplesink/limesdroutput/limesdroutput.h | 19 + .../limesdroutput/limesdroutputgui.cpp | 22 +- .../plutosdroutput/plutosdroutput.cpp | 40 +- .../plutosdroutput/plutosdroutput.h | 19 + .../plutosdroutput/plutosdroutputgui.cpp | 22 +- .../sdrdaemonsink/sdrdaemonsinkgui.cpp | 26 +- .../sdrdaemonsink/sdrdaemonsinkoutput.cpp | 22 ++ .../sdrdaemonsink/sdrdaemonsinkoutput.h | 341 +++++++++--------- plugins/samplesource/airspy/airspygui.cpp | 31 +- plugins/samplesource/airspy/airspygui.h | 2 + plugins/samplesource/airspy/airspyinput.cpp | 22 ++ plugins/samplesource/airspy/airspyinput.h | 19 + plugins/samplesource/fcdpro/fcdprogui.cpp | 28 +- plugins/samplesource/fcdpro/fcdprogui.h | 2 + plugins/samplesource/fcdpro/fcdproinput.cpp | 22 ++ plugins/samplesource/fcdpro/fcdproinput.h | 19 + .../samplesource/fcdproplus/fcdproplusgui.cpp | 28 +- .../samplesource/fcdproplus/fcdproplusgui.h | 2 + .../fcdproplus/fcdproplusinput.cpp | 22 ++ .../samplesource/fcdproplus/fcdproplusinput.h | 19 + .../samplesource/filesource/filesourcegui.cpp | 23 +- .../samplesource/filesource/filesourcegui.h | 2 + .../filesource/filesourceinput.cpp | 22 ++ .../samplesource/filesource/filesourceinput.h | 19 + .../samplesource/hackrfinput/hackrfinput.cpp | 40 +- .../samplesource/hackrfinput/hackrfinput.h | 19 + .../hackrfinput/hackrfinputgui.cpp | 30 +- .../limesdrinput/limesdrinput.cpp | 40 +- .../samplesource/limesdrinput/limesdrinput.h | 19 + .../limesdrinput/limesdrinputgui.cpp | 27 +- .../plutosdrinput/plutosdrinput.cpp | 40 +- .../plutosdrinput/plutosdrinput.h | 18 + .../plutosdrinput/plutosdrinputgui.cpp | 25 +- plugins/samplesource/rtlsdr/rtlsdrgui.cpp | 23 +- plugins/samplesource/rtlsdr/rtlsdrinput.cpp | 40 +- plugins/samplesource/rtlsdr/rtlsdrinput.h | 19 + 42 files changed, 884 insertions(+), 389 deletions(-) diff --git a/plugins/samplesink/bladerfoutput/bladerfoutput.cpp b/plugins/samplesink/bladerfoutput/bladerfoutput.cpp index 115853294..66dfd818e 100644 --- a/plugins/samplesink/bladerfoutput/bladerfoutput.cpp +++ b/plugins/samplesink/bladerfoutput/bladerfoutput.cpp @@ -211,7 +211,7 @@ bool BladerfOutput::handleMessage(const Message& message) if (MsgConfigureBladerf::match(message)) { MsgConfigureBladerf& conf = (MsgConfigureBladerf&) message; - qDebug() << "BladerfInput::handleMessage: MsgConfigureBladerf"; + qDebug() << "BladerfOutput::handleMessage: MsgConfigureBladerf"; if (!applySettings(conf.getSettings(), conf.getForce())) { @@ -223,7 +223,7 @@ bool BladerfOutput::handleMessage(const Message& message) else if (MsgStartStop::match(message)) { MsgStartStop& cmd = (MsgStartStop&) message; - qDebug() << "SDRPlayInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + qDebug() << "BladerfOutput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); if (cmd.getStartStop()) { diff --git a/plugins/samplesink/bladerfoutput/bladerfoutputgui.cpp b/plugins/samplesink/bladerfoutput/bladerfoutputgui.cpp index 3ddc65e8d..b1abe2fe5 100644 --- a/plugins/samplesink/bladerfoutput/bladerfoutputgui.cpp +++ b/plugins/samplesink/bladerfoutput/bladerfoutputgui.cpp @@ -132,6 +132,14 @@ bool BladerfOutputGui::handleMessage(const Message& message) displaySettings(); return true; } + else if (BladerfOutput::MsgStartStop::match(message)) + { + BladerfOutput::MsgStartStop& notif = (BladerfOutput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + return true; + } else { return false; diff --git a/plugins/samplesink/hackrfoutput/hackrfoutput.cpp b/plugins/samplesink/hackrfoutput/hackrfoutput.cpp index 4f9a8dbda..dd2bcd71f 100644 --- a/plugins/samplesink/hackrfoutput/hackrfoutput.cpp +++ b/plugins/samplesink/hackrfoutput/hackrfoutput.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include "SWGDeviceSettings.h" @@ -34,6 +35,7 @@ #include "hackrfoutputthread.h" MESSAGE_CLASS_DEFINITION(HackRFOutput::MsgConfigureHackRF, Message) +MESSAGE_CLASS_DEFINITION(HackRFOutput::MsgStartStop, Message) MESSAGE_CLASS_DEFINITION(HackRFOutput::MsgReportHackRF, Message) HackRFOutput::HackRFOutput(DeviceSinkAPI *deviceAPI) : @@ -205,6 +207,27 @@ bool HackRFOutput::handleMessage(const Message& message) return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "HackRFOutput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initGeneration()) + { + m_deviceAPI->startGeneration(); + DSPEngine::instance()->startAudioInput(); + } + } + else + { + m_deviceAPI->stopGeneration(); + DSPEngine::instance()->stopAudioInput(); + } + + return true; + } else { return false; @@ -413,19 +436,16 @@ int HackRFOutput::webapiRun( SWGSDRangel::SWGDeviceState& response, QString& errorMessage __attribute__((unused))) { - if (run) + MsgStartStop *message = MsgStartStop::create(run); + m_inputMessageQueue.push(message); + + if (m_guiMessageQueue) { - if (m_deviceAPI->initGeneration()) - { - m_deviceAPI->startGeneration(); - DSPEngine::instance()->startAudioInputImmediate(); - } - } - else - { - m_deviceAPI->stopGeneration(); + MsgStartStop *messagetoGui = MsgStartStop::create(run); + m_guiMessageQueue->push(messagetoGui); } + usleep(100000); m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } diff --git a/plugins/samplesink/hackrfoutput/hackrfoutput.h b/plugins/samplesink/hackrfoutput/hackrfoutput.h index aa6778e1a..c18370530 100644 --- a/plugins/samplesink/hackrfoutput/hackrfoutput.h +++ b/plugins/samplesink/hackrfoutput/hackrfoutput.h @@ -54,6 +54,25 @@ public: { } }; + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; + class MsgReportHackRF : public Message { MESSAGE_CLASS_DECLARATION diff --git a/plugins/samplesink/hackrfoutput/hackrfoutputgui.cpp b/plugins/samplesink/hackrfoutput/hackrfoutputgui.cpp index 4675f8d4f..5c877d324 100644 --- a/plugins/samplesink/hackrfoutput/hackrfoutputgui.cpp +++ b/plugins/samplesink/hackrfoutput/hackrfoutputgui.cpp @@ -136,6 +136,14 @@ bool HackRFOutputGui::handleMessage(const Message& message) displaySettings(); return true; } + else if (HackRFOutput::MsgStartStop::match(message)) + { + HackRFOutput::MsgStartStop& notif = (HackRFOutput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + return true; + } else { return false; @@ -298,25 +306,10 @@ void HackRFOutputGui::on_txvga_valueChanged(int value) void HackRFOutputGui::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - // forcibly stop the Rx if present before starting - if (m_deviceUISet->m_deviceSinkAPI->getSourceBuddies().size() > 0) - { - DeviceSourceAPI *buddy = m_deviceUISet->m_deviceSinkAPI->getSourceBuddies()[0]; - buddy->stopAcquisition(); - } - - if (m_deviceUISet->m_deviceSinkAPI->initGeneration()) - { - m_deviceUISet->m_deviceSinkAPI->startGeneration(); - DSPEngine::instance()->startAudioInput(); - } - } - else - { - m_deviceUISet->m_deviceSinkAPI->stopGeneration(); - DSPEngine::instance()->startAudioInput(); + HackRFOutput::MsgStartStop *message = HackRFOutput::MsgStartStop::create(checked); + m_deviceSampleSink->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesink/limesdroutput/limesdroutput.cpp b/plugins/samplesink/limesdroutput/limesdroutput.cpp index d75c30c52..b4c273d2b 100644 --- a/plugins/samplesink/limesdroutput/limesdroutput.cpp +++ b/plugins/samplesink/limesdroutput/limesdroutput.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "lime/LimeSuite.h" #include "SWGDeviceSettings.h" @@ -34,6 +35,7 @@ #include "limesdroutput.h" MESSAGE_CLASS_DEFINITION(LimeSDROutput::MsgConfigureLimeSDR, Message) +MESSAGE_CLASS_DEFINITION(LimeSDROutput::MsgStartStop, Message) MESSAGE_CLASS_DEFINITION(LimeSDROutput::MsgGetStreamInfo, Message) MESSAGE_CLASS_DEFINITION(LimeSDROutput::MsgGetDeviceInfo, Message) MESSAGE_CLASS_DEFINITION(LimeSDROutput::MsgReportStreamInfo, Message) @@ -467,6 +469,27 @@ bool LimeSDROutput::handleMessage(const Message& message) return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "LimeSDROutput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initGeneration()) + { + m_deviceAPI->startGeneration(); + DSPEngine::instance()->startAudioInput(); + } + } + else + { + m_deviceAPI->stopGeneration(); + DSPEngine::instance()->stopAudioInput(); + } + + return true; + } else if (DeviceLimeSDRShared::MsgReportBuddyChange::match(message)) { DeviceLimeSDRShared::MsgReportBuddyChange& report = (DeviceLimeSDRShared::MsgReportBuddyChange&) message; @@ -1093,19 +1116,16 @@ int LimeSDROutput::webapiRun( SWGSDRangel::SWGDeviceState& response, QString& errorMessage __attribute__((unused))) { - if (run) + MsgStartStop *message = MsgStartStop::create(run); + m_inputMessageQueue.push(message); + + if (m_guiMessageQueue) { - if (m_deviceAPI->initGeneration()) - { - m_deviceAPI->startGeneration(); - DSPEngine::instance()->startAudioInputImmediate(); - } - } - else - { - m_deviceAPI->stopGeneration(); + MsgStartStop *messagetoGui = MsgStartStop::create(run); + m_guiMessageQueue->push(messagetoGui); } + usleep(100000); m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } diff --git a/plugins/samplesink/limesdroutput/limesdroutput.h b/plugins/samplesink/limesdroutput/limesdroutput.h index ce0f5d978..82a9c0705 100644 --- a/plugins/samplesink/limesdroutput/limesdroutput.h +++ b/plugins/samplesink/limesdroutput/limesdroutput.h @@ -54,6 +54,25 @@ public: { } }; + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; + class MsgGetStreamInfo : public Message { MESSAGE_CLASS_DECLARATION diff --git a/plugins/samplesink/limesdroutput/limesdroutputgui.cpp b/plugins/samplesink/limesdroutput/limesdroutputgui.cpp index 71e121501..7b0148518 100644 --- a/plugins/samplesink/limesdroutput/limesdroutputgui.cpp +++ b/plugins/samplesink/limesdroutput/limesdroutputgui.cpp @@ -249,6 +249,14 @@ void LimeSDROutputGUI::handleInputMessages() delete message; } + else if (LimeSDROutput::MsgStartStop::match(*message)) + { + LimeSDROutput::MsgStartStop& notif = (LimeSDROutput::MsgStartStop&) *message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + delete message; + } else { if (handleMessage(*message)) { @@ -394,18 +402,10 @@ void LimeSDROutputGUI::blockApplySettings(bool block) void LimeSDROutputGUI::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - if (m_deviceUISet->m_deviceSinkAPI->initGeneration()) - { - m_deviceUISet->m_deviceSinkAPI->startGeneration(); - DSPEngine::instance()->startAudioInput(); - } - } - else - { - m_deviceUISet->m_deviceSinkAPI->stopGeneration(); - DSPEngine::instance()->stopAudioInput(); + LimeSDROutput::MsgStartStop *message = LimeSDROutput::MsgStartStop::create(checked); + m_limeSDROutput->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesink/plutosdroutput/plutosdroutput.cpp b/plugins/samplesink/plutosdroutput/plutosdroutput.cpp index b1ec278ba..85ab01258 100644 --- a/plugins/samplesink/plutosdroutput/plutosdroutput.cpp +++ b/plugins/samplesink/plutosdroutput/plutosdroutput.cpp @@ -15,6 +15,7 @@ /////////////////////////////////////////////////////////////////////////////////// #include +#include #include "SWGDeviceSettings.h" #include "SWGDeviceState.h" @@ -32,6 +33,7 @@ #define PLUTOSDR_BLOCKSIZE_SAMPLES (16*1024) //complex samples per buffer (must be multiple of 64) MESSAGE_CLASS_DEFINITION(PlutoSDROutput::MsgConfigurePlutoSDR, Message) +MESSAGE_CLASS_DEFINITION(PlutoSDROutput::MsgStartStop, Message) PlutoSDROutput::PlutoSDROutput(DeviceSinkAPI *deviceAPI) : m_deviceAPI(deviceAPI), @@ -145,6 +147,27 @@ bool PlutoSDROutput::handleMessage(const Message& message) return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "PlutoSDROutput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initGeneration()) + { + m_deviceAPI->startGeneration(); + DSPEngine::instance()->startAudioInput(); + } + } + else + { + m_deviceAPI->stopGeneration(); + DSPEngine::instance()->stopAudioInput(); + } + + return true; + } else { return false; @@ -491,19 +514,16 @@ int PlutoSDROutput::webapiRun( SWGSDRangel::SWGDeviceState& response, QString& errorMessage __attribute__((unused))) { - if (run) + MsgStartStop *message = MsgStartStop::create(run); + m_inputMessageQueue.push(message); + + if (m_guiMessageQueue) { - if (m_deviceAPI->initGeneration()) - { - m_deviceAPI->startGeneration(); - DSPEngine::instance()->startAudioInputImmediate(); - } - } - else - { - m_deviceAPI->stopGeneration(); + MsgStartStop *messagetoGui = MsgStartStop::create(run); + m_guiMessageQueue->push(messagetoGui); } + usleep(100000); m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } diff --git a/plugins/samplesink/plutosdroutput/plutosdroutput.h b/plugins/samplesink/plutosdroutput/plutosdroutput.h index 596da1f5c..037240c81 100644 --- a/plugins/samplesink/plutosdroutput/plutosdroutput.h +++ b/plugins/samplesink/plutosdroutput/plutosdroutput.h @@ -53,6 +53,25 @@ public: { } }; + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; + PlutoSDROutput(DeviceSinkAPI *deviceAPI); ~PlutoSDROutput(); virtual void destroy(); diff --git a/plugins/samplesink/plutosdroutput/plutosdroutputgui.cpp b/plugins/samplesink/plutosdroutput/plutosdroutputgui.cpp index e6cc6be5c..6f92c1701 100644 --- a/plugins/samplesink/plutosdroutput/plutosdroutputgui.cpp +++ b/plugins/samplesink/plutosdroutput/plutosdroutputgui.cpp @@ -145,6 +145,14 @@ bool PlutoSDROutputGUI::handleMessage(const Message& message __attribute__((unus return true; } + else if (PlutoSDROutput::MsgStartStop::match(message)) + { + PlutoSDROutput::MsgStartStop& notif = (PlutoSDROutput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + return true; + } else { return false; @@ -153,18 +161,10 @@ bool PlutoSDROutputGUI::handleMessage(const Message& message __attribute__((unus void PlutoSDROutputGUI::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - if (m_deviceUISet->m_deviceSinkAPI->initGeneration()) - { - m_deviceUISet->m_deviceSinkAPI->startGeneration(); - DSPEngine::instance()->startAudioOutput(); - } - } - else - { - m_deviceUISet->m_deviceSinkAPI->stopGeneration(); - DSPEngine::instance()->stopAudioOutput(); + PlutoSDROutput::MsgStartStop *message = PlutoSDROutput::MsgStartStop::create(checked); + m_sampleSink->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp index e08580194..9fa17cd3e 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp @@ -177,6 +177,14 @@ bool SDRdaemonSinkGui::handleMessage(const Message& message) updateWithStreamTime(); return true; } + else if (SDRdaemonSinkOutput::MsgStartStop::match(message)) + { + SDRdaemonSinkOutput::MsgStartStop& notif = (SDRdaemonSinkOutput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + return true; + } else { return false; @@ -499,22 +507,10 @@ void SDRdaemonSinkGui::on_sendButton_clicked(bool checked __attribute__((unused) void SDRdaemonSinkGui::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - if (m_deviceUISet->m_deviceSinkAPI->initGeneration()) - { - if (!m_deviceUISet->m_deviceSinkAPI->startGeneration()) - { - qDebug("SDRdaemonSinkGui::on_startStop_toggled: device start failed"); - } - - DSPEngine::instance()->startAudioInput(); - } - } - else - { - m_deviceUISet->m_deviceSinkAPI->stopGeneration(); - DSPEngine::instance()->stopAudioInput(); + SDRdaemonSinkOutput::MsgStartStop *message = SDRdaemonSinkOutput::MsgStartStop::create(checked); + m_deviceSampleSink->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.cpp b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.cpp index 81be1adc8..65d083099 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.cpp +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.cpp @@ -31,6 +31,7 @@ MESSAGE_CLASS_DEFINITION(SDRdaemonSinkOutput::MsgConfigureSDRdaemonSink, Message) MESSAGE_CLASS_DEFINITION(SDRdaemonSinkOutput::MsgConfigureSDRdaemonSinkWork, Message) +MESSAGE_CLASS_DEFINITION(SDRdaemonSinkOutput::MsgStartStop, Message) MESSAGE_CLASS_DEFINITION(SDRdaemonSinkOutput::MsgConfigureSDRdaemonSinkStreamTiming, Message) MESSAGE_CLASS_DEFINITION(SDRdaemonSinkOutput::MsgConfigureSDRdaemonSinkChunkCorrection, Message) MESSAGE_CLASS_DEFINITION(SDRdaemonSinkOutput::MsgReportSDRdaemonSinkStreamTiming, Message) @@ -145,6 +146,27 @@ bool SDRdaemonSinkOutput::handleMessage(const Message& message) return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "SDRdaemonSinkOutput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initGeneration()) + { + m_deviceAPI->startGeneration(); + DSPEngine::instance()->startAudioInput(); + } + } + else + { + m_deviceAPI->stopGeneration(); + DSPEngine::instance()->stopAudioInput(); + } + + return true; + } else if (MsgConfigureSDRdaemonSinkStreamTiming::match(message)) { MsgReportSDRdaemonSinkStreamTiming *report; diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.h b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.h index f1b4b362b..24af6f7a8 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.h +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.h @@ -1,161 +1,180 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2017 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 . // -/////////////////////////////////////////////////////////////////////////////////// - -#ifndef INCLUDE_SDRDAEMONSINKOUTPUT_H -#define INCLUDE_SDRDAEMONSINKOUTPUT_H - -#include -#include -#include -#include -#include - -#include "dsp/devicesamplesink.h" - -#include "sdrdaemonsinksettings.h" - -class SDRdaemonSinkThread; -class DeviceSinkAPI; - -class SDRdaemonSinkOutput : public DeviceSampleSink { -public: - class MsgConfigureSDRdaemonSink : public Message { - MESSAGE_CLASS_DECLARATION - - public: - const SDRdaemonSinkSettings& getSettings() const { return m_settings; } - bool getForce() const { return m_force; } - - static MsgConfigureSDRdaemonSink* create(const SDRdaemonSinkSettings& settings, bool force = false) - { - return new MsgConfigureSDRdaemonSink(settings, force); - } - - private: - SDRdaemonSinkSettings m_settings; - bool m_force; - - MsgConfigureSDRdaemonSink(const SDRdaemonSinkSettings& settings, bool force) : - Message(), - m_settings(settings), - m_force(force) - { } - }; - - class MsgConfigureSDRdaemonSinkWork : public Message { - MESSAGE_CLASS_DECLARATION - - public: - bool isWorking() const { return m_working; } - - static MsgConfigureSDRdaemonSinkWork* create(bool working) - { - return new MsgConfigureSDRdaemonSinkWork(working); - } - - private: - bool m_working; - - MsgConfigureSDRdaemonSinkWork(bool working) : - Message(), - m_working(working) - { } - }; - - class MsgConfigureSDRdaemonSinkChunkCorrection : public Message { - MESSAGE_CLASS_DECLARATION - - public: - int getChunkCorrection() const { return m_chunkCorrection; } - - static MsgConfigureSDRdaemonSinkChunkCorrection* create(int chunkCorrection) - { - return new MsgConfigureSDRdaemonSinkChunkCorrection(chunkCorrection); - } - - private: - int m_chunkCorrection; - - MsgConfigureSDRdaemonSinkChunkCorrection(int chunkCorrection) : - Message(), - m_chunkCorrection(chunkCorrection) - { } - }; - - class MsgConfigureSDRdaemonSinkStreamTiming : public Message { - MESSAGE_CLASS_DECLARATION - - public: - - static MsgConfigureSDRdaemonSinkStreamTiming* create() - { - return new MsgConfigureSDRdaemonSinkStreamTiming(); - } - - private: - - MsgConfigureSDRdaemonSinkStreamTiming() : - Message() - { } - }; - - class MsgReportSDRdaemonSinkStreamTiming : public Message { - MESSAGE_CLASS_DECLARATION - - public: - std::size_t getSamplesCount() const { return m_samplesCount; } - - static MsgReportSDRdaemonSinkStreamTiming* create(std::size_t samplesCount) - { - return new MsgReportSDRdaemonSinkStreamTiming(samplesCount); - } - - protected: - std::size_t m_samplesCount; - - MsgReportSDRdaemonSinkStreamTiming(std::size_t samplesCount) : - Message(), - m_samplesCount(samplesCount) - { } - }; - - SDRdaemonSinkOutput(DeviceSinkAPI *deviceAPI); - virtual ~SDRdaemonSinkOutput(); - virtual void destroy(); - - virtual bool start(); - virtual void stop(); - - virtual const QString& getDeviceDescription() const; - virtual int getSampleRate() const; - virtual quint64 getCenterFrequency() const; - std::time_t getStartingTimeStamp() const; - - virtual bool handleMessage(const Message& message); - -private: - DeviceSinkAPI *m_deviceAPI; - QMutex m_mutex; - SDRdaemonSinkSettings m_settings; - SDRdaemonSinkThread* m_sdrDaemonSinkThread; - QString m_deviceDescription; - std::time_t m_startingTimeStamp; - const QTimer& m_masterTimer; - - void applySettings(const SDRdaemonSinkSettings& settings, bool force = false); -}; - -#endif // INCLUDE_SDRDAEMONSINKOUTPUT_H +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_SDRDAEMONSINKOUTPUT_H +#define INCLUDE_SDRDAEMONSINKOUTPUT_H + +#include +#include +#include +#include +#include + +#include "dsp/devicesamplesink.h" + +#include "sdrdaemonsinksettings.h" + +class SDRdaemonSinkThread; +class DeviceSinkAPI; + +class SDRdaemonSinkOutput : public DeviceSampleSink { +public: + class MsgConfigureSDRdaemonSink : public Message { + MESSAGE_CLASS_DECLARATION + + public: + const SDRdaemonSinkSettings& getSettings() const { return m_settings; } + bool getForce() const { return m_force; } + + static MsgConfigureSDRdaemonSink* create(const SDRdaemonSinkSettings& settings, bool force = false) + { + return new MsgConfigureSDRdaemonSink(settings, force); + } + + private: + SDRdaemonSinkSettings m_settings; + bool m_force; + + MsgConfigureSDRdaemonSink(const SDRdaemonSinkSettings& settings, bool force) : + Message(), + m_settings(settings), + m_force(force) + { } + }; + + class MsgConfigureSDRdaemonSinkWork : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool isWorking() const { return m_working; } + + static MsgConfigureSDRdaemonSinkWork* create(bool working) + { + return new MsgConfigureSDRdaemonSinkWork(working); + } + + private: + bool m_working; + + MsgConfigureSDRdaemonSinkWork(bool working) : + Message(), + m_working(working) + { } + }; + + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; + + class MsgConfigureSDRdaemonSinkChunkCorrection : public Message { + MESSAGE_CLASS_DECLARATION + + public: + int getChunkCorrection() const { return m_chunkCorrection; } + + static MsgConfigureSDRdaemonSinkChunkCorrection* create(int chunkCorrection) + { + return new MsgConfigureSDRdaemonSinkChunkCorrection(chunkCorrection); + } + + private: + int m_chunkCorrection; + + MsgConfigureSDRdaemonSinkChunkCorrection(int chunkCorrection) : + Message(), + m_chunkCorrection(chunkCorrection) + { } + }; + + class MsgConfigureSDRdaemonSinkStreamTiming : public Message { + MESSAGE_CLASS_DECLARATION + + public: + + static MsgConfigureSDRdaemonSinkStreamTiming* create() + { + return new MsgConfigureSDRdaemonSinkStreamTiming(); + } + + private: + + MsgConfigureSDRdaemonSinkStreamTiming() : + Message() + { } + }; + + class MsgReportSDRdaemonSinkStreamTiming : public Message { + MESSAGE_CLASS_DECLARATION + + public: + std::size_t getSamplesCount() const { return m_samplesCount; } + + static MsgReportSDRdaemonSinkStreamTiming* create(std::size_t samplesCount) + { + return new MsgReportSDRdaemonSinkStreamTiming(samplesCount); + } + + protected: + std::size_t m_samplesCount; + + MsgReportSDRdaemonSinkStreamTiming(std::size_t samplesCount) : + Message(), + m_samplesCount(samplesCount) + { } + }; + + SDRdaemonSinkOutput(DeviceSinkAPI *deviceAPI); + virtual ~SDRdaemonSinkOutput(); + virtual void destroy(); + + virtual bool start(); + virtual void stop(); + + virtual const QString& getDeviceDescription() const; + virtual int getSampleRate() const; + virtual quint64 getCenterFrequency() const; + std::time_t getStartingTimeStamp() const; + + virtual bool handleMessage(const Message& message); + +private: + DeviceSinkAPI *m_deviceAPI; + QMutex m_mutex; + SDRdaemonSinkSettings m_settings; + SDRdaemonSinkThread* m_sdrDaemonSinkThread; + QString m_deviceDescription; + std::time_t m_startingTimeStamp; + const QTimer& m_masterTimer; + + void applySettings(const SDRdaemonSinkSettings& settings, bool force = false); +}; + +#endif // INCLUDE_SDRDAEMONSINKOUTPUT_H diff --git a/plugins/samplesource/airspy/airspygui.cpp b/plugins/samplesource/airspy/airspygui.cpp index 736fe10b9..882e0426f 100644 --- a/plugins/samplesource/airspy/airspygui.cpp +++ b/plugins/samplesource/airspy/airspygui.cpp @@ -35,6 +35,7 @@ AirspyGui::AirspyGui(DeviceUISet *deviceUISet, QWidget* parent) : QWidget(parent), ui(new Ui::AirspyGui), m_deviceUISet(deviceUISet), + m_doApplySettings(true), m_forceSettings(true), m_settings(), m_sampleSource(0), @@ -116,9 +117,21 @@ bool AirspyGui::deserialize(const QByteArray& data) } } -bool AirspyGui::handleMessage(const Message& message __attribute__((unused))) +bool AirspyGui::handleMessage(const Message& message) { - return false; + if (AirspyInput::MsgStartStop::match(message)) + { + AirspyInput::MsgStartStop& notif = (AirspyInput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + + return true; + } + else + { + return false; + } } void AirspyGui::handleInputMessages() @@ -340,18 +353,10 @@ void AirspyGui::on_vga_valueChanged(int value) void AirspyGui::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - if (m_deviceUISet->m_deviceSourceAPI->initAcquisition()) - { - m_deviceUISet->m_deviceSourceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutput(); - } - } - else - { - m_deviceUISet->m_deviceSourceAPI->stopAcquisition(); - DSPEngine::instance()->stopAudioOutput(); + AirspyInput::MsgStartStop *message = AirspyInput::MsgStartStop::create(checked); + m_sampleSource->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesource/airspy/airspygui.h b/plugins/samplesource/airspy/airspygui.h index 563bf720b..2c3b77528 100644 --- a/plugins/samplesource/airspy/airspygui.h +++ b/plugins/samplesource/airspy/airspygui.h @@ -58,6 +58,7 @@ private: Ui::AirspyGui* ui; DeviceUISet* m_deviceUISet; + bool m_doApplySettings; bool m_forceSettings; AirspySettings m_settings; QTimer m_updateTimer; @@ -69,6 +70,7 @@ private: int m_lastEngineState; MessageQueue m_inputMessageQueue; + void blockApplySettings(bool block) { m_doApplySettings = !block; } void displaySettings(); void displaySampleRates(); void sendSettings(); diff --git a/plugins/samplesource/airspy/airspyinput.cpp b/plugins/samplesource/airspy/airspyinput.cpp index 8fa9943bd..b7fb98556 100644 --- a/plugins/samplesource/airspy/airspyinput.cpp +++ b/plugins/samplesource/airspy/airspyinput.cpp @@ -29,6 +29,7 @@ #include "airspythread.h" MESSAGE_CLASS_DEFINITION(AirspyInput::MsgConfigureAirspy, Message) +MESSAGE_CLASS_DEFINITION(AirspyInput::MsgStartStop, Message) MESSAGE_CLASS_DEFINITION(AirspyInput::MsgFileRecord, Message) const qint64 AirspyInput::loLowLimitFreq = 24000000L; @@ -236,6 +237,27 @@ bool AirspyInput::handleMessage(const Message& message) return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "AirspyInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initAcquisition()) + { + m_deviceAPI->startAcquisition(); + DSPEngine::instance()->startAudioOutput(); + } + } + else + { + m_deviceAPI->stopAcquisition(); + DSPEngine::instance()->stopAudioOutput(); + } + + return true; + } else if (MsgFileRecord::match(message)) { MsgFileRecord& conf = (MsgFileRecord&) message; diff --git a/plugins/samplesource/airspy/airspyinput.h b/plugins/samplesource/airspy/airspyinput.h index 0692bd1f5..8ef9d7102 100644 --- a/plugins/samplesource/airspy/airspyinput.h +++ b/plugins/samplesource/airspy/airspyinput.h @@ -71,6 +71,25 @@ public: { } }; + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; + AirspyInput(DeviceSourceAPI *deviceAPI); virtual ~AirspyInput(); virtual void destroy(); diff --git a/plugins/samplesource/fcdpro/fcdprogui.cpp b/plugins/samplesource/fcdpro/fcdprogui.cpp index a905dd679..e3c4c7977 100644 --- a/plugins/samplesource/fcdpro/fcdprogui.cpp +++ b/plugins/samplesource/fcdpro/fcdprogui.cpp @@ -210,7 +210,19 @@ bool FCDProGui::deserialize(const QByteArray& data) bool FCDProGui::handleMessage(const Message& message __attribute__((unused))) { - return false; + if (BladerfInput::MsgStartStop::match(message)) + { + BladerfInput::MsgStartStop& notif = (BladerfInput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + + return true; + } + else + { + return false; + } } void FCDProGui::handleInputMessages() @@ -435,18 +447,10 @@ void FCDProGui::on_setDefaults_clicked(bool checked __attribute__((unused))) void FCDProGui::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - if (m_deviceUISet->m_deviceSourceAPI->initAcquisition()) - { - m_deviceUISet->m_deviceSourceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutput(); - } - } - else - { - m_deviceUISet->m_deviceSourceAPI->stopAcquisition(); - DSPEngine::instance()->stopAudioOutput(); + BladerfInput::MsgStartStop *message = BladerfInput::MsgStartStop::create(checked); + m_sampleSource->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesource/fcdpro/fcdprogui.h b/plugins/samplesource/fcdpro/fcdprogui.h index 771c20b9e..de38ae1de 100644 --- a/plugins/samplesource/fcdpro/fcdprogui.h +++ b/plugins/samplesource/fcdpro/fcdprogui.h @@ -55,6 +55,7 @@ private: Ui::FCDProGui* ui; DeviceUISet* m_deviceUISet; + bool m_doApplySettings; bool m_forceSettings; FCDProSettings m_settings; QTimer m_updateTimer; @@ -66,6 +67,7 @@ private: int m_lastEngineState; MessageQueue m_inputMessageQueue; + void blockApplySettings(bool block) { m_doApplySettings = !block; } void displaySettings(); void sendSettings(); void updateSampleRateAndFrequency(); diff --git a/plugins/samplesource/fcdpro/fcdproinput.cpp b/plugins/samplesource/fcdpro/fcdproinput.cpp index 5665b721f..997b83da8 100644 --- a/plugins/samplesource/fcdpro/fcdproinput.cpp +++ b/plugins/samplesource/fcdpro/fcdproinput.cpp @@ -34,6 +34,7 @@ #include "fcdproconst.h" MESSAGE_CLASS_DEFINITION(FCDProInput::MsgConfigureFCD, Message) +MESSAGE_CLASS_DEFINITION(FCDProInput::MsgStartStop, Message) MESSAGE_CLASS_DEFINITION(FCDProInput::MsgFileRecord, Message) FCDProInput::FCDProInput(DeviceSourceAPI *deviceAPI) : @@ -178,6 +179,27 @@ bool FCDProInput::handleMessage(const Message& message) applySettings(conf.getSettings(), conf.getForce()); return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "FCDProInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initAcquisition()) + { + m_deviceAPI->startAcquisition(); + DSPEngine::instance()->startAudioOutput(); + } + } + else + { + m_deviceAPI->stopAcquisition(); + DSPEngine::instance()->stopAudioOutput(); + } + + return true; + } else if (MsgFileRecord::match(message)) { MsgFileRecord& conf = (MsgFileRecord&) message; diff --git a/plugins/samplesource/fcdpro/fcdproinput.h b/plugins/samplesource/fcdpro/fcdproinput.h index c325c3b61..401643365 100644 --- a/plugins/samplesource/fcdpro/fcdproinput.h +++ b/plugins/samplesource/fcdpro/fcdproinput.h @@ -78,6 +78,25 @@ public: { } }; + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; + FCDProInput(DeviceSourceAPI *deviceAPI); virtual ~FCDProInput(); virtual void destroy(); diff --git a/plugins/samplesource/fcdproplus/fcdproplusgui.cpp b/plugins/samplesource/fcdproplus/fcdproplusgui.cpp index 76dd6458f..949fdd334 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusgui.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusgui.cpp @@ -128,7 +128,19 @@ bool FCDProPlusGui::deserialize(const QByteArray& data) bool FCDProPlusGui::handleMessage(const Message& message __attribute__((unused))) { - return false; + if (FCDProPlusInput::MsgStartStop::match(message)) + { + FCDProPlusInput::MsgStartStop& notif = (FCDProPlusInput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + + return true; + } + else + { + return false; + } } void FCDProPlusGui::handleInputMessages() @@ -300,18 +312,10 @@ void FCDProPlusGui::on_ppm_valueChanged(int value) void FCDProPlusGui::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - if (m_deviceUISet->m_deviceSourceAPI->initAcquisition()) - { - m_deviceUISet->m_deviceSourceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutput(); - } - } - else - { - m_deviceUISet->m_deviceSourceAPI->stopAcquisition(); - DSPEngine::instance()->stopAudioOutput(); + BladerfInput::MsgStartStop *message = BladerfInput::MsgStartStop::create(checked); + m_sampleSource->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesource/fcdproplus/fcdproplusgui.h b/plugins/samplesource/fcdproplus/fcdproplusgui.h index 70c566310..56be9dacd 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusgui.h +++ b/plugins/samplesource/fcdproplus/fcdproplusgui.h @@ -54,6 +54,7 @@ private: Ui::FCDProPlusGui* ui; DeviceUISet* m_deviceUISet; + bool m_doApplySettings; bool m_forceSettings; FCDProPlusSettings m_settings; QTimer m_updateTimer; @@ -65,6 +66,7 @@ private: int m_lastEngineState; MessageQueue m_inputMessageQueue; + void blockApplySettings(bool block) { m_doApplySettings = !block; } void displaySettings(); void sendSettings(); void updateSampleRateAndFrequency(); diff --git a/plugins/samplesource/fcdproplus/fcdproplusinput.cpp b/plugins/samplesource/fcdproplus/fcdproplusinput.cpp index e5448404a..b54dd5f80 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusinput.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusinput.cpp @@ -33,6 +33,7 @@ #include "fcdproplusconst.h" MESSAGE_CLASS_DEFINITION(FCDProPlusInput::MsgConfigureFCD, Message) +MESSAGE_CLASS_DEFINITION(FCDProPlusInput::MsgStartStop, Message) MESSAGE_CLASS_DEFINITION(FCDProPlusInput::MsgFileRecord, Message) FCDProPlusInput::FCDProPlusInput(DeviceSourceAPI *deviceAPI) : @@ -172,6 +173,27 @@ bool FCDProPlusInput::handleMessage(const Message& message) applySettings(conf.getSettings(), conf.getForce()); return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "BladerfInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initAcquisition()) + { + m_deviceAPI->startAcquisition(); + DSPEngine::instance()->startAudioOutput(); + } + } + else + { + m_deviceAPI->stopAcquisition(); + DSPEngine::instance()->stopAudioOutput(); + } + + return true; + } else if (MsgFileRecord::match(message)) { MsgFileRecord& conf = (MsgFileRecord&) message; diff --git a/plugins/samplesource/fcdproplus/fcdproplusinput.h b/plugins/samplesource/fcdproplus/fcdproplusinput.h index ebbd7599d..9aa7ef3bc 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusinput.h +++ b/plugins/samplesource/fcdproplus/fcdproplusinput.h @@ -58,6 +58,25 @@ public: { } }; + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; + class MsgFileRecord : public Message { MESSAGE_CLASS_DECLARATION diff --git a/plugins/samplesource/filesource/filesourcegui.cpp b/plugins/samplesource/filesource/filesourcegui.cpp index 8f157db36..af431da91 100644 --- a/plugins/samplesource/filesource/filesourcegui.cpp +++ b/plugins/samplesource/filesource/filesourcegui.cpp @@ -179,6 +179,15 @@ bool FileSourceGui::handleMessage(const Message& message) updateWithStreamTime(); return true; } + else if (FileSourceInput::MsgStartStop::match(message)) + { + FileSourceInput::MsgStartStop& notif = (FileSourceInput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + + return true; + } else { return false; @@ -207,18 +216,10 @@ void FileSourceGui::on_playLoop_toggled(bool checked __attribute__((unused))) void FileSourceGui::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - if (m_deviceUISet->m_deviceSourceAPI->initAcquisition()) - { - m_deviceUISet->m_deviceSourceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutput(); - } - } - else - { - m_deviceUISet->m_deviceSourceAPI->stopAcquisition(); - DSPEngine::instance()->stopAudioOutput(); + FileSourceInput::MsgStartStop *message = FileSourceInput::MsgStartStop::create(checked); + m_sampleSource->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesource/filesource/filesourcegui.h b/plugins/samplesource/filesource/filesourcegui.h index c6a891fb1..ea03c168a 100644 --- a/plugins/samplesource/filesource/filesourcegui.h +++ b/plugins/samplesource/filesource/filesourcegui.h @@ -55,6 +55,7 @@ private: DeviceUISet* m_deviceUISet; FileSourceInput::Settings m_settings; + bool m_doApplySettings; QTimer m_statusTimer; std::vector m_gains; DeviceSampleSource* m_sampleSource; @@ -72,6 +73,7 @@ private: int m_lastEngineState; MessageQueue m_inputMessageQueue; + void blockApplySettings(bool block) { m_doApplySettings = !block; } void displaySettings(); void displayTime(); void sendSettings(); diff --git a/plugins/samplesource/filesource/filesourceinput.cpp b/plugins/samplesource/filesource/filesourceinput.cpp index a724c2f5b..d4183117f 100644 --- a/plugins/samplesource/filesource/filesourceinput.cpp +++ b/plugins/samplesource/filesource/filesourceinput.cpp @@ -36,6 +36,7 @@ MESSAGE_CLASS_DEFINITION(FileSourceInput::MsgConfigureFileSourceName, Message) MESSAGE_CLASS_DEFINITION(FileSourceInput::MsgConfigureFileSourceWork, Message) MESSAGE_CLASS_DEFINITION(FileSourceInput::MsgConfigureFileSourceSeek, Message) MESSAGE_CLASS_DEFINITION(FileSourceInput::MsgConfigureFileSourceStreamTiming, Message) +MESSAGE_CLASS_DEFINITION(FileSourceInput::MsgStartStop, Message) MESSAGE_CLASS_DEFINITION(FileSourceInput::MsgReportFileSourceAcquisition, Message) MESSAGE_CLASS_DEFINITION(FileSourceInput::MsgReportFileSourceStreamData, Message) MESSAGE_CLASS_DEFINITION(FileSourceInput::MsgReportFileSourceStreamTiming, Message) @@ -288,6 +289,27 @@ bool FileSourceInput::handleMessage(const Message& message) return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "FileSourceInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initAcquisition()) + { + m_deviceAPI->startAcquisition(); + DSPEngine::instance()->startAudioOutput(); + } + } + else + { + m_deviceAPI->stopAcquisition(); + DSPEngine::instance()->stopAudioOutput(); + } + + return true; + } else { return false; diff --git a/plugins/samplesource/filesource/filesourceinput.h b/plugins/samplesource/filesource/filesourceinput.h index 20662e585..4abb37655 100644 --- a/plugins/samplesource/filesource/filesourceinput.h +++ b/plugins/samplesource/filesource/filesourceinput.h @@ -155,6 +155,25 @@ public: { } }; + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; + class MsgReportFileSourceStreamData : public Message { MESSAGE_CLASS_DECLARATION diff --git a/plugins/samplesource/hackrfinput/hackrfinput.cpp b/plugins/samplesource/hackrfinput/hackrfinput.cpp index cf4fa8b10..1ad13ef60 100644 --- a/plugins/samplesource/hackrfinput/hackrfinput.cpp +++ b/plugins/samplesource/hackrfinput/hackrfinput.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include "SWGDeviceSettings.h" @@ -38,6 +39,7 @@ MESSAGE_CLASS_DEFINITION(HackRFInput::MsgConfigureHackRF, Message) MESSAGE_CLASS_DEFINITION(HackRFInput::MsgReportHackRF, Message) MESSAGE_CLASS_DEFINITION(HackRFInput::MsgFileRecord, Message) +MESSAGE_CLASS_DEFINITION(HackRFInput::MsgStartStop, Message) HackRFInput::HackRFInput(DeviceSourceAPI *deviceAPI) : m_deviceAPI(deviceAPI), @@ -226,6 +228,27 @@ bool HackRFInput::handleMessage(const Message& message) return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "HackRFInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initAcquisition()) + { + m_deviceAPI->startAcquisition(); + DSPEngine::instance()->startAudioOutput(); + } + } + else + { + m_deviceAPI->stopAcquisition(); + DSPEngine::instance()->stopAudioOutput(); + } + + return true; + } else { return false; @@ -502,19 +525,16 @@ int HackRFInput::webapiRun( SWGSDRangel::SWGDeviceState& response, QString& errorMessage __attribute__((unused))) { - if (run) + MsgStartStop *message = MsgStartStop::create(run); + m_inputMessageQueue.push(message); + + if (m_guiMessageQueue) // forward to GUI if any { - if (m_deviceAPI->initAcquisition()) - { - m_deviceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutputImmediate(); - } - } - else - { - m_deviceAPI->stopAcquisition(); + MsgStartStop *msgToGUI = MsgStartStop::create(run); + m_guiMessageQueue->push(msgToGUI); } + usleep(100000); m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } diff --git a/plugins/samplesource/hackrfinput/hackrfinput.h b/plugins/samplesource/hackrfinput/hackrfinput.h index 29a6654f0..1fe08c1a0 100644 --- a/plugins/samplesource/hackrfinput/hackrfinput.h +++ b/plugins/samplesource/hackrfinput/hackrfinput.h @@ -72,6 +72,25 @@ public: { } }; + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; + class MsgFileRecord : public Message { MESSAGE_CLASS_DECLARATION diff --git a/plugins/samplesource/hackrfinput/hackrfinputgui.cpp b/plugins/samplesource/hackrfinput/hackrfinputgui.cpp index fc1a89b34..1f227cefd 100644 --- a/plugins/samplesource/hackrfinput/hackrfinputgui.cpp +++ b/plugins/samplesource/hackrfinput/hackrfinputgui.cpp @@ -130,6 +130,15 @@ bool HackRFInputGui::handleMessage(const Message& message) displaySettings(); return true; } + else if (HackRFInput::MsgStartStop::match(message)) + { + HackRFInput::MsgStartStop& notif = (HackRFInput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + + return true; + } else { return false; @@ -333,25 +342,10 @@ void HackRFInputGui::on_vga_valueChanged(int value) void HackRFInputGui::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - // forcibly stop the Tx if present before starting - if (m_deviceUISet->m_deviceSourceAPI->getSinkBuddies().size() > 0) - { - DeviceSinkAPI *buddy = m_deviceUISet->m_deviceSourceAPI->getSinkBuddies()[0]; - buddy->stopGeneration(); - } - - if (m_deviceUISet->m_deviceSourceAPI->initAcquisition()) - { - m_deviceUISet->m_deviceSourceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutput(); - } - } - else - { - m_deviceUISet->m_deviceSourceAPI->stopAcquisition(); - DSPEngine::instance()->stopAudioOutput(); + HackRFInput::MsgStartStop *message = HackRFInput::MsgStartStop::create(checked); + m_sampleSource->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesource/limesdrinput/limesdrinput.cpp b/plugins/samplesource/limesdrinput/limesdrinput.cpp index d2ffdc771..d8809076f 100644 --- a/plugins/samplesource/limesdrinput/limesdrinput.cpp +++ b/plugins/samplesource/limesdrinput/limesdrinput.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "lime/LimeSuite.h" #include "SWGDeviceSettings.h" @@ -40,6 +41,7 @@ MESSAGE_CLASS_DEFINITION(LimeSDRInput::MsgGetStreamInfo, Message) MESSAGE_CLASS_DEFINITION(LimeSDRInput::MsgGetDeviceInfo, Message) MESSAGE_CLASS_DEFINITION(LimeSDRInput::MsgReportStreamInfo, Message) MESSAGE_CLASS_DEFINITION(LimeSDRInput::MsgFileRecord, Message) +MESSAGE_CLASS_DEFINITION(LimeSDRInput::MsgStartStop, Message) LimeSDRInput::LimeSDRInput(DeviceSourceAPI *deviceAPI) : m_deviceAPI(deviceAPI), @@ -660,6 +662,27 @@ bool LimeSDRInput::handleMessage(const Message& message) return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "LimeSDRInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initAcquisition()) + { + m_deviceAPI->startAcquisition(); + DSPEngine::instance()->startAudioOutput(); + } + } + else + { + m_deviceAPI->stopAcquisition(); + DSPEngine::instance()->stopAudioOutput(); + } + + return true; + } else { return false; @@ -1258,19 +1281,16 @@ int LimeSDRInput::webapiRun( SWGSDRangel::SWGDeviceState& response, QString& errorMessage __attribute__((unused))) { - if (run) + MsgStartStop *message = MsgStartStop::create(run); + m_inputMessageQueue.push(message); + + if (m_guiMessageQueue) // forward to GUI if any { - if (m_deviceAPI->initAcquisition()) - { - m_deviceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutputImmediate(); - } - } - else - { - m_deviceAPI->stopAcquisition(); + MsgStartStop *msgToGUI = MsgStartStop::create(run); + m_guiMessageQueue->push(msgToGUI); } + usleep(100000); m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } diff --git a/plugins/samplesource/limesdrinput/limesdrinput.h b/plugins/samplesource/limesdrinput/limesdrinput.h index 967b8df15..927280f8b 100644 --- a/plugins/samplesource/limesdrinput/limesdrinput.h +++ b/plugins/samplesource/limesdrinput/limesdrinput.h @@ -185,6 +185,25 @@ public: { } }; + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; + LimeSDRInput(DeviceSourceAPI *deviceAPI); virtual ~LimeSDRInput(); virtual void destroy(); diff --git a/plugins/samplesource/limesdrinput/limesdrinputgui.cpp b/plugins/samplesource/limesdrinput/limesdrinputgui.cpp index 353ef6d38..eea841714 100644 --- a/plugins/samplesource/limesdrinput/limesdrinputgui.cpp +++ b/plugins/samplesource/limesdrinput/limesdrinputgui.cpp @@ -219,8 +219,19 @@ bool LimeSDRInputGUI::handleMessage(const Message& message) ui->temperatureText->setText(tr("%1C").arg(QString::number(report.getTemperature(), 'f', 0))); return true; } + else if (LimeSDRInput::MsgStartStop::match(message)) + { + LimeSDRInput::MsgStartStop& notif = (LimeSDRInput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); - return false; + return true; + } + else + { + return false; + } } void LimeSDRInputGUI::handleInputMessages() @@ -415,18 +426,10 @@ void LimeSDRInputGUI::blockApplySettings(bool block) void LimeSDRInputGUI::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - if (m_deviceUISet->m_deviceSourceAPI->initAcquisition()) - { - m_deviceUISet->m_deviceSourceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutput(); - } - } - else - { - m_deviceUISet->m_deviceSourceAPI->stopAcquisition(); - DSPEngine::instance()->stopAudioOutput(); + LimeSDRInput::MsgStartStop *message = LimeSDRInput::MsgStartStop::create(checked); + m_limeSDRInput->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesource/plutosdrinput/plutosdrinput.cpp b/plugins/samplesource/plutosdrinput/plutosdrinput.cpp index c0e90cf59..a00125204 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinput.cpp +++ b/plugins/samplesource/plutosdrinput/plutosdrinput.cpp @@ -15,6 +15,7 @@ /////////////////////////////////////////////////////////////////////////////////// #include +#include #include "SWGDeviceSettings.h" #include "SWGDeviceState.h" @@ -34,6 +35,7 @@ MESSAGE_CLASS_DEFINITION(PlutoSDRInput::MsgConfigurePlutoSDR, Message) MESSAGE_CLASS_DEFINITION(PlutoSDRInput::MsgFileRecord, Message) +MESSAGE_CLASS_DEFINITION(PlutoSDRInput::MsgStartStop, Message) PlutoSDRInput::PlutoSDRInput(DeviceSourceAPI *deviceAPI) : m_deviceAPI(deviceAPI), @@ -154,6 +156,27 @@ bool PlutoSDRInput::handleMessage(const Message& message) return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "PlutoSDRInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initAcquisition()) + { + m_deviceAPI->startAcquisition(); + DSPEngine::instance()->startAudioOutput(); + } + } + else + { + m_deviceAPI->stopAcquisition(); + DSPEngine::instance()->stopAudioOutput(); + } + + return true; + } else if (DevicePlutoSDRShared::MsgCrossReportToBuddy::match(message)) // message from buddy { DevicePlutoSDRShared::MsgCrossReportToBuddy& conf = (DevicePlutoSDRShared::MsgCrossReportToBuddy&) message; @@ -578,19 +601,16 @@ int PlutoSDRInput::webapiRun( SWGSDRangel::SWGDeviceState& response, QString& errorMessage __attribute__((unused))) { - if (run) + MsgStartStop *message = MsgStartStop::create(run); + m_inputMessageQueue.push(message); + + if (m_guiMessageQueue) // forward to GUI if any { - if (m_deviceAPI->initAcquisition()) - { - m_deviceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutputImmediate(); - } - } - else - { - m_deviceAPI->stopAcquisition(); + MsgStartStop *msgToGUI = MsgStartStop::create(run); + m_guiMessageQueue->push(msgToGUI); } + usleep(100000); m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } diff --git a/plugins/samplesource/plutosdrinput/plutosdrinput.h b/plugins/samplesource/plutosdrinput/plutosdrinput.h index 7b33ca3d8..b1132a5cd 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinput.h +++ b/plugins/samplesource/plutosdrinput/plutosdrinput.h @@ -73,6 +73,24 @@ public: { } }; + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; PlutoSDRInput(DeviceSourceAPI *deviceAPI); ~PlutoSDRInput(); diff --git a/plugins/samplesource/plutosdrinput/plutosdrinputgui.cpp b/plugins/samplesource/plutosdrinput/plutosdrinputgui.cpp index bc404d9a0..8919a423f 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinputgui.cpp +++ b/plugins/samplesource/plutosdrinput/plutosdrinputgui.cpp @@ -131,7 +131,16 @@ bool PlutoSDRInputGui::deserialize(const QByteArray& data) bool PlutoSDRInputGui::handleMessage(const Message& message __attribute__((unused))) { - if (DevicePlutoSDRShared::MsgCrossReportToBuddy::match(message)) // message from buddy + if (PlutoSDRInput::MsgStartStop::match(message)) + { + PlutoSDRInput::MsgStartStop& notif = (PlutoSDRInput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + + return true; + } + else if (DevicePlutoSDRShared::MsgCrossReportToBuddy::match(message)) // message from buddy { DevicePlutoSDRShared::MsgCrossReportToBuddy& conf = (DevicePlutoSDRShared::MsgCrossReportToBuddy&) message; m_settings.m_devSampleRate = conf.getDevSampleRate(); @@ -153,18 +162,10 @@ bool PlutoSDRInputGui::handleMessage(const Message& message __attribute__((unuse void PlutoSDRInputGui::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - if (m_deviceUISet->m_deviceSourceAPI->initAcquisition()) - { - m_deviceUISet->m_deviceSourceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutput(); - } - } - else - { - m_deviceUISet->m_deviceSourceAPI->stopAcquisition(); - DSPEngine::instance()->stopAudioOutput(); + PlutoSDRInput::MsgStartStop *message = PlutoSDRInput::MsgStartStop::create(checked); + m_sampleSource->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp index 7eb93a755..c200fbac6 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp @@ -149,6 +149,15 @@ bool RTLSDRGui::handleMessage(const Message& message) blockApplySettings(false); return true; } + if (RTLSDRInput::MsgStartStop::match(message)) + { + RTLSDRInput::MsgStartStop& notif = (RTLSDRInput::MsgStartStop&) message; + blockApplySettings(true); + ui->startStop->setChecked(notif.getStartStop()); + blockApplySettings(false); + + return true; + } else { return false; @@ -320,18 +329,10 @@ void RTLSDRGui::on_gain_valueChanged(int value) void RTLSDRGui::on_startStop_toggled(bool checked) { - if (checked) + if (m_doApplySettings) { - if (m_deviceUISet->m_deviceSourceAPI->initAcquisition()) - { - m_deviceUISet->m_deviceSourceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutput(); - } - } - else - { - m_deviceUISet->m_deviceSourceAPI->stopAcquisition(); - DSPEngine::instance()->stopAudioOutput(); + RTLSDRInput::MsgStartStop *message = RTLSDRInput::MsgStartStop::create(checked); + m_sampleSource->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp index a691e96bc..bc1c52978 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "SWGDeviceSettings.h" #include "SWGRtlSdrSettings.h" @@ -34,6 +35,7 @@ MESSAGE_CLASS_DEFINITION(RTLSDRInput::MsgConfigureRTLSDR, Message) MESSAGE_CLASS_DEFINITION(RTLSDRInput::MsgReportRTLSDR, Message) MESSAGE_CLASS_DEFINITION(RTLSDRInput::MsgFileRecord, Message) +MESSAGE_CLASS_DEFINITION(RTLSDRInput::MsgStartStop, Message) const quint64 RTLSDRInput::frequencyLowRangeMin = 1000UL; const quint64 RTLSDRInput::frequencyLowRangeMax = 275000UL; @@ -274,6 +276,27 @@ bool RTLSDRInput::handleMessage(const Message& message) return true; } + else if (MsgStartStop::match(message)) + { + MsgStartStop& cmd = (MsgStartStop&) message; + qDebug() << "RTLSDRInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + + if (cmd.getStartStop()) + { + if (m_deviceAPI->initAcquisition()) + { + m_deviceAPI->startAcquisition(); + DSPEngine::instance()->startAudioOutput(); + } + } + else + { + m_deviceAPI->stopAcquisition(); + DSPEngine::instance()->stopAudioOutput(); + } + + return true; + } else { return false; @@ -541,19 +564,16 @@ int RTLSDRInput::webapiRun( SWGSDRangel::SWGDeviceState& response, QString& errorMessage __attribute__((unused))) { - if (run) + MsgStartStop *message = MsgStartStop::create(run); + m_inputMessageQueue.push(message); + + if (m_guiMessageQueue) // forward to GUI if any { - if (m_deviceAPI->initAcquisition()) - { - m_deviceAPI->startAcquisition(); - DSPEngine::instance()->startAudioOutputImmediate(); - } - } - else - { - m_deviceAPI->stopAcquisition(); + MsgStartStop *msgToGUI = MsgStartStop::create(run); + m_guiMessageQueue->push(msgToGUI); } + usleep(100000); m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } diff --git a/plugins/samplesource/rtlsdr/rtlsdrinput.h b/plugins/samplesource/rtlsdr/rtlsdrinput.h index 23ad90866..7b6b7c911 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrinput.h +++ b/plugins/samplesource/rtlsdr/rtlsdrinput.h @@ -92,6 +92,25 @@ public: { } }; + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; + RTLSDRInput(DeviceSourceAPI *deviceAPI); virtual ~RTLSDRInput(); virtual void destroy();