From 793d8b9f493541b4183fd29975ca978533f8bc5f Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 21 Dec 2020 02:30:29 +0100 Subject: [PATCH] Demod Analyzer: implementation for the rest of planned plugins --- plugins/channelrx/demoddsd/dsddemodplugin.cpp | 2 +- plugins/channelrx/demodnfm/nfmplugin.cpp | 2 +- plugins/channelrx/demodssb/ssbdemod.cpp | 1 + .../channelrx/demodssb/ssbdemodbaseband.cpp | 7 ++- plugins/channelrx/demodssb/ssbdemodbaseband.h | 4 +- plugins/channelrx/demodssb/ssbdemodsink.cpp | 38 +++++++++++++++ plugins/channelrx/demodssb/ssbdemodsink.h | 10 +++- plugins/channelrx/demodssb/ssbplugin.cpp | 2 +- plugins/channelrx/demodwfm/wfmdemod.cpp | 1 + .../channelrx/demodwfm/wfmdemodbaseband.cpp | 5 ++ plugins/channelrx/demodwfm/wfmdemodbaseband.h | 2 + plugins/channelrx/demodwfm/wfmdemodsink.cpp | 48 +++++++++++++++++-- plugins/channelrx/demodwfm/wfmdemodsink.h | 9 +++- plugins/channelrx/demodwfm/wfmplugin.cpp | 2 +- plugins/channeltx/modam/ammodsource.cpp | 1 - plugins/channeltx/modam/ammodsource.h | 1 - plugins/channeltx/modnfm/nfmmod.cpp | 1 + plugins/channeltx/modnfm/nfmmodbaseband.cpp | 7 ++- plugins/channeltx/modnfm/nfmmodbaseband.h | 2 + plugins/channeltx/modnfm/nfmmodplugin.cpp | 2 +- plugins/channeltx/modnfm/nfmmodsource.cpp | 47 ++++++++++++++++-- plugins/channeltx/modnfm/nfmmodsource.h | 8 ++++ plugins/channeltx/modpacket/packetmod.cpp | 1 + .../channeltx/modpacket/packetmodbaseband.cpp | 5 ++ .../channeltx/modpacket/packetmodbaseband.h | 3 +- .../channeltx/modpacket/packetmodplugin.cpp | 2 +- .../channeltx/modpacket/packetmodsource.cpp | 39 +++++++++++++++ plugins/channeltx/modpacket/packetmodsource.h | 7 +++ plugins/channeltx/modssb/ssbmod.cpp | 1 + plugins/channeltx/modssb/ssbmodbaseband.cpp | 5 ++ plugins/channeltx/modssb/ssbmodbaseband.h | 2 + plugins/channeltx/modssb/ssbmodplugin.cpp | 2 +- plugins/channeltx/modssb/ssbmodsource.cpp | 40 ++++++++++++++++ plugins/channeltx/modssb/ssbmodsource.h | 7 +++ plugins/channeltx/modwfm/wfmmod.cpp | 1 + plugins/channeltx/modwfm/wfmmodbaseband.cpp | 7 ++- plugins/channeltx/modwfm/wfmmodbaseband.h | 2 + plugins/channeltx/modwfm/wfmmodplugin.cpp | 2 +- plugins/channeltx/modwfm/wfmmodsource.cpp | 42 +++++++++++++++- plugins/channeltx/modwfm/wfmmodsource.h | 8 ++++ .../demodanalyzer/demodanalyzersettings.cpp | 12 +++++ 41 files changed, 363 insertions(+), 27 deletions(-) diff --git a/plugins/channelrx/demoddsd/dsddemodplugin.cpp b/plugins/channelrx/demoddsd/dsddemodplugin.cpp index 4f10b0a35..b63b55742 100644 --- a/plugins/channelrx/demoddsd/dsddemodplugin.cpp +++ b/plugins/channelrx/demoddsd/dsddemodplugin.cpp @@ -30,7 +30,7 @@ const PluginDescriptor DSDDemodPlugin::m_pluginDescriptor = { DSDDemod::m_channelId, QStringLiteral("DSD Demodulator"), - QStringLiteral("6.3.3"), + QStringLiteral("6.4.0"), QStringLiteral("(c) Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channelrx/demodnfm/nfmplugin.cpp b/plugins/channelrx/demodnfm/nfmplugin.cpp index e357d7d47..e8eabc0ca 100644 --- a/plugins/channelrx/demodnfm/nfmplugin.cpp +++ b/plugins/channelrx/demodnfm/nfmplugin.cpp @@ -12,7 +12,7 @@ const PluginDescriptor NFMPlugin::m_pluginDescriptor = { NFMDemod::m_channelId, QStringLiteral("NFM Demodulator"), - QStringLiteral("6.3.3"), + QStringLiteral("6.4.0"), QStringLiteral("(c) Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channelrx/demodssb/ssbdemod.cpp b/plugins/channelrx/demodssb/ssbdemod.cpp index 7bf61f081..1e7beaefd 100644 --- a/plugins/channelrx/demodssb/ssbdemod.cpp +++ b/plugins/channelrx/demodssb/ssbdemod.cpp @@ -58,6 +58,7 @@ SSBDemod::SSBDemod(DeviceAPI *deviceAPI) : m_thread = new QThread(this); m_basebandSink = new SSBDemodBaseband(); m_basebandSink->setSpectrumSink(&m_spectrumVis); + m_basebandSink->setChannel(this); m_basebandSink->moveToThread(m_thread); applySettings(m_settings, true); diff --git a/plugins/channelrx/demodssb/ssbdemodbaseband.cpp b/plugins/channelrx/demodssb/ssbdemodbaseband.cpp index c44798740..7f19ee1e1 100644 --- a/plugins/channelrx/demodssb/ssbdemodbaseband.cpp +++ b/plugins/channelrx/demodssb/ssbdemodbaseband.cpp @@ -63,6 +63,11 @@ void SSBDemodBaseband::reset() m_sampleFifo.reset(); } +void SSBDemodBaseband::setChannel(ChannelAPI *channel) +{ + m_sink.setChannel(channel); +} + void SSBDemodBaseband::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end) { m_sampleFifo.write(begin, end); @@ -198,4 +203,4 @@ void SSBDemodBaseband::setBasebandSampleRate(int sampleRate) { m_channelizer->setBasebandSampleRate(sampleRate); m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset()); -} \ No newline at end of file +} diff --git a/plugins/channelrx/demodssb/ssbdemodbaseband.h b/plugins/channelrx/demodssb/ssbdemodbaseband.h index 6cc518827..2d5402b53 100644 --- a/plugins/channelrx/demodssb/ssbdemodbaseband.h +++ b/plugins/channelrx/demodssb/ssbdemodbaseband.h @@ -28,6 +28,7 @@ #include "ssbdemodsink.h" class DownChannelizer; +class ChannelAPI; class SSBDemodBaseband : public QObject { @@ -69,6 +70,7 @@ public: bool getAudioActive() const { return m_sink.getAudioActive(); } void setBasebandSampleRate(int sampleRate); void setMessageQueueToGUI(MessageQueue *messageQueue) { m_messageQueueToGUI = messageQueue; } + void setChannel(ChannelAPI *channel); private: SampleSinkFifo m_sampleFifo; @@ -90,4 +92,4 @@ private slots: void handleData(); //!< Handle data when samples have to be processed }; -#endif // INCLUDE_SSBDEMODBASEBAND_H \ No newline at end of file +#endif // INCLUDE_SSBDEMODBASEBAND_H diff --git a/plugins/channelrx/demodssb/ssbdemodsink.cpp b/plugins/channelrx/demodssb/ssbdemodsink.cpp index 06a4a5add..fde3c5814 100644 --- a/plugins/channelrx/demodssb/ssbdemodsink.cpp +++ b/plugins/channelrx/demodssb/ssbdemodsink.cpp @@ -25,8 +25,11 @@ #include "dsp/dspcommands.h" #include "dsp/devicesamplemimo.h" #include "dsp/basebandsamplesink.h" +#include "dsp/datafifo.h" #include "device/deviceapi.h" #include "util/db.h" +#include "util/messagequeue.h" +#include "maincore.h" #include "ssbdemodsink.h" @@ -62,6 +65,9 @@ SSBDemodSink::SSBDemodSink() : m_undersampleCount = 0; m_sum = 0; + m_demodBuffer.resize(1<<12); + m_demodBufferFill = 0; + m_usb = true; m_magsq = 0.0f; m_magsqSum = 0.0f; @@ -194,6 +200,25 @@ void SSBDemodSink::processOneSample(Complex &ci) m_audioBuffer[m_audioBufferFill].l = sample; m_audioBuffer[m_audioBufferFill].r = sample; } + + m_demodBuffer[m_demodBufferFill] = (z.real() + z.imag()) * 0.7; + ++m_demodBufferFill; + + if (m_demodBufferFill >= m_demodBuffer.size()) + { + QList *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod"); + + if (dataFifos) + { + QList::iterator it = dataFifos->begin(); + + for (; it != dataFifos->end(); ++it) { + (*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16)); + } + } + + m_demodBufferFill = 0; + } } ++m_audioBufferFill; @@ -279,6 +304,19 @@ void SSBDemodSink::applyAudioSampleRate(int sampleRate) m_audioFifo.setSize(sampleRate); m_audioSampleRate = sampleRate; + + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(m_channel, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(m_channel, sampleRate); + (*it)->push(msg); + } + } } void SSBDemodSink::applySettings(const SSBDemodSettings& settings, bool force) diff --git a/plugins/channelrx/demodssb/ssbdemodsink.h b/plugins/channelrx/demodssb/ssbdemodsink.h index 407458a00..6514b990c 100644 --- a/plugins/channelrx/demodssb/ssbdemodsink.h +++ b/plugins/channelrx/demodssb/ssbdemodsink.h @@ -18,7 +18,7 @@ #ifndef INCLUDE_SSBDEMODSINK_H #define INCLUDE_SSBDEMODSINK_H -#include +#include #include "dsp/channelsamplesink.h" #include "dsp/ncof.h" @@ -31,6 +31,7 @@ #include "ssbdemodsettings.h" class BasebandSampleSink; +class ChannelAPI; class SSBDemodSink : public ChannelSampleSink { public: @@ -47,6 +48,7 @@ public: AudioFifo *getAudioFifo() { return &m_audioFifo; } double getMagSq() const { return m_magsq; } bool getAudioActive() const { return m_audioActive; } + void setChannel(ChannelAPI *channel) { m_channel = channel; } void getMagSqLevels(double& avg, double& peak, int& nbSamples) { @@ -78,6 +80,7 @@ private: }; SSBDemodSettings m_settings; + ChannelAPI *m_channel; Real m_Bandwidth; Real m_LowCutoff; @@ -121,10 +124,13 @@ private: AudioFifo m_audioFifo; quint32 m_audioSampleRate; + QVector m_demodBuffer; + int m_demodBufferFill; + static const int m_ssbFftLen; static const int m_agcTarget; void processOneSample(Complex &ci); }; -#endif // INCLUDE_SSBDEMODSINK_H \ No newline at end of file +#endif // INCLUDE_SSBDEMODSINK_H diff --git a/plugins/channelrx/demodssb/ssbplugin.cpp b/plugins/channelrx/demodssb/ssbplugin.cpp index 22e288c37..a4e79f62c 100644 --- a/plugins/channelrx/demodssb/ssbplugin.cpp +++ b/plugins/channelrx/demodssb/ssbplugin.cpp @@ -12,7 +12,7 @@ const PluginDescriptor SSBPlugin::m_pluginDescriptor = { SSBDemod::m_channelId, QStringLiteral("SSB Demodulator"), - QStringLiteral("6.3.3"), + QStringLiteral("6.4.0"), QStringLiteral("(c) Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channelrx/demodwfm/wfmdemod.cpp b/plugins/channelrx/demodwfm/wfmdemod.cpp index 630e94863..64deec0f3 100644 --- a/plugins/channelrx/demodwfm/wfmdemod.cpp +++ b/plugins/channelrx/demodwfm/wfmdemod.cpp @@ -59,6 +59,7 @@ WFMDemod::WFMDemod(DeviceAPI* deviceAPI) : m_thread = new QThread(this); m_basebandSink = new WFMDemodBaseband(); + m_basebandSink->setChannel(this); m_basebandSink->moveToThread(m_thread); applySettings(m_settings, true); diff --git a/plugins/channelrx/demodwfm/wfmdemodbaseband.cpp b/plugins/channelrx/demodwfm/wfmdemodbaseband.cpp index 15ad153e8..dd78d933d 100644 --- a/plugins/channelrx/demodwfm/wfmdemodbaseband.cpp +++ b/plugins/channelrx/demodwfm/wfmdemodbaseband.cpp @@ -58,6 +58,11 @@ void WFMDemodBaseband::reset() m_sampleFifo.reset(); } +void WFMDemodBaseband::setChannel(ChannelAPI *channel) +{ + m_sink.setChannel(channel); +} + void WFMDemodBaseband::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end) { m_sampleFifo.write(begin, end); diff --git a/plugins/channelrx/demodwfm/wfmdemodbaseband.h b/plugins/channelrx/demodwfm/wfmdemodbaseband.h index b79e289a2..5a5a5b561 100644 --- a/plugins/channelrx/demodwfm/wfmdemodbaseband.h +++ b/plugins/channelrx/demodwfm/wfmdemodbaseband.h @@ -28,6 +28,7 @@ #include "wfmdemodsink.h" class DownChannelizer; +class ChannelAPI; class WFMDemodBaseband : public QObject { @@ -69,6 +70,7 @@ public: bool getSquelchOpen() const { return m_sink.getSquelchOpen(); } int getSquelchState() const { return m_sink.getSquelchState(); } void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_sink.getMagSqLevels(avg, peak, nbSamples); } + void setChannel(ChannelAPI *channel); private: SampleSinkFifo m_sampleFifo; diff --git a/plugins/channelrx/demodwfm/wfmdemodsink.cpp b/plugins/channelrx/demodwfm/wfmdemodsink.cpp index 302a9cc8c..ed2127cf4 100644 --- a/plugins/channelrx/demodwfm/wfmdemodsink.cpp +++ b/plugins/channelrx/demodwfm/wfmdemodsink.cpp @@ -25,7 +25,10 @@ #include "dsp/dspengine.h" #include "dsp/dspcommands.h" #include "dsp/devicesamplemimo.h" +#include "dsp/datafifo.h" #include "util/db.h" +#include "util/messagequeue.h" +#include "maincore.h" #include "wfmdemodsink.h" @@ -35,6 +38,7 @@ WFMDemodSink::WFMDemodSink() : m_channelSampleRate(384000), m_channelFrequencyOffset(0), m_audioSampleRate(48000), + m_squelchState(0), m_squelchOpen(false), m_magsq(0.0f), m_magsqSum(0.0f), @@ -48,6 +52,9 @@ WFMDemodSink::WFMDemodSink() : m_audioBuffer.resize(16384); m_audioBufferFill = 0; + m_demodBuffer.resize(1<<12); + m_demodBufferFill = 0; + applySettings(m_settings, true); applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true); } @@ -130,6 +137,24 @@ void WFMDemodSink::feed(const SampleVector::const_iterator& begin, const SampleV } m_interpolatorDistanceRemain += m_interpolatorDistance; + m_demodBuffer[m_demodBufferFill] = sample; + ++m_demodBufferFill; + + if (m_demodBufferFill >= m_demodBuffer.size()) + { + QList *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod"); + + if (dataFifos) + { + QList::iterator it = dataFifos->begin(); + + for (; it != dataFifos->end(); ++it) { + (*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16)); + } + } + + m_demodBufferFill = 0; + } } } } @@ -162,6 +187,19 @@ void WFMDemodSink::applyAudioSampleRate(int sampleRate) m_interpolatorDistanceRemain = (Real) m_channelSampleRate / sampleRate; m_interpolatorDistance = (Real) m_channelSampleRate / (Real) sampleRate; m_audioSampleRate = sampleRate; + + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(m_channel, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(m_channel, sampleRate); + (*it)->push(msg); + } + } } void WFMDemodSink::applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force) @@ -186,8 +224,8 @@ void WFMDemodSink::applyChannelSettings(int channelSampleRate, int channelFreque Real lowCut = -(m_settings.m_rfBandwidth / 2.0) / channelSampleRate; Real hiCut = (m_settings.m_rfBandwidth / 2.0) / channelSampleRate; m_rfFilter->create_filter(lowCut, hiCut); - m_fmExcursion = m_settings.m_rfBandwidth / (Real) channelSampleRate; - m_phaseDiscri.setFMScaling(1.0f/m_fmExcursion); + //m_fmExcursion = m_settings.m_rfBandwidth / (Real) channelSampleRate; + m_phaseDiscri.setFMScaling((float) channelSampleRate / ((float) 2*m_fmExcursion)); qDebug("WFMDemod::applySettings: m_fmExcursion: %f", m_fmExcursion); } @@ -224,8 +262,10 @@ void WFMDemodSink::applySettings(const WFMDemodSettings& settings, bool force) Real lowCut = -(settings.m_rfBandwidth / 2.0) / m_channelSampleRate; Real hiCut = (settings.m_rfBandwidth / 2.0) / m_channelSampleRate; m_rfFilter->create_filter(lowCut, hiCut); - m_fmExcursion = settings.m_rfBandwidth / (Real) m_channelSampleRate; - m_phaseDiscri.setFMScaling(1.0f/m_fmExcursion); + m_fmExcursion = (settings.m_rfBandwidth / 2) - m_settings.m_afBandwidth; + m_fmExcursion = m_fmExcursion < 2500 ? 2500 : m_fmExcursion; + //m_fmExcursion = settings.m_rfBandwidth / (Real) m_channelSampleRate; + m_phaseDiscri.setFMScaling((float) m_channelSampleRate / ((float) 2*m_fmExcursion)); qDebug("WFMDemodSink::applySettings: m_fmExcursion: %f", m_fmExcursion); } diff --git a/plugins/channelrx/demodwfm/wfmdemodsink.h b/plugins/channelrx/demodwfm/wfmdemodsink.h index 46a1a27d8..ad3018538 100644 --- a/plugins/channelrx/demodwfm/wfmdemodsink.h +++ b/plugins/channelrx/demodwfm/wfmdemodsink.h @@ -18,7 +18,7 @@ #ifndef INCLUDE_WFMDEMODSINK_H #define INCLUDE_WFMDEMODSINK_H -#include +#include #include "dsp/channelsamplesink.h" #include "dsp/nco.h" @@ -32,6 +32,8 @@ #include "wfmdemodsettings.h" +class ChannelAPI; + class WFMDemodSink : public ChannelSampleSink { public: WFMDemodSink(); @@ -67,6 +69,7 @@ public: AudioFifo *getAudioFifo() { return &m_audioFifo; } void applyAudioSampleRate(int sampleRate); int getAudioSampleRate() const { return m_audioSampleRate; } + void setChannel(ChannelAPI *channel) { m_channel = channel; } private: struct MagSqLevelsStore @@ -87,6 +90,7 @@ private: int m_channelSampleRate; int m_channelFrequencyOffset; WFMDemodSettings m_settings; + ChannelAPI *m_channel; int m_audioSampleRate; @@ -115,6 +119,9 @@ private: SampleVector m_sampleBuffer; PhaseDiscriminators m_phaseDiscri; + QVector m_demodBuffer; + int m_demodBufferFill; + static const unsigned int m_rfFilterFftLength; }; diff --git a/plugins/channelrx/demodwfm/wfmplugin.cpp b/plugins/channelrx/demodwfm/wfmplugin.cpp index a45d4f67f..4864b9f41 100644 --- a/plugins/channelrx/demodwfm/wfmplugin.cpp +++ b/plugins/channelrx/demodwfm/wfmplugin.cpp @@ -13,7 +13,7 @@ const PluginDescriptor WFMPlugin::m_pluginDescriptor = { WFMDemod::m_channelId, QStringLiteral("WFM Demodulator"), - QStringLiteral("6.3.3"), + QStringLiteral("6.4.0"), QStringLiteral("(c) Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channeltx/modam/ammodsource.cpp b/plugins/channeltx/modam/ammodsource.cpp index 734eb662f..77b7c9649 100644 --- a/plugins/channeltx/modam/ammodsource.cpp +++ b/plugins/channeltx/modam/ammodsource.cpp @@ -343,7 +343,6 @@ void AMModSource::applyFeedbackAudioSampleRate(int sampleRate) qDebug("AMModSource::applyFeedbackAudioSampleRate: %u", sampleRate); m_feedbackInterpolatorDistanceRemain = 0; - m_feedbackInterpolatorConsumed = false; m_feedbackInterpolatorDistance = (Real) sampleRate / (Real) m_audioSampleRate; Real cutoff = std::min(sampleRate, m_audioSampleRate) / 2.2f; m_feedbackInterpolator.create(48, sampleRate, cutoff, 3.0); diff --git a/plugins/channeltx/modam/ammodsource.h b/plugins/channeltx/modam/ammodsource.h index 528819526..af97dde02 100644 --- a/plugins/channeltx/modam/ammodsource.h +++ b/plugins/channeltx/modam/ammodsource.h @@ -85,7 +85,6 @@ private: Interpolator m_feedbackInterpolator; Real m_feedbackInterpolatorDistance; Real m_feedbackInterpolatorDistanceRemain; - bool m_feedbackInterpolatorConsumed; double m_magsq; MovingAverageUtil m_movingAverage; diff --git a/plugins/channeltx/modnfm/nfmmod.cpp b/plugins/channeltx/modnfm/nfmmod.cpp index 1d6b9210d..4d362b6d0 100644 --- a/plugins/channeltx/modnfm/nfmmod.cpp +++ b/plugins/channeltx/modnfm/nfmmod.cpp @@ -66,6 +66,7 @@ NFMMod::NFMMod(DeviceAPI *deviceAPI) : m_thread = new QThread(this); m_basebandSource = new NFMModBaseband(); m_basebandSource->setInputFileStream(&m_ifstream); + m_basebandSource->setChannel(this); m_basebandSource->moveToThread(m_thread); applySettings(m_settings, true); diff --git a/plugins/channeltx/modnfm/nfmmodbaseband.cpp b/plugins/channeltx/modnfm/nfmmodbaseband.cpp index d5fd7ffe9..fc821e8da 100644 --- a/plugins/channeltx/modnfm/nfmmodbaseband.cpp +++ b/plugins/channeltx/modnfm/nfmmodbaseband.cpp @@ -62,6 +62,11 @@ void NFMModBaseband::reset() m_sampleFifo.reset(); } +void NFMModBaseband::setChannel(ChannelAPI *channel) +{ + m_source.setChannel(channel); +} + void NFMModBaseband::pull(const SampleVector::iterator& begin, unsigned int nbSamples) { unsigned int part1Begin, part1End, part2Begin, part2End; @@ -226,4 +231,4 @@ void NFMModBaseband::applySettings(const NFMModSettings& settings, bool force) int NFMModBaseband::getChannelSampleRate() const { return m_channelizer->getChannelSampleRate(); -} \ No newline at end of file +} diff --git a/plugins/channeltx/modnfm/nfmmodbaseband.h b/plugins/channeltx/modnfm/nfmmodbaseband.h index 378e10777..0057fd5ff 100644 --- a/plugins/channeltx/modnfm/nfmmodbaseband.h +++ b/plugins/channeltx/modnfm/nfmmodbaseband.h @@ -28,6 +28,7 @@ #include "nfmmodsource.h" class UpChannelizer; +class ChannelAPI; class NFMModBaseband : public QObject { @@ -69,6 +70,7 @@ public: void setInputFileStream(std::ifstream *ifstream) { m_source.setInputFileStream(ifstream); } AudioFifo *getAudioFifo() { return m_source.getAudioFifo(); } AudioFifo *getFeedbackAudioFifo() { return m_source.getFeedbackAudioFifo(); } + void setChannel(ChannelAPI *channel); signals: /** diff --git a/plugins/channeltx/modnfm/nfmmodplugin.cpp b/plugins/channeltx/modnfm/nfmmodplugin.cpp index 5c908c06a..df961d521 100644 --- a/plugins/channeltx/modnfm/nfmmodplugin.cpp +++ b/plugins/channeltx/modnfm/nfmmodplugin.cpp @@ -28,7 +28,7 @@ const PluginDescriptor NFMModPlugin::m_pluginDescriptor = { NFMMod::m_channelId, QStringLiteral("NFM Modulator"), - QStringLiteral("6.3.3"), + QStringLiteral("6.4.0"), QStringLiteral("(c) Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channeltx/modnfm/nfmmodsource.cpp b/plugins/channeltx/modnfm/nfmmodsource.cpp index 1eabb40dc..ebe4eb9db 100644 --- a/plugins/channeltx/modnfm/nfmmodsource.cpp +++ b/plugins/channeltx/modnfm/nfmmodsource.cpp @@ -17,6 +17,10 @@ #include +#include "dsp/datafifo.h" +#include "util/messagequeue.h" +#include "maincore.h" + #include "nfmmodsource.h" const int NFMModSource::m_levelNbSamples = 480; // every 10ms @@ -44,6 +48,9 @@ NFMModSource::NFMModSource() : m_feedbackAudioBuffer.resize(1<<14); m_feedbackAudioBufferFill = 0; + m_demodBuffer.resize(1<<12); + m_demodBufferFill = 0; + m_magsq = 0.0; applySettings(m_settings, true); @@ -132,7 +139,7 @@ void NFMModSource::pullAudio(unsigned int nbSamplesAudio) void NFMModSource::modulateSample() { - Real t0, t; + Real t0, t1, t; pullAF(t0); m_preemphasisFilter.process(t0, t); @@ -144,11 +151,13 @@ void NFMModSource::modulateSample() calculateLevel(t); if (m_settings.m_ctcssOn) { - m_modPhasor += (m_settings.m_fmDeviation / (float) m_audioSampleRate) * (0.85f * m_bandpass.filter(t) + 0.15f * 0.625f * m_ctcssNco.next()) * 1.33f; + t1 = (0.85f * m_bandpass.filter(t) + 0.15f * 0.625f * m_ctcssNco.next()) * 1.2f; } else { - m_modPhasor += (m_settings.m_fmDeviation / (float) m_audioSampleRate) * m_bandpass.filter(t) * 1.33f; + t1 = m_bandpass.filter(t) * 1.2f; } + m_modPhasor += (m_settings.m_fmDeviation / (float) m_audioSampleRate) * t1; + // limit phasor range to ]-pi,pi] if (m_modPhasor > M_PI) { m_modPhasor -= (2.0f * M_PI); @@ -156,6 +165,25 @@ void NFMModSource::modulateSample() m_modSample.real(cos(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF); // -1 dB m_modSample.imag(sin(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF); + + m_demodBuffer[m_demodBufferFill] = t1 * std::numeric_limits::max(); + ++m_demodBufferFill; + + if (m_demodBufferFill >= m_demodBuffer.size()) + { + QList *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod"); + + if (dataFifos) + { + QList::iterator it = dataFifos->begin(); + + for (; it != dataFifos->end(); ++it) { + (*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16)); + } + } + + m_demodBufferFill = 0; + } } void NFMModSource::pullAF(Real& sample) @@ -321,6 +349,19 @@ void NFMModSource::applyAudioSampleRate(int sampleRate) m_preemphasisFilter.configure(m_preemphasis*sampleRate); m_audioSampleRate = sampleRate; applyFeedbackAudioSampleRate(m_feedbackAudioSampleRate); + + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(m_channel, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(m_channel, sampleRate); + (*it)->push(msg); + } + } } void NFMModSource::applyFeedbackAudioSampleRate(int sampleRate) diff --git a/plugins/channeltx/modnfm/nfmmodsource.h b/plugins/channeltx/modnfm/nfmmodsource.h index cfad5fe45..73cf14e20 100644 --- a/plugins/channeltx/modnfm/nfmmodsource.h +++ b/plugins/channeltx/modnfm/nfmmodsource.h @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -36,6 +37,8 @@ #include "nfmmodsettings.h" +class ChannelAPI; + class NFMModSource : public QObject, public ChannelSampleSource { Q_OBJECT @@ -54,6 +57,7 @@ public: void applyFeedbackAudioSampleRate(int sampleRate); int getAudioSampleRate() const { return m_audioSampleRate; } int getFeedbackAudioSampleRate() const { return m_feedbackAudioSampleRate; } + void setChannel(ChannelAPI *channel) { m_channel = channel; } CWKeyer& getCWKeyer() { return m_cwKeyer; } double getMagSq() const { return m_magsq; } void getLevels(qreal& rmsLevel, qreal& peakLevel, int& numSamples) const @@ -69,6 +73,7 @@ private: int m_channelSampleRate; int m_channelFrequencyOffset; NFMModSettings m_settings; + ChannelAPI *m_channel; NCO m_carrierNco; NCOF m_toneNco; @@ -86,6 +91,9 @@ private: Real m_feedbackInterpolatorDistanceRemain; bool m_feedbackInterpolatorConsumed; + QVector m_demodBuffer; + int m_demodBufferFill; + Lowpass m_lowpass; Bandpass m_bandpass; HighPassFilterRC m_preemphasisFilter; diff --git a/plugins/channeltx/modpacket/packetmod.cpp b/plugins/channeltx/modpacket/packetmod.cpp index 57db1e210..b84b73403 100644 --- a/plugins/channeltx/modpacket/packetmod.cpp +++ b/plugins/channeltx/modpacket/packetmod.cpp @@ -64,6 +64,7 @@ PacketMod::PacketMod(DeviceAPI *deviceAPI) : m_thread = new QThread(this); m_basebandSource = new PacketModBaseband(); m_basebandSource->setSpectrumSampleSink(&m_spectrumVis); + m_basebandSource->setChannel(this); m_basebandSource->moveToThread(m_thread); applySettings(m_settings, true); diff --git a/plugins/channeltx/modpacket/packetmodbaseband.cpp b/plugins/channeltx/modpacket/packetmodbaseband.cpp index 810cc3807..292ab8bc7 100644 --- a/plugins/channeltx/modpacket/packetmodbaseband.cpp +++ b/plugins/channeltx/modpacket/packetmodbaseband.cpp @@ -56,6 +56,11 @@ void PacketModBaseband::reset() m_sampleFifo.reset(); } +void PacketModBaseband::setChannel(ChannelAPI *channel) +{ + m_source.setChannel(channel); +} + void PacketModBaseband::pull(const SampleVector::iterator& begin, unsigned int nbSamples) { unsigned int part1Begin, part1End, part2Begin, part2End; diff --git a/plugins/channeltx/modpacket/packetmodbaseband.h b/plugins/channeltx/modpacket/packetmodbaseband.h index 5ed3388e1..1ae98d066 100644 --- a/plugins/channeltx/modpacket/packetmodbaseband.h +++ b/plugins/channeltx/modpacket/packetmodbaseband.h @@ -29,6 +29,7 @@ #include "packetmodsource.h" class UpChannelizer; +class ChannelAPI; class PacketModBaseband : public QObject { @@ -65,7 +66,7 @@ public: double getMagSq() const { return m_source.getMagSq(); } int getChannelSampleRate() const; void setSpectrumSampleSink(BasebandSampleSink* sampleSink) { m_source.setSpectrumSink(sampleSink); } - + void setChannel(ChannelAPI *channel); signals: /** diff --git a/plugins/channeltx/modpacket/packetmodplugin.cpp b/plugins/channeltx/modpacket/packetmodplugin.cpp index c29240a33..ba3c698fe 100644 --- a/plugins/channeltx/modpacket/packetmodplugin.cpp +++ b/plugins/channeltx/modpacket/packetmodplugin.cpp @@ -29,7 +29,7 @@ const PluginDescriptor PacketModPlugin::m_pluginDescriptor = { PacketMod::m_channelId, QStringLiteral("Packet Modulator"), - QStringLiteral("6.3.3"), + QStringLiteral("6.4.0"), QStringLiteral("(c) Jon Beniston, M7RCE"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channeltx/modpacket/packetmodsource.cpp b/plugins/channeltx/modpacket/packetmodsource.cpp index 3b668a0be..f4f8431d1 100644 --- a/plugins/channeltx/modpacket/packetmodsource.cpp +++ b/plugins/channeltx/modpacket/packetmodsource.cpp @@ -20,8 +20,11 @@ #include #include "dsp/basebandsamplesink.h" +#include "dsp/datafifo.h" #include "packetmodsource.h" #include "util/crc.h" +#include "util/messagequeue.h" +#include "maincore.h" PacketModSource::PacketModSource() : m_channelSampleRate(48000), @@ -46,6 +49,10 @@ PacketModSource::PacketModSource() : qDebug() << "PacketModSource::PacketModSource creating BPF : " << m_channelSampleRate; m_bandpass.create(301, m_channelSampleRate, 800.0, 2600.0); m_pulseShape.create(0.5, 6, m_channelSampleRate/9600); + + m_demodBuffer.resize(1<<12); + m_demodBufferFill = 0; + applySettings(m_settings, true); applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true); } @@ -266,6 +273,25 @@ void PacketModSource::modulateSample() Real s = std::real(m_modSample); calculateLevel(s); } + + m_demodBuffer[m_demodBufferFill] = audioMod * std::numeric_limits::max(); + ++m_demodBufferFill; + + if (m_demodBufferFill >= m_demodBuffer.size()) + { + QList *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod"); + + if (dataFifos) + { + QList::iterator it = dataFifos->begin(); + + for (; it != dataFifos->end(); ++it) { + (*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16)); + } + } + + m_demodBufferFill = 0; + } } void PacketModSource::calculateLevel(Real& sample) @@ -383,6 +409,19 @@ void PacketModSource::applyChannelSettings(int channelSampleRate, int channelFre qDebug() << "m_samplesPerSymbol: " << m_samplesPerSymbol << " (" << m_channelSampleRate << "/" << m_settings.m_baud << ")"; // Precalculate FM sensensity to save doing it in the loop m_phaseSensitivity = 2.0f * M_PI * m_settings.m_fmDeviation / (double)m_channelSampleRate; + + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(m_channel, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(m_channel, m_channelSampleRate); + (*it)->push(msg); + } + } } static uint8_t *ax25_address(uint8_t *p, QString address, uint8_t crrl) diff --git a/plugins/channeltx/modpacket/packetmodsource.h b/plugins/channeltx/modpacket/packetmodsource.h index 0a9028dee..bc3eb63f8 100644 --- a/plugins/channeltx/modpacket/packetmodsource.h +++ b/plugins/channeltx/modpacket/packetmodsource.h @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -44,6 +45,7 @@ #define AX25_NO_L3 0xf0 class BasebandSampleSink; +class ChannelAPI; class PacketModSource : public ChannelSampleSource { @@ -66,12 +68,14 @@ public: void applySettings(const PacketModSettings& settings, bool force = false); void applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force = false); void addTXPacket(QString callsign, QString to, QString via, QString data); + void setChannel(ChannelAPI *channel) { m_channel = channel; } private: int m_channelSampleRate; int m_channelFrequencyOffset; int m_spectrumRate; PacketModSettings m_settings; + ChannelAPI *m_channel; NCO m_carrierNco; Real m_audioPhase; @@ -126,6 +130,9 @@ private: std::ofstream m_audioFile; // For debug output of baseband waveform + QVector m_demodBuffer; + int m_demodBufferFill; + bool bitsValid(); // Are there and bits to transmit int getBit(); // Get bit from m_bits void addBit(int bit); // Add bit to m_bits, with zero stuffing diff --git a/plugins/channeltx/modssb/ssbmod.cpp b/plugins/channeltx/modssb/ssbmod.cpp index 34e929ff3..e5c09f4df 100644 --- a/plugins/channeltx/modssb/ssbmod.cpp +++ b/plugins/channeltx/modssb/ssbmod.cpp @@ -67,6 +67,7 @@ SSBMod::SSBMod(DeviceAPI *deviceAPI) : m_basebandSource = new SSBModBaseband(); m_basebandSource->setSpectrumSink(&m_spectrumVis); m_basebandSource->setInputFileStream(&m_ifstream); + m_basebandSource->setChannel(this); m_basebandSource->moveToThread(m_thread); applySettings(m_settings, true); diff --git a/plugins/channeltx/modssb/ssbmodbaseband.cpp b/plugins/channeltx/modssb/ssbmodbaseband.cpp index 803ec15e2..9c10252b8 100644 --- a/plugins/channeltx/modssb/ssbmodbaseband.cpp +++ b/plugins/channeltx/modssb/ssbmodbaseband.cpp @@ -63,6 +63,11 @@ void SSBModBaseband::reset() m_sampleFifo.reset(); } +void SSBModBaseband::setChannel(ChannelAPI *channel) +{ + m_source.setChannel(channel); +} + void SSBModBaseband::pull(const SampleVector::iterator& begin, unsigned int nbSamples) { unsigned int part1Begin, part1End, part2Begin, part2End; diff --git a/plugins/channeltx/modssb/ssbmodbaseband.h b/plugins/channeltx/modssb/ssbmodbaseband.h index 6ec4d0faf..b60268a30 100644 --- a/plugins/channeltx/modssb/ssbmodbaseband.h +++ b/plugins/channeltx/modssb/ssbmodbaseband.h @@ -30,6 +30,7 @@ class UpChannelizer; class BasebandSampleSink; class SpectrumVis; +class ChannelAPI; class SSBModBaseband : public QObject { @@ -72,6 +73,7 @@ public: AudioFifo *getAudioFifo() { return m_source.getAudioFifo(); } AudioFifo *getFeedbackAudioFifo() { return m_source.getFeedbackAudioFifo(); } void setSpectrumSink(SpectrumVis *sampleSink) { m_spectrumVis = sampleSink; m_source.setSpectrumSink((BasebandSampleSink *) sampleSink); } + void setChannel(ChannelAPI *channel); signals: /** diff --git a/plugins/channeltx/modssb/ssbmodplugin.cpp b/plugins/channeltx/modssb/ssbmodplugin.cpp index 021cab62f..4890b16f1 100644 --- a/plugins/channeltx/modssb/ssbmodplugin.cpp +++ b/plugins/channeltx/modssb/ssbmodplugin.cpp @@ -28,7 +28,7 @@ const PluginDescriptor SSBModPlugin::m_pluginDescriptor = { SSBMod::m_channelId, QStringLiteral("SSB Modulator"), - QStringLiteral("6.3.3"), + QStringLiteral("6.4.0"), QStringLiteral("(c) Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channeltx/modssb/ssbmodsource.cpp b/plugins/channeltx/modssb/ssbmodsource.cpp index 219de61c5..80e96b515 100644 --- a/plugins/channeltx/modssb/ssbmodsource.cpp +++ b/plugins/channeltx/modssb/ssbmodsource.cpp @@ -19,6 +19,10 @@ #include "dsp/basebandsamplesink.h" #include "dsp/misc.h" +#include "dsp/datafifo.h" +#include "util/messagequeue.h" +#include "maincore.h" + #include "ssbmodsource.h" const int SSBModSource::m_ssbFftLen = 1024; @@ -51,6 +55,9 @@ SSBModSource::SSBModSource() : m_feedbackAudioBuffer.resize(1<<14); m_feedbackAudioBufferFill = 0; + m_demodBuffer.resize(1<<12); + m_demodBufferFill = 0; + m_sum.real(0.0f); m_sum.imag(0.0f); m_undersampleCount = 0; @@ -163,6 +170,26 @@ void SSBModSource::modulateSample() } calculateLevel(m_modSample); + + // take projection on real axis + m_demodBuffer[m_demodBufferFill] = m_modSample.real() * std::numeric_limits::max(); + ++m_demodBufferFill; + + if (m_demodBufferFill >= m_demodBuffer.size()) + { + QList *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod"); + + if (dataFifos) + { + QList::iterator it = dataFifos->begin(); + + for (; it != dataFifos->end(); ++it) { + (*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16)); + } + } + + m_demodBufferFill = 0; + } } void SSBModSource::pullAF(Complex& sample) @@ -574,6 +601,19 @@ void SSBModSource::applyAudioSampleRate(int sampleRate) m_audioSampleRate = sampleRate; applyFeedbackAudioSampleRate(m_feedbackAudioSampleRate); + + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(m_channel, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(m_channel, sampleRate); + (*it)->push(msg); + } + } } void SSBModSource::applyFeedbackAudioSampleRate(int sampleRate) diff --git a/plugins/channeltx/modssb/ssbmodsource.h b/plugins/channeltx/modssb/ssbmodsource.h index a9fe7721c..76275cb12 100644 --- a/plugins/channeltx/modssb/ssbmodsource.h +++ b/plugins/channeltx/modssb/ssbmodsource.h @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -36,6 +37,7 @@ #include "ssbmodsettings.h" class BasebandSampleSink; +class ChannelAPI; class SSBModSource : public QObject, public ChannelSampleSource { @@ -55,6 +57,7 @@ public: void applyFeedbackAudioSampleRate(int sampleRate); int getAudioSampleRate() const { return m_audioSampleRate; } int getFeedbackAudioSampleRate() const { return m_feedbackAudioSampleRate; } + void setChannel(ChannelAPI *channel) { m_channel = channel; } CWKeyer& getCWKeyer() { return m_cwKeyer; } double getMagSq() const { return m_magsq; } void getLevels(qreal& rmsLevel, qreal& peakLevel, int& numSamples) const @@ -71,6 +74,7 @@ private: int m_channelSampleRate; int m_channelFrequencyOffset; SSBModSettings m_settings; + ChannelAPI *m_channel; NCOF m_carrierNco; NCOF m_toneNco; @@ -86,6 +90,9 @@ private: Real m_feedbackInterpolatorDistanceRemain; bool m_feedbackInterpolatorConsumed; + QVector m_demodBuffer; + int m_demodBufferFill; + fftfilt* m_SSBFilter; fftfilt* m_DSBFilter; Complex* m_SSBFilterBuffer; diff --git a/plugins/channeltx/modwfm/wfmmod.cpp b/plugins/channeltx/modwfm/wfmmod.cpp index 2efed5c8a..464633777 100644 --- a/plugins/channeltx/modwfm/wfmmod.cpp +++ b/plugins/channeltx/modwfm/wfmmod.cpp @@ -64,6 +64,7 @@ WFMMod::WFMMod(DeviceAPI *deviceAPI) : m_thread = new QThread(this); m_basebandSource = new WFMModBaseband(); m_basebandSource->setInputFileStream(&m_ifstream); + m_basebandSource->setChannel(this); m_basebandSource->moveToThread(m_thread); applySettings(m_settings, true); diff --git a/plugins/channeltx/modwfm/wfmmodbaseband.cpp b/plugins/channeltx/modwfm/wfmmodbaseband.cpp index 1aa75a934..ee02b0446 100644 --- a/plugins/channeltx/modwfm/wfmmodbaseband.cpp +++ b/plugins/channeltx/modwfm/wfmmodbaseband.cpp @@ -61,6 +61,11 @@ void WFMModBaseband::reset() m_sampleFifo.reset(); } +void WFMModBaseband::setChannel(ChannelAPI *channel) +{ + m_source.setChannel(channel); +} + void WFMModBaseband::pull(const SampleVector::iterator& begin, unsigned int nbSamples) { unsigned int part1Begin, part1End, part2Begin, part2End; @@ -209,4 +214,4 @@ void WFMModBaseband::applySettings(const WFMModSettings& settings, bool force) int WFMModBaseband::getChannelSampleRate() const { return m_channelizer->getChannelSampleRate(); -} \ No newline at end of file +} diff --git a/plugins/channeltx/modwfm/wfmmodbaseband.h b/plugins/channeltx/modwfm/wfmmodbaseband.h index d63f2e4e7..a7ef056cf 100644 --- a/plugins/channeltx/modwfm/wfmmodbaseband.h +++ b/plugins/channeltx/modwfm/wfmmodbaseband.h @@ -28,6 +28,7 @@ #include "wfmmodsource.h" class UpChannelizer; +class ChannelAPI; class WFMModBaseband : public QObject { @@ -68,6 +69,7 @@ public: int getChannelSampleRate() const; void setInputFileStream(std::ifstream *ifstream) { m_source.setInputFileStream(ifstream); } AudioFifo *getAudioFifo() { return m_source.getAudioFifo(); } + void setChannel(ChannelAPI *channel); signals: /** diff --git a/plugins/channeltx/modwfm/wfmmodplugin.cpp b/plugins/channeltx/modwfm/wfmmodplugin.cpp index f5729778d..0b903c297 100644 --- a/plugins/channeltx/modwfm/wfmmodplugin.cpp +++ b/plugins/channeltx/modwfm/wfmmodplugin.cpp @@ -28,7 +28,7 @@ const PluginDescriptor WFMModPlugin::m_pluginDescriptor = { WFMMod::m_channelId, QStringLiteral("WFM Modulator"), - QStringLiteral("6.3.3"), + QStringLiteral("6.4.0"), QStringLiteral("(c) Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channeltx/modwfm/wfmmodsource.cpp b/plugins/channeltx/modwfm/wfmmodsource.cpp index d073c3260..732e67052 100644 --- a/plugins/channeltx/modwfm/wfmmodsource.cpp +++ b/plugins/channeltx/modwfm/wfmmodsource.cpp @@ -16,6 +16,10 @@ #include +#include "dsp/datafifo.h" +#include "util/messagequeue.h" +#include "maincore.h" + #include "wfmmodsource.h" const int WFMModSource::m_rfFilterFFTLength = 1024; @@ -46,6 +50,8 @@ WFMModSource::WFMModSource() : m_magsq = 0.0; m_feedbackAudioBuffer.resize(1<<14); m_feedbackAudioBufferFill = 0; + m_demodBuffer.resize(1<<12); + m_demodBufferFill = 0; applySettings(m_settings, true); applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true); @@ -140,6 +146,25 @@ void WFMModSource::pullOne(Sample& sample) sample.m_real = (FixReal) ci.real(); sample.m_imag = (FixReal) ci.imag(); + + m_demodBuffer[m_demodBufferFill] = t * std::numeric_limits::max(); + ++m_demodBufferFill; + + if (m_demodBufferFill >= m_demodBuffer.size()) + { + QList *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod"); + + if (dataFifos) + { + QList::iterator it = dataFifos->begin(); + + for (; it != dataFifos->end(); ++it) { + (*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16)); + } + } + + m_demodBufferFill = 0; + } } void WFMModSource::modulateAudio() @@ -237,13 +262,13 @@ void WFMModSource::pullAF(Real& sample) if (m_cwKeyer.getSample()) { m_cwKeyer.getCWSmoother().getFadeSample(true, fadeFactor); - sample = m_cwToneNco.next() * m_settings.m_volumeFactor * fadeFactor; + sample = m_cwToneNco.next() * m_settings.m_volumeFactor * fadeFactor * 0.99f; } else { if (m_cwKeyer.getCWSmoother().getFadeSample(false, fadeFactor)) { - sample = m_cwToneNco.next() * m_settings.m_volumeFactor * fadeFactor; + sample = m_cwToneNco.next() * m_settings.m_volumeFactor * fadeFactor * 0.99f; } else { @@ -339,6 +364,19 @@ void WFMModSource::applyAudioSampleRate(int sampleRate) m_cwKeyer.reset(); m_audioSampleRate = sampleRate; applyFeedbackAudioSampleRate(m_feedbackAudioSampleRate); + + QList *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(m_channel, "reportdemod"); + + if (messageQueues) + { + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(m_channel, sampleRate); + (*it)->push(msg); + } + } } void WFMModSource::applyFeedbackAudioSampleRate(int sampleRate) diff --git a/plugins/channeltx/modwfm/wfmmodsource.h b/plugins/channeltx/modwfm/wfmmodsource.h index 3b393e623..78fa6e399 100644 --- a/plugins/channeltx/modwfm/wfmmodsource.h +++ b/plugins/channeltx/modwfm/wfmmodsource.h @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -35,6 +36,8 @@ #include "wfmmodsettings.h" +class ChannelAPI; + class WFMModSource : public QObject, public ChannelSampleSource { Q_OBJECT @@ -53,6 +56,7 @@ public: void applyFeedbackAudioSampleRate(int sampleRate); int getAudioSampleRate() const { return m_audioSampleRate; } int getFeedbackAudioSampleRate() const { return m_feedbackAudioSampleRate; } + void setChannel(ChannelAPI *channel) { m_channel = channel; } CWKeyer& getCWKeyer() { return m_cwKeyer; } double getMagSq() const { return m_magsq; } void getLevels(qreal& rmsLevel, qreal& peakLevel, int& numSamples) const @@ -68,6 +72,7 @@ private: int m_channelSampleRate; int m_channelFrequencyOffset; WFMModSettings m_settings; + ChannelAPI *m_channel; NCO m_carrierNco; NCOF m_toneNco; @@ -85,6 +90,9 @@ private: Real m_feedbackInterpolatorDistanceRemain; bool m_feedbackInterpolatorConsumed; + QVector m_demodBuffer; + int m_demodBufferFill; + fftfilt* m_rfFilter; static const int m_rfFilterFFTLength; fftfilt::cmplx *m_rfFilterBuffer; diff --git a/plugins/feature/demodanalyzer/demodanalyzersettings.cpp b/plugins/feature/demodanalyzer/demodanalyzersettings.cpp index 3ffe5381d..6004ab2b3 100644 --- a/plugins/feature/demodanalyzer/demodanalyzersettings.cpp +++ b/plugins/feature/demodanalyzer/demodanalyzersettings.cpp @@ -27,6 +27,12 @@ const QStringList DemodAnalyzerSettings::m_channelTypes = { QStringLiteral("AMMod"), QStringLiteral("DSDDemod"), QStringLiteral("NFMDemod"), + QStringLiteral("NFMMod"), + QStringLiteral("PacketMod"), + QStringLiteral("SSBDemod"), + QStringLiteral("SSBMod"), + QStringLiteral("WFMDemod"), + QStringLiteral("WFMMod"), }; const QStringList DemodAnalyzerSettings::m_channelURIs = { @@ -34,6 +40,12 @@ const QStringList DemodAnalyzerSettings::m_channelURIs = { QStringLiteral("sdrangel.channeltx.modam"), QStringLiteral("sdrangel.channel.dsddemod"), QStringLiteral("sdrangel.channel.nfmdemod"), + QStringLiteral("sdrangel.channeltx.modnfm"), + QStringLiteral("sdrangel.channeltx.modpacket"), + QStringLiteral("sdrangel.channel.ssbdemod"), + QStringLiteral("sdrangel.channeltx.modssb"), + QStringLiteral("sdrangel.channel.wfmdemod"), + QStringLiteral("sdrangel.channeltx.modwfm"), }; DemodAnalyzerSettings::DemodAnalyzerSettings() :