From 501d8515ebb3467484a4f99ece164f5cff011770 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Mon, 20 Jun 2022 12:55:30 +0100 Subject: [PATCH] Add support for Broadcast FM Demod to send audio to Demod Analyzer feature --- plugins/channelrx/demodbfm/bfmdemod.cpp | 1 + .../channelrx/demodbfm/bfmdemodbaseband.cpp | 5 +++ plugins/channelrx/demodbfm/bfmdemodbaseband.h | 1 + plugins/channelrx/demodbfm/bfmdemodsink.cpp | 32 +++++++++++++++++++ plugins/channelrx/demodbfm/bfmdemodsink.h | 6 ++++ .../demodanalyzer/demodanalyzersettings.cpp | 2 ++ 6 files changed, 47 insertions(+) diff --git a/plugins/channelrx/demodbfm/bfmdemod.cpp b/plugins/channelrx/demodbfm/bfmdemod.cpp index ee65f9a1f..cf2afaea1 100644 --- a/plugins/channelrx/demodbfm/bfmdemod.cpp +++ b/plugins/channelrx/demodbfm/bfmdemod.cpp @@ -59,6 +59,7 @@ BFMDemod::BFMDemod(DeviceAPI *deviceAPI) : m_thread = new QThread(this); m_basebandSink = new BFMDemodBaseband(); m_basebandSink->setSpectrumSink(&m_spectrumVis); + m_basebandSink->setChannel(this); m_basebandSink->moveToThread(m_thread); applySettings(m_settings, true); diff --git a/plugins/channelrx/demodbfm/bfmdemodbaseband.cpp b/plugins/channelrx/demodbfm/bfmdemodbaseband.cpp index bd362e048..b831cb57e 100644 --- a/plugins/channelrx/demodbfm/bfmdemodbaseband.cpp +++ b/plugins/channelrx/demodbfm/bfmdemodbaseband.cpp @@ -69,6 +69,11 @@ void BFMDemodBaseband::feed(const SampleVector::const_iterator& begin, const Sam m_sampleFifo.write(begin, end); } +void BFMDemodBaseband::setChannel(ChannelAPI *channel) +{ + m_sink.setChannel(channel); +} + void BFMDemodBaseband::handleData() { QMutexLocker mutexLocker(&m_mutex); diff --git a/plugins/channelrx/demodbfm/bfmdemodbaseband.h b/plugins/channelrx/demodbfm/bfmdemodbaseband.h index 4ac0b437e..a5f5101f4 100644 --- a/plugins/channelrx/demodbfm/bfmdemodbaseband.h +++ b/plugins/channelrx/demodbfm/bfmdemodbaseband.h @@ -65,6 +65,7 @@ public: int getChannelSampleRate() const; void setBasebandSampleRate(int sampleRate); void setSpectrumSink(SpectrumVis* spectrumSink) { m_spectrumVis = spectrumSink; m_sink.setSpectrumSink((BasebandSampleSink*) spectrumSink); } + void setChannel(ChannelAPI *channel); void setMessageQueueToGUI(MessageQueue *messageQueue) { m_messageQueueToGUI = messageQueue; } int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); } diff --git a/plugins/channelrx/demodbfm/bfmdemodsink.cpp b/plugins/channelrx/demodbfm/bfmdemodsink.cpp index 8667edb67..e22acd0e2 100644 --- a/plugins/channelrx/demodbfm/bfmdemodsink.cpp +++ b/plugins/channelrx/demodbfm/bfmdemodsink.cpp @@ -27,7 +27,10 @@ #include "dsp/dspcommands.h" #include "dsp/devicesamplemimo.h" #include "dsp/basebandsamplesink.h" +#include "dsp/datafifo.h" +#include "pipes/datapipes.h" #include "util/db.h" +#include "maincore.h" #include "rdsparser.h" #include "bfmdemodsink.h" @@ -36,6 +39,7 @@ const Real BFMDemodSink::default_deemphasis = 50.0; // 50 us const int BFMDemodSink::default_excursion = 750000; // +/- 75 kHz BFMDemodSink::BFMDemodSink() : + m_channel(nullptr), m_channelSampleRate(48000), m_channelFrequencyOffset(0), m_audioSampleRate(48000), @@ -75,6 +79,9 @@ BFMDemodSink::BFMDemodSink() : m_audioBuffer.resize(1<<14); m_audioBufferFill = 0; + m_demodBuffer.resize(1<<13); + m_demodBufferFill = 0; + applySettings(m_settings, true); applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true); } @@ -211,6 +218,9 @@ void BFMDemodSink::feed(const SampleVector::const_iterator& begin, const SampleV m_audioBuffer[m_audioBufferFill].r = sample; } + m_demodBuffer[m_demodBufferFill++] = m_audioBuffer[m_audioBufferFill].l; + m_demodBuffer[m_demodBufferFill++] = m_audioBuffer[m_audioBufferFill].r; + ++m_audioBufferFill; if (m_audioBufferFill >= m_audioBuffer.size()) @@ -224,6 +234,28 @@ void BFMDemodSink::feed(const SampleVector::const_iterator& begin, const SampleV m_audioBufferFill = 0; } + if (m_demodBufferFill >= m_demodBuffer.size()) + { + QList dataPipes; + MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes); + + if (dataPipes.size() > 0) + { + QList::iterator it = dataPipes.begin(); + + for (; it != dataPipes.end(); ++it) + { + DataFifo *fifo = qobject_cast((*it)->m_element); + + if (fifo) { + fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeCI16); + } + } + } + + m_demodBufferFill = 0; + } + m_interpolatorDistanceRemain += m_interpolatorDistance; } } diff --git a/plugins/channelrx/demodbfm/bfmdemodsink.h b/plugins/channelrx/demodbfm/bfmdemodsink.h index bb0194e18..c794dbc5e 100644 --- a/plugins/channelrx/demodbfm/bfmdemodsink.h +++ b/plugins/channelrx/demodbfm/bfmdemodsink.h @@ -36,6 +36,7 @@ #include "rdsdemod.h" #include "bfmdemodsettings.h" +class ChannelAPI; class BasebandSampleSink; class BFMDemodSink : public ChannelSampleSink { @@ -46,6 +47,7 @@ public: virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end); void setSpectrumSink(BasebandSampleSink* spectrumSink) { m_spectrumSink = spectrumSink; } + void setChannel(ChannelAPI *channel) { m_channel = channel; } double getMagSq() const { return m_magsq; } @@ -103,6 +105,7 @@ private: RSRunning }; + ChannelAPI *m_channel; int m_channelSampleRate; int m_channelFrequencyOffset; BFMDemodSettings m_settings; @@ -158,6 +161,9 @@ private: PhaseDiscriminators m_phaseDiscri; BasebandSampleSink *m_spectrumSink; + + QVector m_demodBuffer; + int m_demodBufferFill; }; #endif // INCLUDE_BFMDEMODSINK_H diff --git a/plugins/feature/demodanalyzer/demodanalyzersettings.cpp b/plugins/feature/demodanalyzer/demodanalyzersettings.cpp index d261e5417..2741a9aab 100644 --- a/plugins/feature/demodanalyzer/demodanalyzersettings.cpp +++ b/plugins/feature/demodanalyzer/demodanalyzersettings.cpp @@ -27,6 +27,7 @@ const QStringList DemodAnalyzerSettings::m_channelTypes = { QStringLiteral("AISMod"), QStringLiteral("AMDemod"), QStringLiteral("AMMod"), + QStringLiteral("BFMDemod"), QStringLiteral("DABDemod"), QStringLiteral("DSDDemod"), QStringLiteral("NFMDemod"), @@ -45,6 +46,7 @@ const QStringList DemodAnalyzerSettings::m_channelURIs = { QStringLiteral("sdrangel.channel.modais"), QStringLiteral("sdrangel.channel.amdemod"), QStringLiteral("sdrangel.channeltx.modam"), + QStringLiteral("sdrangel.channel.bfm"), QStringLiteral("sdrangel.channel.dabdemod"), QStringLiteral("sdrangel.channel.dsddemod"), QStringLiteral("sdrangel.channel.nfmdemod"),