diff --git a/Readme.md b/Readme.md index 88ad99039..fd9f2da1a 100644 --- a/Readme.md +++ b/Readme.md @@ -129,9 +129,12 @@ Done since the fork - Coarse and fine trigger level sliders - Minimalist recording (no file choice) - File sample source plugin (recording reader) not working - - Make the DSP engine global static - - Fixed startup initialization sequence. New initialization phase in DSP engine and new ready state - - Message queuing and handling redesign + - Redesign: + - Make the DSP engine global static + - Fixed startup initialization sequence. New initialization phase in DSP engine and new ready state + - Synchronous messaging class to push message to thread and wait for completion + - Message queuing and handling redesign + - Many other little things... ===== To Do diff --git a/include-gpl/dsp/channelizer.h b/include-gpl/dsp/channelizer.h index d622515a4..510cb5714 100644 --- a/include-gpl/dsp/channelizer.h +++ b/include-gpl/dsp/channelizer.h @@ -17,10 +17,9 @@ public: void configure(MessageQueue* messageQueue, int sampleRate, int centerFrequency); int getInputSampleRate() const { return m_inputSampleRate; } - virtual bool init(const Message& cmd); - virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); virtual void start(); virtual void stop(); + virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); virtual bool handleMessage(const Message& cmd); protected: diff --git a/include-gpl/dsp/dspcommands.h b/include-gpl/dsp/dspcommands.h index 4f979bab0..382d35f00 100644 --- a/include-gpl/dsp/dspcommands.h +++ b/include-gpl/dsp/dspcommands.h @@ -105,6 +105,30 @@ private: SampleSink* m_sampleSink; }; +class SDRANGELOVE_API DSPAddThreadedSink : public Message { + MESSAGE_CLASS_DECLARATION + +public: + DSPAddThreadedSink(SampleSink* sampleSink) : Message(), m_sampleSink(sampleSink) { } + + SampleSink* getSampleSink() const { return m_sampleSink; } + +private: + SampleSink* m_sampleSink; +}; + +class SDRANGELOVE_API DSPRemoveThreadedSink : public Message { + MESSAGE_CLASS_DECLARATION + +public: + DSPRemoveThreadedSink(SampleSink* sampleSink) : Message(), m_sampleSink(sampleSink) { } + + SampleSink* getSampleSink() const { return m_sampleSink; } + +private: + SampleSink* m_sampleSink; +}; + class SDRANGELOVE_API DSPAddAudioSink : public Message { MESSAGE_CLASS_DECLARATION diff --git a/include-gpl/dsp/dspengine.h b/include-gpl/dsp/dspengine.h index 1f90f7aa8..38e14769e 100644 --- a/include-gpl/dsp/dspengine.h +++ b/include-gpl/dsp/dspengine.h @@ -32,6 +32,7 @@ class SampleSource; class SampleSink; +class ThreadedSampleSink; class AudioFifo; class SDRANGELOVE_API DSPEngine : public QThread { @@ -66,6 +67,9 @@ public: void addSink(SampleSink* sink); //!< Add a sample sink void removeSink(SampleSink* sink); //!< Remove a sample sink + void addThreadedSink(SampleSink* sink); //!< Add a sample sink that will run on its own thread + void removeThreadedSink(SampleSink* sink); //!< Remove a sample sink that runs on its own thread + void addAudioSink(AudioFifo* audioFifo); //!< Add the audio sink void removeAudioSink(AudioFifo* audioFifo); //!< Remove the audio sink @@ -89,7 +93,10 @@ private: SampleSource* m_sampleSource; typedef std::list SampleSinks; - SampleSinks m_sampleSinks; + SampleSinks m_sampleSinks; //!< sample sinks within main thread (usually spectrum, file output) + + typedef std::list ThreadedSampleSinks; + ThreadedSampleSinks m_threadedSampleSinks; //!< sample sinks on their own threads (usually channels) AudioOutput m_audioSink; @@ -120,7 +127,7 @@ private slots: void handleData(); //!< Handle data when samples from source FIFO are ready to be processed void handleSourceMessages(); //!< Handle source message output void handleInputMessages(); //!< Handle input message queue - void handleSynchronousMessages(Message *message); //!< Handle synchronous messages with the thread + void handleSynchronousMessages(const Message& message); //!< Handle synchronous messages with the thread }; #endif // INCLUDE_DSPENGINE_H diff --git a/include-gpl/dsp/filesink.h b/include-gpl/dsp/filesink.h index d42a012ad..821c74cc1 100644 --- a/include-gpl/dsp/filesink.h +++ b/include-gpl/dsp/filesink.h @@ -28,7 +28,6 @@ public: void configure(MessageQueue* msgQueue, const std::string& filename); - virtual bool init(const Message& cmd); virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); virtual void start(); virtual void stop(); diff --git a/include-gpl/dsp/scopevis.h b/include-gpl/dsp/scopevis.h index c620283ef..d56a2da42 100644 --- a/include-gpl/dsp/scopevis.h +++ b/include-gpl/dsp/scopevis.h @@ -35,7 +35,6 @@ public: uint traceSize); void setOneShot(bool oneShot); - virtual bool init(const Message& cmd); virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); virtual void start(); virtual void stop(); diff --git a/include-gpl/dsp/spectrumscopecombovis.h b/include-gpl/dsp/spectrumscopecombovis.h index f18f62316..ae1d4c00b 100644 --- a/include-gpl/dsp/spectrumscopecombovis.h +++ b/include-gpl/dsp/spectrumscopecombovis.h @@ -14,7 +14,6 @@ public: SpectrumScopeComboVis(SpectrumVis* spectrumVis, ScopeVis* scopeVis); virtual ~SpectrumScopeComboVis(); - virtual bool init(const Message& cmd); virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); virtual void start(); virtual void stop(); diff --git a/include-gpl/dsp/spectrumvis.h b/include-gpl/dsp/spectrumvis.h index 53a492282..0837c61ef 100644 --- a/include-gpl/dsp/spectrumvis.h +++ b/include-gpl/dsp/spectrumvis.h @@ -16,7 +16,6 @@ public: void configure(MessageQueue* msgQueue, int fftSize, int overlapPercent, FFTWindow::Function window); - virtual bool init(const Message& cmd); virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); void feedTriggered(SampleVector::const_iterator triggerPoint, SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); virtual void start(); diff --git a/include-gpl/plugin/pluginmanager.h b/include-gpl/plugin/pluginmanager.h index 45d97f782..1a7966fd5 100644 --- a/include-gpl/plugin/pluginmanager.h +++ b/include-gpl/plugin/pluginmanager.h @@ -52,7 +52,7 @@ public: void freeAll(); - bool handleMessage(Message* message); + bool handleMessage(const Message& message); void updateSampleSourceDevices(); void fillSampleSourceSelector(QComboBox* comboBox); diff --git a/include/dsp/samplesink.h b/include/dsp/samplesink.h index a83fbbaa2..5b1e9cf1a 100644 --- a/include/dsp/samplesink.h +++ b/include/dsp/samplesink.h @@ -13,18 +13,18 @@ public: SampleSink(); virtual ~SampleSink(); - virtual bool init(const Message& cmd) = 0; - virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly) = 0; virtual void start() = 0; virtual void stop() = 0; + virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly) = 0; virtual bool handleMessage(const Message& cmd) = 0; //!< Processing of a message. Returns true if message has actually been processed - MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } - MessageQueue *getOutputMessageQueue() { return &m_outputMessageQueue; } + MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication + MessageQueue *getOutputMessageQueue() { return &m_outputMessageQueue; } //!< Get the queue for asynchronous outbound communication protected: - MessageQueue m_inputMessageQueue; - MessageQueue m_outputMessageQueue; + void handleInputMessages(); + MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication + MessageQueue m_outputMessageQueue; //!< Queue for asynchronous outbound communication }; #endif // INCLUDE_SAMPLESINK_H diff --git a/include/dsp/samplesource/samplesource.h b/include/dsp/samplesource/samplesource.h index c6bd0cc29..cdd52fa8d 100644 --- a/include/dsp/samplesource/samplesource.h +++ b/include/dsp/samplesource/samplesource.h @@ -29,13 +29,13 @@ public: SampleSource(); virtual ~SampleSource(); - virtual void init(const Message& cmd) = 0; + virtual bool init(const Message& cmd) = 0; virtual bool start(int device) = 0; virtual void stop() = 0; virtual const QString& getDeviceDescription() const = 0; - virtual int getSampleRate() const { return m_sampleRate; }; - virtual quint64 getCenterFrequency() const { return m_centerFrequency; }; + virtual int getSampleRate() const = 0; //!< Sample rate exposed by the source + virtual quint64 getCenterFrequency() const = 0; //!< Center frequency exposed by the source virtual bool handleMessage(const Message& message) = 0; @@ -44,15 +44,9 @@ public: SampleFifo* getSampleFifo() { return &m_sampleFifo; } protected: - void setSampleRate(int sampleRate); - void setCenterFrequency(quint64 centerFrequency); - void sendNewData(); - SampleFifo m_sampleFifo; MessageQueue m_inputMessageQueue; MessageQueue m_outputMessageQueue; - int m_sampleRate; - quint64 m_centerFrequency; }; #endif // INCLUDE_SAMPLESOURCE_H diff --git a/include/dsp/threadedsamplesink.h b/include/dsp/threadedsamplesink.h index 694e127c3..374d5bf81 100644 --- a/include/dsp/threadedsamplesink.h +++ b/include/dsp/threadedsamplesink.h @@ -1,41 +1,62 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2015 F4EXB // +// written by Edouard Griffiths // +// // +// 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_THREADEDSAMPLESINK_H #define INCLUDE_THREADEDSAMPLESINK_H #include +#include #include "samplesink.h" #include "dsp/samplefifo.h" #include "util/messagequeue.h" #include "util/export.h" +#include "util/syncmessenger.h" -class QThread; class SampleSink; -class SDRANGELOVE_API ThreadedSampleSink : public SampleSink { +/** + * This class is a wrapper for SampleSink that runs the SampleSink object in its own thread + */ +class SDRANGELOVE_API ThreadedSampleSink : public QThread { Q_OBJECT public: ThreadedSampleSink(SampleSink* sampleSink); - virtual ~ThreadedSampleSink(); + ~ThreadedSampleSink(); - MessageQueue* getMessageQueue() { return &m_messageQueue; } + const SampleSink *getSink() const { return m_sampleSink; } + MessageQueue* getInputMessageQueue() { return m_sampleSink->getInputMessageQueue(); } //!< Return pointer to sample sink's input message queue + MessageQueue* getOutputMessageQueue() { return m_sampleSink->getOutputMessageQueue(); } //!< Return pointer to sample sink's output message queue - void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); - void start(); - void stop(); - bool handleMessage(Message* cmd); + void start(); //!< this thread start() + void stop(); //!< this thread exit() and wait() + + bool sendWaitSink(const Message& cmd); //!< Send message to sink synchronously + void feed(SampleVector::const_iterator& begin, SampleVector::const_iterator& end, bool positiveOnly); //!< Feed sink with samples + + QString getSampleSinkObjectName() const; protected: - QMutex m_mutex; - QThread* m_thread; - MessageQueue m_messageQueue; - SampleFifo m_sampleFifo; + SyncMessenger m_syncMessenger; //!< Used to process messages synchronously with the thread SampleSink* m_sampleSink; -protected slots: - void handleData(); - void handleMessages(); - void threadStarted(); - void threadFinished(); +private: + void run(); //!< this thread run() method + void handleSynchronousMessages(const Message& message); //!< Handle synchronous messages with the thread }; #endif // INCLUDE_THREADEDSAMPLESINK_H diff --git a/include/plugin/pluginapi.h b/include/plugin/pluginapi.h index a26ba3414..739d4461c 100644 --- a/include/plugin/pluginapi.h +++ b/include/plugin/pluginapi.h @@ -37,12 +37,14 @@ public: void removeChannelMarker(ChannelMarker* channelMarker); // DSPEngine access + /* Direct access with DSP engine singleton void setSampleSource(SampleSource* sampleSource); void addSampleSink(SampleSink* sampleSink); void removeSampleSink(SampleSink* sampleSink); MessageQueue* getDSPEngineMessageQueue(); void addAudioSource(AudioFifo* audioFifo); void removeAudioSource(AudioFifo* audioFifo); + */ // Sample Source stuff void registerSampleSource(const QString& sourceName, PluginInterface* plugin); diff --git a/include/plugin/plugingui.h b/include/plugin/plugingui.h index b4ec413e5..65f8180ff 100644 --- a/include/plugin/plugingui.h +++ b/include/plugin/plugingui.h @@ -9,6 +9,8 @@ class Message; class SDRANGELOVE_API PluginGUI { public: PluginGUI() { }; + virtual ~PluginGUI() { }; + virtual void destroy() = 0; virtual void setName(const QString& name) = 0; @@ -23,7 +25,7 @@ public: virtual QByteArray serialize() const = 0; virtual bool deserialize(const QByteArray& data) = 0; - virtual bool handleMessage(Message* message) = 0; + virtual bool handleMessage(const Message& message) = 0; }; #endif // INCLUDE_PLUGINGUI_H diff --git a/include/util/message.h b/include/util/message.h index f2540c06d..4ea32b265 100644 --- a/include/util/message.h +++ b/include/util/message.h @@ -43,7 +43,7 @@ protected: public: \ const char* getIdentifier() const; \ bool matchIdentifier(const char* identifier) const; \ - static bool match(const Message* message); \ + static bool match(const Message& message); \ protected: \ static const char* m_identifier; \ private: @@ -54,6 +54,6 @@ protected: bool Name::matchIdentifier(const char* identifier) const {\ return (m_identifier == identifier) ? true : BaseClass::matchIdentifier(identifier); \ } \ - bool Name::match(const Message* message) { return message->matchIdentifier(m_identifier); } + bool Name::match(const Message& message) { return message.matchIdentifier(m_identifier); } #endif // INCLUDE_MESSAGE_H diff --git a/include/util/syncmessenger.h b/include/util/syncmessenger.h index 352998aae..b030784bf 100644 --- a/include/util/syncmessenger.h +++ b/include/util/syncmessenger.h @@ -36,11 +36,11 @@ public: SyncMessenger(); ~SyncMessenger(); - int sendWait(Message *message, unsigned long msPollTime = 100); //!< Send message and waits for its process completion + int sendWait(const Message& message, unsigned long msPollTime = 100); //!< Send message and waits for its process completion void done(int result = 0); //!< Processing of the message is complete signals: - void messageSent(Message *message); + void messageSent(const Message& message); protected: QWaitCondition m_waitCondition; diff --git a/plugins/channel/am/amdemod.cpp b/plugins/channel/am/amdemod.cpp index 2ddcf539c..072666176 100644 --- a/plugins/channel/am/amdemod.cpp +++ b/plugins/channel/am/amdemod.cpp @@ -17,6 +17,7 @@ #include "amdemod.h" #include +#include #include #include #include "audio/audiooutput.h" @@ -55,93 +56,53 @@ AMDemod::~AMDemod() void AMDemod::configure(MessageQueue* messageQueue, Real rfBandwidth, Real afBandwidth, Real volume, Real squelch) { Message* cmd = MsgConfigureAMDemod::create(rfBandwidth, afBandwidth, volume, squelch); - cmd->submit(messageQueue, this); + messageQueue->push(cmd); } -/* -float arctan2(Real y, Real x) -{ - Real coeff_1 = M_PI / 4; - Real coeff_2 = 3 * coeff_1; - Real abs_y = fabs(y) + 1e-10; // kludge to prevent 0/0 condition - Real angle; - if( x>= 0) { - Real r = (x - abs_y) / (x + abs_y); - angle = coeff_1 - coeff_1 * r; - } else { - Real r = (x + abs_y) / (abs_y - x); - angle = coeff_2 - coeff_1 * r; - } - if(y < 0) - return(-angle); - else return(angle); -} - -Real angleDist(Real a, Real b) -{ - Real dist = b - a; - - while(dist <= M_PI) - dist += 2 * M_PI; - while(dist >= M_PI) - dist -= 2 * M_PI; - - return dist; -} -*/ - void AMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool firstOfBurst) { Complex ci; - if(m_audioFifo->size() <= 0) + if (m_audioFifo->size() <= 0) + { return; + } - for(SampleVector::const_iterator it = begin; it != end; ++it) { + for (SampleVector::const_iterator it = begin; it != end; ++it) + { Complex c(it->real() / 32768.0, it->imag() / 32768.0); c *= m_nco.nextIQ(); { - if(m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci)) { + if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci)) + { m_sampleBuffer.push_back(Sample(ci.real() * 32767.0, ci.imag() * 32767.0)); Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag(); m_movingAverage.feed(magsq); - if(m_movingAverage.average() >= m_squelchLevel) + + if (m_movingAverage.average() >= m_squelchLevel) + { m_squelchState = m_running.m_audioSampleRate/ 20; + } qint16 sample; - if(m_squelchState > 0) { + + if (m_squelchState > 0) + { m_squelchState--; - /* - Real argument = arg(ci); - Real demod = argument - m_lastArgument; - m_lastArgument = argument; - */ - - /* NFM demod: - Complex d = conj(m_lastSample) * ci; - m_lastSample = ci; - Real demod = atan2(d.imag(), d.real()); - //Real demod = arctan2(d.imag(), d.real()); - */ - -/* - Real argument1 = arg(ci);//atan2(ci.imag(), ci.real()); - Real argument2 = m_lastSample.real(); - Real demod = angleDist(argument2, argument1); - m_lastSample = Complex(argument1, 0); -*/ Real demod = sqrt(magsq); - //demod /= M_PI; - demod = m_lowpass.filter(demod); - if(demod < -1) + if (demod < -1) + { demod = -1; - else if(demod > 1) + } + else if (demod > 1) + { demod = 1; + } m_volumeAGC.feed(demod); @@ -149,7 +110,9 @@ void AMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_itera demod *= m_running.m_volume; sample = demod * 32700 * 16; - } else { + } + else + { m_volumeAGC.close(); sample = 0; } @@ -157,10 +120,16 @@ void AMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_itera m_audioBuffer[m_audioBufferFill].l = sample; m_audioBuffer[m_audioBufferFill].r = sample; ++m_audioBufferFill; - if(m_audioBufferFill >= m_audioBuffer.size()) { + + if (m_audioBufferFill >= m_audioBuffer.size()) + { uint res = m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1); - if(res != m_audioBufferFill) + + if (res != m_audioBufferFill) + { qDebug("lost %u audio samples", m_audioBufferFill - res); + } + m_audioBufferFill = 0; } @@ -168,15 +137,24 @@ void AMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_itera } } } - if(m_audioBufferFill > 0) { + + if (m_audioBufferFill > 0) + { uint res = m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1); - if(res != m_audioBufferFill) + + if (res != m_audioBufferFill) + { qDebug("lost %u samples", m_audioBufferFill - res); + } + m_audioBufferFill = 0; } - if(m_sampleSink != NULL) + if(m_sampleSink != 0) + { m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), false); + } + m_sampleBuffer.clear(); } @@ -194,28 +172,54 @@ void AMDemod::stop() { } -bool AMDemod::handleMessage(Message* cmd) +bool AMDemod::handleMessage(const Message& cmd) { - if(DSPSignalNotification::match(cmd)) { - DSPSignalNotification* signal = (DSPSignalNotification*)cmd; + qDebug() << "AMDemod::handleMessage"; + + if (DSPSignalNotification::match(cmd)) + { + DSPSignalNotification& notif = (DSPSignalNotification&) cmd; + + m_config.m_inputSampleRate = notif.getSampleRate(); + m_config.m_inputFrequencyOffset = notif.getFrequencyOffset(); - m_config.m_inputSampleRate = signal->getSampleRate(); - m_config.m_inputFrequencyOffset = signal->getFrequencyOffset(); apply(); - cmd->completed(); + + qDebug() << " - DSPSignalNotification:" + << " m_inputSampleRate: " << m_config.m_inputSampleRate + << " m_inputFrequencyOffset: " << m_config.m_inputFrequencyOffset; + return true; - } else if(MsgConfigureAMDemod::match(cmd)) { - MsgConfigureAMDemod* cfg = (MsgConfigureAMDemod*)cmd; - m_config.m_rfBandwidth = cfg->getRFBandwidth(); - m_config.m_afBandwidth = cfg->getAFBandwidth(); - m_config.m_volume = cfg->getVolume(); - m_config.m_squelch = cfg->getSquelch(); + } + else if (MsgConfigureAMDemod::match(cmd)) + { + MsgConfigureAMDemod& cfg = (MsgConfigureAMDemod&) cmd; + + m_config.m_rfBandwidth = cfg.getRFBandwidth(); + m_config.m_afBandwidth = cfg.getAFBandwidth(); + m_config.m_volume = cfg.getVolume(); + m_config.m_squelch = cfg.getSquelch(); + apply(); + + qDebug() << " - MsgConfigureAMDemod:" + << " m_rfBandwidth: " << m_config.m_rfBandwidth + << " m_afBandwidth: " << m_config.m_afBandwidth + << " m_volume: " << m_config.m_volume + << " m_squelch: " << m_config.m_squelch; + return true; - } else { - if(m_sampleSink != NULL) + } + else + { + if(m_sampleSink != 0) + { return m_sampleSink->handleMessage(cmd); - else return false; + } + else + { + return false; + } } } @@ -223,23 +227,27 @@ void AMDemod::apply() { if((m_config.m_inputFrequencyOffset != m_running.m_inputFrequencyOffset) || - (m_config.m_inputSampleRate != m_running.m_inputSampleRate)) { + (m_config.m_inputSampleRate != m_running.m_inputSampleRate)) + { m_nco.setFreq(-m_config.m_inputFrequencyOffset, m_config.m_inputSampleRate); } if((m_config.m_inputSampleRate != m_running.m_inputSampleRate) || - (m_config.m_rfBandwidth != m_running.m_rfBandwidth)) { + (m_config.m_rfBandwidth != m_running.m_rfBandwidth)) + { m_interpolator.create(16, m_config.m_inputSampleRate, m_config.m_rfBandwidth / 2.2); m_interpolatorDistanceRemain = 0; m_interpolatorDistance = (Real) m_config.m_inputSampleRate / (Real) m_config.m_audioSampleRate; } if((m_config.m_afBandwidth != m_running.m_afBandwidth) || - (m_config.m_audioSampleRate != m_running.m_audioSampleRate)) { + (m_config.m_audioSampleRate != m_running.m_audioSampleRate)) + { m_lowpass.create(21, m_config.m_audioSampleRate, m_config.m_afBandwidth); } - if(m_config.m_squelch != m_running.m_squelch) { + if(m_config.m_squelch != m_running.m_squelch) + { m_squelchLevel = pow(10.0, m_config.m_squelch / 20.0); m_squelchLevel *= m_squelchLevel; } diff --git a/plugins/channel/am/amdemod.h b/plugins/channel/am/amdemod.h index 7c068b5a6..5279036e1 100644 --- a/plugins/channel/am/amdemod.h +++ b/plugins/channel/am/amdemod.h @@ -36,10 +36,10 @@ public: void configure(MessageQueue* messageQueue, Real rfBandwidth, Real afBandwidth, Real volume, Real squelch); - void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool po); - void start(); - void stop(); - bool handleMessage(Message* cmd); + virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool po); + virtual void start(); + virtual void stop(); + virtual bool handleMessage(const Message& cmd); private: class MsgConfigureAMDemod : public Message { diff --git a/plugins/channel/am/amdemodgui.cpp b/plugins/channel/am/amdemodgui.cpp index f320418e7..f40b191e7 100644 --- a/plugins/channel/am/amdemodgui.cpp +++ b/plugins/channel/am/amdemodgui.cpp @@ -5,11 +5,11 @@ #include "ui_amdemodgui.h" #include "dsp/threadedsamplesink.h" #include "dsp/channelizer.h" -#include "dsp/nullsink.h" #include "gui/glspectrum.h" #include "plugin/pluginapi.h" #include "util/simpleserializer.h" #include "gui/basicchannelsettingswidget.h" +#include "dsp/dspengine.h" #include "amdemod.h" @@ -100,7 +100,7 @@ bool AMDemodGUI::deserialize(const QByteArray& data) } } -bool AMDemodGUI::handleMessage(Message* message) +bool AMDemodGUI::handleMessage(const Message& message) { return false; } @@ -185,12 +185,10 @@ AMDemodGUI::AMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : connect(this, SIGNAL(menuDoubleClickEvent()), this, SLOT(onMenuDoubleClicked())); m_audioFifo = new AudioFifo(4, 48000); - m_nullSink = new NullSink(); - m_amDemod = new AMDemod(m_audioFifo, m_nullSink); + m_amDemod = new AMDemod(m_audioFifo, 0); m_channelizer = new Channelizer(m_amDemod); - m_threadedSampleSink = new ThreadedSampleSink(m_channelizer); - m_pluginAPI->addAudioSource(m_audioFifo); - m_pluginAPI->addSampleSink(m_threadedSampleSink); + DSPEngine::instance()->addAudioSink(m_audioFifo); + DSPEngine::instance()->addThreadedSink(m_channelizer); m_channelMarker = new ChannelMarker(this); m_channelMarker->setColor(Qt::yellow); @@ -206,12 +204,10 @@ AMDemodGUI::AMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : AMDemodGUI::~AMDemodGUI() { m_pluginAPI->removeChannelInstance(this); - m_pluginAPI->removeAudioSource(m_audioFifo); - m_pluginAPI->removeSampleSink(m_threadedSampleSink); - delete m_threadedSampleSink; + DSPEngine::instance()->removeAudioSink(m_audioFifo); + DSPEngine::instance()->removeThreadedSink(m_channelizer); delete m_channelizer; delete m_amDemod; - delete m_nullSink; delete m_audioFifo; delete m_channelMarker; delete ui; @@ -220,12 +216,15 @@ AMDemodGUI::~AMDemodGUI() void AMDemodGUI::applySettings() { setTitleColor(m_channelMarker->getColor()); - m_channelizer->configure(m_threadedSampleSink->getMessageQueue(), + + m_channelizer->configure(m_channelizer->getInputMessageQueue(), 48000, m_channelMarker->getCenterFrequency()); + ui->deltaFrequency->setValue(abs(m_channelMarker->getCenterFrequency())); ui->deltaMinus->setChecked(m_channelMarker->getCenterFrequency() < 0); - m_amDemod->configure(m_threadedSampleSink->getMessageQueue(), + + m_amDemod->configure(m_amDemod->getInputMessageQueue(), m_rfBW[ui->rfBW->value()], ui->afBW->value() * 1000.0, ui->volume->value() / 10.0, diff --git a/plugins/channel/am/amdemodgui.h b/plugins/channel/am/amdemodgui.h index f60f628c2..ca7566afa 100644 --- a/plugins/channel/am/amdemodgui.h +++ b/plugins/channel/am/amdemodgui.h @@ -8,10 +8,8 @@ class PluginAPI; class ChannelMarker; class AudioFifo; -class ThreadedSampleSink; class Channelizer; class AMDemod; -class NullSink; namespace Ui { class AMDemodGUI; @@ -32,7 +30,7 @@ public: QByteArray serialize() const; bool deserialize(const QByteArray& data); - bool handleMessage(Message* message); + virtual bool handleMessage(const Message& message); private slots: void viewChanged(); @@ -52,10 +50,8 @@ private: bool m_basicSettingsShown; AudioFifo* m_audioFifo; - ThreadedSampleSink* m_threadedSampleSink; Channelizer* m_channelizer; AMDemod* m_amDemod; - NullSink *m_nullSink; static const int m_rfBW[]; diff --git a/plugins/channel/chanalyzer/chanalyzer.cpp b/plugins/channel/chanalyzer/chanalyzer.cpp index db278f954..f6011b619 100644 --- a/plugins/channel/chanalyzer/chanalyzer.cpp +++ b/plugins/channel/chanalyzer/chanalyzer.cpp @@ -17,6 +17,7 @@ /////////////////////////////////////////////////////////////////////////////////// #include +#include #include #include "audio/audiooutput.h" #include "dsp/dspcommands.h" @@ -55,7 +56,7 @@ void ChannelAnalyzer::configure(MessageQueue* messageQueue, bool ssb) { Message* cmd = MsgConfigureChannelAnalyzer::create(Bandwidth, LowCutoff, spanLog2, ssb); - cmd->submit(messageQueue, this); + messageQueue->push(cmd); } void ChannelAnalyzer::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly) @@ -65,13 +66,17 @@ void ChannelAnalyzer::feed(SampleVector::const_iterator begin, SampleVector::con int decim = 1<real() / 32768.0, it->imag() / 32768.0); c *= m_nco.nextIQ(); - if (m_ssb) { + if (m_ssb) + { n_out = SSBFilter->runSSB(c, &sideband, m_usb); - } else { + } + else + { n_out = DSBFilter->runDSB(c, &sideband); } @@ -116,29 +121,41 @@ void ChannelAnalyzer::stop() { } -bool ChannelAnalyzer::handleMessage(Message* cmd) +bool ChannelAnalyzer::handleMessage(const Message& cmd) { float band, lowCutoff; - if(DSPSignalNotification::match(cmd)) { - DSPSignalNotification* signal = (DSPSignalNotification*)cmd; - fprintf(stderr, "ChannelAnalyzer::handleMessage: %d samples/sec, %lld Hz offset\n", signal->getSampleRate(), signal->getFrequencyOffset()); - m_sampleRate = signal->getSampleRate(); - m_nco.setFreq(-signal->getFrequencyOffset(), m_sampleRate); - cmd->completed(); + qDebug() << "ChannelAnalyzer::handleMessage"; + + if (DSPSignalNotification::match(cmd)) + { + DSPSignalNotification& notif = (DSPSignalNotification&) cmd; + + m_sampleRate = notif.getSampleRate(); + m_nco.setFreq(-notif.getFrequencyOffset(), m_sampleRate); + + qDebug() << " - DSPSignalNotification: m_sampleRate: " << m_sampleRate + << " frequencyOffset: " << notif.getFrequencyOffset(); + return true; - } else if(MsgConfigureChannelAnalyzer::match(cmd)) { - MsgConfigureChannelAnalyzer* cfg = (MsgConfigureChannelAnalyzer*)cmd; + } + else if (MsgConfigureChannelAnalyzer::match(cmd)) + { + MsgConfigureChannelAnalyzer& cfg = (MsgConfigureChannelAnalyzer&) cmd; - band = cfg->getBandwidth(); - lowCutoff = cfg->getLoCutoff(); + band = cfg.getBandwidth(); + lowCutoff = cfg.getLoCutoff(); - if (band < 0) { + if (band < 0) + { band = -band; lowCutoff = -lowCutoff; m_usb = false; - } else + } + else + { m_usb = true; + } if (band < 100.0f) { @@ -153,14 +170,25 @@ bool ChannelAnalyzer::handleMessage(Message* cmd) SSBFilter->create_filter(m_LowCutoff / m_sampleRate, m_Bandwidth / m_sampleRate); DSBFilter->create_dsb_filter(m_Bandwidth / m_sampleRate); - m_spanLog2 = cfg->getSpanLog2(); - m_ssb = cfg->getSSB(); + m_spanLog2 = cfg.getSpanLog2(); + m_ssb = cfg.getSSB(); + + qDebug() << " - MsgConfigureChannelAnalyzer: m_Bandwidth: " << m_Bandwidth + << " m_LowCutoff: " << m_LowCutoff + << " m_spanLog2: " << m_spanLog2 + << " m_ssb: " << m_ssb; - cmd->completed(); return true; - } else { - if(m_sampleSink != NULL) + } + else + { + if (m_sampleSink != 0) + { return m_sampleSink->handleMessage(cmd); - else return false; + } + else + { + return false; + } } } diff --git a/plugins/channel/chanalyzer/chanalyzer.h b/plugins/channel/chanalyzer/chanalyzer.h index ccacf012a..f10496ce2 100644 --- a/plugins/channel/chanalyzer/chanalyzer.h +++ b/plugins/channel/chanalyzer/chanalyzer.h @@ -33,7 +33,7 @@ class ChannelAnalyzer : public SampleSink { public: ChannelAnalyzer(SampleSink* m_sampleSink); - ~ChannelAnalyzer(); + virtual ~ChannelAnalyzer(); void configure(MessageQueue* messageQueue, Real Bandwidth, @@ -45,10 +45,10 @@ public: return m_sampleRate; } - void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); - void start(); - void stop(); - bool handleMessage(Message* cmd); + virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); + virtual void start(); + virtual void stop(); + virtual bool handleMessage(const Message& cmd); private: class MsgConfigureChannelAnalyzer : public Message { diff --git a/plugins/channel/chanalyzer/chanalyzergui.cpp b/plugins/channel/chanalyzer/chanalyzergui.cpp index b5cc10ea0..168829124 100644 --- a/plugins/channel/chanalyzer/chanalyzergui.cpp +++ b/plugins/channel/chanalyzer/chanalyzergui.cpp @@ -1,7 +1,6 @@ #include #include #include "ui_chanalyzergui.h" -#include "dsp/threadedsamplesink.h" #include "dsp/channelizer.h" #include "dsp/spectrumscopecombovis.h" #include "dsp/spectrumvis.h" @@ -11,6 +10,7 @@ #include "plugin/pluginapi.h" #include "util/simpleserializer.h" #include "gui/basicchannelsettingswidget.h" +#include "dsp/dspengine.h" #include "mainwindow.h" #include "chanalyzer.h" @@ -103,7 +103,7 @@ bool ChannelAnalyzerGUI::deserialize(const QByteArray& data) } } -bool ChannelAnalyzerGUI::handleMessage(Message* message) +bool ChannelAnalyzerGUI::handleMessage(const Message& message) { return false; } @@ -267,8 +267,7 @@ ChannelAnalyzerGUI::ChannelAnalyzerGUI(PluginAPI* pluginAPI, QWidget* parent) : m_channelAnalyzer = new ChannelAnalyzer(m_spectrumScopeComboVis); m_channelizer = new Channelizer(m_channelAnalyzer); connect(m_channelizer, SIGNAL(inputSampleRateChanged()), this, SLOT(channelSampleRateChanged())); - m_threadedSampleSink = new ThreadedSampleSink(m_channelizer); - m_pluginAPI->addSampleSink(m_threadedSampleSink); + DSPEngine::instance()->addThreadedSink(m_channelizer); ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::ReverseGold)); @@ -290,8 +289,8 @@ ChannelAnalyzerGUI::ChannelAnalyzerGUI(PluginAPI* pluginAPI, QWidget* parent) : connect(m_channelMarker, SIGNAL(changed()), this, SLOT(viewChanged())); m_pluginAPI->addChannelMarker(m_channelMarker); - ui->spectrumGUI->setBuddies(m_threadedSampleSink->getMessageQueue(), m_spectrumVis, ui->glSpectrum); - ui->scopeGUI->setBuddies(m_threadedSampleSink->getMessageQueue(), m_scopeVis, ui->glScope); + ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum); + ui->scopeGUI->setBuddies(m_scopeVis->getInputMessageQueue(), m_scopeVis, ui->glScope); applySettings(); } @@ -299,8 +298,7 @@ ChannelAnalyzerGUI::ChannelAnalyzerGUI(PluginAPI* pluginAPI, QWidget* parent) : ChannelAnalyzerGUI::~ChannelAnalyzerGUI() { m_pluginAPI->removeChannelInstance(this); - m_pluginAPI->removeSampleSink(m_threadedSampleSink); - delete m_threadedSampleSink; + DSPEngine::instance()->removeThreadedSink(m_channelizer); delete m_channelizer; delete m_channelAnalyzer; delete m_spectrumVis; @@ -376,10 +374,12 @@ void ChannelAnalyzerGUI::applySettings() setTitleColor(m_channelMarker->getColor()); ui->deltaFrequency->setValue(abs(m_channelMarker->getCenterFrequency())); ui->deltaMinus->setChecked(m_channelMarker->getCenterFrequency() < 0); - m_channelizer->configure(m_threadedSampleSink->getMessageQueue(), + + m_channelizer->configure(m_channelizer->getInputMessageQueue(), m_channelizer->getInputSampleRate(), m_channelMarker->getCenterFrequency()); - m_channelAnalyzer->configure(m_threadedSampleSink->getMessageQueue(), + + m_channelAnalyzer->configure(m_channelAnalyzer->getInputMessageQueue(), ui->BW->value() * 100.0, ui->lowCut->value() * 100.0, m_spanLog2, diff --git a/plugins/channel/chanalyzer/chanalyzergui.h b/plugins/channel/chanalyzer/chanalyzergui.h index 2b31bb000..b0555857b 100644 --- a/plugins/channel/chanalyzer/chanalyzergui.h +++ b/plugins/channel/chanalyzer/chanalyzergui.h @@ -8,7 +8,6 @@ class PluginAPI; class ChannelMarker; //class AudioFifo; -class ThreadedSampleSink; class Channelizer; class ChannelAnalyzer; class SpectrumScopeComboVis; @@ -34,7 +33,7 @@ public: QByteArray serialize() const; bool deserialize(const QByteArray& data); - bool handleMessage(Message* message); + virtual bool handleMessage(const Message& message); private slots: void viewChanged(); @@ -56,7 +55,6 @@ private: int m_rate; int m_spanLog2; - ThreadedSampleSink* m_threadedSampleSink; Channelizer* m_channelizer; ChannelAnalyzer* m_channelAnalyzer; SpectrumScopeComboVis* m_spectrumScopeComboVis; diff --git a/plugins/channel/lora/lorademod.cpp b/plugins/channel/lora/lorademod.cpp index 558d8ea2f..299899265 100644 --- a/plugins/channel/lora/lorademod.cpp +++ b/plugins/channel/lora/lorademod.cpp @@ -17,6 +17,7 @@ /////////////////////////////////////////////////////////////////////////////////// #include +#include #include #include "lorademod.h" #include "dsp/dspcommands.h" @@ -44,6 +45,7 @@ LoRaDemod::LoRaDemod(SampleSink* sampleSink) : m_count = 0; m_header = 0; m_time = 0; + m_tune = 0; loraFilter = new sfft(LORA_SFFT_LEN); negaFilter = new sfft(LORA_SFFT_LEN); @@ -70,7 +72,7 @@ LoRaDemod::~LoRaDemod() void LoRaDemod::configure(MessageQueue* messageQueue, Real Bandwidth) { Message* cmd = MsgConfigureLoRaDemod::create(Bandwidth); - cmd->submit(messageQueue, this); + messageQueue->push(cmd); } void LoRaDemod::dumpRaw() @@ -79,13 +81,18 @@ void LoRaDemod::dumpRaw() char text[256]; max = m_time / 4 - 3; - if (max > 140) - max = 140; // about 2 symbols to each char - for ( j=0; j < max; j++) { + if (max > 140) + { + max = 140; // about 2 symbols to each char + } + + for ( j=0; j < max; j++) + { bin = (history[(j + 1) * 4] + m_tune ) & (LORA_SFFT_LEN - 1); text[j] = toGray(bin >> 1); } + prng6(text, max); // First block is always 8 symbols interleave6(text, 6); @@ -93,46 +100,75 @@ void LoRaDemod::dumpRaw() hamming6(text, 6); hamming6(&text[8], max); - for ( j=0; j < max / 2; j++) { + for ( j=0; j < max / 2; j++) + { text[j] = (text[j * 2 + 1] << 4) | (0xf & text[j * 2 + 0]); + if ((text[j] < 32 )||( text[j] > 126)) + { text[j] = 0x5f; + } } + text[3] = text[2]; text[2] = text[1]; text[1] = text[0]; text[j] = 0; + printf("%s\n", &text[1]); } short LoRaDemod::synch(short bin) { short i, j; - if (bin < 0) { + + if (bin < 0) + { if (m_time > 70) + { dumpRaw(); + } + m_time = 0; return -1; } + history[m_time] = bin; + if (m_time > 12) + { if (bin == history[m_time - 6]) - if (bin == history[m_time - 12]) { + { + if (bin == history[m_time - 12]) + { m_tune = LORA_SFFT_LEN - bin; j = 0; + for (i=0; i<12; i++) + { j += finetune[15 & (m_time - i)]; + } + if (j < 0) + { m_tune += 1; + } + m_tune &= (LORA_SFFT_LEN - 1); m_time = 0; return -1; } + } + } m_time++; m_time &= 1023; + if (m_time & 3) + { return -1; + } + return (bin + m_tune) & (LORA_SFFT_LEN - 1); } @@ -149,24 +185,34 @@ int LoRaDemod::detect(Complex c, Complex a) // process spectrum twice in FFTLEN if (++m_count & ((1 << DATA_BITS) - 1)) + { return m_result; + } + movpoint = 3 & (m_count >> DATA_BITS); loraFilter->fetch(mag); negaFilter->fetch(rev); peak = negpeak = 0.0f; result = negresult = 0; - for (i = 0; i < LORA_SFFT_LEN; i++) { - if (rev[i] > negpeak) { + + for (i = 0; i < LORA_SFFT_LEN; i++) + { + if (rev[i] > negpeak) + { negpeak = rev[i]; negresult = i; } + tfloat = mov[i] + mov[LORA_SFFT_LEN + i] +mov[2 * LORA_SFFT_LEN + i] + mov[3 * LORA_SFFT_LEN + i] + mag[i]; - if (tfloat > peak) { + + if (tfloat > peak) + { peak = tfloat; result = i; } + mov[movpoint * LORA_SFFT_LEN + i] = mag[i]; } @@ -175,10 +221,17 @@ int LoRaDemod::detect(Complex c, Complex a) finetune[15 & m_time] = (mag[p] > mag[q]) ? -1 : 1; if (peak < negpeak * LORA_SQUELCH) + { result = -1; + } + result = synch(result); + if (result >= 0) + { m_result = result; + } + return m_result; } @@ -188,11 +241,14 @@ void LoRaDemod::feed(SampleVector::const_iterator begin, SampleVector::const_ite Complex ci; m_sampleBuffer.clear(); - for(SampleVector::const_iterator it = begin; it < end; ++it) { + + for(SampleVector::const_iterator it = begin; it < end; ++it) + { Complex c(it->real() / 32768.0, it->imag() / 32768.0); c *= m_nco.nextIQ(); - if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &ci)) { + if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &ci)) + { m_chirp = (m_chirp + 1) & (SPREADFACTOR - 1); m_angle = (m_angle + m_chirp) & (SPREADFACTOR - 1); Complex cangle(cos(M_PI*2*m_angle/SPREADFACTOR),-sin(M_PI*2*m_angle/SPREADFACTOR)); @@ -204,8 +260,11 @@ void LoRaDemod::feed(SampleVector::const_iterator begin, SampleVector::const_ite m_sampleDistanceRemain += (Real)m_sampleRate / m_Bandwidth; } } - if(m_sampleSink != NULL) + + if(m_sampleSink != 0) + { m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), false); + } } void LoRaDemod::start() @@ -216,26 +275,43 @@ void LoRaDemod::stop() { } -bool LoRaDemod::handleMessage(Message* cmd) +bool LoRaDemod::handleMessage(const Message& cmd) { - if(DSPSignalNotification::match(cmd)) { - DSPSignalNotification* signal = (DSPSignalNotification*)cmd; - m_sampleRate = signal->getSampleRate(); - m_nco.setFreq(-signal->getFrequencyOffset(), m_sampleRate); + qDebug() << "LoRaDemod::handleMessage"; + + if (DSPSignalNotification::match(cmd)) + { + DSPSignalNotification& notif = (DSPSignalNotification&) cmd; + + m_sampleRate = notif.getSampleRate(); + m_nco.setFreq(-notif.getFrequencyOffset(), m_sampleRate); m_interpolator.create(16, m_sampleRate, m_Bandwidth/1.9); m_sampleDistanceRemain = m_sampleRate / m_Bandwidth; - cmd->completed(); + + qDebug() << " DSPSignalNotification: m_sampleRate: " << m_sampleRate; + return true; - } else if(MsgConfigureLoRaDemod::match(cmd)) { - MsgConfigureLoRaDemod* cfg = (MsgConfigureLoRaDemod*)cmd; - m_Bandwidth = cfg->getBandwidth(); + } + else if (MsgConfigureLoRaDemod::match(cmd)) + { + MsgConfigureLoRaDemod& cfg = (MsgConfigureLoRaDemod&) cmd; + + m_Bandwidth = cfg.getBandwidth(); m_interpolator.create(16, m_sampleRate, m_Bandwidth/1.9); - cmd->completed(); + + qDebug() << " MsgConfigureLoRaDemod: m_Bandwidth: " << m_Bandwidth; + return true; - } else { - if(m_sampleSink != NULL) + } + else + { + if(m_sampleSink != 0) + { return m_sampleSink->handleMessage(cmd); + } else + { return false; + } } } diff --git a/plugins/channel/lora/lorademod.h b/plugins/channel/lora/lorademod.h index 092bc194f..9ba1c7507 100644 --- a/plugins/channel/lora/lorademod.h +++ b/plugins/channel/lora/lorademod.h @@ -34,14 +34,14 @@ class LoRaDemod : public SampleSink { public: LoRaDemod(SampleSink* sampleSink); - ~LoRaDemod(); + virtual ~LoRaDemod(); void configure(MessageQueue* messageQueue, Real Bandwidth); - void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool pO); - void start(); - void stop(); - bool handleMessage(Message* cmd); + virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool pO); + virtual void start(); + virtual void stop(); + virtual bool handleMessage(const Message& cmd); private: int detect(Complex sample, Complex angle); diff --git a/plugins/channel/lora/lorademodgui.cpp b/plugins/channel/lora/lorademodgui.cpp index bb29518ba..cb3308b5f 100644 --- a/plugins/channel/lora/lorademodgui.cpp +++ b/plugins/channel/lora/lorademodgui.cpp @@ -12,6 +12,7 @@ #include "plugin/pluginapi.h" #include "util/simpleserializer.h" #include "gui/basicchannelsettingswidget.h" +#include "dsp/dspengine.h" LoRaDemodGUI* LoRaDemodGUI::create(PluginAPI* pluginAPI) { @@ -83,7 +84,7 @@ bool LoRaDemodGUI::deserialize(const QByteArray& data) } } -bool LoRaDemodGUI::handleMessage(Message* message) +bool LoRaDemodGUI::handleMessage(const Message& message) { return false; } @@ -137,8 +138,7 @@ LoRaDemodGUI::LoRaDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : m_spectrumVis = new SpectrumVis(ui->glSpectrum); m_LoRaDemod = new LoRaDemod(m_spectrumVis); m_channelizer = new Channelizer(m_LoRaDemod); - m_threadedSampleSink = new ThreadedSampleSink(m_channelizer); - m_pluginAPI->addSampleSink(m_threadedSampleSink); + DSPEngine::instance()->addThreadedSink(m_channelizer); ui->glSpectrum->setCenterFrequency(16000); ui->glSpectrum->setSampleRate(32000); @@ -155,7 +155,7 @@ LoRaDemodGUI::LoRaDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : connect(m_channelMarker, SIGNAL(changed()), this, SLOT(viewChanged())); m_pluginAPI->addChannelMarker(m_channelMarker); - ui->spectrumGUI->setBuddies(m_threadedSampleSink->getMessageQueue(), m_spectrumVis, ui->glSpectrum); + ui->spectrumGUI->setBuddies(m_channelizer->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum); applySettings(); } @@ -163,8 +163,7 @@ LoRaDemodGUI::LoRaDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : LoRaDemodGUI::~LoRaDemodGUI() { m_pluginAPI->removeChannelInstance(this); - m_pluginAPI->removeSampleSink(m_threadedSampleSink); - delete m_threadedSampleSink; + DSPEngine::instance()->removeThreadedSink(m_channelizer); delete m_channelizer; delete m_LoRaDemod; delete m_spectrumVis; @@ -176,8 +175,10 @@ void LoRaDemodGUI::applySettings() { const int loraBW[] = BANDWIDTHSTRING; int thisBW = loraBW[ui->BW->value()]; - m_channelizer->configure(m_threadedSampleSink->getMessageQueue(), + + m_channelizer->configure(m_channelizer->getInputMessageQueue(), thisBW, m_channelMarker->getCenterFrequency()); - m_LoRaDemod->configure(m_threadedSampleSink->getMessageQueue(), thisBW); + + m_LoRaDemod->configure(m_LoRaDemod->getInputMessageQueue(), thisBW); } diff --git a/plugins/channel/lora/lorademodgui.h b/plugins/channel/lora/lorademodgui.h index e9e016162..9f3daadf2 100644 --- a/plugins/channel/lora/lorademodgui.h +++ b/plugins/channel/lora/lorademodgui.h @@ -8,7 +8,6 @@ class PluginAPI; class ChannelMarker; -class ThreadedSampleSink; class Channelizer; class LoRaDemod; class SpectrumVis; @@ -32,7 +31,7 @@ public: QByteArray serialize() const; bool deserialize(const QByteArray& data); - bool handleMessage(Message* message); + virtual bool handleMessage(const Message& message); private slots: void viewChanged(); @@ -47,7 +46,6 @@ private: ChannelMarker* m_channelMarker; bool m_basicSettingsShown; - ThreadedSampleSink* m_threadedSampleSink; Channelizer* m_channelizer; LoRaDemod* m_LoRaDemod; SpectrumVis* m_spectrumVis; diff --git a/plugins/channel/nfm/nfmdemod.cpp b/plugins/channel/nfm/nfmdemod.cpp index df3568291..6bd86f952 100644 --- a/plugins/channel/nfm/nfmdemod.cpp +++ b/plugins/channel/nfm/nfmdemod.cpp @@ -16,6 +16,7 @@ /////////////////////////////////////////////////////////////////////////////////// #include +#include #include #include #include "nfmdemod.h" @@ -23,6 +24,7 @@ #include "audio/audiooutput.h" #include "dsp/dspcommands.h" #include "dsp/pidcontroller.h" +#include "dsp/dspengine.h" static const Real afSqTones[2] = {1200.0, 8000.0}; @@ -68,7 +70,7 @@ NFMDemod::~NFMDemod() void NFMDemod::configure(MessageQueue* messageQueue, Real rfBandwidth, Real afBandwidth, Real volume, Real squelch) { Message* cmd = MsgConfigureNFMDemod::create(rfBandwidth, afBandwidth, volume, squelch); - cmd->submit(messageQueue, this); + messageQueue->push(cmd); } float arctan2(Real y, Real x) @@ -250,52 +252,80 @@ void NFMDemod::stop() { } -bool NFMDemod::handleMessage(Message* cmd) +bool NFMDemod::handleMessage(const Message& cmd) { - if(DSPSignalNotification::match(cmd)) { - DSPSignalNotification* signal = (DSPSignalNotification*)cmd; + qDebug() << "NFMDemod::handleMessage"; + + if (DSPSignalNotification::match(cmd)) + { + DSPSignalNotification& notif = (DSPSignalNotification&) cmd; + + m_config.m_inputSampleRate = notif.getSampleRate(); + m_config.m_inputFrequencyOffset = notif.getFrequencyOffset(); - m_config.m_inputSampleRate = signal->getSampleRate(); - m_config.m_inputFrequencyOffset = signal->getFrequencyOffset(); apply(); - cmd->completed(); + + qDebug() << " - DSPSignalNotification: m_inputSampleRate: " << m_config.m_inputSampleRate + << " m_inputFrequencyOffset: " << m_config.m_inputFrequencyOffset; + return true; - } else if(MsgConfigureNFMDemod::match(cmd)) { - MsgConfigureNFMDemod* cfg = (MsgConfigureNFMDemod*)cmd; - m_config.m_rfBandwidth = cfg->getRFBandwidth(); - m_config.m_afBandwidth = cfg->getAFBandwidth(); - m_config.m_volume = cfg->getVolume(); - m_config.m_squelch = cfg->getSquelch(); + } + else if (MsgConfigureNFMDemod::match(cmd)) + { + MsgConfigureNFMDemod& cfg = (MsgConfigureNFMDemod&) cmd; + + m_config.m_rfBandwidth = cfg.getRFBandwidth(); + m_config.m_afBandwidth = cfg.getAFBandwidth(); + m_config.m_volume = cfg.getVolume(); + m_config.m_squelch = cfg.getSquelch(); + apply(); + + qDebug() << " - MsgConfigureNFMDemod: m_rfBandwidth: " << m_config.m_rfBandwidth + << " m_afBandwidth: " << m_config.m_afBandwidth + << " m_volume: " << m_config.m_volume + << " m_squelch: " << m_config.m_squelch; + return true; - } else { - if(m_sampleSink != NULL) + } + else + { + if (m_sampleSink != 0) + { return m_sampleSink->handleMessage(cmd); - else return false; + } + else + { + return false; + } } } void NFMDemod::apply() { if((m_config.m_inputFrequencyOffset != m_running.m_inputFrequencyOffset) || - (m_config.m_inputSampleRate != m_running.m_inputSampleRate)) { + (m_config.m_inputSampleRate != m_running.m_inputSampleRate)) + { m_nco.setFreq(-m_config.m_inputFrequencyOffset, m_config.m_inputSampleRate); } if((m_config.m_inputSampleRate != m_running.m_inputSampleRate) || - (m_config.m_rfBandwidth != m_running.m_rfBandwidth)) { + (m_config.m_rfBandwidth != m_running.m_rfBandwidth)) + { m_interpolator.create(16, m_config.m_inputSampleRate, m_config.m_rfBandwidth / 2.2); m_interpolatorDistanceRemain = 0; m_interpolatorDistance = (Real) m_config.m_inputSampleRate / (Real) m_config.m_audioSampleRate; } if((m_config.m_afBandwidth != m_running.m_afBandwidth) || - (m_config.m_audioSampleRate != m_running.m_audioSampleRate)) { + (m_config.m_audioSampleRate != m_running.m_audioSampleRate)) + { m_lowpass.create(301, m_config.m_audioSampleRate, 250.0); m_bandpass.create(301, m_config.m_audioSampleRate, 300.0, m_config.m_afBandwidth); } - if(m_config.m_squelch != m_running.m_squelch) { + if(m_config.m_squelch != m_running.m_squelch) + { m_squelchLevel = pow(10.0, m_config.m_squelch / 10.0); m_squelchLevel *= m_squelchLevel; m_afSquelch.setThreshold(m_squelchLevel); diff --git a/plugins/channel/nfm/nfmdemod.h b/plugins/channel/nfm/nfmdemod.h index 305f60ab5..5cf94f283 100644 --- a/plugins/channel/nfm/nfmdemod.h +++ b/plugins/channel/nfm/nfmdemod.h @@ -41,10 +41,10 @@ public: void configure(MessageQueue* messageQueue, Real rfBandwidth, Real afBandwidth, Real volume, Real squelch); - void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool po); - void start(); - void stop(); - bool handleMessage(Message* cmd); + virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool po); + virtual void start(); + virtual void stop(); + virtual bool handleMessage(const Message& cmd); void registerGUI(NFMDemodGUI *nfmDemodGUI) { m_nfmDemodGUI = nfmDemodGUI; diff --git a/plugins/channel/nfm/nfmdemodgui.cpp b/plugins/channel/nfm/nfmdemodgui.cpp index 2e6de59cb..fef4f525c 100644 --- a/plugins/channel/nfm/nfmdemodgui.cpp +++ b/plugins/channel/nfm/nfmdemodgui.cpp @@ -10,6 +10,7 @@ #include "plugin/pluginapi.h" #include "util/simpleserializer.h" #include "gui/basicchannelsettingswidget.h" +#include "dsp/dspengine.h" const int NFMDemodGUI::m_rfBW[] = { 5000, 6250, 8330, 10000, 12500, 15000, 20000, 25000, 40000 @@ -69,12 +70,14 @@ bool NFMDemodGUI::deserialize(const QByteArray& data) { SimpleDeserializer d(data); - if(!d.isValid()) { + if (!d.isValid()) + { resetToDefaults(); return false; } - if(d.getVersion() == 1) { + if (d.getVersion() == 1) + { QByteArray bytetmp; quint32 u32tmp; qint32 tmp; @@ -96,13 +99,15 @@ bool NFMDemodGUI::deserialize(const QByteArray& data) ui->ctcss->setCurrentIndex(tmp); applySettings(); return true; - } else { + } + else + { resetToDefaults(); return false; } } -bool NFMDemodGUI::handleMessage(Message* message) +bool NFMDemodGUI::handleMessage(const Message& message) { return false; } @@ -125,9 +130,12 @@ void NFMDemodGUI::on_deltaMinus_clicked(bool minus) void NFMDemodGUI::on_deltaFrequency_changed(quint64 value) { - if (ui->deltaMinus->isChecked()) { + if (ui->deltaMinus->isChecked()) + { m_channelMarker->setCenterFrequency(-value); - } else { + } + else + { m_channelMarker->setCenterFrequency(value); } } @@ -159,7 +167,8 @@ void NFMDemodGUI::on_squelch_valueChanged(int value) void NFMDemodGUI::on_ctcss_currentIndexChanged(int index) { - if (m_nfmDemod != NULL) { + if (m_nfmDemod != 0) + { m_nfmDemod->setSelectedCtcssIndex(index); } } @@ -174,7 +183,8 @@ void NFMDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown) void NFMDemodGUI::onMenuDoubleClicked() { - if(!m_basicSettingsShown) { + if (!m_basicSettingsShown) + { m_basicSettingsShown = true; BasicChannelSettingsWidget* bcsw = new BasicChannelSettingsWidget(m_channelMarker, this); bcsw->show(); @@ -193,9 +203,8 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : connect(this, SIGNAL(menuDoubleClickEvent()), this, SLOT(onMenuDoubleClicked())); m_audioFifo = new AudioFifo(4, 48000); - m_nullSink = new NullSink(); - m_nfmDemod = new NFMDemod(m_audioFifo, m_nullSink); + m_nfmDemod = new NFMDemod(m_audioFifo, 0); m_nfmDemod->registerGUI(this); int ctcss_nbTones; @@ -203,7 +212,8 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : ui->ctcss->addItem("--"); - for (int i=0; ictcss->addItem(QString("%1").arg(ctcss_tones[i])); } @@ -211,9 +221,8 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : //ui->deltaFrequency->setBold(true); m_channelizer = new Channelizer(m_nfmDemod); - m_threadedSampleSink = new ThreadedSampleSink(m_channelizer); - m_pluginAPI->addAudioSource(m_audioFifo); - m_pluginAPI->addSampleSink(m_threadedSampleSink); + DSPEngine::instance()->addAudioSink(m_audioFifo); + DSPEngine::instance()->addThreadedSink(m_channelizer); m_channelMarker = new ChannelMarker(this); m_channelMarker->setColor(Qt::red); @@ -229,12 +238,10 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : NFMDemodGUI::~NFMDemodGUI() { m_pluginAPI->removeChannelInstance(this); - m_pluginAPI->removeAudioSource(m_audioFifo); - m_pluginAPI->removeSampleSink(m_threadedSampleSink); - delete m_threadedSampleSink; + DSPEngine::instance()->removeAudioSink(m_audioFifo); + DSPEngine::instance()->removeThreadedSink(m_channelizer); delete m_channelizer; delete m_nfmDemod; - delete m_nullSink; delete m_audioFifo; delete m_channelMarker; delete ui; @@ -243,12 +250,15 @@ NFMDemodGUI::~NFMDemodGUI() void NFMDemodGUI::applySettings() { setTitleColor(m_channelMarker->getColor()); - m_channelizer->configure(m_threadedSampleSink->getMessageQueue(), + + m_channelizer->configure(m_channelizer->getInputMessageQueue(), 48000, m_channelMarker->getCenterFrequency()); + ui->deltaFrequency->setValue(abs(m_channelMarker->getCenterFrequency())); ui->deltaMinus->setChecked(m_channelMarker->getCenterFrequency() < 0); - m_nfmDemod->configure(m_threadedSampleSink->getMessageQueue(), + + m_nfmDemod->configure(m_nfmDemod->getInputMessageQueue(), m_rfBW[ui->rfBW->value()], ui->afBW->value() * 1000.0, ui->volume->value() / 10.0, diff --git a/plugins/channel/nfm/nfmdemodgui.h b/plugins/channel/nfm/nfmdemodgui.h index 19d7639ec..44170fd76 100644 --- a/plugins/channel/nfm/nfmdemodgui.h +++ b/plugins/channel/nfm/nfmdemodgui.h @@ -9,10 +9,8 @@ class PluginAPI; class ChannelMarker; class AudioFifo; -class ThreadedSampleSink; class Channelizer; class NFMDemod; -class NullSink; namespace Ui { class NFMDemodGUI; @@ -33,7 +31,7 @@ public: QByteArray serialize() const; bool deserialize(const QByteArray& data); - bool handleMessage(Message* message); + virtual bool handleMessage(const Message& message); void setCtcssFreq(Real ctcssFreq); private slots: @@ -55,10 +53,8 @@ private: bool m_basicSettingsShown; AudioFifo* m_audioFifo; - ThreadedSampleSink* m_threadedSampleSink; Channelizer* m_channelizer; NFMDemod* m_nfmDemod; - NullSink *m_nullSink; static const int m_rfBW[]; diff --git a/plugins/channel/ssb/ssbdemod.cpp b/plugins/channel/ssb/ssbdemod.cpp index 30775baf0..fb2281968 100644 --- a/plugins/channel/ssb/ssbdemod.cpp +++ b/plugins/channel/ssb/ssbdemod.cpp @@ -17,6 +17,7 @@ /////////////////////////////////////////////////////////////////////////////////// #include +#include #include #include "ssbdemod.h" #include "audio/audiooutput.h" @@ -57,7 +58,7 @@ SSBDemod::~SSBDemod() void SSBDemod::configure(MessageQueue* messageQueue, Real Bandwidth, Real LowCutoff, Real volume, int spanLog2) { Message* cmd = MsgConfigureSSBDemod::create(Bandwidth, LowCutoff, volume, spanLog2); - cmd->submit(messageQueue, this); + messageQueue->push(cmd); } void SSBDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly) @@ -69,17 +70,23 @@ void SSBDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iter int decim = 1<<(m_spanLog2 - 1); unsigned char decim_mask = decim - 1; // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1) - for(SampleVector::const_iterator it = begin; it < end; ++it) { + for(SampleVector::const_iterator it = begin; it < end; ++it) + { Complex c(it->real() / 32768.0, it->imag() / 32768.0); c *= m_nco.nextIQ(); - if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &ci)) { + if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &ci)) + { n_out = SSBFilter->runSSB(ci, &sideband, m_usb); m_sampleDistanceRemain += (Real)m_sampleRate / 48000.0; - } else + } + else + { n_out = 0; + } - for (int i = 0; i < n_out; i++) { + for (int i = 0; i < n_out; i++) + { Real demod = (sideband[i].real() + sideband[i].imag()) * 0.7 * 32768.0; // Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display @@ -87,7 +94,8 @@ void SSBDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iter sum += sideband[i]; - if (!(m_undersampleCount++ & decim_mask)) { + if (!(m_undersampleCount++ & decim_mask)) + { avg = (sum.real() + sum.imag()) * 0.7 * 32768.0 / decim; m_sampleBuffer.push_back(Sample(avg, 0.0)); sum.real() = 0.0; @@ -98,20 +106,32 @@ void SSBDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iter m_audioBuffer[m_audioBufferFill].l = sample; m_audioBuffer[m_audioBufferFill].r = sample; ++m_audioBufferFill; - if(m_audioBufferFill >= m_audioBuffer.size()) { + + if (m_audioBufferFill >= m_audioBuffer.size()) + { uint res = m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1); + if (res != m_audioBufferFill) + { qDebug("lost %u samples", m_audioBufferFill - res); + } + m_audioBufferFill = 0; } } } - if(m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 0) != m_audioBufferFill) - ;//qDebug("lost samples"); + + if (m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 0) != m_audioBufferFill) + { + qDebug("SSBDemod::feed: lost samples"); + } m_audioBufferFill = 0; - if(m_sampleSink != NULL) + if(m_sampleSink != 0) + { m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), true); + } + m_sampleBuffer.clear(); } @@ -123,24 +143,32 @@ void SSBDemod::stop() { } -bool SSBDemod::handleMessage(Message* cmd) +bool SSBDemod::handleMessage(const Message& cmd) { float band, lowCutoff; - if(DSPSignalNotification::match(cmd)) { - DSPSignalNotification* signal = (DSPSignalNotification*)cmd; - //fprintf(stderr, "%d samples/sec, %lld Hz offset", signal->getSampleRate(), signal->getFrequencyOffset()); - m_sampleRate = signal->getSampleRate(); - m_nco.setFreq(-signal->getFrequencyOffset(), m_sampleRate); + qDebug() << "SSBDemod::handleMessage"; + + if (DSPSignalNotification::match(cmd)) + { + DSPSignalNotification& notif = (DSPSignalNotification&) cmd; + + m_sampleRate = notif.getSampleRate(); + m_nco.setFreq(-notif.getFrequencyOffset(), m_sampleRate); m_interpolator.create(16, m_sampleRate, m_Bandwidth); m_sampleDistanceRemain = m_sampleRate / 48000.0; - cmd->completed(); - return true; - } else if(MsgConfigureSSBDemod::match(cmd)) { - MsgConfigureSSBDemod* cfg = (MsgConfigureSSBDemod*)cmd; - band = cfg->getBandwidth(); - lowCutoff = cfg->getLoCutoff(); + qDebug() << " - DSPSignalNotification: m_sampleRate: " << m_sampleRate + << " frequencyOffset" << notif.getFrequencyOffset(); + + return true; + } + else if (MsgConfigureSSBDemod::match(cmd)) + { + MsgConfigureSSBDemod& cfg = (MsgConfigureSSBDemod&) cmd; + + band = cfg.getBandwidth(); + lowCutoff = cfg.getLoCutoff(); if (band < 0) { band = -band; @@ -161,16 +189,27 @@ bool SSBDemod::handleMessage(Message* cmd) m_interpolator.create(16, m_sampleRate, band * 2.0f); SSBFilter->create_filter(m_LowCutoff / 48000.0f, m_Bandwidth / 48000.0f); - m_volume = cfg->getVolume(); + m_volume = cfg.getVolume(); m_volume *= m_volume * 0.1; - m_spanLog2 = cfg->getSpanLog2(); + m_spanLog2 = cfg.getSpanLog2(); + + qDebug() << " - MsgConfigureSSBDemod: m_Bandwidth: " << m_Bandwidth + << " m_LowCutoff: " << m_LowCutoff + << " m_volume: " << m_volume + << " m_spanLog2: " << m_spanLog2; - cmd->completed(); return true; - } else { - if(m_sampleSink != NULL) + } + else + { + if(m_sampleSink != 0) + { return m_sampleSink->handleMessage(cmd); - else return false; + } + else + { + return false; + } } } diff --git a/plugins/channel/ssb/ssbdemod.h b/plugins/channel/ssb/ssbdemod.h index 449a48b22..b9a54474c 100644 --- a/plugins/channel/ssb/ssbdemod.h +++ b/plugins/channel/ssb/ssbdemod.h @@ -33,14 +33,14 @@ class AudioFifo; class SSBDemod : public SampleSink { public: SSBDemod(AudioFifo* audioFifo, SampleSink* sampleSink); - ~SSBDemod(); + virtual ~SSBDemod(); void configure(MessageQueue* messageQueue, Real Bandwidth, Real LowCutoff, Real volume, int spanLog2); - void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); - void start(); - void stop(); - bool handleMessage(Message* cmd); + virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); + virtual void start(); + virtual void stop(); + virtual bool handleMessage(const Message& cmd); private: class MsgConfigureSSBDemod : public Message { diff --git a/plugins/channel/ssb/ssbdemodgui.cpp b/plugins/channel/ssb/ssbdemodgui.cpp index f72201f20..a8f210be8 100644 --- a/plugins/channel/ssb/ssbdemodgui.cpp +++ b/plugins/channel/ssb/ssbdemodgui.cpp @@ -12,6 +12,7 @@ #include "plugin/pluginapi.h" #include "util/simpleserializer.h" #include "gui/basicchannelsettingswidget.h" +#include "dsp/dspengine.h" #include "mainwindow.h" SSBDemodGUI* SSBDemodGUI::create(PluginAPI* pluginAPI) @@ -66,12 +67,14 @@ bool SSBDemodGUI::deserialize(const QByteArray& data) { SimpleDeserializer d(data); - if(!d.isValid()) { + if (!d.isValid()) + { resetToDefaults(); return false; } - if(d.getVersion() == 1) { + if (d.getVersion() == 1) + { QByteArray bytetmp; quint32 u32tmp; qint32 tmp; @@ -92,13 +95,15 @@ bool SSBDemodGUI::deserialize(const QByteArray& data) setNewRate(tmp); applySettings(); return true; - } else { + } + else + { resetToDefaults(); return false; } } -bool SSBDemodGUI::handleMessage(Message* message) +bool SSBDemodGUI::handleMessage(const Message& message) { return false; } @@ -121,9 +126,12 @@ void SSBDemodGUI::on_deltaMinus_clicked(bool minus) void SSBDemodGUI::on_deltaFrequency_changed(quint64 value) { - if (ui->deltaMinus->isChecked()) { + if (ui->deltaMinus->isChecked()) + { m_channelMarker->setCenterFrequency(-value); - } else { + } + else + { m_channelMarker->setCenterFrequency(value); } } @@ -134,9 +142,12 @@ void SSBDemodGUI::on_BW_valueChanged(int value) ui->BWText->setText(tr("%1k").arg(s)); m_channelMarker->setBandwidth(value * 100 * 2); - if (value < 0) { + if (value < 0) + { m_channelMarker->setSidebands(ChannelMarker::lsb); - } else { + } + else + { m_channelMarker->setSidebands(ChannelMarker::usb); } @@ -149,18 +160,25 @@ int SSBDemodGUI::getEffectiveLowCutoff(int lowCutoff) int effectiveLowCutoff = lowCutoff; const int guard = 100; - if (ssbBW < 0) { - if (effectiveLowCutoff < ssbBW + guard) { + if (ssbBW < 0) + { + if (effectiveLowCutoff < ssbBW + guard) + { effectiveLowCutoff = ssbBW + guard; } - if (effectiveLowCutoff > 0) { + if (effectiveLowCutoff > 0) + { effectiveLowCutoff = 0; } - } else { - if (effectiveLowCutoff > ssbBW - guard) { + } + else + { + if (effectiveLowCutoff > ssbBW - guard) + { effectiveLowCutoff = ssbBW - guard; } - if (effectiveLowCutoff < 0) { + if (effectiveLowCutoff < 0) + { effectiveLowCutoff = 0; } } @@ -186,7 +204,8 @@ void SSBDemodGUI::on_volume_valueChanged(int value) void SSBDemodGUI::on_spanLog2_valueChanged(int value) { - if (setNewRate(value)) { + if (setNewRate(value)) + { applySettings(); } @@ -202,7 +221,8 @@ void SSBDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown) void SSBDemodGUI::onMenuDoubleClicked() { - if(!m_basicSettingsShown) { + if(!m_basicSettingsShown) + { m_basicSettingsShown = true; BasicChannelSettingsWidget* bcsw = new BasicChannelSettingsWidget(m_channelMarker, this); bcsw->show(); @@ -226,9 +246,8 @@ SSBDemodGUI::SSBDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : m_spectrumVis = new SpectrumVis(ui->glSpectrum); m_ssbDemod = new SSBDemod(m_audioFifo, m_spectrumVis); m_channelizer = new Channelizer(m_ssbDemod); - m_threadedSampleSink = new ThreadedSampleSink(m_channelizer); - m_pluginAPI->addAudioSource(m_audioFifo); - m_pluginAPI->addSampleSink(m_threadedSampleSink); + DSPEngine::instance()->addAudioSink(m_audioFifo); + DSPEngine::instance()->addThreadedSink(m_channelizer); ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::ReverseGold)); @@ -248,7 +267,7 @@ SSBDemodGUI::SSBDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : connect(m_channelMarker, SIGNAL(changed()), this, SLOT(viewChanged())); m_pluginAPI->addChannelMarker(m_channelMarker); - ui->spectrumGUI->setBuddies(m_threadedSampleSink->getMessageQueue(), m_spectrumVis, ui->glSpectrum); + ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum); applySettings(); } @@ -256,9 +275,8 @@ SSBDemodGUI::SSBDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : SSBDemodGUI::~SSBDemodGUI() { m_pluginAPI->removeChannelInstance(this); - m_pluginAPI->removeAudioSource(m_audioFifo); - m_pluginAPI->removeSampleSink(m_threadedSampleSink); - delete m_threadedSampleSink; + DSPEngine::instance()->removeAudioSink(m_audioFifo); + DSPEngine::instance()->removeThreadedSink(m_channelizer); delete m_channelizer; delete m_ssbDemod; delete m_spectrumVis; @@ -269,25 +287,32 @@ SSBDemodGUI::~SSBDemodGUI() bool SSBDemodGUI::setNewRate(int spanLog2) { - if ((spanLog2 < 1) || (spanLog2 > 5)) { + if ((spanLog2 < 1) || (spanLog2 > 5)) + { return false; } m_spanLog2 = spanLog2; m_rate = 48000 / (1<BW->value() < -m_rate/100) { + if (ui->BW->value() < -m_rate/100) + { ui->BW->setValue(-m_rate/100); m_channelMarker->setBandwidth(-m_rate*2); - } else if (ui->BW->value() > m_rate/100) { + } + else if (ui->BW->value() > m_rate/100) + { ui->BW->setValue(m_rate/100); m_channelMarker->setBandwidth(m_rate*2); } - if (ui->lowCut->value() < -m_rate/100) { + if (ui->lowCut->value() < -m_rate/100) + { ui->lowCut->setValue(-m_rate/100); m_channelMarker->setLowCutoff(-m_rate); - } else if (ui->lowCut->value() > m_rate/100) { + } + else if (ui->lowCut->value() > m_rate/100) + { ui->lowCut->setValue(m_rate/100); m_channelMarker->setLowCutoff(m_rate); } @@ -311,10 +336,12 @@ void SSBDemodGUI::applySettings() setTitleColor(m_channelMarker->getColor()); ui->deltaFrequency->setValue(abs(m_channelMarker->getCenterFrequency())); ui->deltaMinus->setChecked(m_channelMarker->getCenterFrequency() < 0); - m_channelizer->configure(m_threadedSampleSink->getMessageQueue(), + + m_channelizer->configure(m_channelizer->getInputMessageQueue(), 48000, m_channelMarker->getCenterFrequency()); - m_ssbDemod->configure(m_threadedSampleSink->getMessageQueue(), + + m_ssbDemod->configure(m_ssbDemod->getInputMessageQueue(), ui->BW->value() * 100.0, ui->lowCut->value() * 100.0, ui->volume->value() / 10.0, diff --git a/plugins/channel/ssb/ssbdemodgui.h b/plugins/channel/ssb/ssbdemodgui.h index 97e23f916..04328b5ad 100644 --- a/plugins/channel/ssb/ssbdemodgui.h +++ b/plugins/channel/ssb/ssbdemodgui.h @@ -8,7 +8,6 @@ class PluginAPI; class ChannelMarker; class AudioFifo; -class ThreadedSampleSink; class Channelizer; class SSBDemod; class SpectrumVis; @@ -32,7 +31,7 @@ public: QByteArray serialize() const; bool deserialize(const QByteArray& data); - bool handleMessage(Message* message); + virtual bool handleMessage(const Message& message); private slots: void viewChanged(); @@ -54,7 +53,6 @@ private: int m_spanLog2; AudioFifo* m_audioFifo; - ThreadedSampleSink* m_threadedSampleSink; Channelizer* m_channelizer; SSBDemod* m_ssbDemod; SpectrumVis* m_spectrumVis; diff --git a/plugins/channel/tcpsrc/tcpsrc.cpp b/plugins/channel/tcpsrc/tcpsrc.cpp index 66a68eada..d4256cef3 100644 --- a/plugins/channel/tcpsrc/tcpsrc.cpp +++ b/plugins/channel/tcpsrc/tcpsrc.cpp @@ -47,6 +47,7 @@ TCPSrc::TCPSrc(MessageQueue* uiMessageQueue, TCPSrcGUI* tcpSrcGUI, SampleSink* s m_last = 0; m_this = 0; m_scale = 0; + m_boost = 0; m_sampleBufferSSB.resize(tcpFftLen); TCPFilter = new fftfilt(0.3 / 48.0, 16.0 / 48.0, tcpFftLen); // if (!TCPFilter) segfault; @@ -60,13 +61,13 @@ TCPSrc::~TCPSrc() void TCPSrc::configure(MessageQueue* messageQueue, SampleFormat sampleFormat, Real outputSampleRate, Real rfBandwidth, int tcpPort, int boost) { Message* cmd = MsgTCPSrcConfigure::create(sampleFormat, outputSampleRate, rfBandwidth, tcpPort, boost); - cmd->submit(messageQueue, this); + messageQueue->push(cmd); } void TCPSrc::setSpectrum(MessageQueue* messageQueue, bool enabled) { Message* cmd = MsgTCPSrcSpectrum::create(enabled); - cmd->submit(messageQueue, this); + messageQueue->push(cmd); } void TCPSrc::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly) @@ -157,61 +158,101 @@ void TCPSrc::stop() delete m_tcpServer; } -bool TCPSrc::handleMessage(Message* cmd) +bool TCPSrc::handleMessage(const Message& cmd) { - if(DSPSignalNotification::match(cmd)) { - DSPSignalNotification* signal = (DSPSignalNotification*)cmd; - qDebug("%d samples/sec, %lld Hz offset", signal->getSampleRate(), signal->getFrequencyOffset()); - m_inputSampleRate = signal->getSampleRate(); - m_nco.setFreq(-signal->getFrequencyOffset(), m_inputSampleRate); + qDebug() << "TCPSrc::handleMessage"; + + if (DSPSignalNotification::match(cmd)) + { + DSPSignalNotification& notif = (DSPSignalNotification&) cmd; + + m_inputSampleRate = notif.getSampleRate(); + m_nco.setFreq(-notif.getFrequencyOffset(), m_inputSampleRate); m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.0); m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate; - cmd->completed(); + + qDebug() << " - DSPSignalNotification: m_inputSampleRate: " << m_inputSampleRate + << " frequencyOffset: " << notif.getFrequencyOffset(); + return true; - } else if(MsgTCPSrcConfigure::match(cmd)) { - MsgTCPSrcConfigure* cfg = (MsgTCPSrcConfigure*)cmd; - m_sampleFormat = cfg->getSampleFormat(); - m_outputSampleRate = cfg->getOutputSampleRate(); - m_rfBandwidth = cfg->getRFBandwidth(); - if(cfg->getTCPPort() != m_tcpPort) { - m_tcpPort = cfg->getTCPPort(); + } + else if (MsgTCPSrcConfigure::match(cmd)) + { + MsgTCPSrcConfigure& cfg = (MsgTCPSrcConfigure&) cmd; + + m_sampleFormat = cfg.getSampleFormat(); + m_outputSampleRate = cfg.getOutputSampleRate(); + m_rfBandwidth = cfg.getRFBandwidth(); + + if (cfg.getTCPPort() != m_tcpPort) + { + m_tcpPort = cfg.getTCPPort(); + if(m_tcpServer->isListening()) + { m_tcpServer->close(); + } + m_tcpServer->listen(QHostAddress::Any, m_tcpPort); } - m_boost = cfg->getBoost(); + + m_boost = cfg.getBoost(); m_interpolator.create(16, m_inputSampleRate, m_rfBandwidth / 2.0); m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate; + if (m_sampleFormat == FormatSSB) + { TCPFilter->create_filter(0.3 / 48.0, m_rfBandwidth / 2.0 / m_outputSampleRate); + } else + { TCPFilter->create_filter(0.0, m_rfBandwidth / 2.0 / m_outputSampleRate); - cmd->completed(); + } + + qDebug() << " - MsgTCPSrcConfigure: m_sampleFormat: " << m_sampleFormat + << " m_outputSampleRate: " << m_outputSampleRate + << " m_rfBandwidth: " << m_rfBandwidth + << " m_boost: " << m_boost; + return true; - } else if(MsgTCPSrcSpectrum::match(cmd)) { - MsgTCPSrcSpectrum* spc = (MsgTCPSrcSpectrum*)cmd; - m_spectrumEnabled = spc->getEnabled(); - cmd->completed(); + } + else if (MsgTCPSrcSpectrum::match(cmd)) + { + MsgTCPSrcSpectrum& spc = (MsgTCPSrcSpectrum&) cmd; + + m_spectrumEnabled = spc.getEnabled(); + + qDebug() << " - MsgTCPSrcSpectrum: m_spectrumEnabled: " << m_spectrumEnabled; + return true; - } else { - if(m_spectrum != NULL) + } + else + { + if(m_spectrum != 0) + { return m_spectrum->handleMessage(cmd); - else return false; + } + else + { + return false; + } } } void TCPSrc::closeAllSockets(Sockets* sockets) { - for(int i = 0; i < sockets->count(); ++i) { + for(int i = 0; i < sockets->count(); ++i) + { MsgTCPSrcConnection* msg = MsgTCPSrcConnection::create(false, sockets->at(i).id, QHostAddress(), 0); - msg->submit(m_uiMessageQueue, (PluginGUI*)m_tcpSrcGUI); + m_uiMessageQueue->push(msg); sockets->at(i).socket->close(); } } void TCPSrc::onNewConnection() { - while(m_tcpServer->hasPendingConnections()) { + while(m_tcpServer->hasPendingConnections()) + { QTcpSocket* connection = m_tcpServer->nextPendingConnection(); connect(connection, SIGNAL(disconnected()), this, SLOT(onDisconnected())); @@ -223,7 +264,7 @@ void TCPSrc::onNewConnection() MsgTCPSrcConnection* msg = MsgTCPSrcConnection::create(true, id, connection->peerAddress(), connection->peerPort()); m_nextSSBId = (m_nextSSBId + 1) & 0xffffff; m_ssbSockets.push_back(Socket(id, connection)); - msg->submit(m_uiMessageQueue, (PluginGUI*)m_tcpSrcGUI); + m_uiMessageQueue->push(msg); break; } @@ -232,7 +273,7 @@ void TCPSrc::onNewConnection() MsgTCPSrcConnection* msg = MsgTCPSrcConnection::create(true, id, connection->peerAddress(), connection->peerPort()); m_nextS16leId = (m_nextS16leId + 1) & 0xffffff; m_s16leSockets.push_back(Socket(id, connection)); - msg->submit(m_uiMessageQueue, (PluginGUI*)m_tcpSrcGUI); + m_uiMessageQueue->push(msg); break; } @@ -246,19 +287,25 @@ void TCPSrc::onNewConnection() void TCPSrc::onDisconnected() { quint32 id; - QTcpSocket* socket = NULL; + QTcpSocket* socket = 0; - for(int i = 0; i < m_ssbSockets.count(); i++) { - if(m_ssbSockets[i].socket == sender()) { + for(int i = 0; i < m_ssbSockets.count(); i++) + { + if(m_ssbSockets[i].socket == sender()) + { id = m_ssbSockets[i].id; socket = m_ssbSockets[i].socket; m_ssbSockets.removeAt(i); break; } } - if(socket == NULL) { - for(int i = 0; i < m_s16leSockets.count(); i++) { - if(m_s16leSockets[i].socket == sender()) { + + if(socket == 0) + { + for(int i = 0; i < m_s16leSockets.count(); i++) + { + if(m_s16leSockets[i].socket == sender()) + { id = m_s16leSockets[i].id; socket = m_s16leSockets[i].socket; m_s16leSockets.removeAt(i); @@ -266,9 +313,11 @@ void TCPSrc::onDisconnected() } } } - if(socket != NULL) { + + if(socket != 0) + { MsgTCPSrcConnection* msg = MsgTCPSrcConnection::create(false, id, QHostAddress(), 0); - msg->submit(m_uiMessageQueue, (PluginGUI*)m_tcpSrcGUI); + m_uiMessageQueue->push(msg); socket->deleteLater(); } } diff --git a/plugins/channel/tcpsrc/tcpsrc.h b/plugins/channel/tcpsrc/tcpsrc.h index d99efcc7f..bb7448c87 100644 --- a/plugins/channel/tcpsrc/tcpsrc.h +++ b/plugins/channel/tcpsrc/tcpsrc.h @@ -26,15 +26,15 @@ public: }; TCPSrc(MessageQueue* uiMessageQueue, TCPSrcGUI* tcpSrcGUI, SampleSink* spectrum); - ~TCPSrc(); + virtual ~TCPSrc(); void configure(MessageQueue* messageQueue, SampleFormat sampleFormat, Real outputSampleRate, Real rfBandwidth, int tcpPort, int boost); void setSpectrum(MessageQueue* messageQueue, bool enabled); - void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); - void start(); - void stop(); - bool handleMessage(Message* cmd); + virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); + virtual void start(); + virtual void stop(); + virtual bool handleMessage(const Message& cmd); class MsgTCPSrcConnection : public Message { MESSAGE_CLASS_DECLARATION diff --git a/plugins/channel/tcpsrc/tcpsrcgui.cpp b/plugins/channel/tcpsrc/tcpsrcgui.cpp index 95792ec5d..b2042e9e3 100644 --- a/plugins/channel/tcpsrc/tcpsrcgui.cpp +++ b/plugins/channel/tcpsrc/tcpsrcgui.cpp @@ -3,7 +3,7 @@ #include "tcpsrc.h" #include "dsp/channelizer.h" #include "dsp/spectrumvis.h" -#include "dsp/threadedsamplesink.h" +#include "dsp/dspengine.h" #include "util/simpleserializer.h" #include "gui/basicchannelsettingswidget.h" #include "ui_tcpsrcgui.h" @@ -64,12 +64,14 @@ bool TCPSrcGUI::deserialize(const QByteArray& data) { SimpleDeserializer d(data); - if(!d.isValid()) { + if (!d.isValid()) + { resetToDefaults(); return false; } - if(d.getVersion() == 1) { + if (d.getVersion() == 1) + { QByteArray bytetmp; qint32 s32tmp; Real realtmp; @@ -104,22 +106,39 @@ bool TCPSrcGUI::deserialize(const QByteArray& data) ui->boost->setValue(s32tmp); applySettings(); return true; - } else { + } + else + { resetToDefaults(); return false; } } -bool TCPSrcGUI::handleMessage(Message* message) +bool TCPSrcGUI::handleMessage(const Message& message) { - if(TCPSrc::MsgTCPSrcConnection::match(message)) { - TCPSrc::MsgTCPSrcConnection* con = (TCPSrc::MsgTCPSrcConnection*)message; - if(con->getConnect()) - addConnection(con->getID(), con->getPeerAddress(), con->getPeerPort()); - else delConnection(con->getID()); - message->completed(); + qDebug() << "TCPSrcGUI::handleMessage"; + + if (TCPSrc::MsgTCPSrcConnection::match(message)) + { + TCPSrc::MsgTCPSrcConnection& con = (TCPSrc::MsgTCPSrcConnection&) message; + + if(con.getConnect()) + { + addConnection(con.getID(), con.getPeerAddress(), con.getPeerPort()); + } + else + { + delConnection(con.getID()); + } + + qDebug() << " - TCPSrc::MsgTCPSrcConnection: ID: " << con.getID() + << " peerAddress: " << con.getPeerAddress() + << " peerPort: " << con.getPeerPort(); + return true; - } else { + } + else + { return false; } } @@ -145,14 +164,13 @@ TCPSrcGUI::TCPSrcGUI(PluginAPI* pluginAPI, QWidget* parent) : m_spectrumVis = new SpectrumVis(ui->glSpectrum); m_tcpSrc = new TCPSrc(m_pluginAPI->getMainWindowMessageQueue(), this, m_spectrumVis); m_channelizer = new Channelizer(m_tcpSrc); - m_threadedSampleSink = new ThreadedSampleSink(m_channelizer); - m_pluginAPI->addSampleSink(m_threadedSampleSink); + DSPEngine::instance()->addThreadedSink(m_channelizer); ui->glSpectrum->setCenterFrequency(0); ui->glSpectrum->setSampleRate(ui->sampleRate->text().toInt()); ui->glSpectrum->setDisplayWaterfall(true); ui->glSpectrum->setDisplayMaxHold(true); - m_spectrumVis->configure(m_threadedSampleSink->getMessageQueue(), 64, 10, FFTWindow::BlackmanHarris); + m_spectrumVis->configure(m_spectrumVis->getInputMessageQueue(), 64, 10, FFTWindow::BlackmanHarris); m_channelMarker = new ChannelMarker(this); m_channelMarker->setBandwidth(16000); @@ -162,7 +180,7 @@ TCPSrcGUI::TCPSrcGUI(PluginAPI* pluginAPI, QWidget* parent) : connect(m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged())); m_pluginAPI->addChannelMarker(m_channelMarker); - ui->spectrumGUI->setBuddies(m_threadedSampleSink->getMessageQueue(), m_spectrumVis, ui->glSpectrum); + ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum); applySettings(); } @@ -170,8 +188,7 @@ TCPSrcGUI::TCPSrcGUI(PluginAPI* pluginAPI, QWidget* parent) : TCPSrcGUI::~TCPSrcGUI() { m_pluginAPI->removeChannelInstance(this); - m_pluginAPI->removeSampleSink(m_threadedSampleSink); - delete m_threadedSampleSink; + DSPEngine::instance()->removeThreadedSink(m_channelizer); delete m_channelizer; delete m_tcpSrc; delete m_spectrumVis; @@ -184,14 +201,26 @@ void TCPSrcGUI::applySettings() bool ok; Real outputSampleRate = ui->sampleRate->text().toDouble(&ok); + if((!ok) || (outputSampleRate < 1000)) + { outputSampleRate = 48000; + } + Real rfBandwidth = ui->rfBandwidth->text().toDouble(&ok); + if((!ok) || (rfBandwidth > outputSampleRate)) + { rfBandwidth = outputSampleRate; + } + int tcpPort = ui->tcpPort->text().toInt(&ok); + if((!ok) || (tcpPort < 1) || (tcpPort > 65535)) + { tcpPort = 9999; + } + int boost = ui->boost->value(); setTitleColor(m_channelMarker->getColor()); @@ -204,12 +233,14 @@ void TCPSrcGUI::applySettings() connect(m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged())); ui->glSpectrum->setSampleRate(outputSampleRate); - m_channelizer->configure(m_threadedSampleSink->getMessageQueue(), + m_channelizer->configure(m_channelizer->getInputMessageQueue(), outputSampleRate, m_channelMarker->getCenterFrequency()); TCPSrc::SampleFormat sampleFormat; - switch(ui->sampleFormat->currentIndex()) { + + switch(ui->sampleFormat->currentIndex()) + { case 0: sampleFormat = TCPSrc::FormatSSB; break; @@ -230,7 +261,7 @@ void TCPSrcGUI::applySettings() m_tcpPort = tcpPort; m_boost = boost; - m_tcpSrc->configure(m_threadedSampleSink->getMessageQueue(), + m_tcpSrc->configure(m_tcpSrc->getInputMessageQueue(), sampleFormat, outputSampleRate, rfBandwidth, @@ -273,13 +304,16 @@ void TCPSrcGUI::on_boost_valueChanged(int value) void TCPSrcGUI::onWidgetRolled(QWidget* widget, bool rollDown) { - if((widget == ui->spectrumBox) && (m_tcpSrc != NULL)) - m_tcpSrc->setSpectrum(m_threadedSampleSink->getMessageQueue(), rollDown); + if ((widget == ui->spectrumBox) && (m_tcpSrc != 0)) + { + m_tcpSrc->setSpectrum(m_tcpSrc->getInputMessageQueue(), rollDown); + } } void TCPSrcGUI::onMenuDoubleClicked() { - if(!m_basicSettingsShown) { + if (!m_basicSettingsShown) + { m_basicSettingsShown = true; BasicChannelSettingsWidget* bcsw = new BasicChannelSettingsWidget(m_channelMarker, this); bcsw->show(); @@ -296,8 +330,10 @@ void TCPSrcGUI::addConnection(quint32 id, const QHostAddress& peerAddress, int p void TCPSrcGUI::delConnection(quint32 id) { - for(int i = 0; i < ui->connections->topLevelItemCount(); i++) { - if(ui->connections->topLevelItem(i)->type() == (int)id) { + for(int i = 0; i < ui->connections->topLevelItemCount(); i++) + { + if(ui->connections->topLevelItem(i)->type() == (int)id) + { delete ui->connections->topLevelItem(i); ui->connectedClientsBox->setWindowTitle(tr("Connected Clients (%1)").arg(ui->connections->topLevelItemCount())); return; diff --git a/plugins/channel/tcpsrc/tcpsrcgui.h b/plugins/channel/tcpsrc/tcpsrcgui.h index 3e3629381..02831c767 100644 --- a/plugins/channel/tcpsrc/tcpsrcgui.h +++ b/plugins/channel/tcpsrc/tcpsrcgui.h @@ -8,7 +8,6 @@ class PluginAPI; class ChannelMarker; -class ThreadedSampleSink; class Channelizer; class TCPSrc; class SpectrumVis; @@ -32,7 +31,7 @@ public: QByteArray serialize() const; bool deserialize(const QByteArray& data); - bool handleMessage(Message* message); + virtual bool handleMessage(const Message& message); private slots: void channelMarkerChanged(); @@ -59,12 +58,11 @@ private: bool m_basicSettingsShown; // RF path - ThreadedSampleSink* m_threadedSampleSink; Channelizer* m_channelizer; SpectrumVis* m_spectrumVis; explicit TCPSrcGUI(PluginAPI* pluginAPI, QWidget* parent = NULL); - ~TCPSrcGUI(); + virtual ~TCPSrcGUI(); void applySettings(); diff --git a/plugins/channel/wfm/wfmdemod.cpp b/plugins/channel/wfm/wfmdemod.cpp index 7a5c9ee78..a76477a18 100644 --- a/plugins/channel/wfm/wfmdemod.cpp +++ b/plugins/channel/wfm/wfmdemod.cpp @@ -16,6 +16,7 @@ /////////////////////////////////////////////////////////////////////////////////// #include +#include #include #include #include "audio/audiooutput.h" @@ -51,13 +52,15 @@ WFMDemod::WFMDemod(AudioFifo* audioFifo, SampleSink* sampleSink) : WFMDemod::~WFMDemod() { if (m_rfFilter) + { delete m_rfFilter; + } } void WFMDemod::configure(MessageQueue* messageQueue, Real rfBandwidth, Real afBandwidth, Real volume, Real squelch) { Message* cmd = MsgConfigureWFMDemod::create(rfBandwidth, afBandwidth, volume, squelch); - cmd->submit(messageQueue, this); + messageQueue->push(cmd); } void WFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool firstOfBurst) @@ -79,13 +82,6 @@ void WFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iter for (int i =0 ; i = m_squelchLevel) - m_squelchState = m_running.m_audioSampleRate/ 20; - - qint16 sample; - if(m_squelchState > 0) { - m_squelchState--; - - /* - Real argument = arg(ci); - argument /= M_PI; - Real demod = argument - m_lastArgument; - m_lastArgument = argument; - */ - - - //ci *= 32768.0; - - /* - Complex d = conj(m_lastSample) * ci; - m_lastSample = ci; - Real demod = atan2(d.imag(), d.real()); - */ - - - //m_lastSample = ci; - - /* - Real argument = atan2(ci.real()*m_lastSample.imag() - m_lastSample.real()*ci.imag(), - ci.real()*m_lastSample.real() + ci.imag()*m_lastSample.imag()); - argument /= M_PI; - Real demod = argument - m_lastArgument; - m_lastArgument = argument; - m_lastSample = ci; - */ - - //Real demod = arctan2(d.imag(), d.real()); -/* - Real argument1 = arg(ci);//atan2(ci.imag(), ci.real()); - Real argument2 = m_lastSample.real(); - Real demod = angleDist(argument2, argument1); - m_lastSample = Complex(argument1, 0); -*/ - //demod /= M_PI; - - demod = m_lowpass.filter(demod); - - /* - if(demod < -1) - demod = -1; - else if(demod > 1) - demod = 1; - */ - - demod *= m_running.m_volume; - sample = demod * 64; - - } else { - sample = 0; - } - - m_audioBuffer[m_audioBufferFill].l = sample; - m_audioBuffer[m_audioBufferFill].r = sample; - ++m_audioBufferFill; - if(m_audioBufferFill >= m_audioBuffer.size()) { - uint res = m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1); - if(res != m_audioBufferFill) - qDebug("lost %u audio samples", m_audioBufferFill - res); - m_audioBufferFill = 0; - } - - m_interpolatorDistanceRemain += m_interpolatorDistance; - } - } -#endif - } if(m_audioBufferFill > 0) { @@ -246,28 +159,50 @@ void WFMDemod::stop() { } -bool WFMDemod::handleMessage(Message* cmd) +bool WFMDemod::handleMessage(const Message& cmd) { - if(DSPSignalNotification::match(cmd)) { - DSPSignalNotification* signal = (DSPSignalNotification*)cmd; + qDebug() << "WFMDemod::handleMessage"; - m_config.m_inputSampleRate = signal->getSampleRate(); - m_config.m_inputFrequencyOffset = signal->getFrequencyOffset(); + if (DSPSignalNotification::match(cmd)) + { + DSPSignalNotification& notif = (DSPSignalNotification&) cmd; + + m_config.m_inputSampleRate = notif.getSampleRate(); + m_config.m_inputFrequencyOffset = notif.getFrequencyOffset(); apply(); - cmd->completed(); + + qDebug() << " - DSPSignalNotification: m_inputSampleRate: " << m_config.m_inputSampleRate + << " m_inputFrequencyOffset: " << m_config.m_inputFrequencyOffset; + return true; - } else if(MsgConfigureWFMDemod::match(cmd)) { - MsgConfigureWFMDemod* cfg = (MsgConfigureWFMDemod*)cmd; - m_config.m_rfBandwidth = cfg->getRFBandwidth(); - m_config.m_afBandwidth = cfg->getAFBandwidth(); - m_config.m_volume = cfg->getVolume(); - m_config.m_squelch = cfg->getSquelch(); + } + else if (MsgConfigureWFMDemod::match(cmd)) + { + MsgConfigureWFMDemod& cfg = (MsgConfigureWFMDemod&) cmd; + + m_config.m_rfBandwidth = cfg.getRFBandwidth(); + m_config.m_afBandwidth = cfg.getAFBandwidth(); + m_config.m_volume = cfg.getVolume(); + m_config.m_squelch = cfg.getSquelch(); apply(); + + qDebug() << " - MsgConfigureWFMDemod: m_rfBandwidth: " << m_config.m_rfBandwidth + << " m_afBandwidth: " << m_config.m_afBandwidth + << " m_volume: " << m_config.m_volume + << " m_squelch: " << m_config.m_squelch; + return true; - } else { - if(m_sampleSink != NULL) + } + else + { + if (m_sampleSink != 0) + { return m_sampleSink->handleMessage(cmd); - else return false; + } + else + { + return false; + } } } diff --git a/plugins/channel/wfm/wfmdemod.h b/plugins/channel/wfm/wfmdemod.h index e0450ebf4..a0f3527a6 100644 --- a/plugins/channel/wfm/wfmdemod.h +++ b/plugins/channel/wfm/wfmdemod.h @@ -35,14 +35,14 @@ class AudioFifo; class WFMDemod : public SampleSink { public: WFMDemod(AudioFifo* audioFifo, SampleSink* sampleSink); - ~WFMDemod(); + virtual ~WFMDemod(); void configure(MessageQueue* messageQueue, Real rfBandwidth, Real afBandwidth, Real volume, Real squelch); - void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool po); - void start(); - void stop(); - bool handleMessage(Message* cmd); + virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool po); + virtual void start(); + virtual void stop(); + virtual bool handleMessage(const Message& cmd); private: class MsgConfigureWFMDemod : public Message { diff --git a/plugins/channel/wfm/wfmdemodgui.cpp b/plugins/channel/wfm/wfmdemodgui.cpp index 629f2b034..4cd4a4d02 100644 --- a/plugins/channel/wfm/wfmdemodgui.cpp +++ b/plugins/channel/wfm/wfmdemodgui.cpp @@ -1,9 +1,10 @@ #include #include +#include #include "ui_wfmdemodgui.h" #include "dsp/threadedsamplesink.h" #include "dsp/channelizer.h" -#include "dsp/nullsink.h" +#include "dsp/dspengine.h" #include "gui/glspectrum.h" #include "plugin/pluginapi.h" #include "util/simpleserializer.h" @@ -79,12 +80,14 @@ bool WFMDemodGUI::deserialize(const QByteArray& data) { SimpleDeserializer d(data); - if(!d.isValid()) { + if (!d.isValid()) + { resetToDefaults(); return false; } - if(d.getVersion() == 1) { + if (d.getVersion() == 1) + { QByteArray bytetmp; quint32 u32tmp; qint32 tmp; @@ -104,13 +107,15 @@ bool WFMDemodGUI::deserialize(const QByteArray& data) m_channelMarker->setColor(u32tmp); applySettings(); return true; - } else { + } + else + { resetToDefaults(); return false; } } -bool WFMDemodGUI::handleMessage(Message* message) +bool WFMDemodGUI::handleMessage(const Message& message) { return false; } @@ -133,9 +138,12 @@ void WFMDemodGUI::on_deltaMinus_clicked(bool minus) void WFMDemodGUI::on_deltaFrequency_changed(quint64 value) { - if (ui->deltaMinus->isChecked()) { + if (ui->deltaMinus->isChecked()) + { m_channelMarker->setCenterFrequency(-value); - } else { + } + else + { m_channelMarker->setCenterFrequency(value); } } @@ -172,7 +180,8 @@ void WFMDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown) void WFMDemodGUI::onMenuDoubleClicked() { - if(!m_basicSettingsShown) { + if(!m_basicSettingsShown) + { m_basicSettingsShown = true; BasicChannelSettingsWidget* bcsw = new BasicChannelSettingsWidget(m_channelMarker, this); bcsw->show(); @@ -191,12 +200,10 @@ WFMDemodGUI::WFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : connect(this, SIGNAL(menuDoubleClickEvent()), this, SLOT(onMenuDoubleClicked())); m_audioFifo = new AudioFifo(4, 250000); // TODO: check. Room for 1s FIFO at max rate - m_nullSink = new NullSink(); - m_wfmDemod = new WFMDemod(m_audioFifo, m_nullSink); + m_wfmDemod = new WFMDemod(m_audioFifo, 0); m_channelizer = new Channelizer(m_wfmDemod); - m_threadedSampleSink = new ThreadedSampleSink(m_channelizer); - m_pluginAPI->addAudioSource(m_audioFifo); - m_pluginAPI->addSampleSink(m_threadedSampleSink); + DSPEngine::instance()->addAudioSink(m_audioFifo); + DSPEngine::instance()->addThreadedSink(m_channelizer); m_channelMarker = new ChannelMarker(this); m_channelMarker->setColor(Qt::blue); @@ -212,12 +219,10 @@ WFMDemodGUI::WFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : WFMDemodGUI::~WFMDemodGUI() { m_pluginAPI->removeChannelInstance(this); - m_pluginAPI->removeAudioSource(m_audioFifo); - m_pluginAPI->removeSampleSink(m_threadedSampleSink); - delete m_threadedSampleSink; + DSPEngine::instance()->removeAudioSink(m_audioFifo); + DSPEngine::instance()->removeThreadedSink(m_channelizer); delete m_channelizer; delete m_wfmDemod; - delete m_nullSink; delete m_audioFifo; delete m_channelMarker; delete ui; @@ -226,12 +231,15 @@ WFMDemodGUI::~WFMDemodGUI() void WFMDemodGUI::applySettings() { setTitleColor(m_channelMarker->getColor()); - m_channelizer->configure(m_threadedSampleSink->getMessageQueue(), + + m_channelizer->configure(m_channelizer->getInputMessageQueue(), requiredBW(m_rfBW[ui->rfBW->value()]), // TODO: this is where requested sample rate is specified m_channelMarker->getCenterFrequency()); + ui->deltaFrequency->setValue(abs(m_channelMarker->getCenterFrequency())); ui->deltaMinus->setChecked(m_channelMarker->getCenterFrequency() < 0); - m_wfmDemod->configure(m_threadedSampleSink->getMessageQueue(), + + m_wfmDemod->configure(m_wfmDemod->getInputMessageQueue(), m_rfBW[ui->rfBW->value()], ui->afBW->value() * 1000.0, ui->volume->value() / 10.0, diff --git a/plugins/channel/wfm/wfmdemodgui.h b/plugins/channel/wfm/wfmdemodgui.h index 66f9c0de7..bdd096a14 100644 --- a/plugins/channel/wfm/wfmdemodgui.h +++ b/plugins/channel/wfm/wfmdemodgui.h @@ -8,10 +8,8 @@ class PluginAPI; class ChannelMarker; class AudioFifo; -class ThreadedSampleSink; class Channelizer; class WFMDemod; -class NullSink; namespace Ui { class WFMDemodGUI; @@ -32,7 +30,7 @@ public: QByteArray serialize() const; bool deserialize(const QByteArray& data); - bool handleMessage(Message* message); + virtual bool handleMessage(const Message& message); private slots: void viewChanged(); @@ -52,15 +50,13 @@ private: bool m_basicSettingsShown; AudioFifo* m_audioFifo; - ThreadedSampleSink* m_threadedSampleSink; Channelizer* m_channelizer; WFMDemod* m_wfmDemod; - NullSink *m_nullSink; static const int m_rfBW[]; explicit WFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent = NULL); - ~WFMDemodGUI(); + virtual ~WFMDemodGUI(); void applySettings(); diff --git a/plugins/samplesource/bladerf/bladerfgui.cpp b/plugins/samplesource/bladerf/bladerfgui.cpp index 05237c7c9..eeace7080 100644 --- a/plugins/samplesource/bladerf/bladerfgui.cpp +++ b/plugins/samplesource/bladerf/bladerfgui.cpp @@ -20,6 +20,7 @@ #include "ui_bladerfgui.h" #include "plugin/pluginapi.h" #include "gui/colormapper.h" +#include "dsp/dspengine.h" #include "bladerfgui.h" BladerfGui::BladerfGui(PluginAPI* pluginAPI, QWidget* parent) : @@ -35,8 +36,8 @@ BladerfGui::BladerfGui(PluginAPI* pluginAPI, QWidget* parent) : connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware())); displaySettings(); - m_sampleSource = new BladerfInput(m_pluginAPI->getMainWindowMessageQueue()); - m_pluginAPI->setSampleSource(m_sampleSource); + m_sampleSource = new BladerfInput(); + DSPEngine::instance()->setSource(m_sampleSource); } BladerfGui::~BladerfGui() @@ -61,32 +62,14 @@ QString BladerfGui::getName() const void BladerfGui::resetToDefaults() { - m_generalSettings.resetToDefaults(); m_settings.resetToDefaults(); displaySettings(); sendSettings(); } -QByteArray BladerfGui::serializeGeneral() const -{ - return m_generalSettings.serialize(); -} - -bool BladerfGui::deserializeGeneral(const QByteArray&data) -{ - if(m_generalSettings.deserialize(data)) { - displaySettings(); - sendSettings(); - return true; - } else { - resetToDefaults(); - return false; - } -} - qint64 BladerfGui::getCenterFrequency() const { - return m_generalSettings.m_centerFrequency; + return m_settings.m_centerFrequency; } QByteArray BladerfGui::serialize() const @@ -106,23 +89,25 @@ bool BladerfGui::deserialize(const QByteArray& data) } } -bool BladerfGui::handleMessage(Message* message) +bool BladerfGui::handleMessage(const Message& message) { - if(BladerfInput::MsgReportBladerf::match(message)) { + if (BladerfInput::MsgReportBladerf::match(message)) + { displaySettings(); - message->completed(); return true; - } else { + } + else + { return false; } } void BladerfGui::displaySettings() { - ui->centerFrequency->setValue(m_generalSettings.m_centerFrequency / 1000); + ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000); - ui->samplerateText->setText(tr("%1k").arg(m_settings.m_samplerate / 1000)); - unsigned int sampleRateIndex = BladerfSampleRates::getRateIndex(m_settings.m_samplerate); + ui->samplerateText->setText(tr("%1k").arg(m_settings.m_devSampleRate / 1000)); + unsigned int sampleRateIndex = BladerfSampleRates::getRateIndex(m_settings.m_devSampleRate); ui->samplerate->setValue(sampleRateIndex); ui->bandwidthText->setText(tr("%1k").arg(m_settings.m_bandwidth / 1000)); @@ -154,7 +139,7 @@ void BladerfGui::sendSettings() void BladerfGui::on_centerFrequency_changed(quint64 value) { - m_generalSettings.m_centerFrequency = value * 1000; + m_settings.m_centerFrequency = value * 1000; sendSettings(); } @@ -162,7 +147,7 @@ void BladerfGui::on_samplerate_valueChanged(int value) { int newrate = BladerfSampleRates::getRate(value); ui->samplerateText->setText(tr("%1k").arg(newrate)); - m_settings.m_samplerate = newrate * 1000; + m_settings.m_devSampleRate = newrate * 1000; sendSettings(); } @@ -291,8 +276,8 @@ void BladerfGui::on_xb200_currentIndexChanged(int index) void BladerfGui::updateHardware() { - BladerfInput::MsgConfigureBladerf* message = BladerfInput::MsgConfigureBladerf::create(m_generalSettings, m_settings); - message->submit(m_pluginAPI->getDSPEngineMessageQueue()); + BladerfInput::MsgConfigureBladerf* message = BladerfInput::MsgConfigureBladerf::create( m_settings); + m_sampleSource->getInputMessageQueue()->push(message); m_updateTimer.stop(); } diff --git a/plugins/samplesource/bladerf/bladerfgui.h b/plugins/samplesource/bladerf/bladerfgui.h index 66c6949fd..fc349b073 100644 --- a/plugins/samplesource/bladerf/bladerfgui.h +++ b/plugins/samplesource/bladerf/bladerfgui.h @@ -34,25 +34,22 @@ class BladerfGui : public QWidget, public PluginGUI { public: explicit BladerfGui(PluginAPI* pluginAPI, QWidget* parent = NULL); - ~BladerfGui(); + virtual ~BladerfGui(); void destroy(); void setName(const QString& name); QString getName() const; void resetToDefaults(); - QByteArray serializeGeneral() const; - bool deserializeGeneral(const QByteArray&data); qint64 getCenterFrequency() const; QByteArray serialize() const; bool deserialize(const QByteArray& data); - bool handleMessage(Message* message); + virtual bool handleMessage(const Message& message); private: Ui::BladerfGui* ui; PluginAPI* m_pluginAPI; - SampleSource::GeneralSettings m_generalSettings; BladerfInput::Settings m_settings; QTimer m_updateTimer; std::vector m_gains; diff --git a/plugins/samplesource/bladerf/bladerfinput.cpp b/plugins/samplesource/bladerf/bladerfinput.cpp index 671403311..d807b9825 100644 --- a/plugins/samplesource/bladerf/bladerfinput.cpp +++ b/plugins/samplesource/bladerf/bladerfinput.cpp @@ -29,10 +29,11 @@ MESSAGE_CLASS_DEFINITION(BladerfInput::MsgConfigureBladerf, Message) MESSAGE_CLASS_DEFINITION(BladerfInput::MsgReportBladerf, Message) BladerfInput::Settings::Settings() : + m_centerFrequency(435000*1000), + m_devSampleRate(3072000), m_lnaGain(0), m_vga1(20), m_vga2(9), - m_samplerate(3072000), m_bandwidth(1500000), m_log2Decim(0), m_fcPos(FC_POS_INFRA), @@ -44,10 +45,11 @@ BladerfInput::Settings::Settings() : void BladerfInput::Settings::resetToDefaults() { + m_centerFrequency = 435000*1000; + m_devSampleRate = 3072000; m_lnaGain = 0; m_vga1 = 20; m_vga2 = 9; - m_samplerate = 3072000; m_bandwidth = 1500000; m_log2Decim = 0; m_fcPos = FC_POS_INFRA; @@ -59,16 +61,17 @@ void BladerfInput::Settings::resetToDefaults() QByteArray BladerfInput::Settings::serialize() const { SimpleSerializer s(1); - s.writeS32(1, m_lnaGain); - s.writeS32(2, m_vga1); - s.writeS32(3, m_vga2); - s.writeS32(4, m_samplerate); - s.writeU32(5, m_log2Decim); - s.writeBool(6, m_xb200); - s.writeS32(7, (int) m_xb200Path); - s.writeS32(8, (int) m_xb200Filter); - s.writeS32(9, m_bandwidth); - s.writeS32(10, (int) m_fcPos); + s.writeU64(1, m_centerFrequency); + s.writeS32(2, m_devSampleRate); + s.writeS32(3, m_lnaGain); + s.writeS32(4, m_vga1); + s.writeS32(5, m_vga2); + s.writeU32(6, m_log2Decim); + s.writeBool(7, m_xb200); + s.writeS32(8, (int) m_xb200Path); + s.writeS32(9, (int) m_xb200Filter); + s.writeS32(10, m_bandwidth); + s.writeS32(11, (int) m_fcPos); return s.final(); } @@ -76,63 +79,75 @@ bool BladerfInput::Settings::deserialize(const QByteArray& data) { SimpleDeserializer d(data); - if(!d.isValid()) { + if (!d.isValid()) + { resetToDefaults(); return false; } - if(d.getVersion() == 1) { + if (d.getVersion() == 1) + { int intval; - d.readS32(1, &m_lnaGain, 0); - d.readS32(2, &m_vga1, 20); - d.readS32(3, &m_vga2, 9); - d.readS32(4, &m_samplerate, 0); - d.readU32(5, &m_log2Decim, 0); - d.readBool(6, &m_xb200); - d.readS32(7, &intval); - m_xb200Path = (bladerf_xb200_path) intval; + d.readU64(1, &m_centerFrequency, 435000*1000); + d.readS32(2, &m_devSampleRate, 3072000); + d.readS32(3, &m_lnaGain, 0); + d.readS32(4, &m_vga1, 20); + d.readS32(5, &m_vga2, 9); + d.readU32(6, &m_log2Decim, 0); + d.readBool(7, &m_xb200); d.readS32(8, &intval); + m_xb200Path = (bladerf_xb200_path) intval; + d.readS32(9, &intval); m_xb200Filter = (bladerf_xb200_filter) intval; - d.readS32(9, &m_bandwidth, 0); - d.readS32(10, &intval, 0); + d.readS32(10, &m_bandwidth, 0); + d.readS32(11, &intval, 0); m_fcPos = (fcPos_t) intval; return true; - } else { + } + else + { resetToDefaults(); return false; } } -BladerfInput::BladerfInput(MessageQueue* msgQueueToGUI) : - SampleSource(msgQueueToGUI), +BladerfInput::BladerfInput() : m_settings(), - m_dev(NULL), - m_bladerfThread(NULL), + m_dev(0), + m_bladerfThread(0), m_deviceDescription("BladeRF") { } BladerfInput::~BladerfInput() { - stopInput(); + stop(); } -bool BladerfInput::startInput(int device) +bool BladerfInput::init(const Message& cmd) +{ + return false; +} + +bool BladerfInput::start(int device) { QMutexLocker mutexLocker(&m_mutex); - if(m_dev != NULL) - stopInput(); + if (m_dev != 0) + { + stop(); + } int res; int fpga_loaded; - if(!m_sampleFifo.setSize(96000 * 4)) { + if (!m_sampleFifo.setSize(96000 * 4)) + { qCritical("Could not allocate SampleFifo"); return false; } - if ((m_dev = open_bladerf_from_serial(0)) == NULL) // TODO: fix; Open first available device as there is no proper handling for multiple devices + if ((m_dev = open_bladerf_from_serial(0)) == 0) // TODO: fix; Open first available device as there is no proper handling for multiple devices { qCritical("could not open BladeRF"); return false; @@ -140,11 +155,14 @@ bool BladerfInput::startInput(int device) fpga_loaded = bladerf_is_fpga_configured(m_dev); - if (fpga_loaded < 0) { + if (fpga_loaded < 0) + { qCritical("Failed to check FPGA state: %s", bladerf_strerror(fpga_loaded)); return false; - } else if (fpga_loaded == 0) { + } + else if (fpga_loaded == 0) + { qCritical("The device's FPGA is not loaded."); return false; } @@ -170,31 +188,34 @@ bool BladerfInput::startInput(int device) m_bladerfThread->startWork(); mutexLocker.unlock(); - applySettings(m_generalSettings, m_settings, true); + applySettings(m_settings, true); qDebug("BladerfInput::startInput: started"); - //MsgReportBladerf::create(m_gains)->submit(m_guiMessageQueue); Pass anything here return true; failed: - stopInput(); + stop(); return false; } -void BladerfInput::stopInput() +void BladerfInput::stop() { QMutexLocker mutexLocker(&m_mutex); - if(m_bladerfThread != NULL) { + if(m_bladerfThread != 0) + { m_bladerfThread->stopWork(); delete m_bladerfThread; - m_bladerfThread = NULL; + m_bladerfThread = 0; } - if(m_dev != NULL) { + + if(m_dev != 0) + { bladerf_close(m_dev); - m_dev = NULL; + m_dev = 0; } + m_deviceDescription.clear(); } @@ -205,28 +226,28 @@ const QString& BladerfInput::getDeviceDescription() const int BladerfInput::getSampleRate() const { - int rate = m_settings.m_samplerate; + int rate = m_settings.m_devSampleRate; return (rate / (1<getGeneralSettings(), conf->getSettings(), false)) { + if (!applySettings(conf.getSettings(), false)) + { qDebug("BladeRF config error"); } - message->completed(); return true; } else @@ -235,7 +256,7 @@ bool BladerfInput::handleMessage(Message* message) } } -bool BladerfInput::applySettings(const GeneralSettings& generalSettings, const Settings& settings, bool force) +bool BladerfInput::applySettings(const Settings& settings, bool force) { QMutexLocker mutexLocker(&m_mutex); @@ -245,11 +266,14 @@ bool BladerfInput::applySettings(const GeneralSettings& generalSettings, const S { m_settings.m_lnaGain = settings.m_lnaGain; - if (m_dev != NULL) + if (m_dev != 0) { - if(bladerf_set_lna_gain(m_dev, getLnaGain(m_settings.m_lnaGain)) != 0) { + if(bladerf_set_lna_gain(m_dev, getLnaGain(m_settings.m_lnaGain)) != 0) + { qDebug("bladerf_set_lna_gain() failed"); - } else { + } + else + { qDebug() << "BladerfInput: LNA gain set to " << getLnaGain(m_settings.m_lnaGain); } } @@ -259,11 +283,14 @@ bool BladerfInput::applySettings(const GeneralSettings& generalSettings, const S { m_settings.m_vga1 = settings.m_vga1; - if (m_dev != NULL) + if (m_dev != 0) { - if(bladerf_set_rxvga1(m_dev, m_settings.m_vga1) != 0) { + if(bladerf_set_rxvga1(m_dev, m_settings.m_vga1) != 0) + { qDebug("bladerf_set_rxvga1() failed"); - } else { + } + else + { qDebug() << "BladerfInput: VGA1 gain set to " << m_settings.m_vga1; } } @@ -273,11 +300,14 @@ bool BladerfInput::applySettings(const GeneralSettings& generalSettings, const S { m_settings.m_vga2 = settings.m_vga2; - if(m_dev != NULL) + if(m_dev != 0) { - if(bladerf_set_rxvga2(m_dev, m_settings.m_vga2) != 0) { + if(bladerf_set_rxvga2(m_dev, m_settings.m_vga2) != 0) + { qDebug("bladerf_set_rxvga2() failed"); - } else { + } + else + { qDebug() << "BladerfInput: VGA2 gain set to " << m_settings.m_vga2; } } @@ -287,21 +317,27 @@ bool BladerfInput::applySettings(const GeneralSettings& generalSettings, const S { m_settings.m_xb200 = settings.m_xb200; - if (m_dev != NULL) + if (m_dev != 0) { if (m_settings.m_xb200) { - if (bladerf_expansion_attach(m_dev, BLADERF_XB_200) != 0) { + if (bladerf_expansion_attach(m_dev, BLADERF_XB_200) != 0) + { qDebug("bladerf_expansion_attach(xb200) failed"); - } else { + } + else + { qDebug() << "BladerfInput: Attach XB200"; } } else { - if (bladerf_expansion_attach(m_dev, BLADERF_XB_NONE) != 0) { + if (bladerf_expansion_attach(m_dev, BLADERF_XB_NONE) != 0) + { qDebug("bladerf_expansion_attach(none) failed"); - } else { + } + else + { qDebug() << "BladerfInput: Detach XB200"; } } @@ -311,11 +347,15 @@ bool BladerfInput::applySettings(const GeneralSettings& generalSettings, const S if ((m_settings.m_xb200Path != settings.m_xb200Path) || force) { m_settings.m_xb200Path = settings.m_xb200Path; - if (m_dev != NULL) + + if (m_dev != 0) { - if(bladerf_xb200_set_path(m_dev, BLADERF_MODULE_RX, m_settings.m_xb200Path) != 0) { + if(bladerf_xb200_set_path(m_dev, BLADERF_MODULE_RX, m_settings.m_xb200Path) != 0) + { qDebug("bladerf_xb200_set_path(BLADERF_MODULE_RX) failed"); - } else { + } + else + { qDebug() << "BladerfInput: set xb200 path to " << m_settings.m_xb200Path; } } @@ -325,32 +365,35 @@ bool BladerfInput::applySettings(const GeneralSettings& generalSettings, const S { m_settings.m_xb200Filter = settings.m_xb200Filter; - if(m_dev != NULL) + if (m_dev != 0) { - if(bladerf_xb200_set_filterbank(m_dev, BLADERF_MODULE_RX, m_settings.m_xb200Filter) != 0) { + if(bladerf_xb200_set_filterbank(m_dev, BLADERF_MODULE_RX, m_settings.m_xb200Filter) != 0) + { qDebug("bladerf_xb200_set_filterbank(BLADERF_MODULE_RX) failed"); - } else { + } + else + { qDebug() << "BladerfInput: set xb200 filter to " << m_settings.m_xb200Filter; } } } - if ((m_settings.m_samplerate != settings.m_samplerate) || force) + if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force) { - m_settings.m_samplerate = settings.m_samplerate; + m_settings.m_devSampleRate = settings.m_devSampleRate; - if (m_dev != NULL) + if (m_dev != 0) { unsigned int actualSamplerate; - if (bladerf_set_sample_rate(m_dev, BLADERF_MODULE_RX, m_settings.m_samplerate, &actualSamplerate) < 0) + if (bladerf_set_sample_rate(m_dev, BLADERF_MODULE_RX, m_settings.m_devSampleRate, &actualSamplerate) < 0) { - qCritical("could not set sample rate: %d", m_settings.m_samplerate); + qCritical("could not set sample rate: %d", m_settings.m_devSampleRate); } else { qDebug() << "bladerf_set_sample_rate(BLADERF_MODULE_RX) actual sample rate is " << actualSamplerate; - m_bladerfThread->setSamplerate(m_settings.m_samplerate); + m_bladerfThread->setSamplerate(m_settings.m_devSampleRate); } } } @@ -359,13 +402,16 @@ bool BladerfInput::applySettings(const GeneralSettings& generalSettings, const S { m_settings.m_bandwidth = settings.m_bandwidth; - if(m_dev != NULL) + if(m_dev != 0) { unsigned int actualBandwidth; if( bladerf_set_bandwidth(m_dev, BLADERF_MODULE_RX, m_settings.m_bandwidth, &actualBandwidth) < 0) - qCritical("could not set sample rate: %d", m_settings.m_samplerate); - else { + { + qCritical("could not set bandwidth: %d", m_settings.m_bandwidth); + } + else + { qDebug() << "bladerf_set_bandwidth(BLADERF_MODULE_RX) actual bandwidth is " << actualBandwidth; } } @@ -375,7 +421,7 @@ bool BladerfInput::applySettings(const GeneralSettings& generalSettings, const S { m_settings.m_log2Decim = settings.m_log2Decim; - if(m_dev != NULL) + if(m_dev != 0) { m_bladerfThread->setLog2Decimation(m_settings.m_log2Decim); qDebug() << "BladerfInput: set decimation to " << (1<setFcPos((int) m_settings.m_fcPos); qDebug() << "BladerfInput: set fc pos (enum) to " << (int) m_settings.m_fcPos; } } - m_generalSettings.m_centerFrequency = generalSettings.m_centerFrequency; + m_settings.m_centerFrequency = settings.m_centerFrequency; - qint64 centerFrequency = m_generalSettings.m_centerFrequency; + qint64 centerFrequency = m_settings.m_centerFrequency; qint64 f_img = centerFrequency; qint64 f_cut = centerFrequency + m_settings.m_bandwidth/2; if ((m_settings.m_log2Decim == 0) || (m_settings.m_fcPos == FC_POS_CENTER)) { - centerFrequency = m_generalSettings.m_centerFrequency; + centerFrequency = m_settings.m_centerFrequency; f_img = centerFrequency; f_cut = centerFrequency + m_settings.m_bandwidth/2; } @@ -409,29 +455,30 @@ bool BladerfInput::applySettings(const GeneralSettings& generalSettings, const S { if (m_settings.m_fcPos == FC_POS_INFRA) { - centerFrequency = m_generalSettings.m_centerFrequency + (m_settings.m_samplerate / 4); - f_img = centerFrequency + m_settings.m_samplerate/2; + centerFrequency = m_settings.m_centerFrequency + (m_settings.m_devSampleRate / 4); + f_img = centerFrequency + m_settings.m_devSampleRate/2; f_cut = centerFrequency + m_settings.m_bandwidth/2; } else if (m_settings.m_fcPos == FC_POS_SUPRA) { - centerFrequency = m_generalSettings.m_centerFrequency - (m_settings.m_samplerate / 4); - f_img = centerFrequency - m_settings.m_samplerate/2; + centerFrequency = m_settings.m_centerFrequency - (m_settings.m_devSampleRate / 4); + f_img = centerFrequency - m_settings.m_devSampleRate/2; f_cut = centerFrequency - m_settings.m_bandwidth/2; } } if (m_dev != NULL) { - if (bladerf_set_frequency( m_dev, BLADERF_MODULE_RX, centerFrequency ) != 0) { - qDebug("bladerf_set_frequency(%lld) failed", m_generalSettings.m_centerFrequency); + if (bladerf_set_frequency( m_dev, BLADERF_MODULE_RX, centerFrequency ) != 0) + { + qDebug("bladerf_set_frequency(%lld) failed", m_settings.m_centerFrequency); } } - qDebug() << " - center freq: " << m_generalSettings.m_centerFrequency << " Hz" + qDebug() << " - center freq: " << m_settings.m_centerFrequency << " Hz" << " RF center freq: " << centerFrequency << " Hz" - << " RF sample rate: " << m_settings.m_samplerate << "Hz" - << " Actual sample rate: " << m_settings.m_samplerate/(1<getMainWindowMessageQueue()); - m_pluginAPI->setSampleSource(m_sampleSource); + m_sampleSource = new FCDInput(); + DSPEngine::instance()->setSource(m_sampleSource); } FCDGui::~FCDGui() @@ -40,34 +41,11 @@ QString FCDGui::getName() const void FCDGui::resetToDefaults() { - m_generalSettings.resetToDefaults(); m_settings.resetToDefaults(); displaySettings(); sendSettings(); } -QByteArray FCDGui::serializeGeneral() const -{ - return m_generalSettings.serialize(); -} - -bool FCDGui::deserializeGeneral(const QByteArray&data) -{ - if(m_generalSettings.deserialize(data)) { - displaySettings(); - sendSettings(); - return true; - } else { - resetToDefaults(); - return false; - } -} - -qint64 FCDGui::getCenterFrequency() const -{ - return m_generalSettings.m_centerFrequency; -} - QByteArray FCDGui::serialize() const { return m_settings.serialize(); @@ -75,24 +53,27 @@ QByteArray FCDGui::serialize() const bool FCDGui::deserialize(const QByteArray& data) { - if(m_settings.deserialize(data)) { + if(m_settings.deserialize(data)) + { displaySettings(); sendSettings(); return true; - } else { + } + else + { resetToDefaults(); return false; } } -bool FCDGui::handleMessage(Message* message) +bool FCDGui::handleMessage(const Message& message) { - return true; + return false; } void FCDGui::displaySettings() { - ui->centerFrequency->setValue(m_generalSettings.m_centerFrequency / 1000); + ui->centerFrequency->setValue(m_settings.centerFrequency / 1000); ui->checkBoxR->setChecked(m_settings.range); ui->checkBoxG->setChecked(m_settings.gain); ui->checkBoxB->setChecked(m_settings.bias); @@ -106,49 +87,61 @@ void FCDGui::sendSettings() void FCDGui::on_centerFrequency_changed(quint64 value) { - m_generalSettings.m_centerFrequency = value * 1000; + m_settings.centerFrequency = value * 1000; sendSettings(); } void FCDGui::updateHardware() { - FCDInput::MsgConfigureFCD* message = FCDInput::MsgConfigureFCD::create(m_generalSettings, m_settings); - message->submit(m_pluginAPI->getDSPEngineMessageQueue()); + FCDInput::MsgConfigureFCD* message = FCDInput::MsgConfigureFCD::create(m_settings); + m_sampleSource->getInputMessageQueue()->push(message); m_updateTimer.stop(); } void FCDGui::on_checkBoxR_stateChanged(int state) { - if (state == Qt::Checked) { + if (state == Qt::Checked) + { ui->centerFrequency->setValueRange(7, 150U, 240000U); ui->centerFrequency->setValue(7000); - m_generalSettings.m_centerFrequency = 7000 * 1000; + m_settings.centerFrequency = 7000 * 1000; m_settings.range = 1; } - else { + else + { ui->centerFrequency->setValueRange(7, 420000U, 1900000U); - ui->centerFrequency->setValue(434450); - m_generalSettings.m_centerFrequency = 434450 * 1000; + ui->centerFrequency->setValue(435000); + m_settings.centerFrequency = 435000 * 1000; m_settings.range = 0; } + sendSettings(); } void FCDGui::on_checkBoxG_stateChanged(int state) { - if (state == Qt::Checked) { + if (state == Qt::Checked) + { m_settings.gain = 1; - } else { + } + else + { m_settings.gain = 0; } + sendSettings(); } + void FCDGui::on_checkBoxB_stateChanged(int state) { - if (state == Qt::Checked) { + if (state == Qt::Checked) + { m_settings.bias = 1; - } else { + } + else + { m_settings.bias = 0; } + sendSettings(); } diff --git a/plugins/samplesource/fcd/fcdgui.h b/plugins/samplesource/fcd/fcdgui.h index 5e719858e..1b4b8d6fe 100644 --- a/plugins/samplesource/fcd/fcdgui.h +++ b/plugins/samplesource/fcd/fcdgui.h @@ -16,25 +16,22 @@ class FCDGui : public QWidget, public PluginGUI { public: explicit FCDGui(PluginAPI* pluginAPI, QWidget* parent = NULL); - ~FCDGui(); + virtual ~FCDGui(); void destroy(); void setName(const QString& name); QString getName() const; void resetToDefaults(); - QByteArray serializeGeneral() const; - bool deserializeGeneral(const QByteArray&data); - qint64 getCenterFrequency() const; QByteArray serialize() const; bool deserialize(const QByteArray& data); - bool handleMessage(Message* message); + + virtual bool handleMessage(const Message& message); private: Ui::FCDGui* ui; PluginAPI* m_pluginAPI; - SampleSource::GeneralSettings m_generalSettings; FCDInput::Settings m_settings; QTimer m_updateTimer; std::vector m_gains; diff --git a/plugins/samplesource/fcd/fcdinput.cpp b/plugins/samplesource/fcd/fcdinput.cpp index 3d3d33250..ff1f89059 100644 --- a/plugins/samplesource/fcd/fcdinput.cpp +++ b/plugins/samplesource/fcd/fcdinput.cpp @@ -20,12 +20,14 @@ #include "fcdinput.h" #include "fcdthread.h" #include "fcdgui.h" +#include "qthid.h" #include "util/simpleserializer.h" MESSAGE_CLASS_DEFINITION(FCDInput::MsgConfigureFCD, Message) //MESSAGE_CLASS_DEFINITION(FCDInput::MsgReportFCD, Message) FCDInput::Settings::Settings() : + centerFrequency(435000000), range(0), gain(0), bias(0) @@ -34,6 +36,7 @@ FCDInput::Settings::Settings() : void FCDInput::Settings::resetToDefaults() { + centerFrequency = 435000000; range = 0; gain = 0; bias = 0; @@ -42,75 +45,92 @@ void FCDInput::Settings::resetToDefaults() QByteArray FCDInput::Settings::serialize() const { SimpleSerializer s(1); - s.writeS32(1, range); - s.writeS32(2, gain); - s.writeS32(3, bias); + s.writeU64(1, centerFrequency); + s.writeS32(2, range); + s.writeS32(3, gain); + s.writeS32(4, bias); return s.final(); } bool FCDInput::Settings::deserialize(const QByteArray& data) { SimpleDeserializer d(data); - if(d.isValid() && d.getVersion() == 1) { - d.readS32(1, &range, 0); - d.readS32(2, &gain, 0); - d.readS32(3, &bias, 0); + + if (d.isValid() && d.getVersion() == 1) + { + d.readU64(1, ¢erFrequency, 435000000); + d.readS32(2, &range, 0); + d.readS32(3, &gain, 0); + d.readS32(4, &bias, 0); return true; } + resetToDefaults(); return true; } -FCDInput::FCDInput(MessageQueue* msgQueueToGUI) : - SampleSource(msgQueueToGUI), +FCDInput::FCDInput() : m_settings(), - m_FCDThread(NULL), + m_FCDThread(0), m_deviceDescription() { } FCDInput::~FCDInput() { - stopInput(); + stop(); } -bool FCDInput::startInput(int device) +bool FCDInput::init(const Message& cmd) +{ + return false; +} + +bool FCDInput::start(int device) { QMutexLocker mutexLocker(&m_mutex); - if(m_FCDThread) + if (m_FCDThread) + { return false; + } + /* Apply settings before streaming to avoid bus contention; * there is very little spare bandwidth on a full speed USB device. * Failure is harmless if no device is found */ - applySettings(m_generalSettings, m_settings, true); - if(!m_sampleFifo.setSize(4096*16)) { + applySettings(m_settings, true); + + if(!m_sampleFifo.setSize(4096*16)) + { qCritical("Could not allocate SampleFifo"); return false; } - if((m_FCDThread = new FCDThread(&m_sampleFifo)) == NULL) { + if ((m_FCDThread = new FCDThread(&m_sampleFifo)) == NULL) + { qFatal("out of memory"); return false; } m_deviceDescription = QString("Funcube Dongle"); - qDebug("FCDInput: start"); + qDebug("FCDInput::start"); return true; } -void FCDInput::stopInput() +void FCDInput::stop() { QMutexLocker mutexLocker(&m_mutex); - if(m_FCDThread) { + if (m_FCDThread) + { m_FCDThread->stopWork(); // wait for thread to quit ? delete m_FCDThread; - m_FCDThread = NULL; + m_FCDThread = 0; } + m_deviceDescription.clear(); } @@ -121,45 +141,66 @@ const QString& FCDInput::getDeviceDescription() const int FCDInput::getSampleRate() const { - return 192000; + return 96000; } quint64 FCDInput::getCenterFrequency() const { - return m_generalSettings.m_centerFrequency; + return m_settings.centerFrequency; } -bool FCDInput::handleMessage(Message* message) +bool FCDInput::handleMessage(const Message& message) { - if(MsgConfigureFCD::match(message)) { - MsgConfigureFCD* conf = (MsgConfigureFCD*)message; - applySettings(conf->getGeneralSettings(), conf->getSettings(), false); - message->completed(); + if(MsgConfigureFCD::match(message)) + { + MsgConfigureFCD& conf = (MsgConfigureFCD&) message; + applySettings(conf.getSettings(), false); return true; - } else { + } + else + { return false; } } -void FCDInput::applySettings(const GeneralSettings& generalSettings, const Settings& settings, bool force) +void FCDInput::applySettings(const Settings& settings, bool force) { - bool freqChange; + bool sampleSourcChange = false; - if((m_generalSettings.m_centerFrequency != generalSettings.m_centerFrequency)) - freqChange = true; - else - freqChange = false; - - if(freqChange || force) { - m_generalSettings.m_centerFrequency = generalSettings.m_centerFrequency; - set_center_freq( (double)(generalSettings.m_centerFrequency) ); + if ((m_settings.centerFrequency != settings.centerFrequency)) + { + m_settings.centerFrequency = settings.centerFrequency; + set_center_freq((double) m_settings.centerFrequency); + sampleSourcChange = true; } - if(!freqChange || force) { - set_lna_gain(settings.gain); - set_bias_t(settings.bias); + if (!sampleSourcChange || force) + { + set_lna_gain(settings.gain > 0); + set_bias_t(settings.bias > 0); } +} +void FCDInput::set_center_freq(double freq) +{ + if (fcdAppSetFreq(freq) == FCD_MODE_NONE) + { + qDebug("No FCD HID found for frquency change"); + } +} + +void FCDInput::set_bias_t(bool on) +{ + quint8 cmd = on ? 1 : 0; + + fcdAppSetParam(FCD_CMD_APP_SET_BIAS_TEE, &cmd, 1); +} + +void FCDInput::set_lna_gain(bool on) +{ + quint8 cmd = on ? 1 : 0; + + fcdAppSetParam(FCD_CMD_APP_SET_LNA_GAIN, &cmd, 1); } diff --git a/plugins/samplesource/fcd/fcdinput.h b/plugins/samplesource/fcd/fcdinput.h index 741722543..4ba1d9d2c 100644 --- a/plugins/samplesource/fcd/fcdinput.h +++ b/plugins/samplesource/fcd/fcdinput.h @@ -23,7 +23,7 @@ struct fcd_buffer { void *start; - size_t length; + std::size_t length; }; class FCDThread; @@ -32,6 +32,7 @@ class FCDInput : public SampleSource { public: struct Settings { Settings(); + quint64 centerFrequency; qint32 range; qint32 gain; qint32 bias; @@ -44,46 +45,46 @@ public: MESSAGE_CLASS_DECLARATION public: - const GeneralSettings& getGeneralSettings() const { return m_generalSettings; } const Settings& getSettings() const { return m_settings; } - static MsgConfigureFCD* create(const GeneralSettings& generalSettings, const Settings& settings) + static MsgConfigureFCD* create(const Settings& settings) { - return new MsgConfigureFCD(generalSettings, settings); + return new MsgConfigureFCD(settings); } private: - GeneralSettings m_generalSettings; Settings m_settings; - MsgConfigureFCD(const GeneralSettings& generalSettings, const Settings& settings) : + MsgConfigureFCD(const Settings& settings) : Message(), - m_generalSettings(generalSettings), m_settings(settings) { } }; + FCDInput(); + virtual ~FCDInput(); - FCDInput(MessageQueue* msgQueueToGUI); - ~FCDInput(); + virtual bool init(const Message& cmd); + virtual bool start(int device); + virtual void stop(); - bool startInput(int device); - void stopInput(); + virtual const QString& getDeviceDescription() const; + virtual int getSampleRate() const; + virtual quint64 getCenterFrequency() const; + + virtual bool handleMessage(const Message& message); - const QString& getDeviceDescription() const; - int getSampleRate() const; void set_center_freq(double freq); void set_bias_t(bool on); void set_lna_gain(bool on); - quint64 getCenterFrequency() const; - bool handleMessage(Message* message); private: + void applySettings(const Settings& settings, bool force); + QMutex m_mutex; Settings m_settings; FCDThread* m_FCDThread; QString m_deviceDescription; - void applySettings(const GeneralSettings& generalSettings, const Settings& settings, bool force); }; #endif // INCLUDE_FCD_H diff --git a/plugins/samplesource/fcd/fcdsource.cpp b/plugins/samplesource/fcd/fcdsource.cpp deleted file mode 100644 index 9e6afc3e6..000000000 --- a/plugins/samplesource/fcd/fcdsource.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* (C)2015 John Greb - * - * Funcube Dongle command line interface - * Copyright 2011 David Pello EA1IDZ - * Copyright 2011 Pieter-Tjerk de Boer PA3FWM - * Copyright 2012-2014 Alexandru Csete OZ9AEC - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public Licence version 3. - */ - -#include "fcdinput.h" -#include "fcdthread.h" -#include "qthid.h" - -bool FCDThread::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 ) - return false; - - snd_pcm_hw_params_alloca(¶ms); - if ( snd_pcm_hw_params_any(fcd_handle, params) < 0 ) - fail = true; - else if ( snd_pcm_hw_params(fcd_handle, params) < 0 ) { - fail = true; - // TODO: check actual samplerate, may be crippled firmware - } else { - if ( snd_pcm_start(fcd_handle) < 0 ) - fail = true; - } - if (fail) { - qCritical("Funcube Dongle stream start failed"); - snd_pcm_close( fcd_handle ); - return false; - } else { - qDebug("Funcube stream started"); - } - return true; -} - -void FCDThread::CloseSource() -{ - if (fcd_handle) - snd_pcm_close( fcd_handle ); - fcd_handle = NULL; -} - -void FCDInput::set_center_freq(double freq) -{ - if (fcdAppSetFreq(freq) == FCD_MODE_NONE) - qDebug("No FCD HID found for frquency change"); -} - -void FCDInput::set_bias_t(bool on) -{ - quint8 cmd = on ? 1 : 0; - - fcdAppSetParam(FCD_CMD_APP_SET_BIAS_TEE, &cmd, 1); -} - -void FCDInput::set_lna_gain(bool on) -{ - quint8 cmd = on ? 1 : 0; - - fcdAppSetParam(FCD_CMD_APP_SET_LNA_GAIN, &cmd, 1); -} - -int FCDThread::work(int n_items) -{ - int l; - SampleVector::iterator it; - void *out; - - it = m_convertBuffer.begin(); - out = (void *)&it[0]; - l = snd_pcm_mmap_readi(fcd_handle, out, (snd_pcm_uframes_t)n_items); - if (l > 0) - m_sampleFifo->write(it, it + l); - if (l == -EPIPE) { - qDebug("FCD: Overrun detected"); - return 0; - } - return l; -} - - diff --git a/plugins/samplesource/fcd/fcdthread.cpp b/plugins/samplesource/fcd/fcdthread.cpp index 13cbd793e..a808f2932 100644 --- a/plugins/samplesource/fcd/fcdthread.cpp +++ b/plugins/samplesource/fcd/fcdthread.cpp @@ -54,3 +54,84 @@ void FCDThread::run() CloseSource(); } +bool FCDThread::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) + { + return false; + } + + snd_pcm_hw_params_alloca(¶ms); + + if (snd_pcm_hw_params_any(fcd_handle, params) < 0) + { + fail = true; + } + else if (snd_pcm_hw_params(fcd_handle, params) < 0) + { + fail = true; + // TODO: check actual samplerate, may be crippled firmware + } + else + { + if (snd_pcm_start(fcd_handle) < 0) + { + fail = true; + } + } + + if (fail) + { + qCritical("Funcube Dongle stream start failed"); + snd_pcm_close( fcd_handle ); + return false; + } + else + { + qDebug("Funcube stream started"); + } + + return true; +} + +void FCDThread::CloseSource() +{ + if (fcd_handle) + { + snd_pcm_close( fcd_handle ); + } + + fcd_handle = NULL; +} + +int FCDThread::work(int n_items) +{ + int l; + SampleVector::iterator it; + void *out; + + it = m_convertBuffer.begin(); + out = (void *)&it[0]; + l = snd_pcm_mmap_readi(fcd_handle, out, (snd_pcm_uframes_t)n_items); + if (l > 0) + m_sampleFifo->write(it, it + l); + if (l == -EPIPE) { + qDebug("FCD: Overrun detected"); + return 0; + } + return l; +} + + diff --git a/plugins/samplesource/filesource/filesourcegui.cpp b/plugins/samplesource/filesource/filesourcegui.cpp index 0905baede..09aabe75a 100644 --- a/plugins/samplesource/filesource/filesourcegui.cpp +++ b/plugins/samplesource/filesource/filesourcegui.cpp @@ -23,6 +23,7 @@ #include "ui_filesourcegui.h" #include "plugin/pluginapi.h" #include "gui/colormapper.h" +#include "dsp/dspengine.h" #include "mainwindow.h" #include "filesourcegui.h" @@ -49,8 +50,8 @@ FileSourceGui::FileSourceGui(PluginAPI* pluginAPI, QWidget* parent) : connect(&(m_pluginAPI->getMainWindow()->getMasterTimer()), SIGNAL(timeout()), this, SLOT(tick())); displaySettings(); - m_sampleSource = new FileSourceInput(m_pluginAPI->getMainWindowMessageQueue(), m_pluginAPI->getMainWindow()->getMasterTimer()); - m_pluginAPI->setSampleSource(m_sampleSource); + m_sampleSource = new FileSourceInput(m_pluginAPI->getMainWindow()->getMasterTimer()); + DSPEngine::instance()->setSource(m_sampleSource); } FileSourceGui::~FileSourceGui() @@ -75,32 +76,14 @@ QString FileSourceGui::getName() const void FileSourceGui::resetToDefaults() { - m_generalSettings.resetToDefaults(); m_settings.resetToDefaults(); displaySettings(); sendSettings(); } -QByteArray FileSourceGui::serializeGeneral() const -{ - return m_generalSettings.serialize(); -} - -bool FileSourceGui::deserializeGeneral(const QByteArray&data) -{ - if(m_generalSettings.deserialize(data)) { - displaySettings(); - sendSettings(); - return true; - } else { - resetToDefaults(); - return false; - } -} - qint64 FileSourceGui::getCenterFrequency() const { - return m_generalSettings.m_centerFrequency; + return m_centerFrequency; } QByteArray FileSourceGui::serialize() const @@ -120,28 +103,25 @@ bool FileSourceGui::deserialize(const QByteArray& data) } } -bool FileSourceGui::handleMessage(Message* message) +bool FileSourceGui::handleMessage(const Message& message) { if(FileSourceInput::MsgReportFileSourceAcquisition::match(message)) { - m_acquisition = ((FileSourceInput::MsgReportFileSourceAcquisition*)message)->getAcquisition(); + m_acquisition = ((FileSourceInput::MsgReportFileSourceAcquisition&)message).getAcquisition(); updateWithAcquisition(); - message->completed(); return true; } else if(FileSourceInput::MsgReportFileSourceStreamData::match(message)) { - m_sampleRate = ((FileSourceInput::MsgReportFileSourceStreamData*)message)->getSampleRate(); - m_centerFrequency = ((FileSourceInput::MsgReportFileSourceStreamData*)message)->getCenterFrequency(); - m_startingTimeStamp = ((FileSourceInput::MsgReportFileSourceStreamData*)message)->getStartingTimeStamp(); - message->completed(); + m_sampleRate = ((FileSourceInput::MsgReportFileSourceStreamData&)message).getSampleRate(); + m_centerFrequency = ((FileSourceInput::MsgReportFileSourceStreamData&)message).getCenterFrequency(); + m_startingTimeStamp = ((FileSourceInput::MsgReportFileSourceStreamData&)message).getStartingTimeStamp(); updateWithStreamData(); return true; } else if(FileSourceInput::MsgReportFileSourceStreamTiming::match(message)) { - m_samplesCount = ((FileSourceInput::MsgReportFileSourceStreamTiming*)message)->getSamplesCount(); - message->completed(); + m_samplesCount = ((FileSourceInput::MsgReportFileSourceStreamTiming&)message).getSamplesCount(); updateWithStreamTime(); return true; } @@ -157,31 +137,25 @@ void FileSourceGui::displaySettings() void FileSourceGui::sendSettings() { - /* - if(!m_updateTimer.isActive()) - m_updateTimer.start(100); - */ } void FileSourceGui::updateHardware() { - /* - FileSourceInput::MsgConfigureFileSource* message = FileSourceInput::MsgConfigureFileSource::create(m_generalSettings, m_settings); - message->submit(m_pluginAPI->getDSPEngineMessageQueue()); - m_updateTimer.stop();*/ } void FileSourceGui::on_play_toggled(bool checked) { FileSourceInput::MsgConfigureFileSourceWork* message = FileSourceInput::MsgConfigureFileSourceWork::create(checked); - message->submit(m_pluginAPI->getDSPEngineMessageQueue()); + m_sampleSource->getInputMessageQueue()->push(message); } void FileSourceGui::on_showFileDialog_clicked(bool checked) { QString fileName = QFileDialog::getOpenFileName(this, tr("Open I/Q record file"), ".", tr("SDR I/Q Files (*.sdriq)")); - if (fileName != "") { + + if (fileName != "") + { m_fileName = fileName; ui->fileNameText->setText(m_fileName); configureFileName(); @@ -192,7 +166,7 @@ void FileSourceGui::configureFileName() { qDebug() << "FileSourceGui::configureFileName: " << m_fileName.toStdString().c_str(); FileSourceInput::MsgConfigureFileSourceName* message = FileSourceInput::MsgConfigureFileSourceName::create(m_fileName); - message->submit(m_pluginAPI->getDSPEngineMessageQueue()); + m_sampleSource->getInputMessageQueue()->push(message); } void FileSourceGui::updateWithAcquisition() @@ -239,6 +213,6 @@ void FileSourceGui::tick() { if ((++m_tickCount & 0xf) == 0) { FileSourceInput::MsgConfigureFileSourceStreamTiming* message = FileSourceInput::MsgConfigureFileSourceStreamTiming::create(); - message->submit(m_pluginAPI->getDSPEngineMessageQueue()); + m_sampleSource->getInputMessageQueue()->push(message); } } diff --git a/plugins/samplesource/filesource/filesourcegui.h b/plugins/samplesource/filesource/filesourcegui.h index 10f61d808..b907eef91 100644 --- a/plugins/samplesource/filesource/filesourcegui.h +++ b/plugins/samplesource/filesource/filesourcegui.h @@ -33,25 +33,22 @@ class FileSourceGui : public QWidget, public PluginGUI { public: explicit FileSourceGui(PluginAPI* pluginAPI, QWidget* parent = NULL); - ~FileSourceGui(); + virtual ~FileSourceGui(); void destroy(); void setName(const QString& name); QString getName() const; void resetToDefaults(); - QByteArray serializeGeneral() const; - bool deserializeGeneral(const QByteArray&data); qint64 getCenterFrequency() const; QByteArray serialize() const; bool deserialize(const QByteArray& data); - bool handleMessage(Message* message); + virtual bool handleMessage(const Message& message); private: Ui::FileSourceGui* ui; PluginAPI* m_pluginAPI; - SampleSource::GeneralSettings m_generalSettings; FileSourceInput::Settings m_settings; QTimer m_updateTimer; std::vector m_gains; diff --git a/plugins/samplesource/filesource/filesourceinput.cpp b/plugins/samplesource/filesource/filesourceinput.cpp index ec73c9305..a2ecb0fa9 100644 --- a/plugins/samplesource/filesource/filesourceinput.cpp +++ b/plugins/samplesource/filesource/filesourceinput.cpp @@ -69,8 +69,7 @@ bool FileSourceInput::Settings::deserialize(const QByteArray& data) } } -FileSourceInput::FileSourceInput(MessageQueue* msgQueueToGUI, const QTimer& masterTimer) : - SampleSource(msgQueueToGUI), +FileSourceInput::FileSourceInput(const QTimer& masterTimer) : m_settings(), m_fileSourceThread(NULL), m_deviceDescription(), @@ -84,7 +83,7 @@ FileSourceInput::FileSourceInput(MessageQueue* msgQueueToGUI, const QTimer& mast FileSourceInput::~FileSourceInput() { - stopInput(); + stop(); } void FileSourceInput::openFileStream() @@ -105,19 +104,15 @@ void FileSourceInput::openFileStream() m_centerFrequency = header.centerFrequency; m_startingTimeStamp = header.startTimeStamp; - MsgReportFileSourceStreamData::create(m_sampleRate, m_centerFrequency, m_startingTimeStamp)->submit(m_guiMessageQueue); // file stream data + MsgReportFileSourceStreamData *report = MsgReportFileSourceStreamData::create(m_sampleRate, m_centerFrequency, m_startingTimeStamp); // file stream data + getOutputMessageQueue()->push(report); } -bool FileSourceInput::startInput(int device) +bool FileSourceInput::start(int device) { QMutexLocker mutexLocker(&m_mutex); qDebug() << "FileSourceInput::startInput"; - /* - if (!m_ifstream.is_open()) { - openFileStream(); - }*/ - if (m_ifstream.tellg() != 0) { m_ifstream.clear(); m_ifstream.seekg(0, std::ios::beg); @@ -132,7 +127,8 @@ bool FileSourceInput::startInput(int device) if((m_fileSourceThread = new FileSourceThread(&m_ifstream, &m_sampleFifo)) == NULL) { qFatal("out of memory"); - goto failed; + stop(); + return false; } m_fileSourceThread->setSamplerate(m_sampleRate); @@ -144,29 +140,28 @@ bool FileSourceInput::startInput(int device) //applySettings(m_generalSettings, m_settings, true); qDebug("FileSourceInput::startInput: started"); - MsgReportFileSourceAcquisition::create(true)->submit(m_guiMessageQueue); // acquisition on + MsgReportFileSourceAcquisition *report = MsgReportFileSourceAcquisition::create(true); // acquisition on + getOutputMessageQueue()->push(report); return true; - -failed: - stopInput(); - return false; } -void FileSourceInput::stopInput() +void FileSourceInput::stop() { - qDebug() << "FileSourceInput::stopInput"; + qDebug() << "FileSourceInput::stop"; QMutexLocker mutexLocker(&m_mutex); - if(m_fileSourceThread != NULL) { + if(m_fileSourceThread != 0) + { m_fileSourceThread->stopWork(); delete m_fileSourceThread; - m_fileSourceThread = NULL; + m_fileSourceThread = 0; } m_deviceDescription.clear(); - MsgReportFileSourceAcquisition::create(false)->submit(m_guiMessageQueue); // acquisition off + MsgReportFileSourceAcquisition *report = MsgReportFileSourceAcquisition::create(false); // acquisition off + getOutputMessageQueue()->push(report); } const QString& FileSourceInput::getDeviceDescription() const @@ -189,40 +184,52 @@ std::time_t FileSourceInput::getStartingTimeStamp() const return m_startingTimeStamp; } -bool FileSourceInput::handleMessage(Message* message) +bool FileSourceInput::handleMessage(const Message& message) { if (MsgConfigureFileSourceName::match(message)) { - MsgConfigureFileSourceName* conf = (MsgConfigureFileSourceName*) message; - m_fileName = conf->getFileName(); + MsgConfigureFileSourceName& conf = (MsgConfigureFileSourceName&) message; + m_fileName = conf.getFileName(); openFileStream(); - message->completed(); return true; } else if (MsgConfigureFileSourceWork::match(message)) { - MsgConfigureFileSourceWork* conf = (MsgConfigureFileSourceWork*) message; - bool working = conf->isWorking(); + MsgConfigureFileSourceWork& conf = (MsgConfigureFileSourceWork&) message; + bool working = conf.isWorking(); + if (m_fileSourceThread != 0) { - if (working) { + if (working) + { m_fileSourceThread->startWork(); - } else { + } + else + { m_fileSourceThread->stopWork(); } - MsgReportFileSourceStreamTiming::create(m_fileSourceThread->getSamplesCount())->submit(m_guiMessageQueue); + MsgReportFileSourceStreamTiming *report = + MsgReportFileSourceStreamTiming::create(m_fileSourceThread->getSamplesCount()); + getOutputMessageQueue()->push(report); } - message->completed(); + return true; } else if (MsgConfigureFileSourceStreamTiming::match(message)) { - if (m_fileSourceThread != 0) { - MsgReportFileSourceStreamTiming::create(m_fileSourceThread->getSamplesCount())->submit(m_guiMessageQueue); - }else { - MsgReportFileSourceStreamTiming::create(0)->submit(m_guiMessageQueue); + MsgReportFileSourceStreamTiming *report; + + if (m_fileSourceThread != 0) + { + report = MsgReportFileSourceStreamTiming::create(m_fileSourceThread->getSamplesCount()); } + else + { + report = MsgReportFileSourceStreamTiming::create(0); + } + + getOutputMessageQueue()->push(report); } else { @@ -230,30 +237,38 @@ bool FileSourceInput::handleMessage(Message* message) } } -bool FileSourceInput::applySettings(const GeneralSettings& generalSettings, const Settings& settings, bool force) +bool FileSourceInput::applySettings(const Settings& settings, bool force) { QMutexLocker mutexLocker(&m_mutex); bool wasRunning = false; - if((m_settings.m_fileName != settings.m_fileName) || force) { + if((m_settings.m_fileName != settings.m_fileName) || force) + { m_settings.m_fileName = settings.m_fileName; - if (m_fileSourceThread != 0) { + if (m_fileSourceThread != 0) + { wasRunning = m_fileSourceThread->isRunning(); - if (wasRunning) { + + if (wasRunning) + { m_fileSourceThread->stopWork(); } } - if (m_ifstream.is_open()) { + if (m_ifstream.is_open()) + { m_ifstream.close(); } openFileStream(); - if (m_fileSourceThread != 0) { + if (m_fileSourceThread != 0) + { m_fileSourceThread->setSamplerate(m_sampleRate); - if (wasRunning) { + + if (wasRunning) + { m_fileSourceThread->startWork(); } } diff --git a/plugins/samplesource/filesource/filesourceinput.h b/plugins/samplesource/filesource/filesourceinput.h index 98b19ee51..7113bea38 100644 --- a/plugins/samplesource/filesource/filesourceinput.h +++ b/plugins/samplesource/filesource/filesourceinput.h @@ -41,21 +41,18 @@ public: MESSAGE_CLASS_DECLARATION public: - const GeneralSettings& getGeneralSettings() const { return m_generalSettings; } const Settings& getSettings() const { return m_settings; } - static MsgConfigureFileSource* create(const GeneralSettings& generalSettings, const Settings& settings) + static MsgConfigureFileSource* create(const Settings& settings) { - return new MsgConfigureFileSource(generalSettings, settings); + return new MsgConfigureFileSource(settings); } private: - GeneralSettings m_generalSettings; Settings m_settings; - MsgConfigureFileSource(const GeneralSettings& generalSettings, const Settings& settings) : + MsgConfigureFileSource(const Settings& settings) : Message(), - m_generalSettings(generalSettings), m_settings(settings) { } }; @@ -183,18 +180,19 @@ public: { } }; - FileSourceInput(MessageQueue* msgQueueToGUI, const QTimer& masterTimer); - ~FileSourceInput(); + FileSourceInput(const QTimer& masterTimer); + virtual ~FileSourceInput(); - bool startInput(int device); - void stopInput(); + virtual bool init(const Message& message); + virtual bool start(int device); + virtual void stop(); - const QString& getDeviceDescription() const; - int getSampleRate() const; - quint64 getCenterFrequency() const; + virtual const QString& getDeviceDescription() const; + virtual int getSampleRate() const; + virtual quint64 getCenterFrequency() const; std::time_t getStartingTimeStamp() const; - bool handleMessage(Message* message); + virtual bool handleMessage(const Message& message); private: QMutex m_mutex; @@ -208,7 +206,7 @@ private: std::time_t m_startingTimeStamp; const QTimer& m_masterTimer; - bool applySettings(const GeneralSettings& generalSettings, const Settings& settings, bool force); + bool applySettings(const Settings& settings, bool force); void openFileStream(); }; diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp index cc98b95a5..360faa057 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp @@ -2,13 +2,14 @@ #include "ui_rtlsdrgui.h" #include "plugin/pluginapi.h" #include "gui/colormapper.h" +#include "dsp/dspengine.h" RTLSDRGui::RTLSDRGui(PluginAPI* pluginAPI, QWidget* parent) : QWidget(parent), ui(new Ui::RTLSDRGui), m_pluginAPI(pluginAPI), m_settings(), - m_sampleSource(NULL) + m_sampleSource(0) { ui->setupUi(this); ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::ReverseGold)); @@ -16,8 +17,8 @@ RTLSDRGui::RTLSDRGui(PluginAPI* pluginAPI, QWidget* parent) : connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware())); displaySettings(); - m_sampleSource = new RTLSDRInput(m_pluginAPI->getMainWindowMessageQueue()); - m_pluginAPI->setSampleSource(m_sampleSource); + m_sampleSource = new RTLSDRInput(); + DSPEngine::instance()->setSource(m_sampleSource); } RTLSDRGui::~RTLSDRGui() @@ -42,32 +43,14 @@ QString RTLSDRGui::getName() const void RTLSDRGui::resetToDefaults() { - m_generalSettings.resetToDefaults(); m_settings.resetToDefaults(); displaySettings(); sendSettings(); } -QByteArray RTLSDRGui::serializeGeneral() const -{ - return m_generalSettings.serialize(); -} - -bool RTLSDRGui::deserializeGeneral(const QByteArray&data) -{ - if(m_generalSettings.deserialize(data)) { - displaySettings(); - sendSettings(); - return true; - } else { - resetToDefaults(); - return false; - } -} - qint64 RTLSDRGui::getCenterFrequency() const { - return m_generalSettings.m_centerFrequency; + return m_settings.m_centerFrequency; } QByteArray RTLSDRGui::serialize() const @@ -77,53 +60,65 @@ QByteArray RTLSDRGui::serialize() const bool RTLSDRGui::deserialize(const QByteArray& data) { - if(m_settings.deserialize(data)) { + if (m_settings.deserialize(data)) + { displaySettings(); sendSettings(); return true; - } else { + } + else + { resetToDefaults(); return false; } } -bool RTLSDRGui::handleMessage(Message* message) +bool RTLSDRGui::handleMessage(const Message& message) { - if(RTLSDRInput::MsgReportRTLSDR::match(message)) { - m_gains = ((RTLSDRInput::MsgReportRTLSDR*)message)->getGains(); + if (RTLSDRInput::MsgReportRTLSDR::match(message)) + { + m_gains = ((RTLSDRInput::MsgReportRTLSDR&) message).getGains(); displaySettings(); - message->completed(); return true; - } else { + } + else + { return false; } } void RTLSDRGui::displaySettings() { - ui->centerFrequency->setValue(m_generalSettings.m_centerFrequency / 1000); - ui->samplerateText->setText(tr("%1k").arg(m_settings.m_samplerate / 1000)); - unsigned int sampleRateIndex = RTLSDRSampleRates::getRateIndex(m_settings.m_samplerate); + ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000); + ui->samplerateText->setText(tr("%1k").arg(m_settings.m_devSampleRate / 1000)); + unsigned int sampleRateIndex = RTLSDRSampleRates::getRateIndex(m_settings.m_devSampleRate); ui->samplerate->setValue(sampleRateIndex); ui->ppm->setValue(m_settings.m_loPpmCorrection); ui->ppmText->setText(tr("%1").arg(m_settings.m_loPpmCorrection)); ui->decimText->setText(tr("%1").arg(1<decim->setValue(m_settings.m_log2Decim); - if(m_gains.size() > 0) { + if (m_gains.size() > 0) + { int dist = abs(m_settings.m_gain - m_gains[0]); int pos = 0; - for(uint i = 1; i < m_gains.size(); i++) { - if(abs(m_settings.m_gain - m_gains[i]) < dist) { + + for (uint i = 1; i < m_gains.size(); i++) + { + if (abs(m_settings.m_gain - m_gains[i]) < dist) + { dist = abs(m_settings.m_gain - m_gains[i]); pos = i; } } + ui->gainText->setText(tr("%1.%2").arg(m_gains[pos] / 10).arg(abs(m_gains[pos] % 10))); ui->gain->setMaximum(m_gains.size() - 1); ui->gain->setEnabled(true); ui->gain->setValue(pos); - } else { + } + else + { ui->gain->setMaximum(0); ui->gain->setEnabled(false); ui->gain->setValue(0); @@ -133,40 +128,54 @@ void RTLSDRGui::displaySettings() void RTLSDRGui::sendSettings() { if(!m_updateTimer.isActive()) + { m_updateTimer.start(100); + } } void RTLSDRGui::on_centerFrequency_changed(quint64 value) { - m_generalSettings.m_centerFrequency = value * 1000; + m_settings.m_centerFrequency = value * 1000; sendSettings(); } void RTLSDRGui::on_decim_valueChanged(int value) { if ((value <0) || (value > 4)) + { return; + } + ui->decimText->setText(tr("%1").arg(1< 99) || (value < -99)) + if ((value > 99) || (value < -99)) + { return; + } + ui->ppmText->setText(tr("%1").arg(value)); m_settings.m_loPpmCorrection = value; + sendSettings(); } void RTLSDRGui::on_gain_valueChanged(int value) { - if(value > (int)m_gains.size()) + if (value > (int)m_gains.size()) + { return; + } + int gain = m_gains[value]; ui->gainText->setText(tr("%1.%2").arg(gain / 10).arg(abs(gain % 10))); m_settings.m_gain = gain; + sendSettings(); } @@ -174,34 +183,39 @@ void RTLSDRGui::on_samplerate_valueChanged(int value) { int newrate = RTLSDRSampleRates::getRate(value); ui->samplerateText->setText(tr("%1k").arg(newrate)); - m_settings.m_samplerate = newrate * 1000; + m_settings.m_devSampleRate = newrate * 1000; + sendSettings(); } void RTLSDRGui::updateHardware() { - RTLSDRInput::MsgConfigureRTLSDR* message = RTLSDRInput::MsgConfigureRTLSDR::create(m_generalSettings, m_settings); - message->submit(m_pluginAPI->getDSPEngineMessageQueue()); + RTLSDRInput::MsgConfigureRTLSDR* message = RTLSDRInput::MsgConfigureRTLSDR::create(m_settings); + m_sampleSource->getInputMessageQueue()->push(message); m_updateTimer.stop(); } -void RTLSDRGui::on_checkBox_stateChanged(int state) { - if (state == Qt::Checked){ +void RTLSDRGui::on_checkBox_stateChanged(int state) +{ + if (state == Qt::Checked) + { // Direct Modes: 0: off, 1: I, 2: Q, 3: NoMod. ((RTLSDRInput*)m_sampleSource)->set_ds_mode(3); ui->gain->setEnabled(false); ui->centerFrequency->setValueRange(7, 1000U, 275000U); ui->centerFrequency->setValue(7000); - m_generalSettings.m_centerFrequency = 7000 * 1000; + m_settings.m_centerFrequency = 7000 * 1000; } - else { + else + { ((RTLSDRInput*)m_sampleSource)->set_ds_mode(0); ui->gain->setEnabled(true); ui->centerFrequency->setValueRange(7, 28500U, 1700000U); ui->centerFrequency->setValue(434000); ui->gain->setValue(0); - m_generalSettings.m_centerFrequency = 434000 * 1000; + m_settings.m_centerFrequency = 435000 * 1000; } + sendSettings(); } diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.h b/plugins/samplesource/rtlsdr/rtlsdrgui.h index 65fd1a8a9..03a3cc3cb 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrgui.h +++ b/plugins/samplesource/rtlsdr/rtlsdrgui.h @@ -17,25 +17,22 @@ class RTLSDRGui : public QWidget, public PluginGUI { public: explicit RTLSDRGui(PluginAPI* pluginAPI, QWidget* parent = NULL); - ~RTLSDRGui(); + virtual ~RTLSDRGui(); void destroy(); void setName(const QString& name); QString getName() const; void resetToDefaults(); - QByteArray serializeGeneral() const; - bool deserializeGeneral(const QByteArray&data); qint64 getCenterFrequency() const; QByteArray serialize() const; bool deserialize(const QByteArray& data); - bool handleMessage(Message* message); + virtual bool handleMessage(const Message& message); private: Ui::RTLSDRGui* ui; PluginAPI* m_pluginAPI; - SampleSource::GeneralSettings m_generalSettings; RTLSDRInput::Settings m_settings; QTimer m_updateTimer; std::vector m_gains; diff --git a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp index 9d7f0d6bb..c1c23bbed 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp @@ -26,8 +26,9 @@ MESSAGE_CLASS_DEFINITION(RTLSDRInput::MsgConfigureRTLSDR, Message) MESSAGE_CLASS_DEFINITION(RTLSDRInput::MsgReportRTLSDR, Message) RTLSDRInput::Settings::Settings() : + m_devSampleRate(1024*1000), + m_centerFrequency(435000*1000), m_gain(0), - m_samplerate(1024000), m_loPpmCorrection(0), m_log2Decim(4) { @@ -35,8 +36,9 @@ RTLSDRInput::Settings::Settings() : void RTLSDRInput::Settings::resetToDefaults() { + m_devSampleRate = 1024*1000; + m_centerFrequency = 435000*1000; m_gain = 0; - m_samplerate = 1024000; m_loPpmCorrection = 0; m_log2Decim = 4; } @@ -44,10 +46,11 @@ void RTLSDRInput::Settings::resetToDefaults() QByteArray RTLSDRInput::Settings::serialize() const { SimpleSerializer s(1); - s.writeS32(1, m_gain); - s.writeS32(2, m_samplerate); - s.writeS32(3, m_loPpmCorrection); - s.writeU32(4, m_log2Decim); + s.writeS32(1, m_devSampleRate); + s.writeU64(2, m_centerFrequency); + s.writeS32(3, m_gain); + s.writeS32(4, m_loPpmCorrection); + s.writeU32(5, m_log2Decim); return s.final(); } @@ -55,43 +58,49 @@ bool RTLSDRInput::Settings::deserialize(const QByteArray& data) { SimpleDeserializer d(data); - if(!d.isValid()) { + if (!d.isValid()) + { resetToDefaults(); return false; } - if(d.getVersion() == 1) { - d.readS32(1, &m_gain, 0); - d.readS32(2, &m_samplerate, 0); - d.readS32(3, &m_loPpmCorrection, 0); - d.readU32(4, &m_log2Decim, 4); + if(d.getVersion() == 1) + { + d.readS32(1, &m_devSampleRate, 1024*1000); + d.readU64(2, &m_centerFrequency, 435000*1000); + d.readS32(3, &m_gain, 0); + d.readS32(4, &m_loPpmCorrection, 0); + d.readU32(5, &m_log2Decim, 4); return true; - } else { + } + else + { resetToDefaults(); return false; } } -RTLSDRInput::RTLSDRInput(MessageQueue* msgQueueToGUI) : - SampleSource(msgQueueToGUI), +RTLSDRInput::RTLSDRInput() : m_settings(), - m_dev(NULL), - m_rtlSDRThread(NULL), + m_dev(0), + m_rtlSDRThread(0), m_deviceDescription() { } RTLSDRInput::~RTLSDRInput() { - stopInput(); + stop(); } -bool RTLSDRInput::startInput(int device) +bool RTLSDRInput::start(int device) { QMutexLocker mutexLocker(&m_mutex); - if(m_dev != NULL) - stopInput(); + if (m_dev != 0) + { + stop(); + } char vendor[256]; char product[256]; @@ -99,12 +108,14 @@ bool RTLSDRInput::startInput(int device) int res; int numberOfGains; - if(!m_sampleFifo.setSize(96000 * 4)) { + if (!m_sampleFifo.setSize(96000 * 4)) + { qCritical("Could not allocate SampleFifo"); return false; } - if((res = rtlsdr_open(&m_dev, device)) < 0) { + if ((res = rtlsdr_open(&m_dev, device)) < 0) + { qCritical("could not open RTLSDR #%d: %s", device, strerror(errno)); return false; } @@ -112,74 +123,101 @@ bool RTLSDRInput::startInput(int device) vendor[0] = '\0'; product[0] = '\0'; serial[0] = '\0'; - if((res = rtlsdr_get_usb_strings(m_dev, vendor, product, serial)) < 0) { + + if ((res = rtlsdr_get_usb_strings(m_dev, vendor, product, serial)) < 0) + { qCritical("error accessing USB device"); - goto failed; + stop(); + return false; } + qWarning("RTLSDRInput open: %s %s, SN: %s", vendor, product, serial); m_deviceDescription = QString("%1 (SN %2)").arg(product).arg(serial); - if((res = rtlsdr_set_sample_rate(m_dev, 1024000)) < 0) { + if ((res = rtlsdr_set_sample_rate(m_dev, 1024000)) < 0) + { qCritical("could not set sample rate: 1024k S/s"); - goto failed; + stop(); + return false; } - if((res = rtlsdr_set_tuner_gain_mode(m_dev, 1)) < 0) { + if ((res = rtlsdr_set_tuner_gain_mode(m_dev, 1)) < 0) + { qCritical("error setting tuner gain mode"); - goto failed; + stop(); + return false; } - if((res = rtlsdr_set_agc_mode(m_dev, 0)) < 0) { + + if ((res = rtlsdr_set_agc_mode(m_dev, 0)) < 0) + { qCritical("error setting agc mode"); - goto failed; + stop(); + return false; } numberOfGains = rtlsdr_get_tuner_gains(m_dev, NULL); - if(numberOfGains < 0) { + + if (numberOfGains < 0) + { qCritical("error getting number of gain values supported"); - goto failed; - } - m_gains.resize(numberOfGains); - if(rtlsdr_get_tuner_gains(m_dev, &m_gains[0]) < 0) { - qCritical("error getting gain values"); - goto failed; - } - if((res = rtlsdr_reset_buffer(m_dev)) < 0) { - qCritical("could not reset USB EP buffers: %s", strerror(errno)); - goto failed; + stop(); + return false; } - if((m_rtlSDRThread = new RTLSDRThread(m_dev, &m_sampleFifo)) == NULL) { - qFatal("out of memory"); - goto failed; + m_gains.resize(numberOfGains); + + if (rtlsdr_get_tuner_gains(m_dev, &m_gains[0]) < 0) + { + qCritical("error getting gain values"); + stop(); + return false; } + + if ((res = rtlsdr_reset_buffer(m_dev)) < 0) + { + qCritical("could not reset USB EP buffers: %s", strerror(errno)); + stop(); + return false; + } + + if ((m_rtlSDRThread = new RTLSDRThread(m_dev, &m_sampleFifo)) == NULL) + { + qFatal("out of memory"); + stop(); + return false; + } + m_rtlSDRThread->startWork(); mutexLocker.unlock(); - applySettings(m_generalSettings, m_settings, true); - qDebug("RTLSDRInput: start"); - MsgReportRTLSDR::create(m_gains)->submit(m_guiMessageQueue); + applySettings(m_settings, true); + + qDebug("RTLSDRInput::start"); + + MsgReportRTLSDR *message = MsgReportRTLSDR::create(m_gains); + getOutputMessageQueue()->push(message); return true; - -failed: - stopInput(); - return false; } -void RTLSDRInput::stopInput() +void RTLSDRInput::stop() { QMutexLocker mutexLocker(&m_mutex); - if(m_rtlSDRThread != NULL) { + if (m_rtlSDRThread != 0) + { m_rtlSDRThread->stopWork(); delete m_rtlSDRThread; - m_rtlSDRThread = NULL; + m_rtlSDRThread = 0; } - if(m_dev != NULL) { + + if (m_dev != 0) + { rtlsdr_close(m_dev); - m_dev = NULL; + m_dev = 0; } + m_deviceDescription.clear(); } @@ -190,88 +228,110 @@ const QString& RTLSDRInput::getDeviceDescription() const int RTLSDRInput::getSampleRate() const { - int rate = m_settings.m_samplerate; + int rate = m_settings.m_devSampleRate; return (rate / (1<getGeneralSettings(), conf->getSettings(), false)) + if (MsgConfigureRTLSDR::match(message)) + { + MsgConfigureRTLSDR& conf = (MsgConfigureRTLSDR&) message; + + if (!applySettings(conf.getSettings(), false)) + { qDebug("RTLSDR config error"); - message->completed(); + } + return true; - } else { + } + else + { return false; } } -bool RTLSDRInput::applySettings(const GeneralSettings& generalSettings, const Settings& settings, bool force) +bool RTLSDRInput::applySettings(const Settings& settings, bool force) { QMutexLocker mutexLocker(&m_mutex); - if((m_settings.m_gain != settings.m_gain) || force) { + if ((m_settings.m_gain != settings.m_gain) || force) + { m_settings.m_gain = settings.m_gain; - if(m_dev != NULL) { + + if(m_dev != 0) + { if(rtlsdr_set_tuner_gain(m_dev, m_settings.m_gain) != 0) + { qDebug("rtlsdr_set_tuner_gain() failed"); - } - } - - if((m_settings.m_samplerate != settings.m_samplerate) || force) { - if(m_dev != NULL) { - if( rtlsdr_set_sample_rate(m_dev, settings.m_samplerate) < 0) - qCritical("could not set sample rate: %d", settings.m_samplerate); - else { - m_settings.m_samplerate = settings.m_samplerate; - m_rtlSDRThread->setSamplerate(settings.m_samplerate); } } } - if((m_settings.m_loPpmCorrection != settings.m_loPpmCorrection) || force) { - if(m_dev != NULL) { - if( rtlsdr_set_freq_correction(m_dev, settings.m_loPpmCorrection) < 0) + if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force) + { + if(m_dev != 0) + { + if( rtlsdr_set_sample_rate(m_dev, settings.m_devSampleRate) < 0) + { + qCritical("could not set sample rate: %d", settings.m_devSampleRate); + } + else + { + m_settings.m_devSampleRate = settings.m_devSampleRate; + m_rtlSDRThread->setSamplerate(settings.m_devSampleRate); + } + } + } + + if ((m_settings.m_loPpmCorrection != settings.m_loPpmCorrection) || force) + { + if (m_dev != 0) + { + if (rtlsdr_set_freq_correction(m_dev, settings.m_loPpmCorrection) < 0) + { qCritical("could not set LO ppm correction: %d", settings.m_loPpmCorrection); - else { + } + else + { m_settings.m_loPpmCorrection = settings.m_loPpmCorrection; - //m_rtlSDRThread->setSamplerate(settings.m_samplerate); } } } - if((m_settings.m_log2Decim != settings.m_log2Decim) || force) { - if(m_dev != NULL) { + if ((m_settings.m_log2Decim != settings.m_log2Decim) || force) + { + if(m_dev != 0) + { m_settings.m_log2Decim = settings.m_log2Decim; m_rtlSDRThread->setLog2Decimation(settings.m_log2Decim); } } - m_generalSettings.m_centerFrequency = generalSettings.m_centerFrequency; - if(m_dev != NULL) { - qint64 centerFrequency = m_generalSettings.m_centerFrequency + (m_settings.m_samplerate / 4); + m_settings.m_centerFrequency = settings.m_centerFrequency; - if (m_settings.m_log2Decim == 0) { // Little wooby-doop if no decimation - centerFrequency = m_generalSettings.m_centerFrequency; - } else { - centerFrequency = m_generalSettings.m_centerFrequency + (m_settings.m_samplerate / 4); + if(m_dev != 0) + { + qint64 centerFrequency = m_settings.m_centerFrequency + (m_settings.m_devSampleRate / 4); + + if (m_settings.m_log2Decim == 0) + { // Little wooby-doop if no decimation + centerFrequency = m_settings.m_centerFrequency; + } + else + { + centerFrequency = m_settings.m_centerFrequency + (m_settings.m_devSampleRate / 4); } - if(rtlsdr_set_center_freq( m_dev, centerFrequency ) != 0) - qDebug("osmosdr_set_center_freq(%lld) failed", m_generalSettings.m_centerFrequency); + if (rtlsdr_set_center_freq( m_dev, centerFrequency ) != 0) + { + qDebug("rtlsdr_set_center_freq(%lld) failed", m_settings.m_centerFrequency); + } } return true; diff --git a/plugins/samplesource/rtlsdr/rtlsdrinput.h b/plugins/samplesource/rtlsdr/rtlsdrinput.h index 1e5d84619..3e173ceb8 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrinput.h +++ b/plugins/samplesource/rtlsdr/rtlsdrinput.h @@ -27,8 +27,9 @@ class RTLSDRThread; class RTLSDRInput : public SampleSource { public: struct Settings { + int m_devSampleRate; + quint64 m_centerFrequency; qint32 m_gain; - qint32 m_samplerate; qint32 m_loPpmCorrection; quint32 m_log2Decim; @@ -42,21 +43,18 @@ public: MESSAGE_CLASS_DECLARATION public: - const GeneralSettings& getGeneralSettings() const { return m_generalSettings; } const Settings& getSettings() const { return m_settings; } - static MsgConfigureRTLSDR* create(const GeneralSettings& generalSettings, const Settings& settings) + static MsgConfigureRTLSDR* create(const Settings& settings) { - return new MsgConfigureRTLSDR(generalSettings, settings); + return new MsgConfigureRTLSDR(settings); } private: - GeneralSettings m_generalSettings; Settings m_settings; - MsgConfigureRTLSDR(const GeneralSettings& generalSettings, const Settings& settings) : + MsgConfigureRTLSDR(const Settings& settings) : Message(), - m_generalSettings(generalSettings), m_settings(settings) { } }; @@ -81,18 +79,18 @@ public: { } }; - RTLSDRInput(MessageQueue* msgQueueToGUI); - ~RTLSDRInput(); + RTLSDRInput(); + virtual ~RTLSDRInput(); - bool startInput(int device); - void stopInput(); + virtual bool init(const Message& message); + virtual bool start(int device); + virtual void stop(); - const QString& getDeviceDescription() const; - int getSampleRate() const; - quint64 getCenterFrequency() const; - - bool handleMessage(Message* message); + virtual const QString& getDeviceDescription() const; + virtual int getSampleRate() const; + virtual quint64 getCenterFrequency() const; + virtual bool handleMessage(const Message& message); void set_ds_mode(int on); @@ -104,7 +102,7 @@ private: QString m_deviceDescription; std::vector m_gains; - bool applySettings(const GeneralSettings& generalSettings, const Settings& settings, bool force); + bool applySettings(const Settings& settings, bool force); }; #endif // INCLUDE_RTLSDRINPUT_H diff --git a/sdrbase/dsp/channelizer.cpp b/sdrbase/dsp/channelizer.cpp index 25770f2cb..68fb87ce9 100644 --- a/sdrbase/dsp/channelizer.cpp +++ b/sdrbase/dsp/channelizer.cpp @@ -20,22 +20,6 @@ Channelizer::~Channelizer() freeFilterChain(); } -bool Channelizer::init(const Message& cmd) -{ - if (DSPSignalNotification::match(&cmd)) - { - DSPSignalNotification* notif = (DSPSignalNotification*) &cmd; - m_inputSampleRate = notif->getSampleRate(); - qDebug() << "FileSink::init: DSPSignalNotification: m_inputSampleRate: " << m_inputSampleRate; - emit inputSampleRateChanged(); - return true; - } - else - { - return false; - } -} - void Channelizer::configure(MessageQueue* messageQueue, int sampleRate, int centerFrequency) { Message* cmd = new DSPConfigureChannelizer(sampleRate, centerFrequency); @@ -84,31 +68,27 @@ bool Channelizer::handleMessage(const Message& cmd) { qDebug() << "Channelizer::handleMessage: " << cmd.getIdentifier(); - /* - if (DSPSignalNotification::match(&cmd)) + if (DSPSignalNotification::match(cmd)) { - DSPSignalNotification* notif = (DSPSignalNotification*) &cmd; - m_inputSampleRate = notif->getSampleRate(); + DSPSignalNotification& notif = (DSPSignalNotification&) cmd; + m_inputSampleRate = notif.getSampleRate(); qDebug() << "Channelizer::handleMessage: DSPSignalNotification: m_inputSampleRate: " << m_inputSampleRate; applyConfiguration(); - delete cmd; - if (m_sampleSink != NULL) { - DSPSignalNotification notif(m_currentOutputSampleRate, m_currentCenterFrequency); - m_sampleSink->handleMessage(notif)) + m_sampleSink->handleMessage(notif); } emit inputSampleRateChanged(); return true; } - else*/ - if (DSPConfigureChannelizer::match(&cmd)) + else + if (DSPConfigureChannelizer::match(cmd)) { - DSPConfigureChannelizer* chan = (DSPConfigureChannelizer*) &cmd; - m_requestedOutputSampleRate = chan->getSampleRate(); - m_requestedCenterFrequency = chan->getCenterFrequency(); + DSPConfigureChannelizer& chan = (DSPConfigureChannelizer&) cmd; + m_requestedOutputSampleRate = chan.getSampleRate(); + m_requestedCenterFrequency = chan.getCenterFrequency(); qDebug() << "Channelizer::handleMessage: DSPConfigureChannelizer:" << " m_requestedOutputSampleRate: " << m_requestedOutputSampleRate diff --git a/sdrbase/dsp/dspcommands.cpp b/sdrbase/dsp/dspcommands.cpp index 41d6ecf27..364a04e13 100644 --- a/sdrbase/dsp/dspcommands.cpp +++ b/sdrbase/dsp/dspcommands.cpp @@ -27,6 +27,8 @@ MESSAGE_CLASS_DEFINITION(DSPGetErrorMessage, Message) MESSAGE_CLASS_DEFINITION(DSPSetSource, Message) MESSAGE_CLASS_DEFINITION(DSPAddSink, Message) MESSAGE_CLASS_DEFINITION(DSPRemoveSink, Message) +MESSAGE_CLASS_DEFINITION(DSPAddThreadedSink, Message) +MESSAGE_CLASS_DEFINITION(DSPRemoveThreadedSink, Message) MESSAGE_CLASS_DEFINITION(DSPAddAudioSink, Message) MESSAGE_CLASS_DEFINITION(DSPRemoveAudioSink, Message) MESSAGE_CLASS_DEFINITION(DSPConfigureSpectrumVis, Message) diff --git a/sdrbase/dsp/dspengine.cpp b/sdrbase/dsp/dspengine.cpp index 0c57f9c5f..dee850619 100644 --- a/sdrbase/dsp/dspengine.cpp +++ b/sdrbase/dsp/dspengine.cpp @@ -21,13 +21,14 @@ #include "dsp/channelizer.h" #include "dsp/samplefifo.h" #include "dsp/samplesink.h" +#include "dsp/threadedsamplesink.h" #include "dsp/dspcommands.h" #include "dsp/samplesource/samplesource.h" DSPEngine::DSPEngine(QObject* parent) : QThread(parent), m_state(StNotStarted), - m_sampleSource(NULL), + m_sampleSource(0), m_sampleSinks(), m_sampleRate(0), m_centerFrequency(0), @@ -71,34 +72,34 @@ void DSPEngine::start() qDebug() << "DSPEngine::start"; DSPPing cmd; QThread::start(); - m_syncMessenger.sendWait(&cmd); + m_syncMessenger.sendWait(cmd); } void DSPEngine::stop() { qDebug() << "DSPEngine::stop"; DSPExit cmd; - m_syncMessenger.sendWait(&cmd); + m_syncMessenger.sendWait(cmd); } bool DSPEngine::initAcquisition() { DSPAcquisitionInit cmd; - return m_syncMessenger.sendWait(&cmd) == StReady; + return m_syncMessenger.sendWait(cmd) == StReady; } bool DSPEngine::startAcquisition() { DSPAcquisitionStart cmd; - return m_syncMessenger.sendWait(&cmd) == StRunning; + return m_syncMessenger.sendWait(cmd) == StRunning; } void DSPEngine::stopAcquistion() { DSPAcquisitionStop cmd; - m_syncMessenger.sendWait(&cmd); + m_syncMessenger.sendWait(cmd); if(m_dcOffsetCorrection) { @@ -109,32 +110,45 @@ void DSPEngine::stopAcquistion() void DSPEngine::setSource(SampleSource* source) { DSPSetSource cmd(source); - m_syncMessenger.sendWait(&cmd); + m_syncMessenger.sendWait(cmd); } void DSPEngine::addSink(SampleSink* sink) { qDebug() << "DSPEngine::addSink: " << sink->objectName().toStdString().c_str(); DSPAddSink cmd(sink); - m_syncMessenger.sendWait(&cmd); + m_syncMessenger.sendWait(cmd); } void DSPEngine::removeSink(SampleSink* sink) { DSPRemoveSink cmd(sink); - m_syncMessenger.sendWait(&cmd); + m_syncMessenger.sendWait(cmd); +} + +void DSPEngine::addThreadedSink(SampleSink* sink) +{ + qDebug() << "DSPEngine::addThreadedSink: " << sink->objectName().toStdString().c_str(); + DSPAddThreadedSink cmd(sink); + m_syncMessenger.sendWait(cmd); +} + +void DSPEngine::removeThreadedSink(SampleSink* sink) +{ + DSPRemoveThreadedSink cmd(sink); + m_syncMessenger.sendWait(cmd); } void DSPEngine::addAudioSink(AudioFifo* audioFifo) { DSPAddAudioSink cmd(audioFifo); - m_syncMessenger.sendWait(&cmd); + m_syncMessenger.sendWait(cmd); } void DSPEngine::removeAudioSink(AudioFifo* audioFifo) { DSPRemoveAudioSink cmd(audioFifo); - m_syncMessenger.sendWait(&cmd); + m_syncMessenger.sendWait(cmd); } void DSPEngine::configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection) @@ -146,14 +160,14 @@ void DSPEngine::configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCo QString DSPEngine::errorMessage() { DSPGetErrorMessage cmd; - m_syncMessenger.sendWait(&cmd); + m_syncMessenger.sendWait(cmd); return cmd.getErrorMessage(); } QString DSPEngine::sourceDeviceDescription() { DSPGetSourceDeviceDescription cmd; - m_syncMessenger.sendWait(&cmd); + m_syncMessenger.sendWait(cmd); return cmd.getDeviceDescription(); } @@ -360,11 +374,18 @@ DSPEngine::State DSPEngine::gotoInit() << " sampleRate: " << m_sampleRate << " centerFrequency: " << m_centerFrequency; - for(SampleSinks::const_iterator it = m_sampleSinks.begin(); it != m_sampleSinks.end(); it++) + DSPSignalNotification notif(m_sampleRate, m_centerFrequency); + + for (SampleSinks::const_iterator it = m_sampleSinks.begin(); it != m_sampleSinks.end(); ++it) { qDebug() << " - initializing " << (*it)->objectName().toStdString().c_str(); - DSPSignalNotification notif(m_sampleRate, m_centerFrequency); - (*it)->init(notif); + (*it)->handleMessage(notif); + } + + for (ThreadedSampleSinks::const_iterator it = m_threadedSampleSinks.begin(); it != m_threadedSampleSinks.end(); ++it) + { + qDebug() << " - initializing ThreadedSampleSink(" << (*it)->getSampleSinkObjectName().toStdString().c_str() << ")"; + (*it)->sendWaitSink(notif); } // pass sample rate to main window @@ -416,6 +437,12 @@ DSPEngine::State DSPEngine::gotoRunning() (*it)->start(); } + for (ThreadedSampleSinks::const_iterator it = m_threadedSampleSinks.begin(); it != m_threadedSampleSinks.end(); ++it) + { + qDebug() << " - starting ThreadedSampleSink(" << (*it)->getSampleSinkObjectName().toStdString().c_str() << ")"; + (*it)->start(); + } + qDebug() << " - input message queue pending: " << m_inputMessageQueue.size(); return StRunning; @@ -459,7 +486,7 @@ void DSPEngine::handleData() } } -void DSPEngine::handleSynchronousMessages(Message *message) +void DSPEngine::handleSynchronousMessages(const Message& message) { if (DSPExit::match(message)) { @@ -493,27 +520,27 @@ void DSPEngine::handleSynchronousMessages(Message *message) } else if (DSPGetSourceDeviceDescription::match(message)) { - ((DSPGetSourceDeviceDescription*)message)->setDeviceDescription(m_deviceDescription); + ((DSPGetSourceDeviceDescription&) message).setDeviceDescription(m_deviceDescription); m_syncMessenger.done(m_state); } else if (DSPGetErrorMessage::match(message)) { - ((DSPGetErrorMessage*)message)->setErrorMessage(m_errorMessage); + ((DSPGetErrorMessage&) message).setErrorMessage(m_errorMessage); m_syncMessenger.done(m_state); } else if (DSPSetSource::match(message)) { - handleSetSource(((DSPSetSource*)message)->getSampleSource()); + handleSetSource(((DSPSetSource&) message).getSampleSource()); m_syncMessenger.done(m_state); } else if (DSPAddSink::match(message)) { - SampleSink* sink = ((DSPAddSink*)message)->getSampleSink(); + SampleSink* sink = ((DSPAddSink&)message).getSampleSink(); m_sampleSinks.push_back(sink); m_syncMessenger.done(m_state); } else if (DSPRemoveSink::match(message)) { - SampleSink* sink = ((DSPRemoveSink*)message)->getSampleSink(); + SampleSink* sink = ((DSPRemoveSink&)message).getSampleSink(); if(m_state == StRunning) { sink->stop(); @@ -522,14 +549,46 @@ void DSPEngine::handleSynchronousMessages(Message *message) m_sampleSinks.remove(sink); m_syncMessenger.done(m_state); } + else if (DSPAddThreadedSink::match(message)) + { + SampleSink* sink = ((DSPAddThreadedSink&) message).getSampleSink(); + ThreadedSampleSink *threadedSink = new ThreadedSampleSink(sink); + m_threadedSampleSinks.push_back(threadedSink); + threadedSink->start(); + m_syncMessenger.done(m_state); + } + else if (DSPRemoveThreadedSink::match(message)) + { + SampleSink* sink = ((DSPRemoveThreadedSink&) message).getSampleSink(); + ThreadedSampleSinks::iterator threadedSinkIt = m_threadedSampleSinks.begin(); + + for (; threadedSinkIt != m_threadedSampleSinks.end(); ++threadedSinkIt) + { + if ((*threadedSinkIt)->getSink() == sink) + { + break; + } + } + + if (threadedSinkIt != m_threadedSampleSinks.end()) + { + if (m_state == StRunning) + { + (*threadedSinkIt)->stop(); + } + + m_threadedSampleSinks.remove(*threadedSinkIt); + delete (*threadedSinkIt); + } + } else if (DSPAddAudioSink::match(message)) { - m_audioSink.addFifo(((DSPAddAudioSink*)message)->getAudioFifo()); + m_audioSink.addFifo(((DSPAddAudioSink&) message).getAudioFifo()); m_syncMessenger.done(m_state); } else if (DSPRemoveAudioSink::match(message)) { - m_audioSink.removeFifo(((DSPRemoveAudioSink*)message)->getAudioFifo()); + m_audioSink.removeFifo(((DSPRemoveAudioSink&) message).getAudioFifo()); m_syncMessenger.done(m_state); } @@ -544,9 +603,9 @@ void DSPEngine::handleInputMessages() { qDebug("DSPEngine::handleInputMessages: Message: %s", message->getIdentifier()); - if (DSPConfigureCorrection::match(message)) + if (DSPConfigureCorrection::match(*message)) { - DSPConfigureCorrection* conf = (DSPConfigureCorrection*)message; + DSPConfigureCorrection* conf = (DSPConfigureCorrection*) message; m_iqImbalanceCorrection = conf->getIQImbalanceCorrection(); if(m_dcOffsetCorrection != conf->getDCOffsetCorrection()) @@ -577,21 +636,29 @@ void DSPEngine::handleSourceMessages() while ((message = m_sampleSource->getOutputMessageQueue()->pop()) != 0) { - if (DSPSignalNotification::match(message)) + if (DSPSignalNotification::match(*message)) { - DSPSignalNotification *notif = (DSPSignalNotification *) &message; + DSPSignalNotification *notif = (DSPSignalNotification *) message; // update DSP values m_sampleRate = notif->getSampleRate(); m_centerFrequency = notif->getFrequencyOffset(); + qDebug() << " - DSPSignalNotification(" << m_sampleRate << "," << m_centerFrequency << ")"; + // forward source changes to sinks for(SampleSinks::const_iterator it = m_sampleSinks.begin(); it != m_sampleSinks.end(); it++) { - qDebug() << " - initializing " << (*it)->objectName().toStdString().c_str(); - (*it)->init(*message); + qDebug() << " - forward message to " << (*it)->objectName().toStdString().c_str(); + (*it)->handleMessage(*message); + } + + for (ThreadedSampleSinks::const_iterator it = m_threadedSampleSinks.begin(); it != m_threadedSampleSinks.end(); ++it) + { + qDebug() << " - forward message to ThreadedSampleSink(" << (*it)->getSampleSinkObjectName().toStdString().c_str() << ")"; + (*it)->sendWaitSink(*message); } // forward changes to listeners diff --git a/sdrbase/dsp/filesink.cpp b/sdrbase/dsp/filesink.cpp index f917463af..4223d2819 100644 --- a/sdrbase/dsp/filesink.cpp +++ b/sdrbase/dsp/filesink.cpp @@ -30,22 +30,6 @@ void FileSink::configure(MessageQueue* msgQueue, const std::string& filename) msgQueue->push(cmd); } -bool FileSink::init(const Message& cmd) -{ - if (DSPSignalNotification::match(&cmd)) - { - DSPSignalNotification* notif = (DSPSignalNotification*) &cmd; - m_sampleRate = notif->getSampleRate(); - m_centerFrequency = notif->getFrequencyOffset(); - qDebug() << "FileSink::init: DSPSignalNotification: m_inputSampleRate: " << m_sampleRate; - return true; - } - else - { - return false; - } -} - void FileSink::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly) { // if no recording is active, send the samples to /dev/null @@ -99,12 +83,22 @@ void FileSink::stopRecording() bool FileSink::handleMessage(const Message& message) { - if (MsgConfigureFileSink::match(&message)) + qDebug() << "FileSink::handleMessage"; + + if (DSPSignalNotification::match(message)) + { + DSPSignalNotification& notif = (DSPSignalNotification&) message; + m_sampleRate = notif.getSampleRate(); + m_centerFrequency = notif.getFrequencyOffset(); + qDebug() << " - DSPSignalNotification: m_inputSampleRate: " << m_sampleRate + << " m_centerFrequency: " << m_centerFrequency; + return true; + } + else if (MsgConfigureFileSink::match(message)) { - MsgConfigureFileSink* conf = (MsgConfigureFileSink*) &message; - handleConfigure(conf->getFileName()); - qDebug() << "FileSink::handleMessage:" - << " fileName: " << m_fileName.c_str(); + MsgConfigureFileSink& conf = (MsgConfigureFileSink&) message; + handleConfigure(conf.getFileName()); + qDebug() << " - MsgConfigureFileSink: fileName: " << m_fileName.c_str(); return true; } else diff --git a/sdrbase/dsp/samplesink.cpp b/sdrbase/dsp/samplesink.cpp index 0db0c283b..87a0bd64c 100644 --- a/sdrbase/dsp/samplesink.cpp +++ b/sdrbase/dsp/samplesink.cpp @@ -1,9 +1,25 @@ #include "dsp/samplesink.h" +#include "util/message.h" SampleSink::SampleSink() { + connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessage())); } SampleSink::~SampleSink() { } + +void SampleSink::handleInputMessages() +{ + Message* message; + + while ((message = m_inputMessageQueue.pop()) != 0) + { + if (handleMessage(*message)) + { + delete message; + } + } +} + diff --git a/sdrbase/dsp/samplesource/samplesource.cpp b/sdrbase/dsp/samplesource/samplesource.cpp index ac91bf4db..4c820171e 100644 --- a/sdrbase/dsp/samplesource/samplesource.cpp +++ b/sdrbase/dsp/samplesource/samplesource.cpp @@ -16,41 +16,11 @@ /////////////////////////////////////////////////////////////////////////////////// #include "dsp/samplesource/samplesource.h" -#include "dsp/dspcommands.h" -#include - -SampleSource::SampleSource() : - m_sampleRate(0), - m_centerFrequency(0) +SampleSource::SampleSource() { } SampleSource::~SampleSource() { } - -void SampleSource::setSampleRate(int sampleRate) -{ - if (sampleRate != m_sampleRate) - { - // TODO: adjust FIFO size - m_sampleRate = sampleRate; - sendNewData(); - } -} - -void SampleSource::setCenterFrequency(quint64 centerFrequency) -{ - if (centerFrequency != m_centerFrequency) - { - m_centerFrequency = centerFrequency; - sendNewData(); - } -} - -void SampleSource::sendNewData() -{ - DSPSignalNotification *notif = new DSPSignalNotification(m_sampleRate, m_centerFrequency); - m_outputMessageQueue.push(notif); -} diff --git a/sdrbase/dsp/scopevis.cpp b/sdrbase/dsp/scopevis.cpp index 9ce1c6c61..f8323a23a 100644 --- a/sdrbase/dsp/scopevis.cpp +++ b/sdrbase/dsp/scopevis.cpp @@ -55,20 +55,6 @@ void ScopeVis::configure(MessageQueue* msgQueue, msgQueue->push(cmd); } -bool ScopeVis::init(const Message& cmd) -{ - if (DSPSignalNotification::match(&cmd)) - { - DSPSignalNotification* signal = (DSPSignalNotification*) &cmd; - m_sampleRate = signal->getSampleRate(); - return true; - } - else - { - return false; - } -} - void ScopeVis::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly) { if (m_triggerChannel == TriggerFreeRun) { @@ -220,28 +206,47 @@ void ScopeVis::stop() bool ScopeVis::handleMessage(const Message& message) { - if (MsgConfigureScopeVis::match(&message)) + qDebug() << "ScopeVis::handleMessage"; + + if (DSPSignalNotification::match(message)) { - MsgConfigureScopeVis* conf = (MsgConfigureScopeVis*) &message; - m_tracebackCount = 0; + DSPSignalNotification& notif = (DSPSignalNotification&) message; + m_sampleRate = notif.getSampleRate(); + qDebug() << " - DSPSignalNotification: m_sampleRate: " << m_sampleRate; + + return true; + } + else if (MsgConfigureScopeVis::match(message)) + { + MsgConfigureScopeVis& conf = (MsgConfigureScopeVis&) message; + + m_tracebackCount = 0; m_triggerState = Config; - m_triggerChannel = (TriggerChannel) conf->getTriggerChannel(); - m_triggerLevel = conf->getTriggerLevel(); - m_triggerPositiveEdge = conf->getTriggerPositiveEdge(); - m_triggerBothEdges = conf->getTriggerBothEdges(); - m_triggerPre = conf->getTriggerPre(); - if (m_triggerPre >= m_traceback.size()) { + m_triggerChannel = (TriggerChannel) conf.getTriggerChannel(); + m_triggerLevel = conf.getTriggerLevel(); + m_triggerPositiveEdge = conf.getTriggerPositiveEdge(); + m_triggerBothEdges = conf.getTriggerBothEdges(); + m_triggerPre = conf.getTriggerPre(); + + if (m_triggerPre >= m_traceback.size()) + { m_triggerPre = m_traceback.size() - 1; // top sample in FIFO is always the triggering one (pre-trigger delay = 0) } - m_triggerDelay = conf->getTriggerDelay(); - uint newSize = conf->getTraceSize(); - if (newSize != m_trace.size()) { + + m_triggerDelay = conf.getTriggerDelay(); + uint newSize = conf.getTraceSize(); + + if (newSize != m_trace.size()) + { m_trace.resize(newSize); } - if (newSize > m_traceback.size()) { // fitting the exact required space is not a requirement for the back trace + + if (newSize > m_traceback.size()) // fitting the exact required space is not a requirement for the back trace + { m_traceback.resize(newSize); } - qDebug() << "ScopeVis::handleMessage:" + + qDebug() << " - MsgConfigureScopeVis:" << " m_triggerChannel: " << m_triggerChannel << " m_triggerLevel: " << m_triggerLevel << " m_triggerPositiveEdge: " << (m_triggerPositiveEdge ? "edge+" : "edge-") @@ -249,6 +254,7 @@ bool ScopeVis::handleMessage(const Message& message) << " m_preTrigger: " << m_triggerPre << " m_triggerDelay: " << m_triggerDelay << " m_traceSize: " << m_trace.size(); + return true; } else diff --git a/sdrbase/dsp/spectrumscopecombovis.cpp b/sdrbase/dsp/spectrumscopecombovis.cpp index a5544cc8d..b75366b13 100644 --- a/sdrbase/dsp/spectrumscopecombovis.cpp +++ b/sdrbase/dsp/spectrumscopecombovis.cpp @@ -13,14 +13,6 @@ SpectrumScopeComboVis::~SpectrumScopeComboVis() { } -bool SpectrumScopeComboVis::init(const Message& cmd) -{ - bool spectDone = m_spectrumVis->init(cmd); - bool scopeDone = m_scopeVis->init(cmd); - - return (spectDone || scopeDone); -} - void SpectrumScopeComboVis::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly) { m_scopeVis->feed(begin, end, false); diff --git a/sdrbase/dsp/spectrumvis.cpp b/sdrbase/dsp/spectrumvis.cpp index 6959b657b..5f85f50b3 100644 --- a/sdrbase/dsp/spectrumvis.cpp +++ b/sdrbase/dsp/spectrumvis.cpp @@ -30,11 +30,6 @@ SpectrumVis::~SpectrumVis() delete m_fft; } -bool SpectrumVis::init(const Message& cmd) -{ - return false; -} - void SpectrumVis::configure(MessageQueue* msgQueue, int fftSize, int overlapPercent, FFTWindow::Function window) { DSPConfigureSpectrumVis* cmd = new DSPConfigureSpectrumVis(fftSize, overlapPercent, window); @@ -69,13 +64,13 @@ void SpectrumVis::feed(SampleVector::const_iterator begin, SampleVector::const_i return; while(begin < end) { - size_t todo = end - begin; - size_t samplesNeeded = m_refillSize - m_fftBufferFill; + std::size_t todo = end - begin; + std::size_t samplesNeeded = m_refillSize - m_fftBufferFill; if(todo >= samplesNeeded) { // fill up the buffer std::vector::iterator it = m_fftBuffer.begin() + m_fftBufferFill; - for(size_t i = 0; i < samplesNeeded; ++i, ++begin) + for(std::size_t i = 0; i < samplesNeeded; ++i, ++begin) *it++ = Complex(begin->real() / 32768.0, begin->imag() / 32768.0); // apply fft window (and copy from m_fftBuffer to m_fftIn) @@ -90,10 +85,10 @@ void SpectrumVis::feed(SampleVector::const_iterator begin, SampleVector::const_i const Complex* fftOut = m_fft->out(); Complex c; Real v; - size_t halfSize = m_fftSize / 2; + std::size_t halfSize = m_fftSize / 2; if ( positiveOnly ) { - for(size_t i = 0; i < halfSize; i++) { + for(std::size_t i = 0; i < halfSize; i++) { c = fftOut[i]; v = c.real() * c.real() + c.imag() * c.imag(); v = mult * log2f(v) + ofs; @@ -101,7 +96,7 @@ void SpectrumVis::feed(SampleVector::const_iterator begin, SampleVector::const_i m_logPowerSpectrum[i * 2 + 1] = v; } } else { - for(size_t i = 0; i < halfSize; i++) { + for(std::size_t i = 0; i < halfSize; i++) { c = fftOut[i + halfSize]; v = c.real() * c.real() + c.imag() * c.imag(); v = mult * log2f(v) + ofs; @@ -143,10 +138,10 @@ void SpectrumVis::stop() bool SpectrumVis::handleMessage(const Message& message) { - if(DSPConfigureSpectrumVis::match(&message)) + if (DSPConfigureSpectrumVis::match(message)) { - DSPConfigureSpectrumVis* conf = (DSPConfigureSpectrumVis*) &message; - handleConfigure(conf->getFFTSize(), conf->getOverlapPercent(), conf->getWindow()); + DSPConfigureSpectrumVis& conf = (DSPConfigureSpectrumVis&) message; + handleConfigure(conf.getFFTSize(), conf.getOverlapPercent(), conf.getWindow()); return true; } else diff --git a/sdrbase/dsp/threadedsamplesink.cpp b/sdrbase/dsp/threadedsamplesink.cpp index 11293a954..913726b12 100644 --- a/sdrbase/dsp/threadedsamplesink.cpp +++ b/sdrbase/dsp/threadedsamplesink.cpp @@ -4,59 +4,56 @@ #include "util/message.h" ThreadedSampleSink::ThreadedSampleSink(SampleSink* sampleSink) : - m_thread(new QThread), m_sampleSink(sampleSink) { - setObjectName("ThreadedSampleSink"); - moveToThread(m_thread); - connect(m_thread, SIGNAL(started()), this, SLOT(threadStarted())); - connect(m_thread, SIGNAL(finished()), this, SLOT(threadFinished())); - - m_messageQueue.moveToThread(m_thread); - connect(&m_messageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleMessages())); - - m_sampleFifo.moveToThread(m_thread); - connect(&m_sampleFifo, SIGNAL(dataReady()), this, SLOT(handleData())); - m_sampleFifo.setSize(262144); - - sampleSink->moveToThread(m_thread); + moveToThread(this); } ThreadedSampleSink::~ThreadedSampleSink() { - m_thread->exit(); - m_thread->wait(); - delete m_thread; -} - -void ThreadedSampleSink::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly) -{ - Q_UNUSED(positiveOnly); - m_sampleFifo.write(begin, end); + wait(); } void ThreadedSampleSink::start() { - m_thread->start(); + QThread::start(); } void ThreadedSampleSink::stop() { - m_thread->exit(); - m_thread->wait(); - m_sampleFifo.readCommit(m_sampleFifo.fill()); + exit(); + wait(); } -bool ThreadedSampleSink::handleMessage(Message* cmd) +void ThreadedSampleSink::run() { - qDebug() << "ThreadedSampleSink::handleMessage: " - << m_sampleSink->objectName().toStdString().c_str() - << ": " << cmd->getIdentifier(); - // called from other thread - m_messageQueue.submit(cmd); - return true; + connect(&m_syncMessenger, SIGNAL(messageSent(const Message&)), this, SLOT(handleSynchronousMessages(const Message&)), Qt::QueuedConnection); + exec(); } +void ThreadedSampleSink::feed(SampleVector::const_iterator& begin, SampleVector::const_iterator& end, bool positiveOnly) +{ + m_sampleSink->feed(begin, end, positiveOnly); +} + +bool ThreadedSampleSink::sendWaitSink(const Message& cmd) +{ + m_syncMessenger.sendWait(cmd); +} + +void ThreadedSampleSink::handleSynchronousMessages(const Message& message) +{ + m_sampleSink->handleMessage(message); // just delegate to the sink + m_syncMessenger.done(); +} + +QString ThreadedSampleSink::getSampleSinkObjectName() const +{ + return m_sampleSink->objectName(); +} + + +/* void ThreadedSampleSink::handleData() { bool positiveOnly = false; @@ -84,30 +81,5 @@ void ThreadedSampleSink::handleData() m_sampleFifo.readCommit(part2end - part2begin); } } -} +}*/ -void ThreadedSampleSink::handleMessages() -{ - Message* message; - while((message = m_messageQueue.accept()) != NULL) { - qDebug("ThreadedSampleSink::handleMessages: %s", message->getIdentifier()); - if(m_sampleSink != NULL) { - if(!m_sampleSink->handleMessage(message)) - message->completed(); - } else { - message->completed(); - } - } -} - -void ThreadedSampleSink::threadStarted() -{ - if(m_sampleSink != NULL) - m_sampleSink->start(); -} - -void ThreadedSampleSink::threadFinished() -{ - if(m_sampleSink != NULL) - m_sampleSink->stop(); -} diff --git a/sdrbase/mainwindow.cpp b/sdrbase/mainwindow.cpp index 53cc8c929..18341643b 100644 --- a/sdrbase/mainwindow.cpp +++ b/sdrbase/mainwindow.cpp @@ -325,9 +325,9 @@ void MainWindow::handleDSPMessages() std::cerr << "MainWindow::handleDSPMessages: " << message->getIdentifier() << std::endl; - if (DSPEngineReport::match(message)) + if (DSPEngineReport::match(*message)) { - DSPEngineReport* rep = (DSPEngineReport*)message; + DSPEngineReport* rep = (DSPEngineReport*) message; m_sampleRate = rep->getSampleRate(); m_centerFrequency = rep->getCenterFrequency(); qDebug("SampleRate:%d, CenterFrequency:%llu", rep->getSampleRate(), rep->getCenterFrequency()); @@ -350,7 +350,7 @@ void MainWindow::handleMessages() qDebug("Message: %s", message->getIdentifier()); std::cerr << "MainWindow::handleMessages: " << message->getIdentifier() << std::endl; - if (!m_pluginManager->handleMessage(message)) + if (!m_pluginManager->handleMessage(*message)) { delete message; } diff --git a/sdrbase/plugin/pluginapi.cpp b/sdrbase/plugin/pluginapi.cpp index 11eb3f522..c580d8456 100644 --- a/sdrbase/plugin/pluginapi.cpp +++ b/sdrbase/plugin/pluginapi.cpp @@ -54,6 +54,7 @@ void PluginAPI::removeChannelMarker(ChannelMarker* channelMarker) m_mainWindow->removeChannelMarker(channelMarker); } +/* void PluginAPI::setSampleSource(SampleSource* sampleSource) { m_dspEngine->stopAcquistion(); @@ -83,7 +84,7 @@ void PluginAPI::addAudioSource(AudioFifo* audioFifo) void PluginAPI::removeAudioSource(AudioFifo* audioFifo) { m_dspEngine->removeAudioSink(audioFifo); -} +}*/ void PluginAPI::registerSampleSource(const QString& sourceName, PluginInterface* plugin) { diff --git a/sdrbase/plugin/pluginmanager.cpp b/sdrbase/plugin/pluginmanager.cpp index 4bcfe9af3..5d57264df 100644 --- a/sdrbase/plugin/pluginmanager.cpp +++ b/sdrbase/plugin/pluginmanager.cpp @@ -177,21 +177,30 @@ void PluginManager::freeAll() } } -bool PluginManager::handleMessage(Message* message) +bool PluginManager::handleMessage(const Message& message) { - if(m_sampleSourceInstance != NULL) { - if((message->getDestination() == NULL) || (message->getDestination() == m_sampleSourceInstance)) { - if(m_sampleSourceInstance->handleMessage(message)) + if (m_sampleSourceInstance != 0) + { + if ((message.getDestination() == 0) || (message.getDestination() == m_sampleSourceInstance)) + { + if (m_sampleSourceInstance->handleMessage(message)) + { return true; + } } } - for(ChannelInstanceRegistrations::iterator it = m_channelInstanceRegistrations.begin(); it != m_channelInstanceRegistrations.end(); ++it) { - if((message->getDestination() == NULL) || (message->getDestination() == it->m_gui)) { - if(it->m_gui->handleMessage(message)) + for (ChannelInstanceRegistrations::iterator it = m_channelInstanceRegistrations.begin(); it != m_channelInstanceRegistrations.end(); ++it) + { + if ((message.getDestination() == 0) || (message.getDestination() == it->m_gui)) + { + if (it->m_gui->handleMessage(message)) + { return true; + } } } + return false; } diff --git a/sdrbase/util/syncmessenger.cpp b/sdrbase/util/syncmessenger.cpp index 890123c20..77a45c334 100644 --- a/sdrbase/util/syncmessenger.cpp +++ b/sdrbase/util/syncmessenger.cpp @@ -26,7 +26,7 @@ SyncMessenger::SyncMessenger() : SyncMessenger::~SyncMessenger() {} -int SyncMessenger::sendWait(Message *message, unsigned long msPollTime) +int SyncMessenger::sendWait(const Message& message, unsigned long msPollTime) { m_mutex.lock(); m_complete.testAndSetAcquire(0, 1);