diff --git a/plugins/channelrx/chanalyzer/chanalyzer.cpp b/plugins/channelrx/chanalyzer/chanalyzer.cpp
index d7c42629f..70c2adf17 100644
--- a/plugins/channelrx/chanalyzer/chanalyzer.cpp
+++ b/plugins/channelrx/chanalyzer/chanalyzer.cpp
@@ -1,236 +1,237 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2015 Edouard Griffiths, F4EXB //
-// //
-// This program is free software; you can redistribute it and/or modify //
-// it under the terms of the GNU General Public License as published by //
-// the Free Software Foundation as version 3 of the License, or //
-// //
-// This program is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU General Public License V3 for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program. If not, see . //
-///////////////////////////////////////////////////////////////////////////////////
-
-#include "chanalyzer.h"
-
-#include
-#include
-#include
-
-#include
-#include "dsp/threadedbasebandsamplesink.h"
-#include "device/devicesourceapi.h"
-#include "audio/audiooutput.h"
-
-
-MESSAGE_CLASS_DEFINITION(ChannelAnalyzer::MsgConfigureChannelAnalyzer, Message)
-MESSAGE_CLASS_DEFINITION(ChannelAnalyzer::MsgConfigureChannelizer, Message)
-MESSAGE_CLASS_DEFINITION(ChannelAnalyzer::MsgReportChannelSampleRateChanged, Message)
-
-ChannelAnalyzer::ChannelAnalyzer(DeviceSourceAPI *deviceAPI) :
- m_deviceAPI(deviceAPI),
- m_sampleSink(0),
- m_settingsMutex(QMutex::Recursive)
-{
- m_Bandwidth = 5000;
- m_LowCutoff = 300;
- m_spanLog2 = 3;
- m_sampleRate = 96000;
- m_frequency = 0;
- m_nco.setFreq(m_frequency, m_sampleRate);
- m_undersampleCount = 0;
- m_sum = 0;
- m_usb = true;
- m_ssb = true;
- m_magsq = 0;
- SSBFilter = new fftfilt(m_LowCutoff / m_sampleRate, m_Bandwidth / m_sampleRate, ssbFftLen);
- DSBFilter = new fftfilt(m_Bandwidth / m_sampleRate, 2*ssbFftLen);
-
- m_channelizer = new DownChannelizer(this);
- m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this);
- connect(m_channelizer, SIGNAL(inputSampleRateChanged()), this, SLOT(channelSampleRateChanged()));
- m_deviceAPI->addThreadedSink(m_threadedChannelizer);
-}
-
-ChannelAnalyzer::~ChannelAnalyzer()
-{
- if (SSBFilter) delete SSBFilter;
- if (DSBFilter) delete DSBFilter;
- m_deviceAPI->removeThreadedSink(m_threadedChannelizer);
- delete m_threadedChannelizer;
- delete m_channelizer;
-}
-
-void ChannelAnalyzer::configure(MessageQueue* messageQueue,
- Real Bandwidth,
- Real LowCutoff,
- int spanLog2,
- bool ssb)
-{
- Message* cmd = MsgConfigureChannelAnalyzer::create(Bandwidth, LowCutoff, spanLog2, ssb);
- messageQueue->push(cmd);
-}
-
-void ChannelAnalyzer::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly __attribute__((unused)))
-{
- fftfilt::cmplx *sideband;
- int n_out;
- int decim = 1<real() / 32768.0f, it->imag() / 32768.0f);
- Complex c(it->real(), it->imag());
- c *= m_nco.nextIQ();
-
- if (m_ssb)
- {
- n_out = SSBFilter->runSSB(c, &sideband, m_usb);
- }
- else
- {
- n_out = DSBFilter->runDSB(c, &sideband);
- }
-
- for (int i = 0; i < n_out; i++)
- {
- // Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display
- // smart decimation with bit gain using float arithmetic (23 bits significand)
-
- m_sum += sideband[i];
-
- if (!(m_undersampleCount++ & decim_mask))
- {
- m_sum /= decim;
- m_magsq = (m_sum.real() * m_sum.real() + m_sum.imag() * m_sum.imag())/ (1<<30);
-
- if (m_ssb & !m_usb)
- { // invert spectrum for LSB
- //m_sampleBuffer.push_back(Sample(m_sum.imag() * 32768.0, m_sum.real() * 32768.0));
- m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real()));
- }
- else
- {
- //m_sampleBuffer.push_back(Sample(m_sum.real() * 32768.0, m_sum.imag() * 32768.0));
- m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag()));
- }
-
- m_sum = 0;
- }
- }
- }
-
- if(m_sampleSink != NULL)
- {
- m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), m_ssb); // m_ssb = positive only
- }
-
- m_sampleBuffer.clear();
-
- m_settingsMutex.unlock();
-}
-
-void ChannelAnalyzer::start()
-{
-}
-
-void ChannelAnalyzer::stop()
-{
-}
-
-void ChannelAnalyzer::channelSampleRateChanged()
-{
- MsgReportChannelSampleRateChanged *msg = MsgReportChannelSampleRateChanged::create();
- getMessageQueueToGUI()->push(msg);
-}
-
-bool ChannelAnalyzer::handleMessage(const Message& cmd)
-{
- float band, lowCutoff;
-
- qDebug() << "ChannelAnalyzer::handleMessage";
-
- if (DownChannelizer::MsgChannelizerNotification::match(cmd))
- {
- DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd;
-
- m_sampleRate = notif.getSampleRate();
- m_nco.setFreq(-notif.getFrequencyOffset(), m_sampleRate);
-
- qDebug() << "ChannelAnalyzer::handleMessage: MsgChannelizerNotification: m_sampleRate: " << m_sampleRate
- << " frequencyOffset: " << notif.getFrequencyOffset();
-
- return true;
- }
- else if (MsgConfigureChannelizer::match(cmd))
- {
- MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
-
- m_channelizer->configure(m_channelizer->getInputMessageQueue(),
- m_channelizer->getInputSampleRate(),
- cfg.getCenterFrequency());
-
- return true;
- }
- else if (MsgConfigureChannelAnalyzer::match(cmd))
- {
- MsgConfigureChannelAnalyzer& cfg = (MsgConfigureChannelAnalyzer&) cmd;
-
- band = cfg.getBandwidth();
- lowCutoff = cfg.getLoCutoff();
-
- if (band < 0)
- {
- band = -band;
- lowCutoff = -lowCutoff;
- m_usb = false;
- }
- else
- {
- m_usb = true;
- }
-
- if (band < 100.0f)
- {
- band = 100.0f;
- lowCutoff = 0;
- }
-
- m_settingsMutex.lock();
-
- m_Bandwidth = band;
- m_LowCutoff = lowCutoff;
-
- 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_settingsMutex.unlock();
-
- qDebug() << " - MsgConfigureChannelAnalyzer: m_Bandwidth: " << m_Bandwidth
- << " m_LowCutoff: " << m_LowCutoff
- << " m_spanLog2: " << m_spanLog2
- << " m_ssb: " << m_ssb;
-
- return true;
- }
- else
- {
- if (m_sampleSink != 0)
- {
- return m_sampleSink->handleMessage(cmd);
- }
- else
- {
- return false;
- }
- }
-}
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2015 Edouard Griffiths, F4EXB //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include "chanalyzer.h"
+
+#include
+#include
+#include
+
+#include
+#include "dsp/threadedbasebandsamplesink.h"
+#include "device/devicesourceapi.h"
+#include "audio/audiooutput.h"
+
+MESSAGE_CLASS_DEFINITION(ChannelAnalyzer::MsgConfigureChannelAnalyzer, Message)
+MESSAGE_CLASS_DEFINITION(ChannelAnalyzer::MsgConfigureChannelizer, Message)
+MESSAGE_CLASS_DEFINITION(ChannelAnalyzer::MsgReportChannelSampleRateChanged, Message)
+
+const QString ChannelAnalyzer::m_channelID = "org.f4exb.sdrangelove.channel.chanalyzer";
+
+ChannelAnalyzer::ChannelAnalyzer(DeviceSourceAPI *deviceAPI) :
+ m_deviceAPI(deviceAPI),
+ m_sampleSink(0),
+ m_settingsMutex(QMutex::Recursive)
+{
+ m_Bandwidth = 5000;
+ m_LowCutoff = 300;
+ m_spanLog2 = 3;
+ m_sampleRate = 96000;
+ m_frequency = 0;
+ m_nco.setFreq(m_frequency, m_sampleRate);
+ m_undersampleCount = 0;
+ m_sum = 0;
+ m_usb = true;
+ m_ssb = true;
+ m_magsq = 0;
+ SSBFilter = new fftfilt(m_LowCutoff / m_sampleRate, m_Bandwidth / m_sampleRate, ssbFftLen);
+ DSBFilter = new fftfilt(m_Bandwidth / m_sampleRate, 2*ssbFftLen);
+
+ m_channelizer = new DownChannelizer(this);
+ m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this);
+ connect(m_channelizer, SIGNAL(inputSampleRateChanged()), this, SLOT(channelSampleRateChanged()));
+ m_deviceAPI->addThreadedSink(m_threadedChannelizer);
+}
+
+ChannelAnalyzer::~ChannelAnalyzer()
+{
+ if (SSBFilter) delete SSBFilter;
+ if (DSBFilter) delete DSBFilter;
+ m_deviceAPI->removeThreadedSink(m_threadedChannelizer);
+ delete m_threadedChannelizer;
+ delete m_channelizer;
+}
+
+void ChannelAnalyzer::configure(MessageQueue* messageQueue,
+ Real Bandwidth,
+ Real LowCutoff,
+ int spanLog2,
+ bool ssb)
+{
+ Message* cmd = MsgConfigureChannelAnalyzer::create(Bandwidth, LowCutoff, spanLog2, ssb);
+ messageQueue->push(cmd);
+}
+
+void ChannelAnalyzer::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly __attribute__((unused)))
+{
+ fftfilt::cmplx *sideband;
+ int n_out;
+ int decim = 1<real() / 32768.0f, it->imag() / 32768.0f);
+ Complex c(it->real(), it->imag());
+ c *= m_nco.nextIQ();
+
+ if (m_ssb)
+ {
+ n_out = SSBFilter->runSSB(c, &sideband, m_usb);
+ }
+ else
+ {
+ n_out = DSBFilter->runDSB(c, &sideband);
+ }
+
+ for (int i = 0; i < n_out; i++)
+ {
+ // Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display
+ // smart decimation with bit gain using float arithmetic (23 bits significand)
+
+ m_sum += sideband[i];
+
+ if (!(m_undersampleCount++ & decim_mask))
+ {
+ m_sum /= decim;
+ m_magsq = (m_sum.real() * m_sum.real() + m_sum.imag() * m_sum.imag())/ (1<<30);
+
+ if (m_ssb & !m_usb)
+ { // invert spectrum for LSB
+ //m_sampleBuffer.push_back(Sample(m_sum.imag() * 32768.0, m_sum.real() * 32768.0));
+ m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real()));
+ }
+ else
+ {
+ //m_sampleBuffer.push_back(Sample(m_sum.real() * 32768.0, m_sum.imag() * 32768.0));
+ m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag()));
+ }
+
+ m_sum = 0;
+ }
+ }
+ }
+
+ if(m_sampleSink != NULL)
+ {
+ m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), m_ssb); // m_ssb = positive only
+ }
+
+ m_sampleBuffer.clear();
+
+ m_settingsMutex.unlock();
+}
+
+void ChannelAnalyzer::start()
+{
+}
+
+void ChannelAnalyzer::stop()
+{
+}
+
+void ChannelAnalyzer::channelSampleRateChanged()
+{
+ MsgReportChannelSampleRateChanged *msg = MsgReportChannelSampleRateChanged::create();
+ getMessageQueueToGUI()->push(msg);
+}
+
+bool ChannelAnalyzer::handleMessage(const Message& cmd)
+{
+ float band, lowCutoff;
+
+ qDebug() << "ChannelAnalyzer::handleMessage";
+
+ if (DownChannelizer::MsgChannelizerNotification::match(cmd))
+ {
+ DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd;
+
+ m_sampleRate = notif.getSampleRate();
+ m_nco.setFreq(-notif.getFrequencyOffset(), m_sampleRate);
+
+ qDebug() << "ChannelAnalyzer::handleMessage: MsgChannelizerNotification: m_sampleRate: " << m_sampleRate
+ << " frequencyOffset: " << notif.getFrequencyOffset();
+
+ return true;
+ }
+ else if (MsgConfigureChannelizer::match(cmd))
+ {
+ MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
+
+ m_channelizer->configure(m_channelizer->getInputMessageQueue(),
+ m_channelizer->getInputSampleRate(),
+ cfg.getCenterFrequency());
+
+ return true;
+ }
+ else if (MsgConfigureChannelAnalyzer::match(cmd))
+ {
+ MsgConfigureChannelAnalyzer& cfg = (MsgConfigureChannelAnalyzer&) cmd;
+
+ band = cfg.getBandwidth();
+ lowCutoff = cfg.getLoCutoff();
+
+ if (band < 0)
+ {
+ band = -band;
+ lowCutoff = -lowCutoff;
+ m_usb = false;
+ }
+ else
+ {
+ m_usb = true;
+ }
+
+ if (band < 100.0f)
+ {
+ band = 100.0f;
+ lowCutoff = 0;
+ }
+
+ m_settingsMutex.lock();
+
+ m_Bandwidth = band;
+ m_LowCutoff = lowCutoff;
+
+ 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_settingsMutex.unlock();
+
+ qDebug() << " - MsgConfigureChannelAnalyzer: m_Bandwidth: " << m_Bandwidth
+ << " m_LowCutoff: " << m_LowCutoff
+ << " m_spanLog2: " << m_spanLog2
+ << " m_ssb: " << m_ssb;
+
+ return true;
+ }
+ else
+ {
+ if (m_sampleSink != 0)
+ {
+ return m_sampleSink->handleMessage(cmd);
+ }
+ else
+ {
+ return false;
+ }
+ }
+}
diff --git a/plugins/channelrx/chanalyzer/chanalyzer.h b/plugins/channelrx/chanalyzer/chanalyzer.h
index 7dd26732f..4c333c7a9 100644
--- a/plugins/channelrx/chanalyzer/chanalyzer.h
+++ b/plugins/channelrx/chanalyzer/chanalyzer.h
@@ -1,154 +1,156 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2015 Edouard Griffiths, F4EXB //
-// //
-// This program is free software; you can redistribute it and/or modify //
-// it under the terms of the GNU General Public License as published by //
-// the Free Software Foundation as version 3 of the License, or //
-// //
-// This program is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU General Public License V3 for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program. If not, see . //
-///////////////////////////////////////////////////////////////////////////////////
-
-#ifndef INCLUDE_CHANALYZER_H
-#define INCLUDE_CHANALYZER_H
-
-#include
-#include
-#include
-#include "dsp/ncof.h"
-#include "dsp/fftfilt.h"
-#include "audio/audiofifo.h"
-#include "util/message.h"
-
-#define ssbFftLen 1024
-
-class DeviceSourceAPI;
-class ThreadedBasebandSampleSink;
-class DownChannelizer;
-
-class ChannelAnalyzer : public BasebandSampleSink {
-public:
- class MsgConfigureChannelAnalyzer : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- Real getBandwidth() const { return m_Bandwidth; }
- Real getLoCutoff() const { return m_LowCutoff; }
- int getSpanLog2() const { return m_spanLog2; }
- bool getSSB() const { return m_ssb; }
-
- static MsgConfigureChannelAnalyzer* create(Real Bandwidth,
- Real LowCutoff,
- int spanLog2,
- bool ssb)
- {
- return new MsgConfigureChannelAnalyzer(Bandwidth, LowCutoff, spanLog2, ssb);
- }
-
- private:
- Real m_Bandwidth;
- Real m_LowCutoff;
- int m_spanLog2;
- bool m_ssb;
-
- MsgConfigureChannelAnalyzer(Real Bandwidth,
- Real LowCutoff,
- int spanLog2,
- bool ssb) :
- Message(),
- m_Bandwidth(Bandwidth),
- m_LowCutoff(LowCutoff),
- m_spanLog2(spanLog2),
- m_ssb(ssb)
- { }
- };
-
- class MsgConfigureChannelizer : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- int getCenterFrequency() const { return m_centerFrequency; }
-
- static MsgConfigureChannelizer* create(int centerFrequency)
- {
- return new MsgConfigureChannelizer(centerFrequency);
- }
-
- private:
- int m_centerFrequency;
-
- MsgConfigureChannelizer(int centerFrequency) :
- Message(),
- m_centerFrequency(centerFrequency)
- { }
- };
-
- class MsgReportChannelSampleRateChanged : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
-
- static MsgReportChannelSampleRateChanged* create()
- {
- return new MsgReportChannelSampleRateChanged();
- }
-
- private:
-
- MsgReportChannelSampleRateChanged() :
- Message()
- { }
- };
-
- ChannelAnalyzer(DeviceSourceAPI *deviceAPI);
- virtual ~ChannelAnalyzer();
- void setSampleSink(BasebandSampleSink* sampleSink) { m_sampleSink = sampleSink; }
-
- void configure(MessageQueue* messageQueue,
- Real Bandwidth,
- Real LowCutoff,
- int spanLog2,
- bool ssb);
-
- int getSampleRate() const { return m_sampleRate; }
- Real getMagSq() const { return m_magsq; }
-
- virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
- virtual void start();
- virtual void stop();
- virtual bool handleMessage(const Message& cmd);
-
-private slots:
- void channelSampleRateChanged();
-
-private:
- DeviceSourceAPI *m_deviceAPI;
- ThreadedBasebandSampleSink* m_threadedChannelizer;
- DownChannelizer* m_channelizer;
-
- Real m_Bandwidth;
- Real m_LowCutoff;
- int m_spanLog2;
- int m_undersampleCount;
- fftfilt::cmplx m_sum;
- int m_sampleRate;
- int m_frequency;
- bool m_usb;
- bool m_ssb;
- Real m_magsq;
-
- NCOF m_nco;
- fftfilt* SSBFilter;
- fftfilt* DSBFilter;
-
- BasebandSampleSink* m_sampleSink;
- SampleVector m_sampleBuffer;
- QMutex m_settingsMutex;
-};
-
-#endif // INCLUDE_CHANALYZER_H
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2015 Edouard Griffiths, F4EXB //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDE_CHANALYZER_H
+#define INCLUDE_CHANALYZER_H
+
+#include
+#include
+#include
+#include "dsp/ncof.h"
+#include "dsp/fftfilt.h"
+#include "audio/audiofifo.h"
+#include "util/message.h"
+
+#define ssbFftLen 1024
+
+class DeviceSourceAPI;
+class ThreadedBasebandSampleSink;
+class DownChannelizer;
+
+class ChannelAnalyzer : public BasebandSampleSink {
+public:
+ class MsgConfigureChannelAnalyzer : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ Real getBandwidth() const { return m_Bandwidth; }
+ Real getLoCutoff() const { return m_LowCutoff; }
+ int getSpanLog2() const { return m_spanLog2; }
+ bool getSSB() const { return m_ssb; }
+
+ static MsgConfigureChannelAnalyzer* create(Real Bandwidth,
+ Real LowCutoff,
+ int spanLog2,
+ bool ssb)
+ {
+ return new MsgConfigureChannelAnalyzer(Bandwidth, LowCutoff, spanLog2, ssb);
+ }
+
+ private:
+ Real m_Bandwidth;
+ Real m_LowCutoff;
+ int m_spanLog2;
+ bool m_ssb;
+
+ MsgConfigureChannelAnalyzer(Real Bandwidth,
+ Real LowCutoff,
+ int spanLog2,
+ bool ssb) :
+ Message(),
+ m_Bandwidth(Bandwidth),
+ m_LowCutoff(LowCutoff),
+ m_spanLog2(spanLog2),
+ m_ssb(ssb)
+ { }
+ };
+
+ class MsgConfigureChannelizer : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ int getCenterFrequency() const { return m_centerFrequency; }
+
+ static MsgConfigureChannelizer* create(int centerFrequency)
+ {
+ return new MsgConfigureChannelizer(centerFrequency);
+ }
+
+ private:
+ int m_centerFrequency;
+
+ MsgConfigureChannelizer(int centerFrequency) :
+ Message(),
+ m_centerFrequency(centerFrequency)
+ { }
+ };
+
+ class MsgReportChannelSampleRateChanged : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+
+ static MsgReportChannelSampleRateChanged* create()
+ {
+ return new MsgReportChannelSampleRateChanged();
+ }
+
+ private:
+
+ MsgReportChannelSampleRateChanged() :
+ Message()
+ { }
+ };
+
+ ChannelAnalyzer(DeviceSourceAPI *deviceAPI);
+ virtual ~ChannelAnalyzer();
+ void setSampleSink(BasebandSampleSink* sampleSink) { m_sampleSink = sampleSink; }
+
+ void configure(MessageQueue* messageQueue,
+ Real Bandwidth,
+ Real LowCutoff,
+ int spanLog2,
+ bool ssb);
+
+ int getSampleRate() const { return m_sampleRate; }
+ Real getMagSq() const { return m_magsq; }
+
+ virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
+ virtual void start();
+ virtual void stop();
+ virtual bool handleMessage(const Message& cmd);
+
+ static const QString m_channelID;
+
+private slots:
+ void channelSampleRateChanged();
+
+private:
+ DeviceSourceAPI *m_deviceAPI;
+ ThreadedBasebandSampleSink* m_threadedChannelizer;
+ DownChannelizer* m_channelizer;
+
+ Real m_Bandwidth;
+ Real m_LowCutoff;
+ int m_spanLog2;
+ int m_undersampleCount;
+ fftfilt::cmplx m_sum;
+ int m_sampleRate;
+ int m_frequency;
+ bool m_usb;
+ bool m_ssb;
+ Real m_magsq;
+
+ NCOF m_nco;
+ fftfilt* SSBFilter;
+ fftfilt* DSBFilter;
+
+ BasebandSampleSink* m_sampleSink;
+ SampleVector m_sampleBuffer;
+ QMutex m_settingsMutex;
+};
+
+#endif // INCLUDE_CHANALYZER_H
diff --git a/plugins/channelrx/chanalyzer/chanalyzergui.cpp b/plugins/channelrx/chanalyzer/chanalyzergui.cpp
index 107f8e1ee..f31599742 100644
--- a/plugins/channelrx/chanalyzer/chanalyzergui.cpp
+++ b/plugins/channelrx/chanalyzer/chanalyzergui.cpp
@@ -38,8 +38,6 @@
#include "chanalyzer.h"
-const QString ChannelAnalyzerGUI::m_channelID = "org.f4exb.sdrangelove.channel.chanalyzer";
-
ChannelAnalyzerGUI* ChannelAnalyzerGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet)
{
ChannelAnalyzerGUI* gui = new ChannelAnalyzerGUI(pluginAPI, deviceUISet);
@@ -370,7 +368,7 @@ ChannelAnalyzerGUI::ChannelAnalyzerGUI(PluginAPI* pluginAPI, DeviceUISet *device
connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(viewChanged()));
- m_deviceUISet->registerRxChannelInstance(m_channelID, this);
+ m_deviceUISet->registerRxChannelInstance(ChannelAnalyzer::m_channelID, this);
m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this);
diff --git a/plugins/channelrx/chanalyzer/chanalyzergui.h b/plugins/channelrx/chanalyzer/chanalyzergui.h
index a56f91a2d..476ff3c71 100644
--- a/plugins/channelrx/chanalyzer/chanalyzergui.h
+++ b/plugins/channelrx/chanalyzer/chanalyzergui.h
@@ -55,8 +55,6 @@ public:
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual bool handleMessage(const Message& message);
- static const QString m_channelID;
-
private slots:
void viewChanged();
void on_deltaFrequency_changed(quint64 value);
diff --git a/plugins/channelrx/chanalyzer/chanalyzerplugin.cpp b/plugins/channelrx/chanalyzer/chanalyzerplugin.cpp
index 97f370c8e..bf772dd0c 100644
--- a/plugins/channelrx/chanalyzer/chanalyzerplugin.cpp
+++ b/plugins/channelrx/chanalyzer/chanalyzerplugin.cpp
@@ -4,6 +4,7 @@
#include "plugin/pluginapi.h"
#include "chanalyzergui.h"
+#include "chanalyzer.h"
const PluginDescriptor ChannelAnalyzerPlugin::m_pluginDescriptor = {
QString("Channel Analyzer"),
@@ -30,12 +31,12 @@ void ChannelAnalyzerPlugin::initPlugin(PluginAPI* pluginAPI)
m_pluginAPI = pluginAPI;
// register demodulator
- m_pluginAPI->registerRxChannel(ChannelAnalyzerGUI::m_channelID, this);
+ m_pluginAPI->registerRxChannel(ChannelAnalyzer::m_channelID, this);
}
PluginInstanceGUI* ChannelAnalyzerPlugin::createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet)
{
- if(channelName == ChannelAnalyzerGUI::m_channelID)
+ if(channelName == ChannelAnalyzer::m_channelID)
{
ChannelAnalyzerGUI* gui = ChannelAnalyzerGUI::create(m_pluginAPI, deviceUISet);
return gui;
@@ -43,3 +44,15 @@ PluginInstanceGUI* ChannelAnalyzerPlugin::createRxChannelGUI(const QString& chan
return NULL;
}
}
+
+
+BasebandSampleSink* ChannelAnalyzerPlugin::createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI)
+{
+ if(channelName == ChannelAnalyzer::m_channelID)
+ {
+ ChannelAnalyzer* sink = new ChannelAnalyzer(deviceAPI);
+ return sink;
+ } else {
+ return 0;
+ }
+}
diff --git a/plugins/channelrx/chanalyzer/chanalyzerplugin.h b/plugins/channelrx/chanalyzer/chanalyzerplugin.h
index 267393132..20624353f 100644
--- a/plugins/channelrx/chanalyzer/chanalyzerplugin.h
+++ b/plugins/channelrx/chanalyzer/chanalyzerplugin.h
@@ -5,6 +5,7 @@
#include "plugin/plugininterface.h"
class DeviceUISet;
+class BasebandSampleSink;
class ChannelAnalyzerPlugin : public QObject, PluginInterface {
Q_OBJECT
@@ -18,6 +19,7 @@ public:
void initPlugin(PluginAPI* pluginAPI);
PluginInstanceGUI* createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet);
+ BasebandSampleSink* createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI);
private:
static const PluginDescriptor m_pluginDescriptor;
diff --git a/plugins/channelrx/chanalyzerng/chanalyzerng.cpp b/plugins/channelrx/chanalyzerng/chanalyzerng.cpp
index ddfa63fc3..5bbd82369 100644
--- a/plugins/channelrx/chanalyzerng/chanalyzerng.cpp
+++ b/plugins/channelrx/chanalyzerng/chanalyzerng.cpp
@@ -1,251 +1,252 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2017 Edouard Griffiths, F4EXB //
-// //
-// This program is free software; you can redistribute it and/or modify //
-// it under the terms of the GNU General Public License as published by //
-// the Free Software Foundation as version 3 of the License, or //
-// //
-// This program is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU General Public License V3 for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program. If not, see . //
-///////////////////////////////////////////////////////////////////////////////////
-
-#include "chanalyzerng.h"
-
-#include
-#include
-#include
-
-#include "device/devicesourceapi.h"
-#include "audio/audiooutput.h"
-#include "dsp/threadedbasebandsamplesink.h"
-#include "dsp/downchannelizer.h"
-
-
-MESSAGE_CLASS_DEFINITION(ChannelAnalyzerNG::MsgConfigureChannelAnalyzer, Message)
-MESSAGE_CLASS_DEFINITION(ChannelAnalyzerNG::MsgConfigureChannelizer, Message)
-MESSAGE_CLASS_DEFINITION(ChannelAnalyzerNG::MsgReportChannelSampleRateChanged, Message)
-
-ChannelAnalyzerNG::ChannelAnalyzerNG(DeviceSourceAPI *deviceAPI) :
- m_deviceAPI(deviceAPI),
- m_sampleSink(0),
- m_settingsMutex(QMutex::Recursive)
-{
- m_undersampleCount = 0;
- m_sum = 0;
- m_usb = true;
- m_magsq = 0;
- m_useInterpolator = false;
- m_interpolatorDistance = 1.0f;
- m_interpolatorDistanceRemain = 0.0f;
- SSBFilter = new fftfilt(m_config.m_LowCutoff / m_config.m_inputSampleRate, m_config.m_Bandwidth / m_config.m_inputSampleRate, ssbFftLen);
- DSBFilter = new fftfilt(m_config.m_Bandwidth / m_config.m_inputSampleRate, 2*ssbFftLen);
-
- m_channelizer = new DownChannelizer(this);
- m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this);
- connect(m_channelizer, SIGNAL(inputSampleRateChanged()), this, SLOT(channelizerInputSampleRateChanged()));
- m_deviceAPI->addThreadedSink(m_threadedChannelizer);
-
- apply(true);
-}
-
-ChannelAnalyzerNG::~ChannelAnalyzerNG()
-{
- if (SSBFilter) delete SSBFilter;
- if (DSBFilter) delete DSBFilter;
- m_deviceAPI->removeThreadedSink(m_threadedChannelizer);
- delete m_threadedChannelizer;
- delete m_channelizer;
-}
-
-void ChannelAnalyzerNG::configure(MessageQueue* messageQueue,
- int channelSampleRate,
- Real Bandwidth,
- Real LowCutoff,
- int spanLog2,
- bool ssb)
-{
- Message* cmd = MsgConfigureChannelAnalyzer::create(channelSampleRate, Bandwidth, LowCutoff, spanLog2, ssb);
- messageQueue->push(cmd);
-}
-
-void ChannelAnalyzerNG::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly __attribute__((unused)))
-{
- fftfilt::cmplx *sideband = 0;
- Complex ci;
-
- m_settingsMutex.lock();
-
- for(SampleVector::const_iterator it = begin; it < end; ++it)
- {
- Complex c(it->real(), it->imag());
- c *= m_nco.nextIQ();
-
- if (m_useInterpolator)
- {
- if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci))
- {
- processOneSample(ci, sideband);
- m_interpolatorDistanceRemain += m_interpolatorDistance;
- }
- }
- else
- {
- processOneSample(c, sideband);
- }
- }
-
- if(m_sampleSink != 0)
- {
- m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), m_running.m_ssb); // m_ssb = positive only
- }
-
- m_sampleBuffer.clear();
-
- m_settingsMutex.unlock();
-}
-
-void ChannelAnalyzerNG::start()
-{
-}
-
-void ChannelAnalyzerNG::stop()
-{
-}
-
-void ChannelAnalyzerNG::channelizerInputSampleRateChanged()
-{
- MsgReportChannelSampleRateChanged *msg = MsgReportChannelSampleRateChanged::create();
- getMessageQueueToGUI()->push(msg);
-}
-
-bool ChannelAnalyzerNG::handleMessage(const Message& cmd)
-{
- qDebug() << "ChannelAnalyzerNG::handleMessage: " << cmd.getIdentifier();
-
- if (DownChannelizer::MsgChannelizerNotification::match(cmd))
- {
- DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd;
-
- m_config.m_inputSampleRate = notif.getSampleRate();
- m_config.m_frequency = notif.getFrequencyOffset();
-
- qDebug() << "ChannelAnalyzerNG::handleMessage: MsgChannelizerNotification:"
- << " m_sampleRate: " << m_config.m_inputSampleRate
- << " frequencyOffset: " << m_config.m_frequency;
-
- apply();
- return true;
- }
- else if (MsgConfigureChannelizer::match(cmd))
- {
- MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
- m_channelizer->configure(m_channelizer->getInputMessageQueue(),
- cfg.getSampleRate(),
- cfg.getCenterFrequency());
- return true;
- }
- else if (MsgConfigureChannelAnalyzer::match(cmd))
- {
- MsgConfigureChannelAnalyzer& cfg = (MsgConfigureChannelAnalyzer&) cmd;
-
- m_config.m_channelSampleRate = cfg.getChannelSampleRate();
- m_config.m_Bandwidth = cfg.getBandwidth();
- m_config.m_LowCutoff = cfg.getLoCutoff();
- m_config.m_spanLog2 = cfg.getSpanLog2();
- m_config.m_ssb = cfg.getSSB();
-
- qDebug() << "ChannelAnalyzerNG::handleMessage: MsgConfigureChannelAnalyzer:"
- << " m_channelSampleRate: " << m_config.m_channelSampleRate
- << " m_Bandwidth: " << m_config.m_Bandwidth
- << " m_LowCutoff: " << m_config.m_LowCutoff
- << " m_spanLog2: " << m_config.m_spanLog2
- << " m_ssb: " << m_config.m_ssb;
-
- apply();
- return true;
- }
- else
- {
- if (m_sampleSink != 0)
- {
- return m_sampleSink->handleMessage(cmd);
- }
- else
- {
- return false;
- }
- }
-}
-
-
-
-void ChannelAnalyzerNG::apply(bool force)
-{
- if ((m_running.m_frequency != m_config.m_frequency) ||
- (m_running.m_inputSampleRate != m_config.m_inputSampleRate) ||
- force)
- {
- m_nco.setFreq(-m_config.m_frequency, m_config.m_inputSampleRate);
- }
-
- if ((m_running.m_inputSampleRate != m_config.m_inputSampleRate) ||
- (m_running.m_channelSampleRate != m_config.m_channelSampleRate) ||
- force)
- {
- m_settingsMutex.lock();
- m_interpolator.create(16, m_config.m_inputSampleRate, m_config.m_inputSampleRate / 2.2);
- m_interpolatorDistanceRemain = 0.0f;
- m_interpolatorDistance = (Real) m_config.m_inputSampleRate / (Real) m_config.m_channelSampleRate;
- m_useInterpolator = (m_config.m_inputSampleRate != m_config.m_channelSampleRate); // optim
- m_settingsMutex.unlock();
- }
-
- if ((m_running.m_channelSampleRate != m_config.m_channelSampleRate) ||
- (m_running.m_Bandwidth != m_config.m_Bandwidth) ||
- (m_running.m_LowCutoff != m_config.m_LowCutoff) ||
- force)
- {
- float bandwidth = m_config.m_Bandwidth;
- float lowCutoff = m_config.m_LowCutoff;
-
- if (bandwidth < 0)
- {
- bandwidth = -bandwidth;
- lowCutoff = -lowCutoff;
- m_usb = false;
- }
- else
- {
- m_usb = true;
- }
-
- if (bandwidth < 100.0f)
- {
- bandwidth = 100.0f;
- lowCutoff = 0;
- }
-
- m_settingsMutex.lock();
-
- SSBFilter->create_filter(lowCutoff / m_config.m_channelSampleRate, bandwidth / m_config.m_channelSampleRate);
- DSBFilter->create_dsb_filter(bandwidth / m_config.m_channelSampleRate);
-
- m_settingsMutex.unlock();
- }
-
- m_running.m_frequency = m_config.m_frequency;
- m_running.m_channelSampleRate = m_config.m_channelSampleRate;
- m_running.m_inputSampleRate = m_config.m_inputSampleRate;
- m_running.m_Bandwidth = m_config.m_Bandwidth;
- m_running.m_LowCutoff = m_config.m_LowCutoff;
-
- //m_settingsMutex.lock();
- m_running.m_spanLog2 = m_config.m_spanLog2;
- m_running.m_ssb = m_config.m_ssb;
- //m_settingsMutex.unlock();
-}
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2017 Edouard Griffiths, F4EXB //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include "chanalyzerng.h"
+
+#include
+#include
+#include
+
+#include "device/devicesourceapi.h"
+#include "audio/audiooutput.h"
+#include "dsp/threadedbasebandsamplesink.h"
+#include "dsp/downchannelizer.h"
+
+MESSAGE_CLASS_DEFINITION(ChannelAnalyzerNG::MsgConfigureChannelAnalyzer, Message)
+MESSAGE_CLASS_DEFINITION(ChannelAnalyzerNG::MsgConfigureChannelizer, Message)
+MESSAGE_CLASS_DEFINITION(ChannelAnalyzerNG::MsgReportChannelSampleRateChanged, Message)
+
+const QString ChannelAnalyzerNG::m_channelID = "sdrangel.channel.chanalyzerng";
+
+ChannelAnalyzerNG::ChannelAnalyzerNG(DeviceSourceAPI *deviceAPI) :
+ m_deviceAPI(deviceAPI),
+ m_sampleSink(0),
+ m_settingsMutex(QMutex::Recursive)
+{
+ m_undersampleCount = 0;
+ m_sum = 0;
+ m_usb = true;
+ m_magsq = 0;
+ m_useInterpolator = false;
+ m_interpolatorDistance = 1.0f;
+ m_interpolatorDistanceRemain = 0.0f;
+ SSBFilter = new fftfilt(m_config.m_LowCutoff / m_config.m_inputSampleRate, m_config.m_Bandwidth / m_config.m_inputSampleRate, ssbFftLen);
+ DSBFilter = new fftfilt(m_config.m_Bandwidth / m_config.m_inputSampleRate, 2*ssbFftLen);
+
+ m_channelizer = new DownChannelizer(this);
+ m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this);
+ connect(m_channelizer, SIGNAL(inputSampleRateChanged()), this, SLOT(channelizerInputSampleRateChanged()));
+ m_deviceAPI->addThreadedSink(m_threadedChannelizer);
+
+ apply(true);
+}
+
+ChannelAnalyzerNG::~ChannelAnalyzerNG()
+{
+ if (SSBFilter) delete SSBFilter;
+ if (DSBFilter) delete DSBFilter;
+ m_deviceAPI->removeThreadedSink(m_threadedChannelizer);
+ delete m_threadedChannelizer;
+ delete m_channelizer;
+}
+
+void ChannelAnalyzerNG::configure(MessageQueue* messageQueue,
+ int channelSampleRate,
+ Real Bandwidth,
+ Real LowCutoff,
+ int spanLog2,
+ bool ssb)
+{
+ Message* cmd = MsgConfigureChannelAnalyzer::create(channelSampleRate, Bandwidth, LowCutoff, spanLog2, ssb);
+ messageQueue->push(cmd);
+}
+
+void ChannelAnalyzerNG::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly __attribute__((unused)))
+{
+ fftfilt::cmplx *sideband = 0;
+ Complex ci;
+
+ m_settingsMutex.lock();
+
+ for(SampleVector::const_iterator it = begin; it < end; ++it)
+ {
+ Complex c(it->real(), it->imag());
+ c *= m_nco.nextIQ();
+
+ if (m_useInterpolator)
+ {
+ if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci))
+ {
+ processOneSample(ci, sideband);
+ m_interpolatorDistanceRemain += m_interpolatorDistance;
+ }
+ }
+ else
+ {
+ processOneSample(c, sideband);
+ }
+ }
+
+ if(m_sampleSink != 0)
+ {
+ m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), m_running.m_ssb); // m_ssb = positive only
+ }
+
+ m_sampleBuffer.clear();
+
+ m_settingsMutex.unlock();
+}
+
+void ChannelAnalyzerNG::start()
+{
+}
+
+void ChannelAnalyzerNG::stop()
+{
+}
+
+void ChannelAnalyzerNG::channelizerInputSampleRateChanged()
+{
+ MsgReportChannelSampleRateChanged *msg = MsgReportChannelSampleRateChanged::create();
+ getMessageQueueToGUI()->push(msg);
+}
+
+bool ChannelAnalyzerNG::handleMessage(const Message& cmd)
+{
+ qDebug() << "ChannelAnalyzerNG::handleMessage: " << cmd.getIdentifier();
+
+ if (DownChannelizer::MsgChannelizerNotification::match(cmd))
+ {
+ DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd;
+
+ m_config.m_inputSampleRate = notif.getSampleRate();
+ m_config.m_frequency = notif.getFrequencyOffset();
+
+ qDebug() << "ChannelAnalyzerNG::handleMessage: MsgChannelizerNotification:"
+ << " m_sampleRate: " << m_config.m_inputSampleRate
+ << " frequencyOffset: " << m_config.m_frequency;
+
+ apply();
+ return true;
+ }
+ else if (MsgConfigureChannelizer::match(cmd))
+ {
+ MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
+ m_channelizer->configure(m_channelizer->getInputMessageQueue(),
+ cfg.getSampleRate(),
+ cfg.getCenterFrequency());
+ return true;
+ }
+ else if (MsgConfigureChannelAnalyzer::match(cmd))
+ {
+ MsgConfigureChannelAnalyzer& cfg = (MsgConfigureChannelAnalyzer&) cmd;
+
+ m_config.m_channelSampleRate = cfg.getChannelSampleRate();
+ m_config.m_Bandwidth = cfg.getBandwidth();
+ m_config.m_LowCutoff = cfg.getLoCutoff();
+ m_config.m_spanLog2 = cfg.getSpanLog2();
+ m_config.m_ssb = cfg.getSSB();
+
+ qDebug() << "ChannelAnalyzerNG::handleMessage: MsgConfigureChannelAnalyzer:"
+ << " m_channelSampleRate: " << m_config.m_channelSampleRate
+ << " m_Bandwidth: " << m_config.m_Bandwidth
+ << " m_LowCutoff: " << m_config.m_LowCutoff
+ << " m_spanLog2: " << m_config.m_spanLog2
+ << " m_ssb: " << m_config.m_ssb;
+
+ apply();
+ return true;
+ }
+ else
+ {
+ if (m_sampleSink != 0)
+ {
+ return m_sampleSink->handleMessage(cmd);
+ }
+ else
+ {
+ return false;
+ }
+ }
+}
+
+
+
+void ChannelAnalyzerNG::apply(bool force)
+{
+ if ((m_running.m_frequency != m_config.m_frequency) ||
+ (m_running.m_inputSampleRate != m_config.m_inputSampleRate) ||
+ force)
+ {
+ m_nco.setFreq(-m_config.m_frequency, m_config.m_inputSampleRate);
+ }
+
+ if ((m_running.m_inputSampleRate != m_config.m_inputSampleRate) ||
+ (m_running.m_channelSampleRate != m_config.m_channelSampleRate) ||
+ force)
+ {
+ m_settingsMutex.lock();
+ m_interpolator.create(16, m_config.m_inputSampleRate, m_config.m_inputSampleRate / 2.2);
+ m_interpolatorDistanceRemain = 0.0f;
+ m_interpolatorDistance = (Real) m_config.m_inputSampleRate / (Real) m_config.m_channelSampleRate;
+ m_useInterpolator = (m_config.m_inputSampleRate != m_config.m_channelSampleRate); // optim
+ m_settingsMutex.unlock();
+ }
+
+ if ((m_running.m_channelSampleRate != m_config.m_channelSampleRate) ||
+ (m_running.m_Bandwidth != m_config.m_Bandwidth) ||
+ (m_running.m_LowCutoff != m_config.m_LowCutoff) ||
+ force)
+ {
+ float bandwidth = m_config.m_Bandwidth;
+ float lowCutoff = m_config.m_LowCutoff;
+
+ if (bandwidth < 0)
+ {
+ bandwidth = -bandwidth;
+ lowCutoff = -lowCutoff;
+ m_usb = false;
+ }
+ else
+ {
+ m_usb = true;
+ }
+
+ if (bandwidth < 100.0f)
+ {
+ bandwidth = 100.0f;
+ lowCutoff = 0;
+ }
+
+ m_settingsMutex.lock();
+
+ SSBFilter->create_filter(lowCutoff / m_config.m_channelSampleRate, bandwidth / m_config.m_channelSampleRate);
+ DSBFilter->create_dsb_filter(bandwidth / m_config.m_channelSampleRate);
+
+ m_settingsMutex.unlock();
+ }
+
+ m_running.m_frequency = m_config.m_frequency;
+ m_running.m_channelSampleRate = m_config.m_channelSampleRate;
+ m_running.m_inputSampleRate = m_config.m_inputSampleRate;
+ m_running.m_Bandwidth = m_config.m_Bandwidth;
+ m_running.m_LowCutoff = m_config.m_LowCutoff;
+
+ //m_settingsMutex.lock();
+ m_running.m_spanLog2 = m_config.m_spanLog2;
+ m_running.m_ssb = m_config.m_ssb;
+ //m_settingsMutex.unlock();
+}
diff --git a/plugins/channelrx/chanalyzerng/chanalyzerng.h b/plugins/channelrx/chanalyzerng/chanalyzerng.h
index bee680725..000222cb8 100644
--- a/plugins/channelrx/chanalyzerng/chanalyzerng.h
+++ b/plugins/channelrx/chanalyzerng/chanalyzerng.h
@@ -1,242 +1,244 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2017 Edouard Griffiths, F4EXB //
-// //
-// This program is free software; you can redistribute it and/or modify //
-// it under the terms of the GNU General Public License as published by //
-// the Free Software Foundation as version 3 of the License, or //
-// //
-// This program is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU General Public License V3 for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program. If not, see . //
-///////////////////////////////////////////////////////////////////////////////////
-
-#ifndef INCLUDE_CHANALYZERNG_H
-#define INCLUDE_CHANALYZERNG_H
-
-#include
-#include
-#include
-
-#include "dsp/interpolator.h"
-#include "dsp/ncof.h"
-#include "dsp/fftfilt.h"
-#include "audio/audiofifo.h"
-#include "util/message.h"
-
-#define ssbFftLen 1024
-
-class DeviceSourceAPI;
-class ThreadedBasebandSampleSink;
-class DownChannelizer;
-
-class ChannelAnalyzerNG : public BasebandSampleSink {
-public:
- class MsgConfigureChannelAnalyzer : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- int getChannelSampleRate() const { return m_channelSampleRate; }
- Real getBandwidth() const { return m_Bandwidth; }
- Real getLoCutoff() const { return m_LowCutoff; }
- int getSpanLog2() const { return m_spanLog2; }
- bool getSSB() const { return m_ssb; }
-
- static MsgConfigureChannelAnalyzer* create(
- int channelSampleRate,
- Real Bandwidth,
- Real LowCutoff,
- int spanLog2,
- bool ssb)
- {
- return new MsgConfigureChannelAnalyzer(
- channelSampleRate,
- Bandwidth,
- LowCutoff,
- spanLog2,
- ssb);
- }
-
- private:
- int m_channelSampleRate;
- Real m_Bandwidth;
- Real m_LowCutoff;
- int m_spanLog2;
- bool m_ssb;
-
- MsgConfigureChannelAnalyzer(
- int channelSampleRate,
- Real Bandwidth,
- Real LowCutoff,
- int spanLog2,
- bool ssb) :
- Message(),
- m_channelSampleRate(channelSampleRate),
- m_Bandwidth(Bandwidth),
- m_LowCutoff(LowCutoff),
- m_spanLog2(spanLog2),
- m_ssb(ssb)
- { }
- };
-
- class MsgConfigureChannelizer : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- int getSampleRate() const { return m_sampleRate; }
- int getCenterFrequency() const { return m_centerFrequency; }
-
- static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
- {
- return new MsgConfigureChannelizer(sampleRate, centerFrequency);
- }
-
- private:
- int m_sampleRate;
- int m_centerFrequency;
-
- MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
- Message(),
- m_sampleRate(sampleRate),
- m_centerFrequency(centerFrequency)
- { }
- };
-
- class MsgReportChannelSampleRateChanged : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
-
- static MsgReportChannelSampleRateChanged* create()
- {
- return new MsgReportChannelSampleRateChanged();
- }
-
- private:
-
- MsgReportChannelSampleRateChanged() :
- Message()
- { }
- };
-
- ChannelAnalyzerNG(DeviceSourceAPI *deviceAPI);
- virtual ~ChannelAnalyzerNG();
- void setSampleSink(BasebandSampleSink* sampleSink) { m_sampleSink = sampleSink; }
-
- void configure(MessageQueue* messageQueue,
- int channelSampleRate,
- Real Bandwidth,
- Real LowCutoff,
- int spanLog2,
- bool ssb);
-
- DownChannelizer *getChannelizer() { return m_channelizer; }
- int getInputSampleRate() const { return m_running.m_inputSampleRate; }
- int getChannelSampleRate() const { return m_running.m_channelSampleRate; }
- double getMagSq() const { return m_magsq; }
-
- virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
- virtual void start();
- virtual void stop();
- virtual bool handleMessage(const Message& cmd);
-
-private slots:
- void channelizerInputSampleRateChanged();
-
-private:
-
- struct Config
- {
- int m_frequency;
- int m_inputSampleRate;
- int m_channelSampleRate;
- Real m_Bandwidth;
- Real m_LowCutoff;
- int m_spanLog2;
- bool m_ssb;
-
- Config() :
- m_frequency(0),
- m_inputSampleRate(96000),
- m_channelSampleRate(96000),
- m_Bandwidth(5000),
- m_LowCutoff(300),
- m_spanLog2(3),
- m_ssb(false)
- {}
- };
-
- Config m_config;
- Config m_running;
-
- DeviceSourceAPI *m_deviceAPI;
- ThreadedBasebandSampleSink* m_threadedChannelizer;
- DownChannelizer* m_channelizer;
-
- int m_undersampleCount;
- fftfilt::cmplx m_sum;
- bool m_usb;
- double m_magsq;
- bool m_useInterpolator;
-
- NCOF m_nco;
- Interpolator m_interpolator;
- Real m_interpolatorDistance;
- Real m_interpolatorDistanceRemain;
-
- fftfilt* SSBFilter;
- fftfilt* DSBFilter;
-
- BasebandSampleSink* m_sampleSink;
- SampleVector m_sampleBuffer;
- QMutex m_settingsMutex;
-
- void apply(bool force = false);
-
- void processOneSample(Complex& c, fftfilt::cmplx *sideband)
- {
- int n_out;
- int decim = 1<runSSB(c, &sideband, m_usb);
- }
- else
- {
- n_out = DSBFilter->runDSB(c, &sideband);
- }
-
- for (int i = 0; i < n_out; i++)
- {
- // Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display
- // smart decimation with bit gain using float arithmetic (23 bits significand)
-
- m_sum += sideband[i];
-
- if (!(m_undersampleCount++ & (decim - 1))) // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1)
- {
- m_sum /= decim;
- m_magsq = (m_sum.real() * m_sum.real() + m_sum.imag() * m_sum.imag())/ (1<<30);
-
- if (m_running.m_ssb & !m_usb)
- { // invert spectrum for LSB
- //m_sampleBuffer.push_back(Sample(m_sum.imag() * 32768.0, m_sum.real() * 32768.0));
- m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real()));
- }
- else
- {
- //m_sampleBuffer.push_back(Sample(m_sum.real() * 32768.0, m_sum.imag() * 32768.0));
- m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag()));
- }
-
- m_sum = 0;
- }
- }
- }
-};
-
-#endif // INCLUDE_CHANALYZERNG_H
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2017 Edouard Griffiths, F4EXB //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDE_CHANALYZERNG_H
+#define INCLUDE_CHANALYZERNG_H
+
+#include
+#include
+#include
+
+#include "dsp/interpolator.h"
+#include "dsp/ncof.h"
+#include "dsp/fftfilt.h"
+#include "audio/audiofifo.h"
+#include "util/message.h"
+
+#define ssbFftLen 1024
+
+class DeviceSourceAPI;
+class ThreadedBasebandSampleSink;
+class DownChannelizer;
+
+class ChannelAnalyzerNG : public BasebandSampleSink {
+public:
+ class MsgConfigureChannelAnalyzer : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ int getChannelSampleRate() const { return m_channelSampleRate; }
+ Real getBandwidth() const { return m_Bandwidth; }
+ Real getLoCutoff() const { return m_LowCutoff; }
+ int getSpanLog2() const { return m_spanLog2; }
+ bool getSSB() const { return m_ssb; }
+
+ static MsgConfigureChannelAnalyzer* create(
+ int channelSampleRate,
+ Real Bandwidth,
+ Real LowCutoff,
+ int spanLog2,
+ bool ssb)
+ {
+ return new MsgConfigureChannelAnalyzer(
+ channelSampleRate,
+ Bandwidth,
+ LowCutoff,
+ spanLog2,
+ ssb);
+ }
+
+ private:
+ int m_channelSampleRate;
+ Real m_Bandwidth;
+ Real m_LowCutoff;
+ int m_spanLog2;
+ bool m_ssb;
+
+ MsgConfigureChannelAnalyzer(
+ int channelSampleRate,
+ Real Bandwidth,
+ Real LowCutoff,
+ int spanLog2,
+ bool ssb) :
+ Message(),
+ m_channelSampleRate(channelSampleRate),
+ m_Bandwidth(Bandwidth),
+ m_LowCutoff(LowCutoff),
+ m_spanLog2(spanLog2),
+ m_ssb(ssb)
+ { }
+ };
+
+ class MsgConfigureChannelizer : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ int getSampleRate() const { return m_sampleRate; }
+ int getCenterFrequency() const { return m_centerFrequency; }
+
+ static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
+ {
+ return new MsgConfigureChannelizer(sampleRate, centerFrequency);
+ }
+
+ private:
+ int m_sampleRate;
+ int m_centerFrequency;
+
+ MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
+ Message(),
+ m_sampleRate(sampleRate),
+ m_centerFrequency(centerFrequency)
+ { }
+ };
+
+ class MsgReportChannelSampleRateChanged : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+
+ static MsgReportChannelSampleRateChanged* create()
+ {
+ return new MsgReportChannelSampleRateChanged();
+ }
+
+ private:
+
+ MsgReportChannelSampleRateChanged() :
+ Message()
+ { }
+ };
+
+ ChannelAnalyzerNG(DeviceSourceAPI *deviceAPI);
+ virtual ~ChannelAnalyzerNG();
+ void setSampleSink(BasebandSampleSink* sampleSink) { m_sampleSink = sampleSink; }
+
+ void configure(MessageQueue* messageQueue,
+ int channelSampleRate,
+ Real Bandwidth,
+ Real LowCutoff,
+ int spanLog2,
+ bool ssb);
+
+ DownChannelizer *getChannelizer() { return m_channelizer; }
+ int getInputSampleRate() const { return m_running.m_inputSampleRate; }
+ int getChannelSampleRate() const { return m_running.m_channelSampleRate; }
+ double getMagSq() const { return m_magsq; }
+
+ virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
+ virtual void start();
+ virtual void stop();
+ virtual bool handleMessage(const Message& cmd);
+
+ static const QString m_channelID;
+
+private slots:
+ void channelizerInputSampleRateChanged();
+
+private:
+
+ struct Config
+ {
+ int m_frequency;
+ int m_inputSampleRate;
+ int m_channelSampleRate;
+ Real m_Bandwidth;
+ Real m_LowCutoff;
+ int m_spanLog2;
+ bool m_ssb;
+
+ Config() :
+ m_frequency(0),
+ m_inputSampleRate(96000),
+ m_channelSampleRate(96000),
+ m_Bandwidth(5000),
+ m_LowCutoff(300),
+ m_spanLog2(3),
+ m_ssb(false)
+ {}
+ };
+
+ Config m_config;
+ Config m_running;
+
+ DeviceSourceAPI *m_deviceAPI;
+ ThreadedBasebandSampleSink* m_threadedChannelizer;
+ DownChannelizer* m_channelizer;
+
+ int m_undersampleCount;
+ fftfilt::cmplx m_sum;
+ bool m_usb;
+ double m_magsq;
+ bool m_useInterpolator;
+
+ NCOF m_nco;
+ Interpolator m_interpolator;
+ Real m_interpolatorDistance;
+ Real m_interpolatorDistanceRemain;
+
+ fftfilt* SSBFilter;
+ fftfilt* DSBFilter;
+
+ BasebandSampleSink* m_sampleSink;
+ SampleVector m_sampleBuffer;
+ QMutex m_settingsMutex;
+
+ void apply(bool force = false);
+
+ void processOneSample(Complex& c, fftfilt::cmplx *sideband)
+ {
+ int n_out;
+ int decim = 1<runSSB(c, &sideband, m_usb);
+ }
+ else
+ {
+ n_out = DSBFilter->runDSB(c, &sideband);
+ }
+
+ for (int i = 0; i < n_out; i++)
+ {
+ // Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display
+ // smart decimation with bit gain using float arithmetic (23 bits significand)
+
+ m_sum += sideband[i];
+
+ if (!(m_undersampleCount++ & (decim - 1))) // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1)
+ {
+ m_sum /= decim;
+ m_magsq = (m_sum.real() * m_sum.real() + m_sum.imag() * m_sum.imag())/ (1<<30);
+
+ if (m_running.m_ssb & !m_usb)
+ { // invert spectrum for LSB
+ //m_sampleBuffer.push_back(Sample(m_sum.imag() * 32768.0, m_sum.real() * 32768.0));
+ m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real()));
+ }
+ else
+ {
+ //m_sampleBuffer.push_back(Sample(m_sum.real() * 32768.0, m_sum.imag() * 32768.0));
+ m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag()));
+ }
+
+ m_sum = 0;
+ }
+ }
+ }
+};
+
+#endif // INCLUDE_CHANALYZERNG_H
diff --git a/plugins/channelrx/chanalyzerng/chanalyzernggui.cpp b/plugins/channelrx/chanalyzerng/chanalyzernggui.cpp
index 255fec1d1..38c872202 100644
--- a/plugins/channelrx/chanalyzerng/chanalyzernggui.cpp
+++ b/plugins/channelrx/chanalyzerng/chanalyzernggui.cpp
@@ -38,8 +38,6 @@
#include "chanalyzerng.h"
-const QString ChannelAnalyzerNGGUI::m_channelID = "sdrangel.channel.chanalyzerng";
-
ChannelAnalyzerNGGUI* ChannelAnalyzerNGGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet)
{
ChannelAnalyzerNGGUI* gui = new ChannelAnalyzerNGGUI(pluginAPI, deviceUISet);
@@ -407,7 +405,7 @@ ChannelAnalyzerNGGUI::ChannelAnalyzerNGGUI(PluginAPI* pluginAPI, DeviceUISet *de
connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(viewChanged()));
- m_deviceUISet->registerRxChannelInstance(m_channelID, this);
+ m_deviceUISet->registerRxChannelInstance(ChannelAnalyzerNG::m_channelID, this);
m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this);
diff --git a/plugins/channelrx/chanalyzerng/chanalyzernggui.h b/plugins/channelrx/chanalyzerng/chanalyzernggui.h
index 1b71d1de1..b1c26f625 100644
--- a/plugins/channelrx/chanalyzerng/chanalyzernggui.h
+++ b/plugins/channelrx/chanalyzerng/chanalyzernggui.h
@@ -55,8 +55,6 @@ public:
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual bool handleMessage(const Message& message);
- static const QString m_channelID;
-
private slots:
void viewChanged();
// void channelizerInputSampleRateChanged();
diff --git a/plugins/channelrx/chanalyzerng/chanalyzerngplugin.cpp b/plugins/channelrx/chanalyzerng/chanalyzerngplugin.cpp
index f5881edec..d61d48721 100644
--- a/plugins/channelrx/chanalyzerng/chanalyzerngplugin.cpp
+++ b/plugins/channelrx/chanalyzerng/chanalyzerngplugin.cpp
@@ -19,10 +19,11 @@
#include "plugin/pluginapi.h"
#include "chanalyzerngplugin.h"
#include "chanalyzernggui.h"
+#include "chanalyzerng.h"
const PluginDescriptor ChannelAnalyzerNGPlugin::m_pluginDescriptor = {
QString("Channel Analyzer NG"),
- QString("3.8.0"),
+ QString("3.8.2"),
QString("(c) Edouard Griffiths, F4EXB"),
QString("https://github.com/f4exb/sdrangel"),
true,
@@ -45,16 +46,28 @@ void ChannelAnalyzerNGPlugin::initPlugin(PluginAPI* pluginAPI)
m_pluginAPI = pluginAPI;
// register demodulator
- m_pluginAPI->registerRxChannel(ChannelAnalyzerNGGUI::m_channelID, this);
+ m_pluginAPI->registerRxChannel(ChannelAnalyzerNG::m_channelID, this);
}
PluginInstanceGUI* ChannelAnalyzerNGPlugin::createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet)
{
- if(channelName == ChannelAnalyzerNGGUI::m_channelID)
+ if(channelName == ChannelAnalyzerNG::m_channelID)
{
ChannelAnalyzerNGGUI* gui = ChannelAnalyzerNGGUI::create(m_pluginAPI, deviceUISet);
return gui;
} else {
- return NULL;
+ return 0;
}
}
+
+BasebandSampleSink* ChannelAnalyzerNGPlugin::createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI)
+{
+ if(channelName == ChannelAnalyzerNG::m_channelID)
+ {
+ ChannelAnalyzerNG* sink = new ChannelAnalyzerNG(deviceAPI);
+ return sink;
+ } else {
+ return 0;
+ }
+}
+
diff --git a/plugins/channelrx/chanalyzerng/chanalyzerngplugin.h b/plugins/channelrx/chanalyzerng/chanalyzerngplugin.h
index 90993336e..04ed80427 100644
--- a/plugins/channelrx/chanalyzerng/chanalyzerngplugin.h
+++ b/plugins/channelrx/chanalyzerng/chanalyzerngplugin.h
@@ -22,6 +22,7 @@
#include "plugin/plugininterface.h"
class DeviceUISet;
+class BasebandSampleSink;
class ChannelAnalyzerNGPlugin : public QObject, PluginInterface {
Q_OBJECT
@@ -35,6 +36,7 @@ public:
void initPlugin(PluginAPI* pluginAPI);
PluginInstanceGUI* createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet);
+ BasebandSampleSink* createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI);
private:
static const PluginDescriptor m_pluginDescriptor;
diff --git a/plugins/channelrx/demodam/amdemod.cpp b/plugins/channelrx/demodam/amdemod.cpp
index 7e4e3c0fe..9392965a5 100644
--- a/plugins/channelrx/demodam/amdemod.cpp
+++ b/plugins/channelrx/demodam/amdemod.cpp
@@ -32,6 +32,7 @@
MESSAGE_CLASS_DEFINITION(AMDemod::MsgConfigureAMDemod, Message)
MESSAGE_CLASS_DEFINITION(AMDemod::MsgConfigureChannelizer, Message)
+const QString AMDemod::m_channelID = "de.maintech.sdrangelove.channel.am";
const int AMDemod::m_udpBlockSize = 512;
AMDemod::AMDemod(DeviceSourceAPI *deviceAPI) :
diff --git a/plugins/channelrx/demodam/amdemod.h b/plugins/channelrx/demodam/amdemod.h
index 8c48c2914..a7a0a5bff 100644
--- a/plugins/channelrx/demodam/amdemod.h
+++ b/plugins/channelrx/demodam/amdemod.h
@@ -1,227 +1,229 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2015 Edouard Griffiths, F4EXB. //
-// //
-// This program is free software; you can redistribute it and/or modify //
-// it under the terms of the GNU General Public License as published by //
-// the Free Software Foundation as version 3 of the License, or //
-// //
-// This program is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU General Public License V3 for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program. If not, see . //
-///////////////////////////////////////////////////////////////////////////////////
-
-#ifndef INCLUDE_AMDEMOD_H
-#define INCLUDE_AMDEMOD_H
-
-#include
-#include
-#include
-#include "dsp/nco.h"
-#include "dsp/interpolator.h"
-#include "dsp/movingaverage.h"
-#include "dsp/agc.h"
-#include "dsp/bandpass.h"
-#include "audio/audiofifo.h"
-#include "util/message.h"
-#include "amdemodsettings.h"
-
-class DeviceSourceAPI;
-class DownChannelizer;
-class ThreadedBasebandSampleSink;
-
-class AMDemod : public BasebandSampleSink {
- Q_OBJECT
-public:
- class MsgConfigureAMDemod : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- const AMDemodSettings& getSettings() const { return m_settings; }
- bool getForce() const { return m_force; }
-
- static MsgConfigureAMDemod* create(const AMDemodSettings& settings, bool force)
- {
- return new MsgConfigureAMDemod(settings, force);
- }
-
- private:
- AMDemodSettings m_settings;
- bool m_force;
-
- MsgConfigureAMDemod(const AMDemodSettings& settings, bool force) :
- Message(),
- m_settings(settings),
- m_force(force)
- { }
- };
-
- class MsgConfigureChannelizer : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- int getSampleRate() const { return m_sampleRate; }
- int getCenterFrequency() const { return m_centerFrequency; }
-
- static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
- {
- return new MsgConfigureChannelizer(sampleRate, centerFrequency);
- }
-
- private:
- int m_sampleRate;
- int m_centerFrequency;
-
- MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
- Message(),
- m_sampleRate(sampleRate),
- m_centerFrequency(centerFrequency)
- { }
- };
-
- AMDemod(DeviceSourceAPI *deviceAPI);
- ~AMDemod();
-
- virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po);
- virtual void start();
- virtual void stop();
- virtual bool handleMessage(const Message& cmd);
-
- double getMagSq() const { return m_magsq; }
- bool getSquelchOpen() const { return m_squelchOpen; }
-
- void getMagSqLevels(double& avg, double& peak, int& nbSamples)
- {
- avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount;
- peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak;
- nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount;
- m_magsqSum = 0.0f;
- m_magsqPeak = 0.0f;
- m_magsqCount = 0;
- }
-
-private:
- enum RateState {
- RSInitialFill,
- RSRunning
- };
-
- DeviceSourceAPI *m_deviceAPI;
- ThreadedBasebandSampleSink* m_threadedChannelizer;
- DownChannelizer* m_channelizer;
-
- AMDemodSettings m_settings;
-
- NCO m_nco;
- Interpolator m_interpolator;
- Real m_interpolatorDistance;
- Real m_interpolatorDistanceRemain;
-
- Real m_squelchLevel;
- uint32_t m_squelchCount;
- bool m_squelchOpen;
- double m_magsq;
- double m_magsqSum;
- double m_magsqPeak;
- int m_magsqCount;
-
- MovingAverage m_movingAverage;
- SimpleAGC m_volumeAGC;
- Bandpass m_bandpass;
-
- AudioVector m_audioBuffer;
- uint32_t m_audioBufferFill;
- AudioFifo m_audioFifo;
- UDPSink *m_udpBufferAudio;
-
- static const int m_udpBlockSize;
-
- QMutex m_settingsMutex;
-
-// void apply(bool force = false);
- void applySettings(const AMDemodSettings& settings, bool force = false);
-
- void processOneSample(Complex &ci)
- {
- Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
- magsq /= (1<<30);
- m_movingAverage.feed(magsq);
- m_magsq = m_movingAverage.average();
- m_magsqSum += magsq;
-
- if (magsq > m_magsqPeak)
- {
- m_magsqPeak = magsq;
- }
-
- m_magsqCount++;
-
- if (m_magsq >= m_squelchLevel)
- {
- if (m_squelchCount <= m_settings.m_audioSampleRate / 10)
- {
- if (m_squelchCount == m_settings.m_audioSampleRate / 20) {
- m_volumeAGC.fill(1.0);
- }
-
- m_squelchCount++;
- }
- }
- else
- {
- if (m_squelchCount > 1)
- {
- m_squelchCount -= 2;
- }
- }
-
- qint16 sample;
-
- if ((m_squelchCount >= m_settings.m_audioSampleRate / 20) && !m_settings.m_audioMute)
- {
- Real demod = sqrt(magsq);
- m_volumeAGC.feed(demod);
- demod = (demod - m_volumeAGC.getValue()) / m_volumeAGC.getValue();
-
- if (m_settings.m_bandpassEnable)
- {
- demod = m_bandpass.filter(demod);
- demod /= 301.0f;
- }
-
- Real attack = (m_squelchCount - 0.05f * m_settings.m_audioSampleRate) / (0.05f * m_settings.m_audioSampleRate);
- sample = demod * attack * 2048 * m_settings.m_volume;
- if (m_settings.m_copyAudioToUDP) m_udpBufferAudio->write(demod * attack * 32768);
-
- m_squelchOpen = true;
- }
- else
- {
- sample = 0;
- if (m_settings.m_copyAudioToUDP) m_udpBufferAudio->write(0);
- m_squelchOpen = false;
- }
-
- 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, 10);
-
- if (res != m_audioBufferFill)
- {
- qDebug("AMDemod::feed: %u/%u audio samples written", res, m_audioBufferFill);
- }
-
- m_audioBufferFill = 0;
- }
- }
-
-};
-
-#endif // INCLUDE_AMDEMOD_H
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2015 Edouard Griffiths, F4EXB. //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDE_AMDEMOD_H
+#define INCLUDE_AMDEMOD_H
+
+#include
+#include
+#include
+#include "dsp/nco.h"
+#include "dsp/interpolator.h"
+#include "dsp/movingaverage.h"
+#include "dsp/agc.h"
+#include "dsp/bandpass.h"
+#include "audio/audiofifo.h"
+#include "util/message.h"
+#include "amdemodsettings.h"
+
+class DeviceSourceAPI;
+class DownChannelizer;
+class ThreadedBasebandSampleSink;
+
+class AMDemod : public BasebandSampleSink {
+ Q_OBJECT
+public:
+ class MsgConfigureAMDemod : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ const AMDemodSettings& getSettings() const { return m_settings; }
+ bool getForce() const { return m_force; }
+
+ static MsgConfigureAMDemod* create(const AMDemodSettings& settings, bool force)
+ {
+ return new MsgConfigureAMDemod(settings, force);
+ }
+
+ private:
+ AMDemodSettings m_settings;
+ bool m_force;
+
+ MsgConfigureAMDemod(const AMDemodSettings& settings, bool force) :
+ Message(),
+ m_settings(settings),
+ m_force(force)
+ { }
+ };
+
+ class MsgConfigureChannelizer : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ int getSampleRate() const { return m_sampleRate; }
+ int getCenterFrequency() const { return m_centerFrequency; }
+
+ static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
+ {
+ return new MsgConfigureChannelizer(sampleRate, centerFrequency);
+ }
+
+ private:
+ int m_sampleRate;
+ int m_centerFrequency;
+
+ MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
+ Message(),
+ m_sampleRate(sampleRate),
+ m_centerFrequency(centerFrequency)
+ { }
+ };
+
+ AMDemod(DeviceSourceAPI *deviceAPI);
+ ~AMDemod();
+
+ virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po);
+ virtual void start();
+ virtual void stop();
+ virtual bool handleMessage(const Message& cmd);
+
+ double getMagSq() const { return m_magsq; }
+ bool getSquelchOpen() const { return m_squelchOpen; }
+
+ void getMagSqLevels(double& avg, double& peak, int& nbSamples)
+ {
+ avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount;
+ peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak;
+ nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount;
+ m_magsqSum = 0.0f;
+ m_magsqPeak = 0.0f;
+ m_magsqCount = 0;
+ }
+
+ static const QString m_channelID;
+
+private:
+ enum RateState {
+ RSInitialFill,
+ RSRunning
+ };
+
+ DeviceSourceAPI *m_deviceAPI;
+ ThreadedBasebandSampleSink* m_threadedChannelizer;
+ DownChannelizer* m_channelizer;
+
+ AMDemodSettings m_settings;
+
+ NCO m_nco;
+ Interpolator m_interpolator;
+ Real m_interpolatorDistance;
+ Real m_interpolatorDistanceRemain;
+
+ Real m_squelchLevel;
+ uint32_t m_squelchCount;
+ bool m_squelchOpen;
+ double m_magsq;
+ double m_magsqSum;
+ double m_magsqPeak;
+ int m_magsqCount;
+
+ MovingAverage m_movingAverage;
+ SimpleAGC m_volumeAGC;
+ Bandpass m_bandpass;
+
+ AudioVector m_audioBuffer;
+ uint32_t m_audioBufferFill;
+ AudioFifo m_audioFifo;
+ UDPSink *m_udpBufferAudio;
+
+ static const int m_udpBlockSize;
+
+ QMutex m_settingsMutex;
+
+// void apply(bool force = false);
+ void applySettings(const AMDemodSettings& settings, bool force = false);
+
+ void processOneSample(Complex &ci)
+ {
+ Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
+ magsq /= (1<<30);
+ m_movingAverage.feed(magsq);
+ m_magsq = m_movingAverage.average();
+ m_magsqSum += magsq;
+
+ if (magsq > m_magsqPeak)
+ {
+ m_magsqPeak = magsq;
+ }
+
+ m_magsqCount++;
+
+ if (m_magsq >= m_squelchLevel)
+ {
+ if (m_squelchCount <= m_settings.m_audioSampleRate / 10)
+ {
+ if (m_squelchCount == m_settings.m_audioSampleRate / 20) {
+ m_volumeAGC.fill(1.0);
+ }
+
+ m_squelchCount++;
+ }
+ }
+ else
+ {
+ if (m_squelchCount > 1)
+ {
+ m_squelchCount -= 2;
+ }
+ }
+
+ qint16 sample;
+
+ if ((m_squelchCount >= m_settings.m_audioSampleRate / 20) && !m_settings.m_audioMute)
+ {
+ Real demod = sqrt(magsq);
+ m_volumeAGC.feed(demod);
+ demod = (demod - m_volumeAGC.getValue()) / m_volumeAGC.getValue();
+
+ if (m_settings.m_bandpassEnable)
+ {
+ demod = m_bandpass.filter(demod);
+ demod /= 301.0f;
+ }
+
+ Real attack = (m_squelchCount - 0.05f * m_settings.m_audioSampleRate) / (0.05f * m_settings.m_audioSampleRate);
+ sample = demod * attack * 2048 * m_settings.m_volume;
+ if (m_settings.m_copyAudioToUDP) m_udpBufferAudio->write(demod * attack * 32768);
+
+ m_squelchOpen = true;
+ }
+ else
+ {
+ sample = 0;
+ if (m_settings.m_copyAudioToUDP) m_udpBufferAudio->write(0);
+ m_squelchOpen = false;
+ }
+
+ 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, 10);
+
+ if (res != m_audioBufferFill)
+ {
+ qDebug("AMDemod::feed: %u/%u audio samples written", res, m_audioBufferFill);
+ }
+
+ m_audioBufferFill = 0;
+ }
+ }
+
+};
+
+#endif // INCLUDE_AMDEMOD_H
diff --git a/plugins/channelrx/demodam/amdemodgui.cpp b/plugins/channelrx/demodam/amdemodgui.cpp
index a4a836353..87fd18a19 100644
--- a/plugins/channelrx/demodam/amdemodgui.cpp
+++ b/plugins/channelrx/demodam/amdemodgui.cpp
@@ -34,8 +34,6 @@
#include "amdemod.h"
-const QString AMDemodGUI::m_channelID = "de.maintech.sdrangelove.channel.am";
-
AMDemodGUI* AMDemodGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet)
{
AMDemodGUI* gui = new AMDemodGUI(pluginAPI, deviceUISet);
@@ -206,7 +204,7 @@ AMDemodGUI::AMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, QWidget*
connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged()));
- m_deviceUISet->registerRxChannelInstance(m_channelID, this);
+ m_deviceUISet->registerRxChannelInstance(AMDemod::m_channelID, this);
m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this);
diff --git a/plugins/channelrx/demodam/amdemodgui.h b/plugins/channelrx/demodam/amdemodgui.h
index 32833328b..52a0211e0 100644
--- a/plugins/channelrx/demodam/amdemodgui.h
+++ b/plugins/channelrx/demodam/amdemodgui.h
@@ -37,8 +37,6 @@ public:
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual bool handleMessage(const Message& message);
- static const QString m_channelID;
-
private slots:
void channelMarkerChanged();
void on_deltaFrequency_changed(qint64 value);
diff --git a/plugins/channelrx/demodam/amdemodplugin.cpp b/plugins/channelrx/demodam/amdemodplugin.cpp
index c93b20857..b551ab1c1 100644
--- a/plugins/channelrx/demodam/amdemodplugin.cpp
+++ b/plugins/channelrx/demodam/amdemodplugin.cpp
@@ -31,12 +31,12 @@ void AMDemodPlugin::initPlugin(PluginAPI* pluginAPI)
m_pluginAPI = pluginAPI;
// register AM demodulator
- m_pluginAPI->registerRxChannel(AMDemodGUI::m_channelID, this);
+ m_pluginAPI->registerRxChannel(AMDemod::m_channelID, this);
}
PluginInstanceGUI* AMDemodPlugin::createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet)
{
- if(channelName == AMDemodGUI::m_channelID)
+ if(channelName == AMDemod::m_channelID)
{
AMDemodGUI* gui = AMDemodGUI::create(m_pluginAPI, deviceUISet);
return gui;
@@ -47,7 +47,7 @@ PluginInstanceGUI* AMDemodPlugin::createRxChannelGUI(const QString& channelName,
BasebandSampleSink* AMDemodPlugin::createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI)
{
- if(channelName == AMDemodGUI::m_channelID)
+ if(channelName == AMDemod::m_channelID)
{
AMDemod* sink = new AMDemod(deviceAPI);
return sink;
diff --git a/plugins/channelrx/demodatv/atvdemod.cpp b/plugins/channelrx/demodatv/atvdemod.cpp
index f9209bf1a..47543dc10 100644
--- a/plugins/channelrx/demodatv/atvdemod.cpp
+++ b/plugins/channelrx/demodatv/atvdemod.cpp
@@ -35,6 +35,7 @@ MESSAGE_CLASS_DEFINITION(ATVDemod::MsgReportEffectiveSampleRate, Message)
MESSAGE_CLASS_DEFINITION(ATVDemod::MsgConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(ATVDemod::MsgReportChannelSampleRateChanged, Message)
+const QString ATVDemod::m_channelID = "sdrangel.channel.demodatv";
const int ATVDemod::m_ssbFftLen = 1024;
ATVDemod::ATVDemod(DeviceSourceAPI *deviceAPI) :
diff --git a/plugins/channelrx/demodatv/atvdemod.h b/plugins/channelrx/demodatv/atvdemod.h
index 7013d3e23..c1fd93ddb 100644
--- a/plugins/channelrx/demodatv/atvdemod.h
+++ b/plugins/channelrx/demodatv/atvdemod.h
@@ -227,6 +227,8 @@ public:
double getMagSq() const { return m_objMagSqAverage.average(); } //!< Beware this is scaled to 2^30
bool getBFOLocked();
+ static const QString m_channelID;
+
private slots:
void channelSampleRateChanged();
diff --git a/plugins/channelrx/demodatv/atvdemodgui.cpp b/plugins/channelrx/demodatv/atvdemodgui.cpp
index 83cc9b83c..c671027a3 100644
--- a/plugins/channelrx/demodatv/atvdemodgui.cpp
+++ b/plugins/channelrx/demodatv/atvdemodgui.cpp
@@ -36,8 +36,6 @@
#include "atvdemod.h"
-const QString ATVDemodGUI::m_strChannelID = "sdrangel.channel.demodatv";
-
ATVDemodGUI* ATVDemodGUI::create(PluginAPI* objPluginAPI,
DeviceUISet *deviceUISet)
{
@@ -312,7 +310,7 @@ ATVDemodGUI::ATVDemodGUI(PluginAPI* objPluginAPI, DeviceUISet *deviceUISet,
connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(viewChanged()));
- m_deviceUISet->registerRxChannelInstance(m_strChannelID, this);
+ m_deviceUISet->registerRxChannelInstance(ATVDemod::m_channelID, this);
m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this);
diff --git a/plugins/channelrx/demodatv/atvdemodgui.h b/plugins/channelrx/demodatv/atvdemodgui.h
index 0fdbdeb7a..abacc0a8d 100644
--- a/plugins/channelrx/demodatv/atvdemodgui.h
+++ b/plugins/channelrx/demodatv/atvdemodgui.h
@@ -54,8 +54,6 @@ public:
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual bool handleMessage(const Message& objMessage);
- static const QString m_strChannelID;
-
private slots:
void viewChanged();
void handleSourceMessages();
diff --git a/plugins/channelrx/demodatv/atvdemodplugin.cpp b/plugins/channelrx/demodatv/atvdemodplugin.cpp
index 2cb0de19c..4dfa93be3 100644
--- a/plugins/channelrx/demodatv/atvdemodplugin.cpp
+++ b/plugins/channelrx/demodatv/atvdemodplugin.cpp
@@ -21,6 +21,7 @@
#include "plugin/pluginapi.h"
#include "atvdemodgui.h"
+#include "atvdemod.h"
#include "atvdemodplugin.h"
const PluginDescriptor ATVDemodPlugin::m_ptrPluginDescriptor =
@@ -50,18 +51,30 @@ void ATVDemodPlugin::initPlugin(PluginAPI* ptrPluginAPI)
m_ptrPluginAPI = ptrPluginAPI;
// register ATV demodulator
- m_ptrPluginAPI->registerRxChannel(ATVDemodGUI::m_strChannelID, this);
+ m_ptrPluginAPI->registerRxChannel(ATVDemod::m_channelID, this);
}
PluginInstanceGUI* ATVDemodPlugin::createRxChannelGUI(const QString& strChannelName, DeviceUISet *deviceUISet)
{
- if(strChannelName == ATVDemodGUI::m_strChannelID)
+ if(strChannelName == ATVDemod::m_channelID)
{
ATVDemodGUI* ptrGui = ATVDemodGUI::create(m_ptrPluginAPI, deviceUISet);
return ptrGui;
}
else
{
- return NULL;
+ return 0;
}
}
+
+BasebandSampleSink* ATVDemodPlugin::createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI)
+{
+ if(channelName == ATVDemod::m_channelID)
+ {
+ ATVDemod* sink = new ATVDemod(deviceAPI);
+ return sink;
+ } else {
+ return 0;
+ }
+}
+
diff --git a/plugins/channelrx/demodatv/atvdemodplugin.h b/plugins/channelrx/demodatv/atvdemodplugin.h
index e8f61e681..c8dde4005 100644
--- a/plugins/channelrx/demodatv/atvdemodplugin.h
+++ b/plugins/channelrx/demodatv/atvdemodplugin.h
@@ -22,6 +22,7 @@
#include "plugin/plugininterface.h"
class DeviceUISet;
+class BasebandSampleSink;
class ATVDemodPlugin : public QObject, PluginInterface
{
@@ -36,6 +37,7 @@ public:
void initPlugin(PluginAPI* ptrPluginAPI);
PluginInstanceGUI* createRxChannelGUI(const QString& strChannelName, DeviceUISet *deviceUISet);
+ BasebandSampleSink* createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI);
private:
static const PluginDescriptor m_ptrPluginDescriptor;
diff --git a/plugins/channelrx/demodbfm/bfmdemod.cpp b/plugins/channelrx/demodbfm/bfmdemod.cpp
index bda23fc3d..8954c65c0 100644
--- a/plugins/channelrx/demodbfm/bfmdemod.cpp
+++ b/plugins/channelrx/demodbfm/bfmdemod.cpp
@@ -34,6 +34,7 @@ MESSAGE_CLASS_DEFINITION(BFMDemod::MsgConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(BFMDemod::MsgReportChannelSampleRateChanged, Message)
MESSAGE_CLASS_DEFINITION(BFMDemod::MsgConfigureBFMDemod, Message)
+const QString BFMDemod::m_channelID = "sdrangel.channel.bfm";
const Real BFMDemod::default_deemphasis = 50.0; // 50 us
const int BFMDemod::m_udpBlockSize = 512;
diff --git a/plugins/channelrx/demodbfm/bfmdemod.h b/plugins/channelrx/demodbfm/bfmdemod.h
index 3c403bb19..1d5ddf13e 100644
--- a/plugins/channelrx/demodbfm/bfmdemod.h
+++ b/plugins/channelrx/demodbfm/bfmdemod.h
@@ -1,219 +1,221 @@
-///////////////////////////////////////////////////////////////////////////////////
-// 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_BFMDEMOD_H
-#define INCLUDE_BFMDEMOD_H
-
-#include
-#include
-#include
-#include "dsp/nco.h"
-#include "dsp/interpolator.h"
-#include "dsp/lowpass.h"
-#include "dsp/movingaverage.h"
-#include "dsp/fftfilt.h"
-#include "dsp/phaselock.h"
-#include "dsp/filterrc.h"
-#include "dsp/phasediscri.h"
-#include "audio/audiofifo.h"
-#include "util/message.h"
-#include "util/udpsink.h"
-
-#include "rdsparser.h"
-#include "rdsdecoder.h"
-#include "rdsdemod.h"
-#include "bfmdemodsettings.h"
-
-class DeviceSourceAPI;
-class ThreadedBasebandSampleSink;
-class DownChannelizer;
-
-class BFMDemod : public BasebandSampleSink {
-public:
- class MsgConfigureBFMDemod : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- const BFMDemodSettings& getSettings() const { return m_settings; }
- bool getForce() const { return m_force; }
-
- static MsgConfigureBFMDemod* create(const BFMDemodSettings& settings, bool force)
- {
- return new MsgConfigureBFMDemod(settings, force);
- }
-
- private:
- BFMDemodSettings m_settings;
- bool m_force;
-
- MsgConfigureBFMDemod(const BFMDemodSettings& settings, bool force) :
- Message(),
- m_settings(settings),
- m_force(force)
- { }
- };
-
- class MsgConfigureChannelizer : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- int getSampleRate() const { return m_sampleRate; }
- int getCenterFrequency() const { return m_centerFrequency; }
-
- static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
- {
- return new MsgConfigureChannelizer(sampleRate, centerFrequency);
- }
-
- private:
- int m_sampleRate;
- int m_centerFrequency;
-
- MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
- Message(),
- m_sampleRate(sampleRate),
- m_centerFrequency(centerFrequency)
- { }
- };
-
- class MsgReportChannelSampleRateChanged : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- int getSampleRate() const { return m_sampleRate; }
-
- static MsgReportChannelSampleRateChanged* create(int sampleRate)
- {
- return new MsgReportChannelSampleRateChanged(sampleRate);
- }
-
- private:
- int m_sampleRate;
-
- MsgReportChannelSampleRateChanged(int sampleRate) :
- Message(),
- m_sampleRate(sampleRate)
- { }
- };
-
- BFMDemod(DeviceSourceAPI *deviceAPI);
- virtual ~BFMDemod();
- void setSampleSink(BasebandSampleSink* sampleSink) { m_sampleSink = sampleSink; }
-
- int getSampleRate() const { return m_settings.m_inputSampleRate; }
- virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po);
- virtual void start();
- virtual void stop();
- virtual bool handleMessage(const Message& cmd);
-
- double getMagSq() const { return m_magsq; }
-
- bool getPilotLock() const { return m_pilotPLL.locked(); }
- Real getPilotLevel() const { return m_pilotPLL.get_pilot_level(); }
-
- Real getDecoderQua() const { return m_rdsDecoder.m_qua; }
- bool getDecoderSynced() const { return m_rdsDecoder.synced(); }
- Real getDemodAcc() const { return m_rdsDemod.m_report.acc; }
- Real getDemodQua() const { return m_rdsDemod.m_report.qua; }
- Real getDemodFclk() const { return m_rdsDemod.m_report.fclk; }
-
- void getMagSqLevels(double& avg, double& peak, int& nbSamples)
- {
- avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount;
- m_magsq = avg;
- peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak;
- nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount;
- m_magsqSum = 0.0f;
- m_magsqPeak = 0.0f;
- m_magsqCount = 0;
- }
-
- RDSParser& getRDSParser() { return m_rdsParser; }
-
-private slots:
- void channelSampleRateChanged();
-
-private:
- enum RateState {
- RSInitialFill,
- RSRunning
- };
-
- DeviceSourceAPI *m_deviceAPI;
- ThreadedBasebandSampleSink* m_threadedChannelizer;
- DownChannelizer* m_channelizer;
-
- BFMDemodSettings m_settings;
-
- NCO m_nco;
- Interpolator m_interpolator; //!< Interpolator between fixed demod bandwidth and audio bandwidth (rational)
- Real m_interpolatorDistance;
- Real m_interpolatorDistanceRemain;
-
- Interpolator m_interpolatorStereo; //!< Twin Interpolator for stereo subcarrier
- Real m_interpolatorStereoDistance;
- Real m_interpolatorStereoDistanceRemain;
-
- Interpolator m_interpolatorRDS; //!< Twin Interpolator for stereo subcarrier
- Real m_interpolatorRDSDistance;
- Real m_interpolatorRDSDistanceRemain;
-
- Lowpass m_lowpass;
- fftfilt* m_rfFilter;
- static const int filtFftLen = 1024;
-
- Real m_squelchLevel;
- int m_squelchState;
-
- Real m_m1Arg; //!> x^-1 real sample
-
- double m_magsq;
- double m_magsqSum;
- double m_magsqPeak;
- int m_magsqCount;
-
- AudioVector m_audioBuffer;
- uint m_audioBufferFill;
-
- BasebandSampleSink* m_sampleSink;
- AudioFifo m_audioFifo;
- SampleVector m_sampleBuffer;
- QMutex m_settingsMutex;
-
- RDSPhaseLock m_pilotPLL;
- Real m_pilotPLLSamples[4];
-
- RDSDemod m_rdsDemod;
- RDSDecoder m_rdsDecoder;
- RDSParser m_rdsParser;
-
- LowPassFilterRC m_deemphasisFilterX;
- LowPassFilterRC m_deemphasisFilterY;
- static const Real default_deemphasis;
-
- Real m_fmExcursion;
- static const int default_excursion = 750000; // +/- 75 kHz
-
- PhaseDiscriminators m_phaseDiscri;
- UDPSink *m_udpBufferAudio;
-
- static const int m_udpBlockSize;
-
- void applySettings(const BFMDemodSettings& settings, bool force = false);
-};
-
-#endif // INCLUDE_BFMDEMOD_H
+///////////////////////////////////////////////////////////////////////////////////
+// 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_BFMDEMOD_H
+#define INCLUDE_BFMDEMOD_H
+
+#include
+#include
+#include
+#include "dsp/nco.h"
+#include "dsp/interpolator.h"
+#include "dsp/lowpass.h"
+#include "dsp/movingaverage.h"
+#include "dsp/fftfilt.h"
+#include "dsp/phaselock.h"
+#include "dsp/filterrc.h"
+#include "dsp/phasediscri.h"
+#include "audio/audiofifo.h"
+#include "util/message.h"
+#include "util/udpsink.h"
+
+#include "rdsparser.h"
+#include "rdsdecoder.h"
+#include "rdsdemod.h"
+#include "bfmdemodsettings.h"
+
+class DeviceSourceAPI;
+class ThreadedBasebandSampleSink;
+class DownChannelizer;
+
+class BFMDemod : public BasebandSampleSink {
+public:
+ class MsgConfigureBFMDemod : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ const BFMDemodSettings& getSettings() const { return m_settings; }
+ bool getForce() const { return m_force; }
+
+ static MsgConfigureBFMDemod* create(const BFMDemodSettings& settings, bool force)
+ {
+ return new MsgConfigureBFMDemod(settings, force);
+ }
+
+ private:
+ BFMDemodSettings m_settings;
+ bool m_force;
+
+ MsgConfigureBFMDemod(const BFMDemodSettings& settings, bool force) :
+ Message(),
+ m_settings(settings),
+ m_force(force)
+ { }
+ };
+
+ class MsgConfigureChannelizer : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ int getSampleRate() const { return m_sampleRate; }
+ int getCenterFrequency() const { return m_centerFrequency; }
+
+ static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
+ {
+ return new MsgConfigureChannelizer(sampleRate, centerFrequency);
+ }
+
+ private:
+ int m_sampleRate;
+ int m_centerFrequency;
+
+ MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
+ Message(),
+ m_sampleRate(sampleRate),
+ m_centerFrequency(centerFrequency)
+ { }
+ };
+
+ class MsgReportChannelSampleRateChanged : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ int getSampleRate() const { return m_sampleRate; }
+
+ static MsgReportChannelSampleRateChanged* create(int sampleRate)
+ {
+ return new MsgReportChannelSampleRateChanged(sampleRate);
+ }
+
+ private:
+ int m_sampleRate;
+
+ MsgReportChannelSampleRateChanged(int sampleRate) :
+ Message(),
+ m_sampleRate(sampleRate)
+ { }
+ };
+
+ BFMDemod(DeviceSourceAPI *deviceAPI);
+ virtual ~BFMDemod();
+ void setSampleSink(BasebandSampleSink* sampleSink) { m_sampleSink = sampleSink; }
+
+ int getSampleRate() const { return m_settings.m_inputSampleRate; }
+ virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po);
+ virtual void start();
+ virtual void stop();
+ virtual bool handleMessage(const Message& cmd);
+
+ double getMagSq() const { return m_magsq; }
+
+ bool getPilotLock() const { return m_pilotPLL.locked(); }
+ Real getPilotLevel() const { return m_pilotPLL.get_pilot_level(); }
+
+ Real getDecoderQua() const { return m_rdsDecoder.m_qua; }
+ bool getDecoderSynced() const { return m_rdsDecoder.synced(); }
+ Real getDemodAcc() const { return m_rdsDemod.m_report.acc; }
+ Real getDemodQua() const { return m_rdsDemod.m_report.qua; }
+ Real getDemodFclk() const { return m_rdsDemod.m_report.fclk; }
+
+ void getMagSqLevels(double& avg, double& peak, int& nbSamples)
+ {
+ avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount;
+ m_magsq = avg;
+ peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak;
+ nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount;
+ m_magsqSum = 0.0f;
+ m_magsqPeak = 0.0f;
+ m_magsqCount = 0;
+ }
+
+ RDSParser& getRDSParser() { return m_rdsParser; }
+
+ static const QString m_channelID;
+
+private slots:
+ void channelSampleRateChanged();
+
+private:
+ enum RateState {
+ RSInitialFill,
+ RSRunning
+ };
+
+ DeviceSourceAPI *m_deviceAPI;
+ ThreadedBasebandSampleSink* m_threadedChannelizer;
+ DownChannelizer* m_channelizer;
+
+ BFMDemodSettings m_settings;
+
+ NCO m_nco;
+ Interpolator m_interpolator; //!< Interpolator between fixed demod bandwidth and audio bandwidth (rational)
+ Real m_interpolatorDistance;
+ Real m_interpolatorDistanceRemain;
+
+ Interpolator m_interpolatorStereo; //!< Twin Interpolator for stereo subcarrier
+ Real m_interpolatorStereoDistance;
+ Real m_interpolatorStereoDistanceRemain;
+
+ Interpolator m_interpolatorRDS; //!< Twin Interpolator for stereo subcarrier
+ Real m_interpolatorRDSDistance;
+ Real m_interpolatorRDSDistanceRemain;
+
+ Lowpass m_lowpass;
+ fftfilt* m_rfFilter;
+ static const int filtFftLen = 1024;
+
+ Real m_squelchLevel;
+ int m_squelchState;
+
+ Real m_m1Arg; //!> x^-1 real sample
+
+ double m_magsq;
+ double m_magsqSum;
+ double m_magsqPeak;
+ int m_magsqCount;
+
+ AudioVector m_audioBuffer;
+ uint m_audioBufferFill;
+
+ BasebandSampleSink* m_sampleSink;
+ AudioFifo m_audioFifo;
+ SampleVector m_sampleBuffer;
+ QMutex m_settingsMutex;
+
+ RDSPhaseLock m_pilotPLL;
+ Real m_pilotPLLSamples[4];
+
+ RDSDemod m_rdsDemod;
+ RDSDecoder m_rdsDecoder;
+ RDSParser m_rdsParser;
+
+ LowPassFilterRC m_deemphasisFilterX;
+ LowPassFilterRC m_deemphasisFilterY;
+ static const Real default_deemphasis;
+
+ Real m_fmExcursion;
+ static const int default_excursion = 750000; // +/- 75 kHz
+
+ PhaseDiscriminators m_phaseDiscri;
+ UDPSink *m_udpBufferAudio;
+
+ static const int m_udpBlockSize;
+
+ void applySettings(const BFMDemodSettings& settings, bool force = false);
+};
+
+#endif // INCLUDE_BFMDEMOD_H
diff --git a/plugins/channelrx/demodbfm/bfmdemodgui.cpp b/plugins/channelrx/demodbfm/bfmdemodgui.cpp
index 0476f702f..4a2b0b84a 100644
--- a/plugins/channelrx/demodbfm/bfmdemodgui.cpp
+++ b/plugins/channelrx/demodbfm/bfmdemodgui.cpp
@@ -43,8 +43,6 @@
#include "rdstmc.h"
#include "ui_bfmdemodgui.h"
-const QString BFMDemodGUI::m_channelID = "sdrangel.channel.bfm";
-
BFMDemodGUI* BFMDemodGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUIset)
{
BFMDemodGUI* gui = new BFMDemodGUI(pluginAPI, deviceUIset);
@@ -364,7 +362,7 @@ BFMDemodGUI::BFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, QWidget
connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged()));
- m_deviceUISet->registerRxChannelInstance(m_channelID, this);
+ m_deviceUISet->registerRxChannelInstance(BFMDemod::m_channelID, this);
m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this);
diff --git a/plugins/channelrx/demodbfm/bfmdemodgui.h b/plugins/channelrx/demodbfm/bfmdemodgui.h
index 5d83edd10..9b6307436 100644
--- a/plugins/channelrx/demodbfm/bfmdemodgui.h
+++ b/plugins/channelrx/demodbfm/bfmdemodgui.h
@@ -56,8 +56,6 @@ public:
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual bool handleMessage(const Message& message);
- static const QString m_channelID;
-
private slots:
void on_deltaFrequency_changed(qint64 value);
void on_rfBW_valueChanged(int value);
diff --git a/plugins/channelrx/demodbfm/bfmplugin.cpp b/plugins/channelrx/demodbfm/bfmplugin.cpp
index 923f7a20f..fa2c9ffa4 100644
--- a/plugins/channelrx/demodbfm/bfmplugin.cpp
+++ b/plugins/channelrx/demodbfm/bfmplugin.cpp
@@ -21,6 +21,7 @@
#include "plugin/pluginapi.h"
#include "bfmdemodgui.h"
+#include "bfmdemod.h"
const PluginDescriptor BFMPlugin::m_pluginDescriptor = {
QString("Broadcast FM Demodulator"),
@@ -47,12 +48,12 @@ void BFMPlugin::initPlugin(PluginAPI* pluginAPI)
m_pluginAPI = pluginAPI;
// register BFM demodulator
- m_pluginAPI->registerRxChannel(BFMDemodGUI::m_channelID, this);
+ m_pluginAPI->registerRxChannel(BFMDemod::m_channelID, this);
}
PluginInstanceGUI* BFMPlugin::createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet)
{
- if(channelName == BFMDemodGUI::m_channelID)
+ if(channelName == BFMDemod::m_channelID)
{
BFMDemodGUI* gui = BFMDemodGUI::create(m_pluginAPI, deviceUISet);
return gui;
@@ -60,3 +61,15 @@ PluginInstanceGUI* BFMPlugin::createRxChannelGUI(const QString& channelName, Dev
return 0;
}
}
+
+
+BasebandSampleSink* BFMPlugin::createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI)
+{
+ if(channelName == BFMDemod::m_channelID)
+ {
+ BFMDemod* sink = new BFMDemod(deviceAPI);
+ return sink;
+ } else {
+ return 0;
+ }
+}
diff --git a/plugins/channelrx/demodbfm/bfmplugin.h b/plugins/channelrx/demodbfm/bfmplugin.h
index 8377ac745..c03991768 100644
--- a/plugins/channelrx/demodbfm/bfmplugin.h
+++ b/plugins/channelrx/demodbfm/bfmplugin.h
@@ -35,6 +35,7 @@ public:
void initPlugin(PluginAPI* pluginAPI);
PluginInstanceGUI* createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet);
+ BasebandSampleSink* createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI);
private:
static const PluginDescriptor m_pluginDescriptor;
diff --git a/plugins/channelrx/demoddsd/dsddemod.cpp b/plugins/channelrx/demoddsd/dsddemod.cpp
index 9230ac579..d18120847 100644
--- a/plugins/channelrx/demoddsd/dsddemod.cpp
+++ b/plugins/channelrx/demoddsd/dsddemod.cpp
@@ -35,6 +35,7 @@ MESSAGE_CLASS_DEFINITION(DSDDemod::MsgConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(DSDDemod::MsgConfigureDSDDemod, Message)
MESSAGE_CLASS_DEFINITION(DSDDemod::MsgConfigureMyPosition, Message)
+const QString DSDDemod::m_channelID = "sdrangel.channel.dsddemod";
const int DSDDemod::m_udpBlockSize = 512;
DSDDemod::DSDDemod(DeviceSourceAPI *deviceAPI) :
diff --git a/plugins/channelrx/demoddsd/dsddemod.h b/plugins/channelrx/demoddsd/dsddemod.h
index 501c58ccc..1b4e0e896 100644
--- a/plugins/channelrx/demoddsd/dsddemod.h
+++ b/plugins/channelrx/demoddsd/dsddemod.h
@@ -1,194 +1,195 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2016 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_DSDDEMOD_H
-#define INCLUDE_DSDDEMOD_H
-
-#include
-#include
-#include
-#include
-#include "dsp/nco.h"
-#include "dsp/interpolator.h"
-#include "dsp/lowpass.h"
-#include "dsp/bandpass.h"
-#include "dsp/afsquelch.h"
-#include "dsp/movingaverage.h"
-#include "dsp/afsquelch.h"
-#include "audio/audiofifo.h"
-#include "util/message.h"
-#include "util/udpsink.h"
-
-#include "dsddemodsettings.h"
-#include "dsddecoder.h"
-
-class DeviceSourceAPI;
-class ThreadedBasebandSampleSink;
-class DownChannelizer;
-
-class DSDDemod : public BasebandSampleSink {
-public:
- class MsgConfigureDSDDemod : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- const DSDDemodSettings& getSettings() const { return m_settings; }
- bool getForce() const { return m_force; }
-
- static MsgConfigureDSDDemod* create(const DSDDemodSettings& settings, bool force)
- {
- return new MsgConfigureDSDDemod(settings, force);
- }
-
- private:
- DSDDemodSettings m_settings;
- bool m_force;
-
- MsgConfigureDSDDemod(const DSDDemodSettings& settings, bool force) :
- Message(),
- m_settings(settings),
- m_force(force)
- { }
- };
-
- class MsgConfigureChannelizer : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- int getSampleRate() const { return m_sampleRate; }
- int getCenterFrequency() const { return m_centerFrequency; }
-
- static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
- {
- return new MsgConfigureChannelizer(sampleRate, centerFrequency);
- }
-
- private:
- int m_sampleRate;
- int m_centerFrequency;
-
- MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
- Message(),
- m_sampleRate(sampleRate),
- m_centerFrequency(centerFrequency)
- { }
- };
-
- DSDDemod(DeviceSourceAPI *deviceAPI);
- ~DSDDemod();
- void setScopeSink(BasebandSampleSink* sampleSink) { m_scope = sampleSink; }
-
- void configureMyPosition(MessageQueue* messageQueue, float myLatitude, float myLongitude);
-
- virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po);
- virtual void start();
- virtual void stop();
- virtual bool handleMessage(const Message& cmd);
-
- double getMagSq() { return m_magsq; }
- bool getSquelchOpen() const { return m_squelchOpen; }
-
- const DSDDecoder& getDecoder() const { return m_dsdDecoder; }
-
- void getMagSqLevels(double& avg, double& peak, int& nbSamples)
- {
- avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount;
- m_magsq = avg;
- peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak;
- nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount;
- m_magsqSum = 0.0f;
- m_magsqPeak = 0.0f;
- m_magsqCount = 0;
- }
-
-
-private:
- class MsgConfigureMyPosition : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- float getMyLatitude() const { return m_myLatitude; }
- float getMyLongitude() const { return m_myLongitude; }
-
- static MsgConfigureMyPosition* create(float myLatitude, float myLongitude)
- {
- return new MsgConfigureMyPosition(myLatitude, myLongitude);
- }
-
- private:
- float m_myLatitude;
- float m_myLongitude;
-
- MsgConfigureMyPosition(float myLatitude, float myLongitude) :
- m_myLatitude(myLatitude),
- m_myLongitude(myLongitude)
- {}
- };
-
- enum RateState {
- RSInitialFill,
- RSRunning
- };
-
- DSDDemodSettings m_settings;
-
- DeviceSourceAPI *m_deviceAPI;
- ThreadedBasebandSampleSink* m_threadedChannelizer;
- DownChannelizer* m_channelizer;
-
- NCO m_nco;
- Interpolator m_interpolator;
- Real m_interpolatorDistance;
- Real m_interpolatorDistanceRemain;
- int m_sampleCount;
- int m_squelchCount;
- int m_squelchGate;
-
- double m_squelchLevel;
- bool m_squelchOpen;
-
- MovingAverage m_movingAverage;
- double m_magsq;
- double m_magsqSum;
- double m_magsqPeak;
- int m_magsqCount;
-
- Real m_fmExcursion;
-
- SampleVector m_scopeSampleBuffer;
- AudioVector m_audioBuffer;
- uint m_audioBufferFill;
- qint16 *m_sampleBuffer; //!< samples ring buffer
- int m_sampleBufferIndex;
-
- AudioFifo m_audioFifo1;
- AudioFifo m_audioFifo2;
- BasebandSampleSink* m_scope;
- bool m_scopeEnabled;
-
- DSDDecoder m_dsdDecoder;
- QMutex m_settingsMutex;
-
- PhaseDiscriminators m_phaseDiscri;
- UDPSink *m_udpBufferAudio;
-
- static const int m_udpBlockSize;
-
- void applySettings(DSDDemodSettings& settings, bool force = false);
-};
-
-#endif // INCLUDE_DSDDEMOD_H
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2016 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_DSDDEMOD_H
+#define INCLUDE_DSDDEMOD_H
+
+#include
+#include
+#include
+#include
+#include "dsp/nco.h"
+#include "dsp/interpolator.h"
+#include "dsp/lowpass.h"
+#include "dsp/bandpass.h"
+#include "dsp/afsquelch.h"
+#include "dsp/movingaverage.h"
+#include "dsp/afsquelch.h"
+#include "audio/audiofifo.h"
+#include "util/message.h"
+#include "util/udpsink.h"
+
+#include "dsddemodsettings.h"
+#include "dsddecoder.h"
+
+class DeviceSourceAPI;
+class ThreadedBasebandSampleSink;
+class DownChannelizer;
+
+class DSDDemod : public BasebandSampleSink {
+public:
+ class MsgConfigureDSDDemod : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ const DSDDemodSettings& getSettings() const { return m_settings; }
+ bool getForce() const { return m_force; }
+
+ static MsgConfigureDSDDemod* create(const DSDDemodSettings& settings, bool force)
+ {
+ return new MsgConfigureDSDDemod(settings, force);
+ }
+
+ private:
+ DSDDemodSettings m_settings;
+ bool m_force;
+
+ MsgConfigureDSDDemod(const DSDDemodSettings& settings, bool force) :
+ Message(),
+ m_settings(settings),
+ m_force(force)
+ { }
+ };
+
+ class MsgConfigureChannelizer : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ int getSampleRate() const { return m_sampleRate; }
+ int getCenterFrequency() const { return m_centerFrequency; }
+
+ static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
+ {
+ return new MsgConfigureChannelizer(sampleRate, centerFrequency);
+ }
+
+ private:
+ int m_sampleRate;
+ int m_centerFrequency;
+
+ MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
+ Message(),
+ m_sampleRate(sampleRate),
+ m_centerFrequency(centerFrequency)
+ { }
+ };
+
+ DSDDemod(DeviceSourceAPI *deviceAPI);
+ ~DSDDemod();
+ void setScopeSink(BasebandSampleSink* sampleSink) { m_scope = sampleSink; }
+
+ void configureMyPosition(MessageQueue* messageQueue, float myLatitude, float myLongitude);
+
+ virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po);
+ virtual void start();
+ virtual void stop();
+ virtual bool handleMessage(const Message& cmd);
+
+ double getMagSq() { return m_magsq; }
+ bool getSquelchOpen() const { return m_squelchOpen; }
+
+ const DSDDecoder& getDecoder() const { return m_dsdDecoder; }
+
+ void getMagSqLevels(double& avg, double& peak, int& nbSamples)
+ {
+ avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount;
+ m_magsq = avg;
+ peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak;
+ nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount;
+ m_magsqSum = 0.0f;
+ m_magsqPeak = 0.0f;
+ m_magsqCount = 0;
+ }
+
+ static const QString m_channelID;
+
+private:
+ class MsgConfigureMyPosition : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ float getMyLatitude() const { return m_myLatitude; }
+ float getMyLongitude() const { return m_myLongitude; }
+
+ static MsgConfigureMyPosition* create(float myLatitude, float myLongitude)
+ {
+ return new MsgConfigureMyPosition(myLatitude, myLongitude);
+ }
+
+ private:
+ float m_myLatitude;
+ float m_myLongitude;
+
+ MsgConfigureMyPosition(float myLatitude, float myLongitude) :
+ m_myLatitude(myLatitude),
+ m_myLongitude(myLongitude)
+ {}
+ };
+
+ enum RateState {
+ RSInitialFill,
+ RSRunning
+ };
+
+ DSDDemodSettings m_settings;
+
+ DeviceSourceAPI *m_deviceAPI;
+ ThreadedBasebandSampleSink* m_threadedChannelizer;
+ DownChannelizer* m_channelizer;
+
+ NCO m_nco;
+ Interpolator m_interpolator;
+ Real m_interpolatorDistance;
+ Real m_interpolatorDistanceRemain;
+ int m_sampleCount;
+ int m_squelchCount;
+ int m_squelchGate;
+
+ double m_squelchLevel;
+ bool m_squelchOpen;
+
+ MovingAverage m_movingAverage;
+ double m_magsq;
+ double m_magsqSum;
+ double m_magsqPeak;
+ int m_magsqCount;
+
+ Real m_fmExcursion;
+
+ SampleVector m_scopeSampleBuffer;
+ AudioVector m_audioBuffer;
+ uint m_audioBufferFill;
+ qint16 *m_sampleBuffer; //!< samples ring buffer
+ int m_sampleBufferIndex;
+
+ AudioFifo m_audioFifo1;
+ AudioFifo m_audioFifo2;
+ BasebandSampleSink* m_scope;
+ bool m_scopeEnabled;
+
+ DSDDecoder m_dsdDecoder;
+ QMutex m_settingsMutex;
+
+ PhaseDiscriminators m_phaseDiscri;
+ UDPSink *m_udpBufferAudio;
+
+ static const int m_udpBlockSize;
+
+ void applySettings(DSDDemodSettings& settings, bool force = false);
+};
+
+#endif // INCLUDE_DSDDEMOD_H
diff --git a/plugins/channelrx/demoddsd/dsddemodgui.cpp b/plugins/channelrx/demoddsd/dsddemodgui.cpp
index 16aa89359..88eb2e04a 100644
--- a/plugins/channelrx/demoddsd/dsddemodgui.cpp
+++ b/plugins/channelrx/demoddsd/dsddemodgui.cpp
@@ -38,8 +38,6 @@
#include "dsddemodbaudrates.h"
#include "dsddemod.h"
-const QString DSDDemodGUI::m_channelID = "sdrangel.channel.dsddemod";
-
DSDDemodGUI* DSDDemodGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet)
{
DSDDemodGUI* gui = new DSDDemodGUI(pluginAPI, deviceUISet);
@@ -281,7 +279,7 @@ DSDDemodGUI::DSDDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, QWidget
connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged()));
- m_deviceUISet->registerRxChannelInstance(m_channelID, this);
+ m_deviceUISet->registerRxChannelInstance(DSDDemod::m_channelID, this);
m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this);
diff --git a/plugins/channelrx/demoddsd/dsddemodgui.h b/plugins/channelrx/demoddsd/dsddemodgui.h
index 46a9a7362..1edad84b4 100644
--- a/plugins/channelrx/demoddsd/dsddemodgui.h
+++ b/plugins/channelrx/demoddsd/dsddemodgui.h
@@ -57,8 +57,6 @@ public:
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual bool handleMessage(const Message& message);
- static const QString m_channelID;
-
private slots:
void formatStatusText();
void channelMarkerChanged();
diff --git a/plugins/channelrx/demoddsd/dsddemodplugin.cpp b/plugins/channelrx/demoddsd/dsddemodplugin.cpp
index 6fdd2ae7f..df46e57bd 100644
--- a/plugins/channelrx/demoddsd/dsddemodplugin.cpp
+++ b/plugins/channelrx/demoddsd/dsddemodplugin.cpp
@@ -21,6 +21,7 @@
#include
#include "plugin/pluginapi.h"
#include "dsddemodgui.h"
+#include "dsddemod.h"
const PluginDescriptor DSDDemodPlugin::m_pluginDescriptor = {
QString("DSD Demodulator"),
@@ -47,16 +48,27 @@ void DSDDemodPlugin::initPlugin(PluginAPI* pluginAPI)
m_pluginAPI = pluginAPI;
// register DSD demodulator
- m_pluginAPI->registerRxChannel(DSDDemodGUI::m_channelID, this);
+ m_pluginAPI->registerRxChannel(DSDDemod::m_channelID, this);
}
PluginInstanceGUI* DSDDemodPlugin::createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet)
{
- if(channelName == DSDDemodGUI::m_channelID)
+ if(channelName == DSDDemod::m_channelID)
{
DSDDemodGUI* gui = DSDDemodGUI::create(m_pluginAPI, deviceUISet);
return gui;
} else {
- return NULL;
+ return 0;
}
}
+
+BasebandSampleSink* DSDDemodPlugin::createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI)
+{
+ if(channelName == DSDDemod::m_channelID)
+ {
+ DSDDemod* sink = new DSDDemod(deviceAPI);
+ return sink;
+ } else {
+ return 0;
+ }
+}
diff --git a/plugins/channelrx/demoddsd/dsddemodplugin.h b/plugins/channelrx/demoddsd/dsddemodplugin.h
index 5342f8b21..a996fb1e3 100644
--- a/plugins/channelrx/demoddsd/dsddemodplugin.h
+++ b/plugins/channelrx/demoddsd/dsddemodplugin.h
@@ -22,6 +22,7 @@
#include "plugin/plugininterface.h"
class DeviceUISet;
+class BasebandSampleSink;
class DSDDemodPlugin : public QObject, PluginInterface {
Q_OBJECT
@@ -35,6 +36,7 @@ public:
void initPlugin(PluginAPI* pluginAPI);
PluginInstanceGUI* createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet);
+ BasebandSampleSink* createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI);
private:
static const PluginDescriptor m_pluginDescriptor;
diff --git a/plugins/channelrx/demodlora/lorademod.cpp b/plugins/channelrx/demodlora/lorademod.cpp
index 637867163..a731d03e2 100644
--- a/plugins/channelrx/demodlora/lorademod.cpp
+++ b/plugins/channelrx/demodlora/lorademod.cpp
@@ -31,6 +31,8 @@
MESSAGE_CLASS_DEFINITION(LoRaDemod::MsgConfigureLoRaDemod, Message)
MESSAGE_CLASS_DEFINITION(LoRaDemod::MsgConfigureChannelizer, Message)
+const QString LoRaDemod::m_channelID = "de.maintech.sdrangelove.channel.lora";
+
LoRaDemod::LoRaDemod(DeviceSourceAPI* deviceAPI) :
m_deviceAPI(deviceAPI),
m_sampleSink(0),
diff --git a/plugins/channelrx/demodlora/lorademod.h b/plugins/channelrx/demodlora/lorademod.h
index 032016e25..1bb53d7f2 100644
--- a/plugins/channelrx/demodlora/lorademod.h
+++ b/plugins/channelrx/demodlora/lorademod.h
@@ -96,6 +96,8 @@ public:
virtual void stop();
virtual bool handleMessage(const Message& cmd);
+ static const QString m_channelID;
+
private:
int detect(Complex sample, Complex angle);
void dumpRaw(void);
diff --git a/plugins/channelrx/demodlora/lorademodgui.cpp b/plugins/channelrx/demodlora/lorademodgui.cpp
index 9920453fd..56f897ede 100644
--- a/plugins/channelrx/demodlora/lorademodgui.cpp
+++ b/plugins/channelrx/demodlora/lorademodgui.cpp
@@ -16,8 +16,6 @@
#include "lorademod.h"
#include "lorademodgui.h"
-const QString LoRaDemodGUI::m_channelID = "de.maintech.sdrangelove.channel.lora";
-
LoRaDemodGUI* LoRaDemodGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet)
{
LoRaDemodGUI* gui = new LoRaDemodGUI(pluginAPI, deviceUISet);
@@ -153,7 +151,7 @@ LoRaDemodGUI::LoRaDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, QWidg
connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(viewChanged()));
- m_deviceUISet->registerRxChannelInstance(m_channelID, this);
+ m_deviceUISet->registerRxChannelInstance(LoRaDemod::m_channelID, this);
m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this);
diff --git a/plugins/channelrx/demodlora/lorademodgui.h b/plugins/channelrx/demodlora/lorademodgui.h
index 343bbcd02..cb0458fb8 100644
--- a/plugins/channelrx/demodlora/lorademodgui.h
+++ b/plugins/channelrx/demodlora/lorademodgui.h
@@ -35,8 +35,6 @@ public:
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual bool handleMessage(const Message& message);
- static const QString m_channelID;
-
private slots:
void viewChanged();
void on_BW_valueChanged(int value);
diff --git a/plugins/channelrx/demodlora/loraplugin.cpp b/plugins/channelrx/demodlora/loraplugin.cpp
index f777ed66c..f357de6b3 100644
--- a/plugins/channelrx/demodlora/loraplugin.cpp
+++ b/plugins/channelrx/demodlora/loraplugin.cpp
@@ -3,6 +3,7 @@
#include "loraplugin.h"
#include "lorademodgui.h"
+#include "lorademod.h"
const PluginDescriptor LoRaPlugin::m_pluginDescriptor = {
QString("LoRa Demodulator"),
@@ -29,16 +30,27 @@ void LoRaPlugin::initPlugin(PluginAPI* pluginAPI)
m_pluginAPI = pluginAPI;
// register demodulator
- m_pluginAPI->registerRxChannel(LoRaDemodGUI::m_channelID, this);
+ m_pluginAPI->registerRxChannel(LoRaDemod::m_channelID, this);
}
PluginInstanceGUI* LoRaPlugin::createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet)
{
- if(channelName == LoRaDemodGUI::m_channelID)
+ if(channelName == LoRaDemod::m_channelID)
{
LoRaDemodGUI* gui = LoRaDemodGUI::create(m_pluginAPI, deviceUISet);
return gui;
} else {
- return NULL;
+ return 0;
}
}
+
+BasebandSampleSink* LoRaPlugin::createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI)
+{
+ if(channelName == LoRaDemod::m_channelID)
+ {
+ LoRaDemod* sink = new LoRaDemod(deviceAPI);
+ return sink;
+ } else {
+ return 0;
+ }
+}
diff --git a/plugins/channelrx/demodlora/loraplugin.h b/plugins/channelrx/demodlora/loraplugin.h
index 2745db53d..1a2ead455 100644
--- a/plugins/channelrx/demodlora/loraplugin.h
+++ b/plugins/channelrx/demodlora/loraplugin.h
@@ -5,6 +5,7 @@
#include "plugin/plugininterface.h"
class DeviceUISet;
+class BasebandSampleSink;
class LoRaPlugin : public QObject, PluginInterface {
Q_OBJECT
@@ -18,6 +19,7 @@ public:
void initPlugin(PluginAPI* pluginAPI);
PluginInstanceGUI* createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet);
+ BasebandSampleSink* createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI);
private:
static const PluginDescriptor m_pluginDescriptor;
diff --git a/plugins/channelrx/demodnfm/nfmdemod.cpp b/plugins/channelrx/demodnfm/nfmdemod.cpp
index a1d1fdbb9..8fd641a97 100644
--- a/plugins/channelrx/demodnfm/nfmdemod.cpp
+++ b/plugins/channelrx/demodnfm/nfmdemod.cpp
@@ -35,6 +35,8 @@ MESSAGE_CLASS_DEFINITION(NFMDemod::MsgConfigureNFMDemod, Message)
MESSAGE_CLASS_DEFINITION(NFMDemod::MsgConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(NFMDemod::MsgReportCTCSSFreq, Message)
+const QString NFMDemod::m_channelID = "de.maintech.sdrangelove.channel.nfm";
+
static const double afSqTones[2] = {1000.0, 6000.0}; // {1200.0, 8000.0};
const int NFMDemod::m_udpBlockSize = 512;
diff --git a/plugins/channelrx/demodnfm/nfmdemod.h b/plugins/channelrx/demodnfm/nfmdemod.h
index decaeada0..c0d403c0f 100644
--- a/plugins/channelrx/demodnfm/nfmdemod.h
+++ b/plugins/channelrx/demodnfm/nfmdemod.h
@@ -138,6 +138,8 @@ public:
m_magsqCount = 0;
}
+ static const QString m_channelID;
+
private:
enum RateState {
RSInitialFill,
diff --git a/plugins/channelrx/demodnfm/nfmdemodgui.cpp b/plugins/channelrx/demodnfm/nfmdemodgui.cpp
index edb2e2fc0..2767a2178 100644
--- a/plugins/channelrx/demodnfm/nfmdemodgui.cpp
+++ b/plugins/channelrx/demodnfm/nfmdemodgui.cpp
@@ -16,8 +16,6 @@
#include "mainwindow.h"
#include "nfmdemod.h"
-const QString NFMDemodGUI::m_channelID = "de.maintech.sdrangelove.channel.nfm";
-
NFMDemodGUI* NFMDemodGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet)
{
NFMDemodGUI* gui = new NFMDemodGUI(pluginAPI, deviceUISet);
@@ -277,7 +275,7 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, QWidget
connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged()));
- m_deviceUISet->registerRxChannelInstance(m_channelID, this);
+ m_deviceUISet->registerRxChannelInstance(NFMDemod::m_channelID, this);
m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this);
diff --git a/plugins/channelrx/demodnfm/nfmdemodgui.h b/plugins/channelrx/demodnfm/nfmdemodgui.h
index 317ce2f4f..3d5c2b6ad 100644
--- a/plugins/channelrx/demodnfm/nfmdemodgui.h
+++ b/plugins/channelrx/demodnfm/nfmdemodgui.h
@@ -38,8 +38,6 @@ public:
virtual bool handleMessage(const Message& message);
void setCtcssFreq(Real ctcssFreq);
- static const QString m_channelID;
-
private slots:
void channelMarkerChanged();
void on_deltaFrequency_changed(qint64 value);
diff --git a/plugins/channelrx/demodnfm/nfmplugin.cpp b/plugins/channelrx/demodnfm/nfmplugin.cpp
index 3536a243e..173362284 100644
--- a/plugins/channelrx/demodnfm/nfmplugin.cpp
+++ b/plugins/channelrx/demodnfm/nfmplugin.cpp
@@ -3,6 +3,7 @@
#include "nfmplugin.h"
#include "nfmdemodgui.h"
+#include "nfmdemod.h"
const PluginDescriptor NFMPlugin::m_pluginDescriptor = {
QString("NFM Demodulator"),
@@ -29,15 +30,26 @@ void NFMPlugin::initPlugin(PluginAPI* pluginAPI)
m_pluginAPI = pluginAPI;
// register NFM demodulator
- m_pluginAPI->registerRxChannel(NFMDemodGUI::m_channelID, this);
+ m_pluginAPI->registerRxChannel(NFMDemod::m_channelID, this);
}
PluginInstanceGUI* NFMPlugin::createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet)
{
- if(channelName == NFMDemodGUI::m_channelID) {
+ if(channelName == NFMDemod::m_channelID) {
NFMDemodGUI* gui = NFMDemodGUI::create(m_pluginAPI, deviceUISet);
return gui;
} else {
- return NULL;
+ return 0;
}
}
+
+BasebandSampleSink* NFMPlugin::createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI)
+{
+ if(channelName == NFMDemod::m_channelID)
+ {
+ NFMDemod* sink = new NFMDemod(deviceAPI);
+ return sink;
+ } else {
+ return 0;
+ }
+}
diff --git a/plugins/channelrx/demodnfm/nfmplugin.h b/plugins/channelrx/demodnfm/nfmplugin.h
index d43e9c122..2e28e63f5 100644
--- a/plugins/channelrx/demodnfm/nfmplugin.h
+++ b/plugins/channelrx/demodnfm/nfmplugin.h
@@ -5,6 +5,7 @@
#include "plugin/plugininterface.h"
class DeviceUISet;
+class BasebandSampleSink;
class NFMPlugin : public QObject, PluginInterface {
Q_OBJECT
@@ -18,6 +19,7 @@ public:
void initPlugin(PluginAPI* pluginAPI);
PluginInstanceGUI* createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet);
+ BasebandSampleSink* createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI);
private:
static const PluginDescriptor m_pluginDescriptor;
diff --git a/plugins/channelrx/demodssb/ssbdemod.cpp b/plugins/channelrx/demodssb/ssbdemod.cpp
index a6efae9e4..2932fc348 100644
--- a/plugins/channelrx/demodssb/ssbdemod.cpp
+++ b/plugins/channelrx/demodssb/ssbdemod.cpp
@@ -34,6 +34,8 @@ MESSAGE_CLASS_DEFINITION(SSBDemod::MsgConfigureSSBDemod, Message)
MESSAGE_CLASS_DEFINITION(SSBDemod::MsgConfigureSSBDemodPrivate, Message)
MESSAGE_CLASS_DEFINITION(SSBDemod::MsgConfigureChannelizer, Message)
+const QString SSBDemod::m_channelID = "de.maintech.sdrangelove.channel.ssb";
+
SSBDemod::SSBDemod(DeviceSourceAPI *deviceAPI) :
m_deviceAPI(deviceAPI),
m_audioBinaual(false),
diff --git a/plugins/channelrx/demodssb/ssbdemod.h b/plugins/channelrx/demodssb/ssbdemod.h
index f5b148f3d..4357c45f4 100644
--- a/plugins/channelrx/demodssb/ssbdemod.h
+++ b/plugins/channelrx/demodssb/ssbdemod.h
@@ -1,270 +1,272 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
-// written by Christian Daniel //
-// //
-// 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_SSBDEMOD_H
-#define INCLUDE_SSBDEMOD_H
-
-#include
-#include
-
-#include
-#include "dsp/ncof.h"
-#include "dsp/interpolator.h"
-#include "dsp/fftfilt.h"
-#include "dsp/agc.h"
-#include "audio/audiofifo.h"
-#include "util/message.h"
-
-#include "ssbdemodsettings.h"
-
-#define ssbFftLen 1024
-#define agcTarget 3276.8 // -10 dB amplitude => -20 dB power: center of normal signal
-
-class DeviceSourceAPI;
-class ThreadedBasebandSampleSink;
-class DownChannelizer;
-
-class SSBDemod : public BasebandSampleSink {
-public:
- class MsgConfigureSSBDemod : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- const SSBDemodSettings& getSettings() const { return m_settings; }
- bool getForce() const { return m_force; }
-
- static MsgConfigureSSBDemod* create(const SSBDemodSettings& settings, bool force)
- {
- return new MsgConfigureSSBDemod(settings, force);
- }
-
- private:
- SSBDemodSettings m_settings;
- bool m_force;
-
- MsgConfigureSSBDemod(const SSBDemodSettings& settings, bool force) :
- Message(),
- m_settings(settings),
- m_force(force)
- { }
- };
-
- class MsgConfigureChannelizer : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- int getSampleRate() const { return m_sampleRate; }
- int getCenterFrequency() const { return m_centerFrequency; }
-
- static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
- {
- return new MsgConfigureChannelizer(sampleRate, centerFrequency);
- }
-
- private:
- int m_sampleRate;
- int m_centerFrequency;
-
- MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
- Message(),
- m_sampleRate(sampleRate),
- m_centerFrequency(centerFrequency)
- { }
- };
-
- SSBDemod(DeviceSourceAPI *deviceAPI);
- virtual ~SSBDemod();
- void setSampleSink(BasebandSampleSink* sampleSink) { m_sampleSink = sampleSink; }
-
- void configure(MessageQueue* messageQueue,
- Real Bandwidth,
- Real LowCutoff,
- Real volume,
- int spanLog2,
- bool audioBinaural,
- bool audioFlipChannels,
- bool dsb,
- bool audioMute,
- bool agc,
- bool agcClamping,
- int agcTimeLog2,
- int agcPowerThreshold,
- int agcThresholdGate);
-
- virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
- virtual void start();
- virtual void stop();
- virtual bool handleMessage(const Message& cmd);
-
- double getMagSq() const { return m_magsq; }
- bool getAudioActive() const { return m_audioActive; }
-
- void getMagSqLevels(double& avg, double& peak, int& nbSamples)
- {
- avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount;
- m_magsq = avg;
- peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak;
- nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount;
- m_magsqSum = 0.0f;
- m_magsqPeak = 0.0f;
- m_magsqCount = 0;
- }
-
-private:
- class MsgConfigureSSBDemodPrivate : public Message {
- MESSAGE_CLASS_DECLARATION
-
- public:
- Real getBandwidth() const { return m_Bandwidth; }
- Real getLoCutoff() const { return m_LowCutoff; }
- Real getVolume() const { return m_volume; }
- int getSpanLog2() const { return m_spanLog2; }
- bool getAudioBinaural() const { return m_audioBinaural; }
- bool getAudioFlipChannels() const { return m_audioFlipChannels; }
- bool getDSB() const { return m_dsb; }
- bool getAudioMute() const { return m_audioMute; }
- bool getAGC() const { return m_agc; }
- bool getAGCClamping() const { return m_agcClamping; }
- int getAGCTimeLog2() const { return m_agcTimeLog2; }
- int getAGCPowerThershold() const { return m_agcPowerThreshold; }
- int getAGCThersholdGate() const { return m_agcThresholdGate; }
-
- static MsgConfigureSSBDemodPrivate* create(Real Bandwidth,
- Real LowCutoff,
- Real volume,
- int spanLog2,
- bool audioBinaural,
- bool audioFlipChannels,
- bool dsb,
- bool audioMute,
- bool agc,
- bool agcClamping,
- int agcTimeLog2,
- int agcPowerThreshold,
- int agcThresholdGate)
- {
- return new MsgConfigureSSBDemodPrivate(
- Bandwidth,
- LowCutoff,
- volume,
- spanLog2,
- audioBinaural,
- audioFlipChannels,
- dsb,
- audioMute,
- agc,
- agcClamping,
- agcTimeLog2,
- agcPowerThreshold,
- agcThresholdGate);
- }
-
- private:
- Real m_Bandwidth;
- Real m_LowCutoff;
- Real m_volume;
- int m_spanLog2;
- bool m_audioBinaural;
- bool m_audioFlipChannels;
- bool m_dsb;
- bool m_audioMute;
- bool m_agc;
- bool m_agcClamping;
- int m_agcTimeLog2;
- int m_agcPowerThreshold;
- int m_agcThresholdGate;
-
- MsgConfigureSSBDemodPrivate(Real Bandwidth,
- Real LowCutoff,
- Real volume,
- int spanLog2,
- bool audioBinaural,
- bool audioFlipChannels,
- bool dsb,
- bool audioMute,
- bool agc,
- bool agcClamping,
- int agcTimeLog2,
- int agcPowerThreshold,
- int agcThresholdGate) :
- Message(),
- m_Bandwidth(Bandwidth),
- m_LowCutoff(LowCutoff),
- m_volume(volume),
- m_spanLog2(spanLog2),
- m_audioBinaural(audioBinaural),
- m_audioFlipChannels(audioFlipChannels),
- m_dsb(dsb),
- m_audioMute(audioMute),
- m_agc(agc),
- m_agcClamping(agcClamping),
- m_agcTimeLog2(agcTimeLog2),
- m_agcPowerThreshold(agcPowerThreshold),
- m_agcThresholdGate(agcThresholdGate)
- { }
- };
-
- DeviceSourceAPI *m_deviceAPI;
- ThreadedBasebandSampleSink* m_threadedChannelizer;
- DownChannelizer* m_channelizer;
- SSBDemodSettings m_settings;
-
- Real m_Bandwidth;
- Real m_LowCutoff;
- Real m_volume;
- int m_spanLog2;
- fftfilt::cmplx m_sum;
- int m_undersampleCount;
- int m_sampleRate;
- int m_frequency;
- bool m_audioBinaual;
- bool m_audioFlipChannels;
- bool m_usb;
- bool m_dsb;
- bool m_audioMute;
- double m_magsq;
- double m_magsqSum;
- double m_magsqPeak;
- int m_magsqCount;
- MagAGC m_agc;
- bool m_agcActive;
- bool m_agcClamping;
- int m_agcNbSamples; //!< number of audio (48 kHz) samples for AGC averaging
- double m_agcPowerThreshold; //!< AGC power threshold (linear)
- int m_agcThresholdGate; //!< Gate length in number of samples befor threshold triggers
- bool m_audioActive; //!< True if an audio signal is produced (no AGC or AGC and above threshold)
-
- NCOF m_nco;
- Interpolator m_interpolator;
- Real m_sampleDistanceRemain;
- fftfilt* SSBFilter;
- fftfilt* DSBFilter;
-
- BasebandSampleSink* m_sampleSink;
- SampleVector m_sampleBuffer;
-
- AudioVector m_audioBuffer;
- uint m_audioBufferFill;
- AudioFifo m_audioFifo;
- quint32 m_audioSampleRate;
-
- QMutex m_settingsMutex;
-
- void applySettings(const SSBDemodSettings& settings, bool force = false);
-};
-
-#endif // INCLUDE_SSBDEMOD_H
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
+// written by Christian Daniel //
+// //
+// 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_SSBDEMOD_H
+#define INCLUDE_SSBDEMOD_H
+
+#include
+#include
+
+#include
+#include "dsp/ncof.h"
+#include "dsp/interpolator.h"
+#include "dsp/fftfilt.h"
+#include "dsp/agc.h"
+#include "audio/audiofifo.h"
+#include "util/message.h"
+
+#include "ssbdemodsettings.h"
+
+#define ssbFftLen 1024
+#define agcTarget 3276.8 // -10 dB amplitude => -20 dB power: center of normal signal
+
+class DeviceSourceAPI;
+class ThreadedBasebandSampleSink;
+class DownChannelizer;
+
+class SSBDemod : public BasebandSampleSink {
+public:
+ class MsgConfigureSSBDemod : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ const SSBDemodSettings& getSettings() const { return m_settings; }
+ bool getForce() const { return m_force; }
+
+ static MsgConfigureSSBDemod* create(const SSBDemodSettings& settings, bool force)
+ {
+ return new MsgConfigureSSBDemod(settings, force);
+ }
+
+ private:
+ SSBDemodSettings m_settings;
+ bool m_force;
+
+ MsgConfigureSSBDemod(const SSBDemodSettings& settings, bool force) :
+ Message(),
+ m_settings(settings),
+ m_force(force)
+ { }
+ };
+
+ class MsgConfigureChannelizer : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ int getSampleRate() const { return m_sampleRate; }
+ int getCenterFrequency() const { return m_centerFrequency; }
+
+ static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
+ {
+ return new MsgConfigureChannelizer(sampleRate, centerFrequency);
+ }
+
+ private:
+ int m_sampleRate;
+ int m_centerFrequency;
+
+ MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
+ Message(),
+ m_sampleRate(sampleRate),
+ m_centerFrequency(centerFrequency)
+ { }
+ };
+
+ SSBDemod(DeviceSourceAPI *deviceAPI);
+ virtual ~SSBDemod();
+ void setSampleSink(BasebandSampleSink* sampleSink) { m_sampleSink = sampleSink; }
+
+ void configure(MessageQueue* messageQueue,
+ Real Bandwidth,
+ Real LowCutoff,
+ Real volume,
+ int spanLog2,
+ bool audioBinaural,
+ bool audioFlipChannels,
+ bool dsb,
+ bool audioMute,
+ bool agc,
+ bool agcClamping,
+ int agcTimeLog2,
+ int agcPowerThreshold,
+ int agcThresholdGate);
+
+ virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
+ virtual void start();
+ virtual void stop();
+ virtual bool handleMessage(const Message& cmd);
+
+ double getMagSq() const { return m_magsq; }
+ bool getAudioActive() const { return m_audioActive; }
+
+ void getMagSqLevels(double& avg, double& peak, int& nbSamples)
+ {
+ avg = m_magsqCount == 0 ? 1e-10 : m_magsqSum / m_magsqCount;
+ m_magsq = avg;
+ peak = m_magsqPeak == 0.0 ? 1e-10 : m_magsqPeak;
+ nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount;
+ m_magsqSum = 0.0f;
+ m_magsqPeak = 0.0f;
+ m_magsqCount = 0;
+ }
+
+ static const QString m_channelID;
+
+private:
+ class MsgConfigureSSBDemodPrivate : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ Real getBandwidth() const { return m_Bandwidth; }
+ Real getLoCutoff() const { return m_LowCutoff; }
+ Real getVolume() const { return m_volume; }
+ int getSpanLog2() const { return m_spanLog2; }
+ bool getAudioBinaural() const { return m_audioBinaural; }
+ bool getAudioFlipChannels() const { return m_audioFlipChannels; }
+ bool getDSB() const { return m_dsb; }
+ bool getAudioMute() const { return m_audioMute; }
+ bool getAGC() const { return m_agc; }
+ bool getAGCClamping() const { return m_agcClamping; }
+ int getAGCTimeLog2() const { return m_agcTimeLog2; }
+ int getAGCPowerThershold() const { return m_agcPowerThreshold; }
+ int getAGCThersholdGate() const { return m_agcThresholdGate; }
+
+ static MsgConfigureSSBDemodPrivate* create(Real Bandwidth,
+ Real LowCutoff,
+ Real volume,
+ int spanLog2,
+ bool audioBinaural,
+ bool audioFlipChannels,
+ bool dsb,
+ bool audioMute,
+ bool agc,
+ bool agcClamping,
+ int agcTimeLog2,
+ int agcPowerThreshold,
+ int agcThresholdGate)
+ {
+ return new MsgConfigureSSBDemodPrivate(
+ Bandwidth,
+ LowCutoff,
+ volume,
+ spanLog2,
+ audioBinaural,
+ audioFlipChannels,
+ dsb,
+ audioMute,
+ agc,
+ agcClamping,
+ agcTimeLog2,
+ agcPowerThreshold,
+ agcThresholdGate);
+ }
+
+ private:
+ Real m_Bandwidth;
+ Real m_LowCutoff;
+ Real m_volume;
+ int m_spanLog2;
+ bool m_audioBinaural;
+ bool m_audioFlipChannels;
+ bool m_dsb;
+ bool m_audioMute;
+ bool m_agc;
+ bool m_agcClamping;
+ int m_agcTimeLog2;
+ int m_agcPowerThreshold;
+ int m_agcThresholdGate;
+
+ MsgConfigureSSBDemodPrivate(Real Bandwidth,
+ Real LowCutoff,
+ Real volume,
+ int spanLog2,
+ bool audioBinaural,
+ bool audioFlipChannels,
+ bool dsb,
+ bool audioMute,
+ bool agc,
+ bool agcClamping,
+ int agcTimeLog2,
+ int agcPowerThreshold,
+ int agcThresholdGate) :
+ Message(),
+ m_Bandwidth(Bandwidth),
+ m_LowCutoff(LowCutoff),
+ m_volume(volume),
+ m_spanLog2(spanLog2),
+ m_audioBinaural(audioBinaural),
+ m_audioFlipChannels(audioFlipChannels),
+ m_dsb(dsb),
+ m_audioMute(audioMute),
+ m_agc(agc),
+ m_agcClamping(agcClamping),
+ m_agcTimeLog2(agcTimeLog2),
+ m_agcPowerThreshold(agcPowerThreshold),
+ m_agcThresholdGate(agcThresholdGate)
+ { }
+ };
+
+ DeviceSourceAPI *m_deviceAPI;
+ ThreadedBasebandSampleSink* m_threadedChannelizer;
+ DownChannelizer* m_channelizer;
+ SSBDemodSettings m_settings;
+
+ Real m_Bandwidth;
+ Real m_LowCutoff;
+ Real m_volume;
+ int m_spanLog2;
+ fftfilt::cmplx m_sum;
+ int m_undersampleCount;
+ int m_sampleRate;
+ int m_frequency;
+ bool m_audioBinaual;
+ bool m_audioFlipChannels;
+ bool m_usb;
+ bool m_dsb;
+ bool m_audioMute;
+ double m_magsq;
+ double m_magsqSum;
+ double m_magsqPeak;
+ int m_magsqCount;
+ MagAGC m_agc;
+ bool m_agcActive;
+ bool m_agcClamping;
+ int m_agcNbSamples; //!< number of audio (48 kHz) samples for AGC averaging
+ double m_agcPowerThreshold; //!< AGC power threshold (linear)
+ int m_agcThresholdGate; //!< Gate length in number of samples befor threshold triggers
+ bool m_audioActive; //!< True if an audio signal is produced (no AGC or AGC and above threshold)
+
+ NCOF m_nco;
+ Interpolator m_interpolator;
+ Real m_sampleDistanceRemain;
+ fftfilt* SSBFilter;
+ fftfilt* DSBFilter;
+
+ BasebandSampleSink* m_sampleSink;
+ SampleVector m_sampleBuffer;
+
+ AudioVector m_audioBuffer;
+ uint m_audioBufferFill;
+ AudioFifo m_audioFifo;
+ quint32 m_audioSampleRate;
+
+ QMutex m_settingsMutex;
+
+ void applySettings(const SSBDemodSettings& settings, bool force = false);
+};
+
+#endif // INCLUDE_SSBDEMOD_H
diff --git a/plugins/channelrx/demodssb/ssbdemodgui.cpp b/plugins/channelrx/demodssb/ssbdemodgui.cpp
index 95cb97b0b..e273c6702 100644
--- a/plugins/channelrx/demodssb/ssbdemodgui.cpp
+++ b/plugins/channelrx/demodssb/ssbdemodgui.cpp
@@ -17,8 +17,6 @@
#include "mainwindow.h"
#include "ssbdemod.h"
-const QString SSBDemodGUI::m_channelID = "de.maintech.sdrangelove.channel.ssb";
-
SSBDemodGUI* SSBDemodGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet)
{
SSBDemodGUI* gui = new SSBDemodGUI(pluginAPI, deviceUISet);
@@ -253,7 +251,7 @@ SSBDemodGUI::SSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, QWidget
connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(viewChanged()));
- m_deviceUISet->registerRxChannelInstance(m_channelID, this);
+ m_deviceUISet->registerRxChannelInstance(SSBDemod::m_channelID, this);
m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this);
diff --git a/plugins/channelrx/demodssb/ssbdemodgui.h b/plugins/channelrx/demodssb/ssbdemodgui.h
index a812f9eb7..9bed86064 100644
--- a/plugins/channelrx/demodssb/ssbdemodgui.h
+++ b/plugins/channelrx/demodssb/ssbdemodgui.h
@@ -37,8 +37,6 @@ public:
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual bool handleMessage(const Message& message);
- static const QString m_channelID;
-
private slots:
void viewChanged();
void on_deltaFrequency_changed(qint64 value);
diff --git a/plugins/channelrx/demodssb/ssbplugin.cpp b/plugins/channelrx/demodssb/ssbplugin.cpp
index f0ce112ed..c29465200 100644
--- a/plugins/channelrx/demodssb/ssbplugin.cpp
+++ b/plugins/channelrx/demodssb/ssbplugin.cpp
@@ -4,6 +4,7 @@
#include
#include "plugin/pluginapi.h"
#include "ssbdemodgui.h"
+#include "ssbdemod.h"
const PluginDescriptor SSBPlugin::m_pluginDescriptor = {
QString("SSB Demodulator"),
@@ -30,16 +31,27 @@ void SSBPlugin::initPlugin(PluginAPI* pluginAPI)
m_pluginAPI = pluginAPI;
// register demodulator
- m_pluginAPI->registerRxChannel(SSBDemodGUI::m_channelID, this);
+ m_pluginAPI->registerRxChannel(SSBDemod::m_channelID, this);
}
PluginInstanceGUI* SSBPlugin::createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet)
{
- if(channelName == SSBDemodGUI::m_channelID)
+ if(channelName == SSBDemod::m_channelID)
{
SSBDemodGUI* gui = SSBDemodGUI::create(m_pluginAPI, deviceUISet);
return gui;
} else {
- return NULL;
+ return 0;
}
}
+
+BasebandSampleSink* SSBPlugin::createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI)
+{
+ if(channelName == SSBDemod::m_channelID)
+ {
+ SSBDemod* sink = new SSBDemod(deviceAPI);
+ return sink;
+ } else {
+ return 0;
+ }
+}
diff --git a/plugins/channelrx/demodssb/ssbplugin.h b/plugins/channelrx/demodssb/ssbplugin.h
index b9c52b929..ba71a0381 100644
--- a/plugins/channelrx/demodssb/ssbplugin.h
+++ b/plugins/channelrx/demodssb/ssbplugin.h
@@ -5,6 +5,7 @@
#include "plugin/plugininterface.h"
class DeviceUISet;
+class BasebandSampleSink;
class SSBPlugin : public QObject, PluginInterface {
Q_OBJECT
@@ -18,6 +19,7 @@ public:
void initPlugin(PluginAPI* pluginAPI);
PluginInstanceGUI* createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet);
+ BasebandSampleSink* createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI);
private:
static const PluginDescriptor m_pluginDescriptor;
diff --git a/plugins/channelrx/demodwfm/wfmdemod.cpp b/plugins/channelrx/demodwfm/wfmdemod.cpp
index 4c5a672ef..4673e7242 100644
--- a/plugins/channelrx/demodwfm/wfmdemod.cpp
+++ b/plugins/channelrx/demodwfm/wfmdemod.cpp
@@ -33,6 +33,8 @@
MESSAGE_CLASS_DEFINITION(WFMDemod::MsgConfigureWFMDemod, Message)
MESSAGE_CLASS_DEFINITION(WFMDemod::MsgConfigureChannelizer, Message)
+const QString WFMDemod::m_channelID = "de.maintech.sdrangelove.channel.wfm";
+
WFMDemod::WFMDemod(DeviceSourceAPI* deviceAPI) :
m_deviceAPI(deviceAPI),
m_squelchOpen(false),
diff --git a/plugins/channelrx/demodwfm/wfmdemod.h b/plugins/channelrx/demodwfm/wfmdemod.h
index 39740bd07..cb98dbcd2 100644
--- a/plugins/channelrx/demodwfm/wfmdemod.h
+++ b/plugins/channelrx/demodwfm/wfmdemod.h
@@ -109,6 +109,8 @@ public:
m_magsqCount = 0;
}
+ static const QString m_channelID;
+
private:
enum RateState {
RSInitialFill,
diff --git a/plugins/channelrx/demodwfm/wfmdemodgui.cpp b/plugins/channelrx/demodwfm/wfmdemodgui.cpp
index 11e57216c..0b7cde1bb 100644
--- a/plugins/channelrx/demodwfm/wfmdemodgui.cpp
+++ b/plugins/channelrx/demodwfm/wfmdemodgui.cpp
@@ -18,8 +18,6 @@
#include "wfmdemod.h"
-const QString WFMDemodGUI::m_channelID = "de.maintech.sdrangelove.channel.wfm";
-
WFMDemodGUI* WFMDemodGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet)
{
WFMDemodGUI* gui = new WFMDemodGUI(pluginAPI, deviceUISet);
@@ -187,7 +185,7 @@ WFMDemodGUI::WFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, QWidget
connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged()));
- m_deviceUISet->registerRxChannelInstance(m_channelID, this);
+ m_deviceUISet->registerRxChannelInstance(WFMDemod::m_channelID, this);
m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this);
diff --git a/plugins/channelrx/demodwfm/wfmdemodgui.h b/plugins/channelrx/demodwfm/wfmdemodgui.h
index ac6379066..9fe62a0be 100644
--- a/plugins/channelrx/demodwfm/wfmdemodgui.h
+++ b/plugins/channelrx/demodwfm/wfmdemodgui.h
@@ -36,8 +36,6 @@ public:
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual bool handleMessage(const Message& message);
- static const QString m_channelID;
-
private slots:
void channelMarkerChanged();
void on_deltaFrequency_changed(qint64 value);
diff --git a/plugins/channelrx/demodwfm/wfmplugin.cpp b/plugins/channelrx/demodwfm/wfmplugin.cpp
index 3d56a2891..0a7432f80 100644
--- a/plugins/channelrx/demodwfm/wfmplugin.cpp
+++ b/plugins/channelrx/demodwfm/wfmplugin.cpp
@@ -4,6 +4,7 @@
#include "plugin/pluginapi.h"
#include "wfmdemodgui.h"
+#include "wfmdemod.h"
const PluginDescriptor WFMPlugin::m_pluginDescriptor = {
QString("WFM Demodulator"),
@@ -30,16 +31,27 @@ void WFMPlugin::initPlugin(PluginAPI* pluginAPI)
m_pluginAPI = pluginAPI;
// register WFM demodulator
- m_pluginAPI->registerRxChannel(WFMDemodGUI::m_channelID, this);
+ m_pluginAPI->registerRxChannel(WFMDemod::m_channelID, this);
}
PluginInstanceGUI* WFMPlugin::createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet)
{
- if(channelName == WFMDemodGUI::m_channelID)
+ if(channelName == WFMDemod::m_channelID)
{
WFMDemodGUI* gui = WFMDemodGUI::create(m_pluginAPI, deviceUISet);
return gui;
} else {
- return NULL;
+ return 0;
}
}
+
+BasebandSampleSink* WFMPlugin::createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI)
+{
+ if(channelName == WFMDemod::m_channelID)
+ {
+ WFMDemod* sink = new WFMDemod(deviceAPI);
+ return sink;
+ } else {
+ return 0;
+ }
+}
diff --git a/plugins/channelrx/demodwfm/wfmplugin.h b/plugins/channelrx/demodwfm/wfmplugin.h
index 077cb78fb..30caa534c 100644
--- a/plugins/channelrx/demodwfm/wfmplugin.h
+++ b/plugins/channelrx/demodwfm/wfmplugin.h
@@ -5,6 +5,7 @@
#include "plugin/plugininterface.h"
class DeviceUISet;
+class BasebandSampleSink;
class WFMPlugin : public QObject, PluginInterface {
Q_OBJECT
@@ -18,6 +19,7 @@ public:
void initPlugin(PluginAPI* pluginAPI);
PluginInstanceGUI* createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet);
+ BasebandSampleSink* createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI);
private:
static const PluginDescriptor m_pluginDescriptor;
diff --git a/plugins/channelrx/tcpsrc/tcpsrc.cpp b/plugins/channelrx/tcpsrc/tcpsrc.cpp
index 0f749965b..739d5260d 100644
--- a/plugins/channelrx/tcpsrc/tcpsrc.cpp
+++ b/plugins/channelrx/tcpsrc/tcpsrc.cpp
@@ -30,6 +30,8 @@ MESSAGE_CLASS_DEFINITION(TCPSrc::MsgConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(TCPSrc::MsgTCPSrcConnection, Message)
MESSAGE_CLASS_DEFINITION(TCPSrc::MsgTCPSrcSpectrum, Message)
+const QString TCPSrc::m_channelID = "sdrangel.channel.tcpsrc";
+
TCPSrc::TCPSrc(DeviceSourceAPI* deviceAPI) :
m_deviceAPI(deviceAPI),
m_settingsMutex(QMutex::Recursive)
diff --git a/plugins/channelrx/tcpsrc/tcpsrc.h b/plugins/channelrx/tcpsrc/tcpsrc.h
index ac58155f0..36931185b 100644
--- a/plugins/channelrx/tcpsrc/tcpsrc.h
+++ b/plugins/channelrx/tcpsrc/tcpsrc.h
@@ -113,6 +113,8 @@ public:
virtual void stop();
virtual bool handleMessage(const Message& cmd);
+ static const QString m_channelID;
+
protected:
class MsgTCPSrcSpectrum : public Message {
MESSAGE_CLASS_DECLARATION
diff --git a/plugins/channelrx/tcpsrc/tcpsrcgui.cpp b/plugins/channelrx/tcpsrc/tcpsrcgui.cpp
index 8965e911f..6c53c09bc 100644
--- a/plugins/channelrx/tcpsrc/tcpsrcgui.cpp
+++ b/plugins/channelrx/tcpsrc/tcpsrcgui.cpp
@@ -12,8 +12,6 @@
#include "mainwindow.h"
#include "tcpsrc.h"
-const QString TCPSrcGUI::m_channelID = "sdrangel.channel.tcpsrc";
-
TCPSrcGUI* TCPSrcGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet)
{
TCPSrcGUI* gui = new TCPSrcGUI(pluginAPI, deviceUISet);
@@ -165,7 +163,7 @@ TCPSrcGUI::TCPSrcGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, QWidget* pa
connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged()));
- m_deviceUISet->registerRxChannelInstance(m_channelID, this);
+ m_deviceUISet->registerRxChannelInstance(TCPSrc::m_channelID, this);
m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this);
diff --git a/plugins/channelrx/tcpsrc/tcpsrcgui.h b/plugins/channelrx/tcpsrc/tcpsrcgui.h
index a4697732d..6c34d96a8 100644
--- a/plugins/channelrx/tcpsrc/tcpsrcgui.h
+++ b/plugins/channelrx/tcpsrc/tcpsrcgui.h
@@ -39,8 +39,6 @@ public:
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual bool handleMessage(const Message& message);
- static const QString m_channelID;
-
private slots:
void channelMarkerChanged();
void on_deltaFrequency_changed(qint64 value);
diff --git a/plugins/channelrx/tcpsrc/tcpsrcplugin.cpp b/plugins/channelrx/tcpsrc/tcpsrcplugin.cpp
index c6baaedb3..0edf913f6 100644
--- a/plugins/channelrx/tcpsrc/tcpsrcplugin.cpp
+++ b/plugins/channelrx/tcpsrc/tcpsrcplugin.cpp
@@ -4,6 +4,7 @@
#include "plugin/pluginapi.h"
#include "tcpsrcgui.h"
+#include "tcpsrc.h"
const PluginDescriptor TCPSrcPlugin::m_pluginDescriptor = {
QString("TCP Channel Source"),
@@ -30,18 +31,29 @@ void TCPSrcPlugin::initPlugin(PluginAPI* pluginAPI)
m_pluginAPI = pluginAPI;
// register TCP Channel Source
- m_pluginAPI->registerRxChannel(TCPSrcGUI::m_channelID, this);
+ m_pluginAPI->registerRxChannel(TCPSrc::m_channelID, this);
}
PluginInstanceGUI* TCPSrcPlugin::createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet)
{
- if(channelName == TCPSrcGUI::m_channelID)
+ if(channelName == TCPSrc::m_channelID)
{
TCPSrcGUI* gui = TCPSrcGUI::create(m_pluginAPI, deviceUISet);
// deviceAPI->registerChannelInstance("sdrangel.channel.tcpsrc", gui);
// m_pluginAPI->addChannelRollup(gui);
return gui;
} else {
- return NULL;
+ return 0;
}
}
+
+BasebandSampleSink* TCPSrcPlugin::createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI)
+{
+ if(channelName == TCPSrc::m_channelID)
+ {
+ TCPSrc* sink = new TCPSrc(deviceAPI);
+ return sink;
+ } else {
+ return 0;
+ }
+}
diff --git a/plugins/channelrx/tcpsrc/tcpsrcplugin.h b/plugins/channelrx/tcpsrc/tcpsrcplugin.h
index dcd15ea22..162285f21 100644
--- a/plugins/channelrx/tcpsrc/tcpsrcplugin.h
+++ b/plugins/channelrx/tcpsrc/tcpsrcplugin.h
@@ -5,6 +5,7 @@
#include "plugin/plugininterface.h"
class DeviceUISet;
+class BasebandSampleSink;
class TCPSrcPlugin : public QObject, PluginInterface {
Q_OBJECT
@@ -18,6 +19,7 @@ public:
void initPlugin(PluginAPI* pluginAPI);
PluginInstanceGUI* createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet);
+ BasebandSampleSink* createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI);
private:
static const PluginDescriptor m_pluginDescriptor;
diff --git a/plugins/channelrx/udpsrc/udpsrc.cpp b/plugins/channelrx/udpsrc/udpsrc.cpp
index b601c098e..c5d2d41c1 100644
--- a/plugins/channelrx/udpsrc/udpsrc.cpp
+++ b/plugins/channelrx/udpsrc/udpsrc.cpp
@@ -33,6 +33,8 @@ MESSAGE_CLASS_DEFINITION(UDPSrc::MsgConfigureUDPSrc, Message)
MESSAGE_CLASS_DEFINITION(UDPSrc::MsgConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(UDPSrc::MsgUDPSrcSpectrum, Message)
+const QString UDPSrc::m_channelID = "sdrangel.channel.udpsrc";
+
UDPSrc::UDPSrc(DeviceSourceAPI *deviceAPI) :
m_deviceAPI(deviceAPI),
m_outMovingAverage(480, 1e-10),
diff --git a/plugins/channelrx/udpsrc/udpsrc.h b/plugins/channelrx/udpsrc/udpsrc.h
index 441c22a75..391c378c9 100644
--- a/plugins/channelrx/udpsrc/udpsrc.h
+++ b/plugins/channelrx/udpsrc/udpsrc.h
@@ -104,6 +104,7 @@ public:
virtual void stop();
virtual bool handleMessage(const Message& cmd);
+ static const QString m_channelID;
static const int udpBlockSize = 512; // UDP block size in number of bytes
public slots:
diff --git a/plugins/channelrx/udpsrc/udpsrcgui.cpp b/plugins/channelrx/udpsrc/udpsrcgui.cpp
index 9141cdd82..f8a45f0dc 100644
--- a/plugins/channelrx/udpsrc/udpsrcgui.cpp
+++ b/plugins/channelrx/udpsrc/udpsrcgui.cpp
@@ -30,8 +30,6 @@
#include "udpsrc.h"
-const QString UDPSrcGUI::m_channelID = "sdrangel.channel.udpsrc";
-
UDPSrcGUI* UDPSrcGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet)
{
UDPSrcGUI* gui = new UDPSrcGUI(pluginAPI, deviceUISet);
@@ -185,7 +183,7 @@ UDPSrcGUI::UDPSrcGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, QWidget* pa
connect(&m_channelMarker, SIGNAL(changed()), this, SLOT(channelMarkerChanged()));
- m_deviceUISet->registerRxChannelInstance(m_channelID, this);
+ m_deviceUISet->registerRxChannelInstance(UDPSrc::m_channelID, this);
m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this);
diff --git a/plugins/channelrx/udpsrc/udpsrcgui.h b/plugins/channelrx/udpsrc/udpsrcgui.h
index 63ad4e994..d5c7edd29 100644
--- a/plugins/channelrx/udpsrc/udpsrcgui.h
+++ b/plugins/channelrx/udpsrc/udpsrcgui.h
@@ -55,8 +55,6 @@ public:
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual bool handleMessage(const Message& message);
- static const QString m_channelID;
-
private slots:
void channelMarkerChanged();
void on_deltaFrequency_changed(qint64 value);
diff --git a/plugins/channelrx/udpsrc/udpsrcplugin.cpp b/plugins/channelrx/udpsrc/udpsrcplugin.cpp
index b7043a4ea..ecd456ec3 100644
--- a/plugins/channelrx/udpsrc/udpsrcplugin.cpp
+++ b/plugins/channelrx/udpsrc/udpsrcplugin.cpp
@@ -21,6 +21,7 @@
#include "plugin/pluginapi.h"
#include "udpsrcgui.h"
+#include "udpsrc.h"
const PluginDescriptor UDPSrcPlugin::m_pluginDescriptor = {
QString("UDP Channel Source"),
@@ -47,12 +48,12 @@ void UDPSrcPlugin::initPlugin(PluginAPI* pluginAPI)
m_pluginAPI = pluginAPI;
// register TCP Channel Source
- m_pluginAPI->registerRxChannel(UDPSrcGUI::m_channelID, this);
+ m_pluginAPI->registerRxChannel(UDPSrc::m_channelID, this);
}
PluginInstanceGUI* UDPSrcPlugin::createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet)
{
- if(channelName == UDPSrcGUI::m_channelID)
+ if(channelName == UDPSrc::m_channelID)
{
UDPSrcGUI* gui = UDPSrcGUI::create(m_pluginAPI, deviceUISet);
// deviceAPI->registerChannelInstance("sdrangel.channel.udpsrc", gui);
@@ -62,3 +63,14 @@ PluginInstanceGUI* UDPSrcPlugin::createRxChannelGUI(const QString& channelName,
return 0;
}
}
+
+BasebandSampleSink* UDPSrcPlugin::createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI)
+{
+ if(channelName == UDPSrc::m_channelID)
+ {
+ UDPSrc* sink = new UDPSrc(deviceAPI);
+ return sink;
+ } else {
+ return 0;
+ }
+}
diff --git a/plugins/channelrx/udpsrc/udpsrcplugin.h b/plugins/channelrx/udpsrc/udpsrcplugin.h
index 2b75fab30..e96bc082d 100644
--- a/plugins/channelrx/udpsrc/udpsrcplugin.h
+++ b/plugins/channelrx/udpsrc/udpsrcplugin.h
@@ -22,6 +22,7 @@
#include "plugin/plugininterface.h"
class DeviceUISet;
+class BasebandSampleSink;
class UDPSrcPlugin : public QObject, PluginInterface {
Q_OBJECT
@@ -35,6 +36,7 @@ public:
void initPlugin(PluginAPI* pluginAPI);
PluginInstanceGUI* createRxChannelGUI(const QString& channelName, DeviceUISet *deviceUISet);
+ BasebandSampleSink* createRxChannel(const QString& channelName, DeviceSourceAPI *deviceAPI);
private:
static const PluginDescriptor m_pluginDescriptor;