1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-16 05:11:49 -05:00

Demod Analyzer: implementation for DSDDemod and NFMDemod

This commit is contained in:
f4exb 2020-12-20 11:52:10 +01:00
parent 11e1d1c684
commit d93186e059
10 changed files with 109 additions and 6 deletions

View File

@ -59,6 +59,7 @@ DSDDemod::DSDDemod(DeviceAPI *deviceAPI) :
m_thread = new QThread(this); m_thread = new QThread(this);
m_basebandSink = new DSDDemodBaseband(); m_basebandSink = new DSDDemodBaseband();
m_basebandSink->setChannel(this);
m_basebandSink->moveToThread(m_thread); m_basebandSink->moveToThread(m_thread);
applySettings(m_settings, true); applySettings(m_settings, true);

View File

@ -61,6 +61,11 @@ void DSDDemodBaseband::reset()
m_sampleFifo.reset(); m_sampleFifo.reset();
} }
void DSDDemodBaseband::setChannel(ChannelAPI *channel)
{
m_sink.setChannel(channel);
}
void DSDDemodBaseband::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end) void DSDDemodBaseband::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
{ {
m_sampleFifo.write(begin, end); m_sampleFifo.write(begin, end);

View File

@ -28,6 +28,7 @@
#include "dsddemodsink.h" #include "dsddemodsink.h"
class DownChannelizer; class DownChannelizer;
class ChannelAPI;
class DSDDemodBaseband : public QObject class DSDDemodBaseband : public QObject
{ {
@ -71,6 +72,7 @@ public:
void configureMyPosition(float myLatitude, float myLongitude) { m_sink.configureMyPosition(myLatitude, myLongitude); } void configureMyPosition(float myLatitude, float myLongitude) { m_sink.configureMyPosition(myLatitude, myLongitude); }
const DSDDecoder& getDecoder() const { return m_sink.getDecoder(); } const DSDDecoder& getDecoder() const { return m_sink.getDecoder(); }
const char *updateAndGetStatusText() { return m_sink.updateAndGetStatusText(); } const char *updateAndGetStatusText() { return m_sink.updateAndGetStatusText(); }
void setChannel(ChannelAPI *channel);
private: private:
SampleSinkFifo m_sampleFifo; SampleSinkFifo m_sampleFifo;

View File

@ -33,8 +33,11 @@
#include "dsp/dspengine.h" #include "dsp/dspengine.h"
#include "dsp/basebandsamplesink.h" #include "dsp/basebandsamplesink.h"
#include "dsp/datafifo.h"
#include "audio/audiooutputdevice.h" #include "audio/audiooutputdevice.h"
#include "util/db.h" #include "util/db.h"
#include "util/messagequeue.h"
#include "maincore.h"
#include "dsddemodsink.h" #include "dsddemodsink.h"
@ -59,6 +62,8 @@ DSDDemodSink::DSDDemodSink() :
{ {
m_audioBuffer.resize(1<<14); m_audioBuffer.resize(1<<14);
m_audioBufferFill = 0; m_audioBufferFill = 0;
m_demodBuffer.resize(1<<12);
m_demodBufferFill = 0;
m_sampleBuffer = new FixReal[1<<17]; // 128 kS m_sampleBuffer = new FixReal[1<<17]; // 128 kS
m_sampleBufferIndex = 0; m_sampleBufferIndex = 0;
@ -170,6 +175,25 @@ void DSDDemodSink::feed(const SampleVector::const_iterator& begin, const SampleV
m_dsdDecoder.pushSample(sampleDSD); m_dsdDecoder.pushSample(sampleDSD);
m_demodBuffer[m_demodBufferFill] = sampleDSD;
++m_demodBufferFill;
if (m_demodBufferFill >= m_demodBuffer.size())
{
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
if (dataFifos)
{
QList<DataFifo*>::iterator it = dataFifos->begin();
for (; it != dataFifos->end(); ++it) {
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16));
}
}
m_demodBufferFill = 0;
}
if (m_settings.m_enableCosineFiltering) { // show actual input to FSK demod if (m_settings.m_enableCosineFiltering) { // show actual input to FSK demod
sample = m_dsdDecoder.getFilteredSample() * m_scaleFromShort; sample = m_dsdDecoder.getFilteredSample() * m_scaleFromShort;
} }
@ -297,6 +321,19 @@ void DSDDemodSink::applyAudioSampleRate(int sampleRate)
m_dsdDecoder.setUpsampling(upsampling); m_dsdDecoder.setUpsampling(upsampling);
m_audioSampleRate = sampleRate; m_audioSampleRate = sampleRate;
QList<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(m_channel, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::iterator it = messageQueues->begin();
for (; it != messageQueues->end(); ++it)
{
MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(m_channel, sampleRate);
(*it)->push(msg);
}
}
} }
void DSDDemodSink::applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force) void DSDDemodSink::applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force)

View File

@ -18,6 +18,8 @@
#ifndef INCLUDE_DSDDEMODSINK_H #ifndef INCLUDE_DSDDEMODSINK_H
#define INCLUDE_DSDDEMODSINK_H #define INCLUDE_DSDDEMODSINK_H
#include <QVector>
#include "dsp/channelsamplesink.h" #include "dsp/channelsamplesink.h"
#include "dsp/phasediscri.h" #include "dsp/phasediscri.h"
#include "dsp/nco.h" #include "dsp/nco.h"
@ -33,6 +35,7 @@
#include "dsddecoder.h" #include "dsddecoder.h"
class BasebandSampleSink; class BasebandSampleSink;
class ChannelAPI;
class DSDDemodSink : public ChannelSampleSink { class DSDDemodSink : public ChannelSampleSink {
public: public:
@ -47,6 +50,7 @@ public:
AudioFifo *getAudioFifo1() { return &m_audioFifo1; } AudioFifo *getAudioFifo1() { return &m_audioFifo1; }
AudioFifo *getAudioFifo2() { return &m_audioFifo2; } AudioFifo *getAudioFifo2() { return &m_audioFifo2; }
int getAudioSampleRate() const { return m_audioSampleRate; } int getAudioSampleRate() const { return m_audioSampleRate; }
void setChannel(ChannelAPI *channel) { m_channel = channel; }
void setScopeXYSink(BasebandSampleSink* scopeSink) { m_scopeXY = scopeSink; } void setScopeXYSink(BasebandSampleSink* scopeSink) { m_scopeXY = scopeSink; }
void configureMyPosition(float myLatitude, float myLongitude); void configureMyPosition(float myLatitude, float myLongitude);
@ -105,7 +109,10 @@ private:
int m_channelSampleRate; int m_channelSampleRate;
int m_channelFrequencyOffset; int m_channelFrequencyOffset;
DSDDemodSettings m_settings; DSDDemodSettings m_settings;
ChannelAPI *m_channel;
int m_audioSampleRate; int m_audioSampleRate;
QVector<qint16> m_demodBuffer;
int m_demodBufferFill;
NCO m_nco; NCO m_nco;
Interpolator m_interpolator; Interpolator m_interpolator;

View File

@ -58,6 +58,7 @@ NFMDemod::NFMDemod(DeviceAPI *devieAPI) :
m_thread = new QThread(this); m_thread = new QThread(this);
m_basebandSink = new NFMDemodBaseband(); m_basebandSink = new NFMDemodBaseband();
m_basebandSink->setChannel(this);
m_basebandSink->moveToThread(m_thread); m_basebandSink->moveToThread(m_thread);
applySettings(m_settings, true); applySettings(m_settings, true);

View File

@ -58,6 +58,11 @@ void NFMDemodBaseband::reset()
m_sampleFifo.reset(); m_sampleFifo.reset();
} }
void NFMDemodBaseband::setChannel(ChannelAPI *channel)
{
m_sink.setChannel(channel);
}
void NFMDemodBaseband::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end) void NFMDemodBaseband::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
{ {
m_sampleFifo.write(begin, end); m_sampleFifo.write(begin, end);

View File

@ -28,6 +28,7 @@
#include "nfmdemodsink.h" #include "nfmdemodsink.h"
class DownChannelizer; class DownChannelizer;
class ChannelAPI;
class NFMDemodBaseband : public QObject class NFMDemodBaseband : public QObject
{ {
@ -69,6 +70,7 @@ public:
void setMessageQueueToGUI(MessageQueue *messageQueue) { m_sink.setMessageQueueToGUI(messageQueue); } void setMessageQueueToGUI(MessageQueue *messageQueue) { m_sink.setMessageQueueToGUI(messageQueue); }
int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); } int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); }
void setBasebandSampleRate(int sampleRate); void setBasebandSampleRate(int sampleRate);
void setChannel(ChannelAPI *channel);
private: private:
SampleSinkFifo m_sampleFifo; SampleSinkFifo m_sampleFifo;

View File

@ -23,12 +23,15 @@
#include "util/stepfunctions.h" #include "util/stepfunctions.h"
#include "util/db.h" #include "util/db.h"
#include "util/messagequeue.h"
#include "audio/audiooutputdevice.h" #include "audio/audiooutputdevice.h"
#include "dsp/dspengine.h" #include "dsp/dspengine.h"
#include "dsp/dspcommands.h" #include "dsp/dspcommands.h"
#include "dsp/devicesamplemimo.h" #include "dsp/devicesamplemimo.h"
#include "dsp/misc.h" #include "dsp/misc.h"
#include "dsp/datafifo.h"
#include "device/deviceapi.h" #include "device/deviceapi.h"
#include "maincore.h"
#include "nfmdemodreport.h" #include "nfmdemodreport.h"
#include "nfmdemodsink.h" #include "nfmdemodsink.h"
@ -62,6 +65,8 @@ NFMDemodSink::NFMDemodSink() :
m_messageQueueToGUI(nullptr) m_messageQueueToGUI(nullptr)
{ {
m_audioBuffer.resize(1<<16); m_audioBuffer.resize(1<<16);
m_demodBuffer.resize(1<<12);
m_demodBufferFill = 0;
applySettings(m_settings, true); applySettings(m_settings, true);
applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true); applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true);
@ -219,6 +224,25 @@ void NFMDemodSink::processOneSample(Complex &ci)
m_audioBufferFill = 0; m_audioBufferFill = 0;
} }
m_demodBuffer[m_demodBufferFill] = sample;
++m_demodBufferFill;
if (m_demodBufferFill >= m_demodBuffer.size())
{
QList<DataFifo*> *dataFifos = MainCore::instance()->getDataPipes().getFifos(m_channel, "demod");
if (dataFifos)
{
QList<DataFifo*>::iterator it = dataFifos->begin();
for (; it != dataFifos->end(); ++it) {
(*it)->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16));
}
}
m_demodBufferFill = 0;
}
} }
@ -343,4 +367,17 @@ void NFMDemodSink::applyAudioSampleRate(unsigned int sampleRate)
m_interpolatorDistance = Real(m_channelSampleRate) / Real(sampleRate); m_interpolatorDistance = Real(m_channelSampleRate) / Real(sampleRate);
m_interpolatorDistanceRemain = m_interpolatorDistance; m_interpolatorDistanceRemain = m_interpolatorDistance;
m_audioSampleRate = sampleRate; m_audioSampleRate = sampleRate;
QList<MessageQueue*> *messageQueues = MainCore::instance()->getMessagePipes().getMessageQueues(m_channel, "reportdemod");
if (messageQueues)
{
QList<MessageQueue*>::iterator it = messageQueues->begin();
for (; it != messageQueues->end(); ++it)
{
MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(m_channel, sampleRate);
(*it)->push(msg);
}
}
} }

View File

@ -18,7 +18,7 @@
#ifndef INCLUDE_NFMDEMODSINK_H #ifndef INCLUDE_NFMDEMODSINK_H
#define INCLUDE_NFMDEMODSINK_H #define INCLUDE_NFMDEMODSINK_H
#include <vector> #include <QVector>
#include "dsp/channelsamplesink.h" #include "dsp/channelsamplesink.h"
#include "dsp/phasediscri.h" #include "dsp/phasediscri.h"
@ -35,6 +35,8 @@
#include "nfmdemodsettings.h" #include "nfmdemodsettings.h"
class ChannelAPI;
class NFMDemodSink : public ChannelSampleSink { class NFMDemodSink : public ChannelSampleSink {
public: public:
NFMDemodSink(); NFMDemodSink();
@ -77,6 +79,7 @@ public:
AudioFifo *getAudioFifo() { return &m_audioFifo; } AudioFifo *getAudioFifo() { return &m_audioFifo; }
void applyAudioSampleRate(unsigned int sampleRate); void applyAudioSampleRate(unsigned int sampleRate);
int getAudioSampleRate() const { return m_audioSampleRate; } int getAudioSampleRate() const { return m_audioSampleRate; }
void setChannel(ChannelAPI *channel) { m_channel = channel; }
private: private:
struct MagSqLevelsStore struct MagSqLevelsStore
@ -97,11 +100,14 @@ private:
int m_channelSampleRate; int m_channelSampleRate;
int m_channelFrequencyOffset; int m_channelFrequencyOffset;
NFMDemodSettings m_settings; NFMDemodSettings m_settings;
ChannelAPI *m_channel;
int m_audioSampleRate; int m_audioSampleRate;
AudioVector m_audioBuffer; AudioVector m_audioBuffer;
uint m_audioBufferFill; uint m_audioBufferFill;
AudioFifo m_audioFifo; AudioFifo m_audioFifo;
QVector<qint16> m_demodBuffer;
int m_demodBufferFill;
NCO m_nco; NCO m_nco;
Interpolator m_interpolator; Interpolator m_interpolator;