diff --git a/plugins/samplesource/fcdproplus/fcdproplusgui.cpp b/plugins/samplesource/fcdproplus/fcdproplusgui.cpp index e557f160a..7b261a9ca 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusgui.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusgui.cpp @@ -159,18 +159,20 @@ void FCDProPlusGui::handleInputMessages() while ((message = m_inputMessageQueue.pop()) != 0) { - qDebug("RTLSDRGui::handleInputMessages: message: %s", message->getIdentifier()); - if (DSPSignalNotification::match(*message)) { DSPSignalNotification* notif = (DSPSignalNotification*) message; m_sampleRate = notif->getSampleRate(); m_deviceCenterFrequency = notif->getCenterFrequency(); - qDebug("RTLSDRGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu", notif->getSampleRate(), notif->getCenterFrequency()); + qDebug("FCDProPlusGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu", notif->getSampleRate(), notif->getCenterFrequency()); updateSampleRateAndFrequency(); delete message; } + else + { + qWarning("FCDProPlusGui::handleInputMessages: message: %s. No action.", message->getIdentifier()); + } } } @@ -322,11 +324,8 @@ void FCDProPlusGui::on_ppm_valueChanged(int value) void FCDProPlusGui::on_startStop_toggled(bool checked) { - if (m_doApplySettings) - { - FCDProPlusInput::MsgStartStop *message = FCDProPlusInput::MsgStartStop::create(checked); - m_sampleSource->getInputMessageQueue()->push(message); - } + FCDProPlusInput::MsgStartStop *message = FCDProPlusInput::MsgStartStop::create(checked); + m_sampleSource->getInputMessageQueue()->push(message); } void FCDProPlusGui::on_record_toggled(bool checked) diff --git a/plugins/samplesource/fcdproplus/fcdproplusinput.cpp b/plugins/samplesource/fcdproplus/fcdproplusinput.cpp index be4902914..dcb17cd09 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusinput.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusinput.cpp @@ -41,6 +41,7 @@ MESSAGE_CLASS_DEFINITION(FCDProPlusInput::MsgFileRecord, Message) FCDProPlusInput::FCDProPlusInput(DeviceSourceAPI *deviceAPI) : m_deviceAPI(deviceAPI), m_dev(0), + fcd_handle(0), m_settings(), m_FCDThread(0), m_deviceDescription(fcd_traits::displayedName), @@ -87,14 +88,15 @@ void FCDProPlusInput::init() bool FCDProPlusInput::start() { - // QMutexLocker mutexLocker(&m_mutex); if (!m_dev) { return false; } - if (m_running) stop(); + if (m_running) { + stop(); + } qDebug() << "FCDProPlusInput::start"; @@ -105,13 +107,23 @@ bool FCDProPlusInput::start() //applySettings(m_settings, true); - if(!m_sampleFifo.setSize(96000*4)) + if (!m_sampleFifo.setSize(96000*4)) { - qCritical("Could not allocate SampleFifo"); + qCritical("FCDProPlusInput::start: could not allocate SampleFifo"); return false; } - m_FCDThread = new FCDProPlusThread(&m_sampleFifo); + if (!openSource(fcd_traits::alsaDeviceName)) + { + qCritical("FCDProPlusInput::start: could not open source"); + return false; + } + else + { + qDebug("FCDProPlusInput::start: source opened"); + } + + m_FCDThread = new FCDProPlusThread(&m_sampleFifo, fcd_handle); m_FCDThread->startWork(); // mutexLocker.unlock(); @@ -133,6 +145,75 @@ void FCDProPlusInput::closeDevice() m_dev = 0; } +bool FCDProPlusInput::openSource(const char* cardname) +{ + bool fail = false; + snd_pcm_hw_params_t* params; + //fcd_rate = FCDPP_RATE; + //fcd_channels =2; + //fcd_format = SND_PCM_SFMT_U16_LE; + snd_pcm_stream_t fcd_stream = SND_PCM_STREAM_CAPTURE; + + if (fcd_handle) + { + qDebug("FCDProPlusInput::OpenSource: already opened"); + return false; + } + + if (snd_pcm_open(&fcd_handle, cardname, fcd_stream, 0) < 0) + { + qCritical("FCDProPlusInput::OpenSource: cannot open %s", cardname); + return false; + } + + snd_pcm_hw_params_alloca(¶ms); + + if (snd_pcm_hw_params_any(fcd_handle, params) < 0) + { + qCritical("FCDProPlusInput::OpenSource: snd_pcm_hw_params_any failed"); + fail = true; + } + else if (snd_pcm_hw_params(fcd_handle, params) < 0) + { + qCritical("FCDProPlusInput::OpenSource: snd_pcm_hw_params failed"); + fail = true; + // TODO: check actual samplerate, may be crippled firmware + } + else + { + if (snd_pcm_start(fcd_handle) < 0) + { + qCritical("FCDProPlusInput::OpenSource: snd_pcm_start failed"); + fail = true; + } + else + { + qDebug("FCDProPlusInput::OpenSource: snd_pcm_start OK"); + } + } + + if (fail) + { + snd_pcm_close(fcd_handle); + return false; + } + else + { + qDebug("FCDProPlusInput::OpenSource: Funcube stream started"); + } + + return true; +} + +void FCDProPlusInput::closeSource() +{ + if (fcd_handle) { + snd_pcm_close(fcd_handle); + } + + fcd_handle = nullptr; +} + void FCDProPlusInput::stop() { QMutexLocker mutexLocker(&m_mutex); @@ -142,7 +223,8 @@ void FCDProPlusInput::stop() m_FCDThread->stopWork(); // wait for thread to quit ? delete m_FCDThread; - m_FCDThread = 0; + m_FCDThread = nullptr; + closeSource(); } m_running = false; @@ -217,7 +299,7 @@ bool FCDProPlusInput::handleMessage(const Message& message) else if (MsgStartStop::match(message)) { MsgStartStop& cmd = (MsgStartStop&) message; - qDebug() << "BladerfInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + qDebug() << "FCDProPlusInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); if (cmd.getStartStop()) { diff --git a/plugins/samplesource/fcdproplus/fcdproplusinput.h b/plugins/samplesource/fcdproplus/fcdproplusinput.h index 38c4cac11..26eb53e61 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusinput.h +++ b/plugins/samplesource/fcdproplus/fcdproplusinput.h @@ -21,6 +21,8 @@ #include #include +#include + #include #include "fcdproplussettings.h" #include "fcdhid.h" @@ -147,11 +149,14 @@ public: private: bool openDevice(); void closeDevice(); + bool openSource(const char *filename); + void closeSource(); void applySettings(const FCDProPlusSettings& settings, bool force); void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const FCDProPlusSettings& settings); DeviceSourceAPI *m_deviceAPI; hid_device *m_dev; + snd_pcm_t* fcd_handle; QMutex m_mutex; FCDProPlusSettings m_settings; FCDProPlusThread* m_FCDThread; diff --git a/plugins/samplesource/fcdproplus/fcdproplusthread.cpp b/plugins/samplesource/fcdproplus/fcdproplusthread.cpp index a29ca1411..1be59d82a 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusthread.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusthread.cpp @@ -23,9 +23,9 @@ #include "dsp/samplesinkfifo.h" #include "fcdtraits.h" -FCDProPlusThread::FCDProPlusThread(SampleSinkFifo* sampleFifo, QObject* parent) : +FCDProPlusThread::FCDProPlusThread(SampleSinkFifo* sampleFifo, snd_pcm_t *fcd_handle, QObject* parent) : QThread(parent), - fcd_handle(NULL), + m_fcd_handle(fcd_handle), m_running(false), m_convertBuffer(fcd_traits::convBufSize), m_sampleFifo(sampleFifo) @@ -59,89 +59,17 @@ void FCDProPlusThread::stopWork() void FCDProPlusThread::run() { - if ( !OpenSource(fcd_traits::alsaDeviceName) ) - { - qCritical() << "FCDThread::run: cannot open FCD sound card"; - return; - } - // TODO: fallback to original fcd - m_running = true; + qDebug("FCDThread::run: start running loop"); - while(m_running) + while (m_running) { - if (work(fcd_traits::convBufSize) < 0) - { + if (work(fcd_traits::convBufSize) < 0) { break; } } - CloseSource(); -} - -bool FCDProPlusThread::OpenSource(const char* cardname) -{ - bool fail = false; - snd_pcm_hw_params_t* params; - //fcd_rate = FCDPP_RATE; - //fcd_channels =2; - //fcd_format = SND_PCM_SFMT_U16_LE; - snd_pcm_stream_t fcd_stream = SND_PCM_STREAM_CAPTURE; - - if (fcd_handle) - { - return false; - } - - if (snd_pcm_open(&fcd_handle, cardname, fcd_stream, 0) < 0) - { - qCritical("FCDThread::OpenSource: cannot open %s", cardname); - return false; - } - - snd_pcm_hw_params_alloca(¶ms); - - if (snd_pcm_hw_params_any(fcd_handle, params) < 0) - { - qCritical("FCDProPlusThread::OpenSource: snd_pcm_hw_params_any failed"); - fail = true; - } - else if (snd_pcm_hw_params(fcd_handle, params) < 0) - { - qCritical("FCDProPlusThread::OpenSource: snd_pcm_hw_params failed"); - fail = true; - // TODO: check actual samplerate, may be crippled firmware - } - else - { - if (snd_pcm_start(fcd_handle) < 0) - { - qCritical("FCDProPlusThread::OpenSource: snd_pcm_start failed"); - fail = true; - } - } - - if (fail) - { - snd_pcm_close( fcd_handle ); - return false; - } - else - { - qDebug("FCDProPlusThread::OpenSource: Funcube stream started"); - } - - return true; -} - -void FCDProPlusThread::CloseSource() -{ - if (fcd_handle) - { - snd_pcm_close( fcd_handle ); - } - - fcd_handle = NULL; + qDebug("FCDThread::run: running loop stopped"); } int FCDProPlusThread::work(int n_items) @@ -152,14 +80,25 @@ int FCDProPlusThread::work(int n_items) it = m_convertBuffer.begin(); out = (void *)&it[0]; - l = snd_pcm_mmap_readi(fcd_handle, out, (snd_pcm_uframes_t)n_items); + + l = snd_pcm_mmap_readi(m_fcd_handle, out, (snd_pcm_uframes_t)n_items); + if (l > 0) - m_sampleFifo->write(it, it + l); - if (l == -EPIPE) { - qDebug("FCDProPlusThread::work: Overrun detected"); - return 0; + { + m_sampleFifo->write(it, it + l); } + else + { + if (l == -EPIPE) { + qDebug("FCDProPlusThread::work: Overrun detected"); + } else if (l < 0) { + qDebug("FCDProPlusThread::work: snd_pcm_mmap_readi failed with code %d", l); + } else { + qDebug("FCDProPlusThread::work: snd_pcm_mmap_readi empty"); + } + + return 0; + } + return l; } - - diff --git a/plugins/samplesource/fcdproplus/fcdproplusthread.h b/plugins/samplesource/fcdproplus/fcdproplusthread.h index 74e7f6d75..e797433cb 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusthread.h +++ b/plugins/samplesource/fcdproplus/fcdproplusthread.h @@ -21,24 +21,23 @@ #include #include #include -#include "dsp/inthalfbandfilter.h" #include + +#include "dsp/inthalfbandfilter.h" #include "dsp/samplesinkfifo.h" class FCDProPlusThread : public QThread { Q_OBJECT public: - FCDProPlusThread(SampleSinkFifo* sampleFifo, QObject* parent = NULL); + FCDProPlusThread(SampleSinkFifo* sampleFifo, snd_pcm_t *fcd_handle, QObject* parent = nullptr); ~FCDProPlusThread(); void startWork(); void stopWork(); - bool OpenSource(const char *filename); - void CloseSource(); private: - snd_pcm_t* fcd_handle; + snd_pcm_t* m_fcd_handle; QMutex m_startWaitMutex; QWaitCondition m_startWaiter;