SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
Classes | Public Member Functions | Static Public Attributes | Private Types | Private Slots | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
NFMDemod Class Reference

#include <nfmdemod.h>

+ Inheritance diagram for NFMDemod:
+ Collaboration diagram for NFMDemod:

Classes

struct  MagSqLevelsStore
 
class  MsgConfigureChannelizer
 
class  MsgConfigureNFMDemod
 
class  MsgReportCTCSSFreq
 

Public Member Functions

 NFMDemod (DeviceAPI *deviceAPI)
 
 ~NFMDemod ()
 
virtual void destroy ()
 
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)
 Processing of a message. Returns true if message has actually been processed. More...
 
virtual void getIdentifier (QString &id)
 
virtual void getTitle (QString &title)
 
virtual qint64 getCenterFrequency () const
 Applies to a default stream. More...
 
virtual QByteArray serialize () const
 
virtual bool deserialize (const QByteArray &data)
 
virtual int getNbSinkStreams () const
 
virtual int getNbSourceStreams () const
 
virtual qint64 getStreamCenterFrequency (int streamIndex, bool sinkElseSource) const
 
virtual int webapiSettingsGet (SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
 
virtual int webapiSettingsPutPatch (bool force, const QStringList &channelSettingsKeys, SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
 
virtual int webapiReportGet (SWGSDRangel::SWGChannelReport &response, QString &errorMessage)
 
const RealgetCtcssToneSet (int &nbTones) const
 
void setSelectedCtcssIndex (int selectedCtcssIndex)
 
Real getMag ()
 
bool getSquelchOpen () const
 
void getMagSqLevels (double &avg, double &peak, int &nbSamples)
 
- Public Member Functions inherited from BasebandSampleSink
 BasebandSampleSink ()
 
virtual ~BasebandSampleSink ()
 
MessageQueuegetInputMessageQueue ()
 Get the queue for asynchronous inbound communication. More...
 
virtual void setMessageQueueToGUI (MessageQueue *queue)
 
MessageQueuegetMessageQueueToGUI ()
 
- Public Member Functions inherited from ChannelAPI
 ChannelAPI (const QString &name, StreamType streamType)
 
virtual ~ChannelAPI ()
 
virtual void setName (const QString &name)
 
virtual const QString & getName () const
 
int getIndexInDeviceSet () const
 
void setIndexInDeviceSet (int indexInDeviceSet)
 
int getDeviceSetIndex () const
 
void setDeviceSetIndex (int deviceSetIndex)
 
DeviceAPIgetDeviceAPI ()
 
void setDeviceAPI (DeviceAPI *deviceAPI)
 
uint64_t getUID () const
 
StreamType getStreamType () const
 

Static Public Attributes

static const QString m_channelIdURI = "sdrangel.channel.nfmdemod"
 
static const QString m_channelId = "NFMDemod"
 

Private Types

enum  RateState { RSInitialFill, RSRunning }
 

Private Slots

void networkManagerFinished (QNetworkReply *reply)
 

Private Member Functions

void applyChannelSettings (int inputSampleRate, int inputFrequencyOffset, bool force=false)
 
void applySettings (const NFMDemodSettings &settings, bool force=false)
 
void applyAudioSampleRate (int sampleRate)
 
void webapiFormatChannelSettings (SWGSDRangel::SWGChannelSettings &response, const NFMDemodSettings &settings)
 
void webapiFormatChannelReport (SWGSDRangel::SWGChannelReport &response)
 
void webapiReverseSendSettings (QList< QString > &channelSettingsKeys, const NFMDemodSettings &settings, bool force)
 
void processOneSample (Complex &ci)
 

Private Attributes

DeviceAPIm_deviceAPI
 
ThreadedBasebandSampleSinkm_threadedChannelizer
 
DownChannelizerm_channelizer
 
int m_inputSampleRate
 
int m_inputFrequencyOffset
 
NFMDemodSettings m_settings
 
uint32_t m_audioSampleRate
 
float m_discriCompensation
 compensation factor that depends on audio rate (1 for 48 kS/s) More...
 
bool m_running
 
NCO m_nco
 
Interpolator m_interpolator
 
Real m_interpolatorDistance
 
Real m_interpolatorDistanceRemain
 
Lowpass< Realm_ctcssLowpass
 
Bandpass< Realm_bandpass
 
Lowpass< Realm_lowpass
 
CTCSSDetector m_ctcssDetector
 
int m_ctcssIndex
 
int m_ctcssIndexSelected
 
int m_sampleCount
 
int m_squelchCount
 
int m_squelchGate
 
Real m_squelchLevel
 
bool m_squelchOpen
 
bool m_afSquelchOpen
 
double m_magsq
 displayed averaged value More...
 
double m_magsqSum
 
double m_magsqPeak
 
int m_magsqCount
 
MagSqLevelsStore m_magSqLevelStore
 
MovingAverageUtil< Real, double, 32 > m_movingAverage
 
AFSquelch m_afSquelch
 
Real m_agcLevel
 
DoubleBufferFIFO< Realm_squelchDelayLine
 
AudioVector m_audioBuffer
 
uint m_audioBufferFill
 
AudioFifo m_audioFifo
 
QMutex m_settingsMutex
 
PhaseDiscriminators m_phaseDiscri
 
QNetworkAccessManager * m_networkManager
 
QNetworkRequest m_networkRequest
 

Static Private Attributes

static const int m_udpBlockSize = 512
 

Additional Inherited Members

- Public Types inherited from ChannelAPI
enum  StreamType { StreamSingleSink, StreamSingleSource, StreamMIMO }
 < This is the same enum as in PluginInterface More...
 
- Protected Slots inherited from BasebandSampleSink
void handleInputMessages ()
 
- Protected Attributes inherited from BasebandSampleSink
MessageQueue m_inputMessageQueue
 Queue for asynchronous inbound communication. More...
 
MessageQueuem_guiMessageQueue
 Input message queue to the GUI. More...
 

Detailed Description

Definition at line 50 of file nfmdemod.h.

Member Enumeration Documentation

◆ RateState

enum NFMDemod::RateState
private
Enumerator
RSInitialFill 
RSRunning 

Definition at line 203 of file nfmdemod.h.

Constructor & Destructor Documentation

◆ NFMDemod()

NFMDemod::NFMDemod ( DeviceAPI deviceAPI)

Definition at line 55 of file nfmdemod.cpp.

References AudioDeviceManager::addAudioSink(), DSPEngine::getAudioDeviceManager(), BasebandSampleSink::getInputMessageQueue(), AudioDeviceManager::getOutputSampleRate(), DSPEngine::instance(), m_afSquelch, m_agcLevel, m_audioBuffer, m_audioBufferFill, m_audioFifo, m_audioSampleRate, m_channelId, m_ctcssDetector, m_discriCompensation, CTCSSDetector::setCoefficients(), AFSquelch::setCoefficients(), and sqrt().

Referenced by NFMDemod::MsgReportCTCSSFreq::MsgReportCTCSSFreq().

55  :
57  m_deviceAPI(devieAPI),
58  m_inputSampleRate(48000),
60  m_running(false),
61  m_ctcssIndex(0),
62  m_sampleCount(0),
63  m_squelchCount(0),
64  m_squelchGate(4800),
65  m_squelchLevel(-990),
66  m_squelchOpen(false),
67  m_afSquelchOpen(false),
68  m_magsq(0.0f),
69  m_magsqSum(0.0f),
70  m_magsqPeak(0.0f),
71  m_magsqCount(0),
72  m_afSquelch(),
73  m_squelchDelayLine(24000),
74  m_audioFifo(48000),
75  m_settingsMutex(QMutex::Recursive)
76 {
77  qDebug("NFMDemod::NFMDemod");
78  setObjectName(m_channelId);
79 
80  m_audioBuffer.resize(1<<14);
82 
83  m_agcLevel = 1.0;
84 
89 
90  m_ctcssDetector.setCoefficients(m_audioSampleRate/16, m_audioSampleRate/8.0f); // 0.5s / 2 Hz resolution
91  m_afSquelch.setCoefficients(m_audioSampleRate/2000, 600, m_audioSampleRate, 200, 0, afSqTones); // 0.5ms test period, 300ms average span, audio SR, 100ms attack, no decay
92 
94 
97 
98  m_channelizer = new DownChannelizer(this);
102 
103  m_networkManager = new QNetworkAccessManager();
104  connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
105 }
void addAudioSink(AudioFifo *audioFifo, MessageQueue *sampleSinkMessageQueue, int outputDeviceIndex=-1)
Add the audio sink.
uint m_audioBufferFill
Definition: nfmdemod.h:248
double m_magsq
displayed averaged value
Definition: nfmdemod.h:236
int getOutputSampleRate(int outputDeviceIndex=-1)
int m_sampleCount
Definition: nfmdemod.h:229
void setCoefficients(int zN, int SampleRate)
float m_discriCompensation
compensation factor that depends on audio rate (1 for 48 kS/s)
Definition: nfmdemod.h:216
QMutex m_settingsMutex
Definition: nfmdemod.h:251
void addChannelSinkAPI(ChannelAPI *channelAPI, int streamIndex=0)
Definition: deviceapi.cpp:156
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
bool m_running
Definition: nfmdemod.h:217
double m_magsqSum
Definition: nfmdemod.h:237
void create(int nTaps, double sampleRate, double cutoff)
Definition: lowpass.h:15
AFSquelch m_afSquelch
Definition: nfmdemod.h:243
uint32_t m_audioSampleRate
Definition: nfmdemod.h:215
ThreadedBasebandSampleSink * m_threadedChannelizer
Definition: nfmdemod.h:209
int m_squelchCount
Definition: nfmdemod.h:230
static const QString m_channelIdURI
Definition: nfmdemod.h:189
static DSPEngine * instance()
Definition: dspengine.cpp:51
AudioFifo m_audioFifo
Definition: nfmdemod.h:249
ChannelAPI(const QString &name, StreamType streamType)
Definition: channelapi.cpp:23
bool m_squelchOpen
Definition: nfmdemod.h:234
int m_magsqCount
Definition: nfmdemod.h:239
DeviceAPI * m_deviceAPI
Definition: nfmdemod.h:208
bool m_afSquelchOpen
Definition: nfmdemod.h:235
Fixed< IntType, IntBits > sqrt(Fixed< IntType, IntBits > const &x)
Definition: fixed.h:2283
Real m_squelchLevel
Definition: nfmdemod.h:233
Exposes a single sink stream (input, Rx)
Definition: channelapi.h:41
Real m_agcLevel
Definition: nfmdemod.h:244
QNetworkAccessManager * m_networkManager
Definition: nfmdemod.h:255
double m_magsqPeak
Definition: nfmdemod.h:238
AudioDeviceManager * getAudioDeviceManager()
Definition: dspengine.h:55
void addChannelSink(ThreadedBasebandSampleSink *sink, int streamIndex=0)
Add a channel sink (Rx)
Definition: deviceapi.cpp:118
Lowpass< Real > m_ctcssLowpass
Definition: nfmdemod.h:223
void applySettings(const NFMDemodSettings &settings, bool force=false)
Definition: nfmdemod.cpp:508
void networkManagerFinished(QNetworkReply *reply)
Definition: nfmdemod.cpp:918
NFMDemodSettings m_settings
Definition: nfmdemod.h:214
int m_ctcssIndex
Definition: nfmdemod.h:227
int m_inputSampleRate
Definition: nfmdemod.h:212
DownChannelizer * m_channelizer
Definition: nfmdemod.h:210
AudioVector m_audioBuffer
Definition: nfmdemod.h:247
CTCSSDetector m_ctcssDetector
Definition: nfmdemod.h:226
int m_squelchGate
Definition: nfmdemod.h:231
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force=false)
Definition: nfmdemod.cpp:483
static const QString m_channelId
Definition: nfmdemod.h:190
DoubleBufferFIFO< Real > m_squelchDelayLine
Definition: nfmdemod.h:245
int m_inputFrequencyOffset
Definition: nfmdemod.h:213
void setCoefficients(unsigned int N, unsigned int nbAvg, unsigned int sampleRate, unsigned int samplesAttack, unsigned int samplesDecay, const double *tones)
center frequency of tones tested
Definition: afsquelch.cpp:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ~NFMDemod()

NFMDemod::~NFMDemod ( )

Definition at line 107 of file nfmdemod.cpp.

References DSPEngine::getAudioDeviceManager(), DSPEngine::instance(), m_audioFifo, m_channelizer, m_deviceAPI, m_networkManager, m_threadedChannelizer, networkManagerFinished(), AudioDeviceManager::removeAudioSink(), DeviceAPI::removeChannelSink(), and DeviceAPI::removeChannelSinkAPI().

Referenced by NFMDemod::MsgReportCTCSSFreq::MsgReportCTCSSFreq().

108 {
109  disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
110  delete m_networkManager;
114  delete m_threadedChannelizer;
115  delete m_channelizer;
116 }
void removeChannelSinkAPI(ChannelAPI *channelAPI, int streamIndex=0)
Definition: deviceapi.cpp:163
void removeAudioSink(AudioFifo *audioFifo)
Remove the audio sink.
ThreadedBasebandSampleSink * m_threadedChannelizer
Definition: nfmdemod.h:209
static DSPEngine * instance()
Definition: dspengine.cpp:51
AudioFifo m_audioFifo
Definition: nfmdemod.h:249
void removeChannelSink(ThreadedBasebandSampleSink *sink, int streamIndex=0)
Remove a channel sink (Rx)
Definition: deviceapi.cpp:127
DeviceAPI * m_deviceAPI
Definition: nfmdemod.h:208
QNetworkAccessManager * m_networkManager
Definition: nfmdemod.h:255
AudioDeviceManager * getAudioDeviceManager()
Definition: dspengine.h:55
void networkManagerFinished(QNetworkReply *reply)
Definition: nfmdemod.cpp:918
DownChannelizer * m_channelizer
Definition: nfmdemod.h:210
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Function Documentation

◆ applyAudioSampleRate()

void NFMDemod::applyAudioSampleRate ( int  sampleRate)
private

Definition at line 444 of file nfmdemod.cpp.

References Lowpass< Type >::create(), Bandpass< Type >::create(), Interpolator::create(), NFMDemod::MsgConfigureChannelizer::create(), NFMDemodSettings::m_afBandwidth, m_afSquelch, m_bandpass, m_ctcssDetector, m_ctcssLowpass, NFMDemodSettings::m_inputFrequencyOffset, BasebandSampleSink::m_inputMessageQueue, m_inputSampleRate, m_interpolator, m_interpolatorDistance, m_interpolatorDistanceRemain, m_lowpass, NFMDemodSettings::m_rfBandwidth, m_settings, m_settingsMutex, m_squelchCount, NFMDemodSettings::m_squelchGate, m_squelchGate, MessageQueue::push(), CTCSSDetector::setCoefficients(), and AFSquelch::setCoefficients().

Referenced by applySettings(), and handleMessage().

445 {
446  qDebug("NFMDemod::applyAudioSampleRate: %d", sampleRate);
447 
448  MsgConfigureChannelizer* channelConfigMsg = MsgConfigureChannelizer::create(
449  sampleRate, m_settings.m_inputFrequencyOffset);
450  m_inputMessageQueue.push(channelConfigMsg);
451 
452  m_settingsMutex.lock();
453 
457  m_ctcssLowpass.create(301, sampleRate, 250.0);
458  m_bandpass.create(301, sampleRate, 300.0, m_settings.m_afBandwidth);
459  m_lowpass.create(301, sampleRate, m_settings.m_afBandwidth);
460  m_squelchGate = (sampleRate / 100) * m_settings.m_squelchGate; // gate is given in 10s of ms at 48000 Hz audio sample rate
461  m_squelchCount = 0; // reset squelch open counter
462  m_ctcssDetector.setCoefficients(sampleRate/16, sampleRate/8.0f); // 0.5s / 2 Hz resolution
463 
464  if (sampleRate < 16000) {
465  m_afSquelch.setCoefficients(sampleRate/2000, 600, sampleRate, 200, 0, afSqTones_lowrate); // 0.5ms test period, 300ms average span, audio SR, 100ms attack, no decay
466 
467  } else {
468  m_afSquelch.setCoefficients(sampleRate/2000, 600, sampleRate, 200, 0, afSqTones); // 0.5ms test period, 300ms average span, audio SR, 100ms attack, no decay
469  }
470 
471  m_discriCompensation = (sampleRate/48000.0f);
473 
474  m_phaseDiscri.setFMScaling(sampleRate / static_cast<float>(m_settings.m_fmDeviation));
475  m_audioFifo.setSize(sampleRate);
476  m_squelchDelayLine.resize(sampleRate/2);
477 
478  m_settingsMutex.unlock();
479 
480  m_audioSampleRate = sampleRate;
481 }
Real m_interpolatorDistanceRemain
Definition: nfmdemod.h:222
void resize(int size)
void setCoefficients(int zN, int SampleRate)
float m_discriCompensation
compensation factor that depends on audio rate (1 for 48 kS/s)
Definition: nfmdemod.h:216
PhaseDiscriminators m_phaseDiscri
Definition: nfmdemod.h:253
void push(Message *message, bool emitSignal=true)
Push message onto queue.
QMutex m_settingsMutex
Definition: nfmdemod.h:251
void create(int nTaps, double sampleRate, double lowCutoff, double highCutoff)
Definition: bandpass.h:15
void create(int phaseSteps, double sampleRate, double cutoff, double nbTapsPerPhase=4.5)
void setFMScaling(Real fmScaling)
Definition: phasediscri.h:42
void create(int nTaps, double sampleRate, double cutoff)
Definition: lowpass.h:15
AFSquelch m_afSquelch
Definition: nfmdemod.h:243
static MsgConfigureChannelizer * create(int sampleRate, int centerFrequency)
Definition: nfmdemod.h:83
uint32_t m_audioSampleRate
Definition: nfmdemod.h:215
MessageQueue m_inputMessageQueue
Queue for asynchronous inbound communication.
Interpolator m_interpolator
Definition: nfmdemod.h:220
int m_squelchCount
Definition: nfmdemod.h:230
AudioFifo m_audioFifo
Definition: nfmdemod.h:249
Real m_interpolatorDistance
Definition: nfmdemod.h:221
Fixed< IntType, IntBits > sqrt(Fixed< IntType, IntBits > const &x)
Definition: fixed.h:2283
Lowpass< Real > m_lowpass
Definition: nfmdemod.h:225
Lowpass< Real > m_ctcssLowpass
Definition: nfmdemod.h:223
bool setSize(uint32_t numSamples)
Definition: audiofifo.cpp:59
NFMDemodSettings m_settings
Definition: nfmdemod.h:214
int m_inputSampleRate
Definition: nfmdemod.h:212
int32_t m_inputFrequencyOffset
CTCSSDetector m_ctcssDetector
Definition: nfmdemod.h:226
int m_squelchGate
Definition: nfmdemod.h:231
float Real
Definition: dsptypes.h:42
Bandpass< Real > m_bandpass
Definition: nfmdemod.h:224
DoubleBufferFIFO< Real > m_squelchDelayLine
Definition: nfmdemod.h:245
void setCoefficients(unsigned int N, unsigned int nbAvg, unsigned int sampleRate, unsigned int samplesAttack, unsigned int samplesDecay, const double *tones)
center frequency of tones tested
Definition: afsquelch.cpp:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ applyChannelSettings()

void NFMDemod::applyChannelSettings ( int  inputSampleRate,
int  inputFrequencyOffset,
bool  force = false 
)
private

Definition at line 483 of file nfmdemod.cpp.

References Interpolator::create(), m_audioSampleRate, m_inputFrequencyOffset, m_inputSampleRate, m_interpolator, m_interpolatorDistance, m_interpolatorDistanceRemain, m_nco, NFMDemodSettings::m_rfBandwidth, m_settings, m_settingsMutex, and NCO::setFreq().

Referenced by handleMessage(), and start().

484 {
485  qDebug() << "NFMDemod::applyChannelSettings:"
486  << " inputSampleRate: " << inputSampleRate
487  << " inputFrequencyOffset: " << inputFrequencyOffset;
488 
489  if ((inputFrequencyOffset != m_inputFrequencyOffset) ||
490  (inputSampleRate != m_inputSampleRate) || force)
491  {
492  m_nco.setFreq(-inputFrequencyOffset, inputSampleRate);
493  }
494 
495  if ((inputSampleRate != m_inputSampleRate) || force)
496  {
497  m_settingsMutex.lock();
498  m_interpolator.create(16, inputSampleRate, m_settings.m_rfBandwidth / 2.2f);
500  m_interpolatorDistance = (Real) inputSampleRate / (Real) m_audioSampleRate;
501  m_settingsMutex.unlock();
502  }
503 
504  m_inputSampleRate = inputSampleRate;
505  m_inputFrequencyOffset = inputFrequencyOffset;
506 }
Real m_interpolatorDistanceRemain
Definition: nfmdemod.h:222
QMutex m_settingsMutex
Definition: nfmdemod.h:251
void create(int phaseSteps, double sampleRate, double cutoff, double nbTapsPerPhase=4.5)
uint32_t m_audioSampleRate
Definition: nfmdemod.h:215
NCO m_nco
Definition: nfmdemod.h:219
Interpolator m_interpolator
Definition: nfmdemod.h:220
Real m_interpolatorDistance
Definition: nfmdemod.h:221
void setFreq(Real freq, Real sampleRate)
Definition: nco.cpp:49
NFMDemodSettings m_settings
Definition: nfmdemod.h:214
int m_inputSampleRate
Definition: nfmdemod.h:212
float Real
Definition: dsptypes.h:42
int m_inputFrequencyOffset
Definition: nfmdemod.h:213
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ applySettings()

void NFMDemod::applySettings ( const NFMDemodSettings settings,
bool  force = false 
)
private

Definition at line 508 of file nfmdemod.cpp.

References AudioDeviceManager::addAudioSink(), applyAudioSampleRate(), Bandpass< Type >::create(), Lowpass< Type >::create(), Interpolator::create(), DSPEngine::getAudioDeviceManager(), BasebandSampleSink::getInputMessageQueue(), AudioDeviceManager::getOutputDeviceIndex(), AudioDeviceManager::getOutputSampleRate(), DSPEngine::instance(), NFMDemodSettings::m_afBandwidth, m_afSquelch, NFMDemodSettings::m_audioDeviceName, m_audioFifo, NFMDemodSettings::m_audioMute, m_audioSampleRate, m_bandpass, NFMDemodSettings::m_ctcssIndex, NFMDemodSettings::m_ctcssOn, NFMDemodSettings::m_deltaSquelch, NFMDemodSettings::m_fmDeviation, NFMDemodSettings::m_highPass, NFMDemodSettings::m_inputFrequencyOffset, m_inputSampleRate, m_interpolator, m_interpolatorDistance, m_interpolatorDistanceRemain, m_lowpass, m_movingAverage, m_phaseDiscri, NFMDemodSettings::m_reverseAPIAddress, NFMDemodSettings::m_reverseAPIChannelIndex, NFMDemodSettings::m_reverseAPIDeviceIndex, NFMDemodSettings::m_reverseAPIPort, NFMDemodSettings::m_rfBandwidth, NFMDemodSettings::m_rgbColor, m_settings, m_settingsMutex, NFMDemodSettings::m_squelch, m_squelchCount, NFMDemodSettings::m_squelchGate, m_squelchGate, m_squelchLevel, NFMDemodSettings::m_title, NFMDemodSettings::m_useReverseAPI, NFMDemodSettings::m_volume, MovingAverageUtil< T, Total, N >::reset(), AFSquelch::reset(), PhaseDiscriminators::setFMScaling(), setSelectedCtcssIndex(), AFSquelch::setThreshold(), and webapiReverseSendSettings().

Referenced by handleMessage().

509 {
510  qDebug() << "NFMDemod::applySettings:"
511  << " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
512  << " m_rfBandwidth: " << settings.m_rfBandwidth
513  << " m_afBandwidth: " << settings.m_afBandwidth
514  << " m_fmDeviation: " << settings.m_fmDeviation
515  << " m_volume: " << settings.m_volume
516  << " m_squelchGate: " << settings.m_squelchGate
517  << " m_deltaSquelch: " << settings.m_deltaSquelch
518  << " m_squelch: " << settings.m_squelch
519  << " m_ctcssIndex: " << settings.m_ctcssIndex
520  << " m_ctcssOn: " << settings.m_ctcssOn
521  << " m_highPass: " << settings.m_highPass
522  << " m_audioMute: " << settings.m_audioMute
523  << " m_audioDeviceName: " << settings.m_audioDeviceName
524  << " m_useReverseAPI: " << settings.m_useReverseAPI
525  << " m_reverseAPIAddress: " << settings.m_reverseAPIAddress
526  << " m_reverseAPIPort: " << settings.m_reverseAPIPort
527  << " m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex
528  << " m_reverseAPIChannelIndex: " << settings.m_reverseAPIChannelIndex
529  << " force: " << force;
530 
531  QList<QString> reverseAPIKeys;
532 
533  if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) {
534  reverseAPIKeys.append("inputFrequencyOffset");
535  }
536  if ((settings.m_volume != m_settings.m_volume) || force) {
537  reverseAPIKeys.append("volume");
538  }
539  if ((settings.m_ctcssOn != m_settings.m_ctcssOn) || force) {
540  reverseAPIKeys.append("ctcssOn");
541  }
542  if ((settings.m_audioMute != m_settings.m_audioMute) || force) {
543  reverseAPIKeys.append("audioMute");
544  }
545  if ((settings.m_rgbColor != m_settings.m_rgbColor) || force) {
546  reverseAPIKeys.append("rgbColor");
547  }
548  if ((settings.m_title != m_settings.m_title) || force) {
549  reverseAPIKeys.append("title");
550  }
551 
552  if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force)
553  {
554  reverseAPIKeys.append("rfBandwidth");
555  m_settingsMutex.lock();
559  m_settingsMutex.unlock();
560  }
561 
562  if ((settings.m_fmDeviation != m_settings.m_fmDeviation) || force)
563  {
564  reverseAPIKeys.append("fmDeviation");
565  m_phaseDiscri.setFMScaling((8.0f*m_audioSampleRate) / static_cast<float>(settings.m_fmDeviation)); // integrate 4x factor
566  }
567 
568  if ((settings.m_afBandwidth != m_settings.m_afBandwidth) || force)
569  {
570  reverseAPIKeys.append("afBandwidth");
571  m_settingsMutex.lock();
572  m_bandpass.create(301, m_audioSampleRate, 300.0, settings.m_afBandwidth);
573  m_lowpass.create(301, m_audioSampleRate, settings.m_afBandwidth);
574  m_settingsMutex.unlock();
575  }
576 
577  if ((settings.m_squelchGate != m_settings.m_squelchGate) || force)
578  {
579  reverseAPIKeys.append("squelchGate");
580  m_squelchGate = (m_audioSampleRate / 100) * settings.m_squelchGate; // gate is given in 10s of ms at 48000 Hz audio sample rate
581  m_squelchCount = 0; // reset squelch open counter
582  }
583 
584  if ((settings.m_squelch != m_settings.m_squelch) || force) {
585  reverseAPIKeys.append("squelch");
586  }
587  if ((settings.m_deltaSquelch != m_settings.m_deltaSquelch) || force) {
588  reverseAPIKeys.append("deltaSquelch");
589  }
590 
591  if ((settings.m_squelch != m_settings.m_squelch) ||
592  (settings.m_deltaSquelch != m_settings.m_deltaSquelch) || force)
593  {
594  if (settings.m_deltaSquelch)
595  { // input is a value in negative centis
596  m_squelchLevel = (- settings.m_squelch) / 100.0;
598  m_afSquelch.reset();
599  }
600  else
601  { // input is a value in deci-Bels
602  m_squelchLevel = std::pow(10.0, settings.m_squelch / 10.0);
604  }
605 
606  m_squelchCount = 0; // reset squelch open counter
607  }
608 
609  if ((settings.m_ctcssIndex != m_settings.m_ctcssIndex) || force)
610  {
611  reverseAPIKeys.append("ctcssIndex");
613  }
614 
615  if ((settings.m_highPass != m_settings.m_highPass) || force) {
616  reverseAPIKeys.append("highPass");
617  }
618 
619  if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
620  {
621  reverseAPIKeys.append("audioDeviceName");
623  int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName);
624  //qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex);
625  audioDeviceManager->addAudioSink(&m_audioFifo, getInputMessageQueue(), audioDeviceIndex);
626  uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
627 
628  if (m_audioSampleRate != audioSampleRate) {
629  applyAudioSampleRate(audioSampleRate);
630  }
631  }
632 
633  if (settings.m_useReverseAPI)
634  {
635  bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
640  webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
641  }
642 
643  m_settings = settings;
644 }
Real m_interpolatorDistanceRemain
Definition: nfmdemod.h:222
void addAudioSink(AudioFifo *audioFifo, MessageQueue *sampleSinkMessageQueue, int outputDeviceIndex=-1)
Add the audio sink.
uint16_t m_reverseAPIPort
int getOutputSampleRate(int outputDeviceIndex=-1)
PhaseDiscriminators m_phaseDiscri
Definition: nfmdemod.h:253
QMutex m_settingsMutex
Definition: nfmdemod.h:251
void create(int nTaps, double sampleRate, double lowCutoff, double highCutoff)
Definition: bandpass.h:15
void create(int phaseSteps, double sampleRate, double cutoff, double nbTapsPerPhase=4.5)
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
void setFMScaling(Real fmScaling)
Definition: phasediscri.h:42
void create(int nTaps, double sampleRate, double cutoff)
Definition: lowpass.h:15
int getOutputDeviceIndex(const QString &deviceName) const
AFSquelch m_afSquelch
Definition: nfmdemod.h:243
MovingAverageUtil< Real, double, 32 > m_movingAverage
Definition: nfmdemod.h:242
uint32_t m_audioSampleRate
Definition: nfmdemod.h:215
Real m_squelch
deci-Bels
void setSelectedCtcssIndex(int selectedCtcssIndex)
Definition: nfmdemod.h:164
unsigned int uint32_t
Definition: rtptypes_win.h:46
QString m_reverseAPIAddress
Interpolator m_interpolator
Definition: nfmdemod.h:220
int m_squelchCount
Definition: nfmdemod.h:230
static DSPEngine * instance()
Definition: dspengine.cpp:51
uint16_t m_reverseAPIChannelIndex
AudioFifo m_audioFifo
Definition: nfmdemod.h:249
Real m_interpolatorDistance
Definition: nfmdemod.h:221
Lowpass< Real > m_lowpass
Definition: nfmdemod.h:225
uint16_t m_reverseAPIDeviceIndex
Real m_squelchLevel
Definition: nfmdemod.h:233
AudioDeviceManager * getAudioDeviceManager()
Definition: dspengine.h:55
void applyAudioSampleRate(int sampleRate)
Definition: nfmdemod.cpp:444
NFMDemodSettings m_settings
Definition: nfmdemod.h:214
int m_inputSampleRate
Definition: nfmdemod.h:212
void setThreshold(double _threshold)
Definition: afsquelch.cpp:271
int32_t m_inputFrequencyOffset
void reset()
Definition: afsquelch.cpp:172
void webapiReverseSendSettings(QList< QString > &channelSettingsKeys, const NFMDemodSettings &settings, bool force)
Definition: nfmdemod.cpp:841
int m_squelchGate
Definition: nfmdemod.h:231
float Real
Definition: dsptypes.h:42
Bandpass< Real > m_bandpass
Definition: nfmdemod.h:224
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ deserialize()

bool NFMDemod::deserialize ( const QByteArray &  data)
virtual

Implements ChannelAPI.

Definition at line 651 of file nfmdemod.cpp.

References NFMDemod::MsgConfigureNFMDemod::create(), NFMDemod::MsgConfigureChannelizer::create(), NFMDemodSettings::deserialize(), m_audioSampleRate, NFMDemodSettings::m_inputFrequencyOffset, BasebandSampleSink::m_inputMessageQueue, m_settings, MessageQueue::push(), and NFMDemodSettings::resetToDefaults().

Referenced by getCenterFrequency().

652 {
653  bool success = true;
654 
655  if (!m_settings.deserialize(data))
656  {
658  success = false;
659  }
660 
663  m_inputMessageQueue.push(channelConfigMsg);
664 
665  MsgConfigureNFMDemod *msg = MsgConfigureNFMDemod::create(m_settings, true);
667 
668  return success;
669 }
bool deserialize(const QByteArray &data)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
static MsgConfigureChannelizer * create(int sampleRate, int centerFrequency)
Definition: nfmdemod.h:83
uint32_t m_audioSampleRate
Definition: nfmdemod.h:215
static MsgConfigureNFMDemod * create(const NFMDemodSettings &settings, bool force)
Definition: nfmdemod.h:60
MessageQueue m_inputMessageQueue
Queue for asynchronous inbound communication.
NFMDemodSettings m_settings
Definition: nfmdemod.h:214
int32_t m_inputFrequencyOffset
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ destroy()

virtual void NFMDemod::destroy ( )
inlinevirtual

Implements ChannelAPI.

Definition at line 121 of file nfmdemod.h.

References feed(), handleMessage(), start(), and stop().

121 { delete this; }
+ Here is the call graph for this function:

◆ feed()

void NFMDemod::feed ( const SampleVector::const_iterator &  begin,
const SampleVector::const_iterator &  end,
bool  po 
)
virtual

Implements BasebandSampleSink.

Definition at line 150 of file nfmdemod.cpp.

References Interpolator::decimate(), Interpolator::interpolate(), m_interpolator, m_interpolatorDistance, m_interpolatorDistanceRemain, m_nco, m_running, m_settingsMutex, NCO::nextIQ(), and processOneSample().

Referenced by destroy().

151 {
152  (void) firstOfBurst;
153  Complex ci;
154 
155  if (!m_running) {
156  return;
157  }
158 
159  m_settingsMutex.lock();
160 
161  for (SampleVector::const_iterator it = begin; it != end; ++it)
162  {
163  Complex c(it->real(), it->imag());
164  c *= m_nco.nextIQ();
165 
166  if (m_interpolatorDistance < 1.0f) // interpolate
167  {
169  {
170  processOneSample(ci);
172  }
173  }
174  else // decimate
175  {
177  {
178  processOneSample(ci);
180  }
181  }
182  }
183 
184  m_settingsMutex.unlock();
185 }
Real m_interpolatorDistanceRemain
Definition: nfmdemod.h:222
Complex nextIQ()
Return next complex sample.
Definition: nco.cpp:61
bool decimate(Real *distance, const Complex &next, Complex *result)
Definition: interpolator.h:38
QMutex m_settingsMutex
Definition: nfmdemod.h:251
void processOneSample(Complex &ci)
Definition: nfmdemod.cpp:187
bool m_running
Definition: nfmdemod.h:217
bool interpolate(Real *distance, const Complex &next, Complex *result)
Definition: interpolator.h:53
NCO m_nco
Definition: nfmdemod.h:219
Interpolator m_interpolator
Definition: nfmdemod.h:220
Real m_interpolatorDistance
Definition: nfmdemod.h:221
std::complex< Real > Complex
Definition: dsptypes.h:43
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getCenterFrequency()

virtual qint64 NFMDemod::getCenterFrequency ( ) const
inlinevirtual

Applies to a default stream.

Implements ChannelAPI.

Definition at line 130 of file nfmdemod.h.

References deserialize(), NFMDemodSettings::m_inputFrequencyOffset, NFMDemod::MsgConfigureNFMDemod::m_settings, and serialize().

NFMDemodSettings m_settings
Definition: nfmdemod.h:214
int32_t m_inputFrequencyOffset
+ Here is the call graph for this function:

◆ getCtcssToneSet()

const Real* NFMDemod::getCtcssToneSet ( int &  nbTones) const
inline

Definition at line 159 of file nfmdemod.h.

References CTCSSDetector::getNTones(), CTCSSDetector::getToneSet(), and m_ctcssDetector.

Referenced by NFMDemodGUI::NFMDemodGUI().

159  {
160  nbTones = m_ctcssDetector.getNTones();
161  return m_ctcssDetector.getToneSet();
162  }
const Real * getToneSet() const
Definition: ctcssdetector.h:45
int getNTones() const
Definition: ctcssdetector.h:40
CTCSSDetector m_ctcssDetector
Definition: nfmdemod.h:226
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getIdentifier()

virtual void NFMDemod::getIdentifier ( QString &  id)
inlinevirtual

Implements ChannelAPI.

Definition at line 128 of file nfmdemod.h.

128 { id = objectName(); }

◆ getMag()

Real NFMDemod::getMag ( )
inline

Definition at line 168 of file nfmdemod.h.

References m_magsq.

168 { return m_magsq; }
double m_magsq
displayed averaged value
Definition: nfmdemod.h:236

◆ getMagSqLevels()

void NFMDemod::getMagSqLevels ( double &  avg,
double &  peak,
int &  nbSamples 
)
inline

Definition at line 171 of file nfmdemod.h.

References NFMDemod::MagSqLevelsStore::m_magsq, m_magsq, m_magsqCount, m_magSqLevelStore, NFMDemod::MagSqLevelsStore::m_magsqPeak, m_magsqPeak, and m_magsqSum.

Referenced by NFMDemodGUI::tick(), and webapiFormatChannelReport().

172  {
173  if (m_magsqCount > 0)
174  {
178  }
179 
182  nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount;
183 
184  m_magsqSum = 0.0f;
185  m_magsqPeak = 0.0f;
186  m_magsqCount = 0;
187  }
double m_magsq
displayed averaged value
Definition: nfmdemod.h:236
double m_magsqSum
Definition: nfmdemod.h:237
MagSqLevelsStore m_magSqLevelStore
Definition: nfmdemod.h:240
int m_magsqCount
Definition: nfmdemod.h:239
double m_magsqPeak
Definition: nfmdemod.h:238
+ Here is the caller graph for this function:

◆ getNbSinkStreams()

virtual int NFMDemod::getNbSinkStreams ( ) const
inlinevirtual

Implements ChannelAPI.

Definition at line 135 of file nfmdemod.h.

135 { return 1; }

◆ getNbSourceStreams()

virtual int NFMDemod::getNbSourceStreams ( ) const
inlinevirtual

Implements ChannelAPI.

Definition at line 136 of file nfmdemod.h.

136 { return 0; }

◆ getSquelchOpen()

bool NFMDemod::getSquelchOpen ( ) const
inline

Definition at line 169 of file nfmdemod.h.

References m_squelchOpen.

Referenced by NFMDemodGUI::tick().

169 { return m_squelchOpen; }
bool m_squelchOpen
Definition: nfmdemod.h:234
+ Here is the caller graph for this function:

◆ getStreamCenterFrequency()

virtual qint64 NFMDemod::getStreamCenterFrequency ( int  streamIndex,
bool  sinkElseSource 
) const
inlinevirtual

Implements ChannelAPI.

Definition at line 138 of file nfmdemod.h.

References NFMDemodSettings::m_inputFrequencyOffset, NFMDemod::MsgConfigureNFMDemod::m_settings, webapiReportGet(), webapiSettingsGet(), and webapiSettingsPutPatch().

139  {
140  (void) streamIndex;
141  (void) sinkElseSource;
143  }
NFMDemodSettings m_settings
Definition: nfmdemod.h:214
int32_t m_inputFrequencyOffset
+ Here is the call graph for this function:

◆ getTitle()

virtual void NFMDemod::getTitle ( QString &  title)
inlinevirtual

Implements ChannelAPI.

Definition at line 129 of file nfmdemod.h.

References NFMDemod::MsgConfigureNFMDemod::m_settings, and NFMDemodSettings::m_title.

129 { title = m_settings.m_title; }
NFMDemodSettings m_settings
Definition: nfmdemod.h:214

◆ handleMessage()

bool NFMDemod::handleMessage ( const Message cmd)
virtual

Processing of a message. Returns true if message has actually been processed.

Implements BasebandSampleSink.

Definition at line 379 of file nfmdemod.cpp.

References applyAudioSampleRate(), applyChannelSettings(), applySettings(), DownChannelizer::configure(), NFMDemod::MsgConfigureChannelizer::getCenterFrequency(), NFMDemod::MsgConfigureNFMDemod::getForce(), DownChannelizer::MsgChannelizerNotification::getFrequencyOffset(), BasebandSampleSink::getInputMessageQueue(), DownChannelizer::MsgChannelizerNotification::getSampleRate(), NFMDemod::MsgConfigureChannelizer::getSampleRate(), DSPConfigureAudio::getSampleRate(), NFMDemod::MsgConfigureNFMDemod::getSettings(), BasebandSampleSink::MsgThreadedSink::getThread(), m_audioSampleRate, m_channelizer, and Message::match().

Referenced by destroy().

380 {
382  {
384  qDebug() << "NFMDemod::handleMessage: DownChannelizer::MsgChannelizerNotification";
385 
387 
388  return true;
389  }
390  else if (MsgConfigureChannelizer::match(cmd))
391  {
392  MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
393 
394  qDebug() << "NFMDemod::handleMessage: MsgConfigureChannelizer:"
395  << " sampleRate: " << cfg.getSampleRate()
396  << " centerFrequency: " << cfg.getCenterFrequency();
397 
399  cfg.getSampleRate(),
400  cfg.getCenterFrequency());
401 
402  return true;
403  }
404  else if (MsgConfigureNFMDemod::match(cmd))
405  {
406  MsgConfigureNFMDemod& cfg = (MsgConfigureNFMDemod&) cmd;
407  qDebug() << "NFMDemod::handleMessage: MsgConfigureNFMDemod";
408 
409  applySettings(cfg.getSettings(), cfg.getForce());
410 
411  return true;
412  }
414  {
416  const QThread *thread = cfg.getThread();
417  qDebug("NFMDemod::handleMessage: BasebandSampleSink::MsgThreadedSink: %p", thread);
418  return true;
419  }
420  else if (DSPConfigureAudio::match(cmd))
421  {
422  DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
423  uint32_t sampleRate = cfg.getSampleRate();
424 
425  qDebug() << "NFMDemod::handleMessage: DSPConfigureAudio:"
426  << " sampleRate: " << sampleRate;
427 
428  if (sampleRate != m_audioSampleRate) {
429  applyAudioSampleRate(sampleRate);
430  }
431 
432  return true;
433  }
434  else if (DSPSignalNotification::match(cmd))
435  {
436  return true;
437  }
438  else
439  {
440  return false;
441  }
442 }
void configure(MessageQueue *messageQueue, int sampleRate, int centerFrequency)
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
uint32_t m_audioSampleRate
Definition: nfmdemod.h:215
unsigned int uint32_t
Definition: rtptypes_win.h:46
int getSampleRate() const
Definition: dspcommands.h:390
static bool match(const Message *message)
Definition: message.cpp:45
void applyAudioSampleRate(int sampleRate)
Definition: nfmdemod.cpp:444
void applySettings(const NFMDemodSettings &settings, bool force=false)
Definition: nfmdemod.cpp:508
DownChannelizer * m_channelizer
Definition: nfmdemod.h:210
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force=false)
Definition: nfmdemod.cpp:483
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ networkManagerFinished

void NFMDemod::networkManagerFinished ( QNetworkReply *  reply)
privateslot

Definition at line 918 of file nfmdemod.cpp.

Referenced by ~NFMDemod().

919 {
920  QNetworkReply::NetworkError replyError = reply->error();
921 
922  if (replyError)
923  {
924  qWarning() << "NFMDemod::networkManagerFinished:"
925  << " error(" << (int) replyError
926  << "): " << replyError
927  << ": " << reply->errorString();
928  return;
929  }
930 
931  QString answer = reply->readAll();
932  answer.chop(1); // remove last \n
933  qDebug("NFMDemod::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
934 }
+ Here is the caller graph for this function:

◆ processOneSample()

void NFMDemod::processOneSample ( Complex ci)
private

Definition at line 187 of file nfmdemod.cpp.

References CTCSSDetector::analyze(), AFSquelch::analyze(), NFMDemod::MsgReportCTCSSFreq::create(), AFSquelch::evaluate(), Lowpass< Type >::filter(), Bandpass< Type >::filter(), CTCSSDetector::getDetectedTone(), BasebandSampleSink::getMessageQueueToGUI(), CTCSSDetector::getToneSet(), m_afSquelch, m_afSquelchOpen, m_audioBuffer, m_audioBufferFill, m_audioFifo, NFMDemodSettings::m_audioMute, m_audioSampleRate, m_bandpass, m_ctcssDetector, m_ctcssIndex, m_ctcssIndexSelected, m_ctcssLowpass, NFMDemodSettings::m_ctcssOn, NFMDemodSettings::m_deltaSquelch, m_discriCompensation, NFMDemodSettings::m_highPass, m_lowpass, m_magsqCount, m_magsqPeak, m_magsqSum, m_movingAverage, m_phaseDiscri, m_sampleCount, m_settings, m_squelchCount, m_squelchDelayLine, m_squelchGate, m_squelchLevel, m_squelchOpen, NFMDemodSettings::m_volume, PhaseDiscriminators::phaseDiscriminatorDelta(), MessageQueue::push(), DoubleBufferFIFO< T >::readBack(), SDR_RX_SCALED, AudioFifo::write(), DoubleBufferFIFO< T >::write(), and DoubleBufferFIFO< T >::zeroBack().

Referenced by feed().

188 {
189  qint16 sample;
190 
191  double magsqRaw; // = ci.real()*ci.real() + c.imag()*c.imag();
192  Real deviation;
193 
194  Real demod = m_phaseDiscri.phaseDiscriminatorDelta(ci, magsqRaw, deviation);
195 
196  Real magsq = magsqRaw / (SDR_RX_SCALED*SDR_RX_SCALED);
197  m_movingAverage(magsq);
198  m_magsqSum += magsq;
199 
200  if (magsq > m_magsqPeak)
201  {
202  m_magsqPeak = magsq;
203  }
204 
205  m_magsqCount++;
206  m_sampleCount++;
207 
208  // AF processing
209 
211  {
213  {
214  m_afSquelchOpen = m_afSquelch.evaluate(); // ? m_squelchGate + m_squelchDecay : 0;
215 
216  if (!m_afSquelchOpen) {
217  m_squelchDelayLine.zeroBack(m_audioSampleRate/10); // zero out evaluation period
218  }
219  }
220 
221  if (m_afSquelchOpen)
222  {
223  m_squelchDelayLine.write(demod * m_discriCompensation);
224 
225  if (m_squelchCount < 2*m_squelchGate) {
226  m_squelchCount++;
227  }
228  }
229  else
230  {
232 
233  if (m_squelchCount > 0) {
234  m_squelchCount--;
235  }
236  }
237  }
238  else
239  {
241  {
243 
244  if (m_squelchCount > 0) {
245  m_squelchCount--;
246  }
247  }
248  else
249  {
250  m_squelchDelayLine.write(demod * m_discriCompensation);
251 
252  if (m_squelchCount < 2*m_squelchGate) {
253  m_squelchCount++;
254  }
255  }
256  }
257 
259 
261  {
262  sample = 0;
263  }
264  else
265  {
266  if (m_squelchOpen)
267  {
268  if (m_settings.m_ctcssOn)
269  {
270  Real ctcss_sample = m_ctcssLowpass.filter(demod * m_discriCompensation);
271 
272  if ((m_sampleCount & 7) == 7) // decimate 48k -> 6k
273  {
274  if (m_ctcssDetector.analyze(&ctcss_sample))
275  {
276  int maxToneIndex;
277 
278  if (m_ctcssDetector.getDetectedTone(maxToneIndex))
279  {
280  if (maxToneIndex+1 != m_ctcssIndex)
281  {
282  if (getMessageQueueToGUI()) {
283  MsgReportCTCSSFreq *msg = MsgReportCTCSSFreq::create(m_ctcssDetector.getToneSet()[maxToneIndex]);
284  getMessageQueueToGUI()->push(msg);
285  }
286  m_ctcssIndex = maxToneIndex+1;
287  }
288  }
289  else
290  {
291  if (m_ctcssIndex != 0)
292  {
293  if (getMessageQueueToGUI()) {
294  MsgReportCTCSSFreq *msg = MsgReportCTCSSFreq::create(0);
295  getMessageQueueToGUI()->push(msg);
296  }
297  m_ctcssIndex = 0;
298  }
299  }
300  }
301  }
302  }
303 
305  {
306  sample = 0;
307  }
308  else
309  {
310  if (m_settings.m_highPass) {
312  } else {
314  }
315  }
316  }
317  else
318  {
319  if (m_ctcssIndex != 0)
320  {
321  if (getMessageQueueToGUI()) {
322  MsgReportCTCSSFreq *msg = MsgReportCTCSSFreq::create(0);
323  getMessageQueueToGUI()->push(msg);
324  }
325 
326  m_ctcssIndex = 0;
327  }
328 
329  sample = 0;
330  }
331  }
332 
333 
334  m_audioBuffer[m_audioBufferFill].l = sample;
335  m_audioBuffer[m_audioBufferFill].r = sample;
337 
338  if (m_audioBufferFill >= m_audioBuffer.size())
339  {
340  uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill);
341 
342  if (res != m_audioBufferFill)
343  {
344  qDebug("NFMDemod::feed: %u/%u audio samples written", res, m_audioBufferFill);
345  }
346 
347  m_audioBufferFill = 0;
348  }
349 
350  if (m_audioBufferFill > 0)
351  {
352  uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill);
353 
354  if (res != m_audioBufferFill)
355  {
356  qDebug("NFMDemod::feed: %u/%u tail samples written", res, m_audioBufferFill);
357  }
358 
359  m_audioBufferFill = 0;
360  }
361 }
uint m_audioBufferFill
Definition: nfmdemod.h:248
int m_sampleCount
Definition: nfmdemod.h:229
float m_discriCompensation
compensation factor that depends on audio rate (1 for 48 kS/s)
Definition: nfmdemod.h:216
PhaseDiscriminators m_phaseDiscri
Definition: nfmdemod.h:253
void push(Message *message, bool emitSignal=true)
Push message onto queue.
const Real * getToneSet() const
Definition: ctcssdetector.h:45
double m_magsqSum
Definition: nfmdemod.h:237
AFSquelch m_afSquelch
Definition: nfmdemod.h:243
MovingAverageUtil< Real, double, 32 > m_movingAverage
Definition: nfmdemod.h:242
bool analyze(double sample)
Definition: afsquelch.cpp:116
uint32_t m_audioSampleRate
Definition: nfmdemod.h:215
Type filter(Type sample)
Definition: bandpass.h:77
void zeroBack(int delay)
void write(const T &element)
bool getDetectedTone(int &maxTone) const
Definition: ctcssdetector.h:51
int m_squelchCount
Definition: nfmdemod.h:230
bool evaluate()
Definition: afsquelch.cpp:188
AudioFifo m_audioFifo
Definition: nfmdemod.h:249
bool m_squelchOpen
Definition: nfmdemod.h:234
int m_magsqCount
Definition: nfmdemod.h:239
bool m_afSquelchOpen
Definition: nfmdemod.h:235
int m_ctcssIndexSelected
Definition: nfmdemod.h:228
Lowpass< Real > m_lowpass
Definition: nfmdemod.h:225
MessageQueue * getMessageQueueToGUI()
Real m_squelchLevel
Definition: nfmdemod.h:233
double m_magsqPeak
Definition: nfmdemod.h:238
T & readBack(int delay)
Lowpass< Real > m_ctcssLowpass
Definition: nfmdemod.h:223
Type filter(Type sample)
Definition: lowpass.h:55
NFMDemodSettings m_settings
Definition: nfmdemod.h:214
int m_ctcssIndex
Definition: nfmdemod.h:227
AudioVector m_audioBuffer
Definition: nfmdemod.h:247
CTCSSDetector m_ctcssDetector
Definition: nfmdemod.h:226
int m_squelchGate
Definition: nfmdemod.h:231
Real phaseDiscriminatorDelta(const Complex &sample, double &magsq, Real &fmDev)
Definition: phasediscri.h:62
#define SDR_RX_SCALED
Definition: dsptypes.h:34
float Real
Definition: dsptypes.h:42
Bandpass< Real > m_bandpass
Definition: nfmdemod.h:224
DoubleBufferFIFO< Real > m_squelchDelayLine
Definition: nfmdemod.h:245
uint32_t write(const quint8 *data, uint32_t numSamples)
Definition: audiofifo.cpp:66
bool analyze(Real *sample)
static MsgReportCTCSSFreq * create(Real freq)
Definition: nfmdemod.h:105
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ serialize()

QByteArray NFMDemod::serialize ( ) const
virtual

Implements ChannelAPI.

Definition at line 646 of file nfmdemod.cpp.

References m_settings, and NFMDemodSettings::serialize().

Referenced by getCenterFrequency().

647 {
648  return m_settings.serialize();
649 }
QByteArray serialize() const
NFMDemodSettings m_settings
Definition: nfmdemod.h:214
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setSelectedCtcssIndex()

void NFMDemod::setSelectedCtcssIndex ( int  selectedCtcssIndex)
inline

Definition at line 164 of file nfmdemod.h.

References m_ctcssIndexSelected.

Referenced by applySettings().

164  {
165  m_ctcssIndexSelected = selectedCtcssIndex;
166  }
int m_ctcssIndexSelected
Definition: nfmdemod.h:228
+ Here is the caller graph for this function:

◆ start()

void NFMDemod::start ( )
virtual

Implements BasebandSampleSink.

Definition at line 363 of file nfmdemod.cpp.

References applyChannelSettings(), AudioFifo::clear(), m_audioFifo, m_inputFrequencyOffset, m_inputSampleRate, m_phaseDiscri, m_running, m_squelchCount, and PhaseDiscriminators::reset().

Referenced by destroy().

364 {
365  qDebug() << "NFMDemod::start";
366  m_squelchCount = 0;
367  m_audioFifo.clear();
370  m_running = true;
371 }
PhaseDiscriminators m_phaseDiscri
Definition: nfmdemod.h:253
bool m_running
Definition: nfmdemod.h:217
void clear()
Definition: audiofifo.cpp:156
int m_squelchCount
Definition: nfmdemod.h:230
AudioFifo m_audioFifo
Definition: nfmdemod.h:249
int m_inputSampleRate
Definition: nfmdemod.h:212
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force=false)
Definition: nfmdemod.cpp:483
int m_inputFrequencyOffset
Definition: nfmdemod.h:213
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ stop()

void NFMDemod::stop ( )
virtual

Implements BasebandSampleSink.

Definition at line 373 of file nfmdemod.cpp.

References m_running.

Referenced by destroy().

374 {
375  qDebug() << "NFMDemod::stop";
376  m_running = false;
377 }
bool m_running
Definition: nfmdemod.h:217
+ Here is the caller graph for this function:

◆ webapiFormatChannelReport()

void NFMDemod::webapiFormatChannelReport ( SWGSDRangel::SWGChannelReport response)
private

Definition at line 828 of file nfmdemod.cpp.

References CalcDb::dbPower(), getMagSqLevels(), SWGSDRangel::SWGChannelReport::getNfmDemodReport(), CTCSSDetector::getToneSet(), m_audioSampleRate, m_ctcssDetector, m_ctcssIndex, NFMDemodSettings::m_ctcssOn, m_inputSampleRate, m_settings, m_squelchOpen, SWGSDRangel::SWGNFMDemodReport::setAudioSampleRate(), SWGSDRangel::SWGNFMDemodReport::setChannelPowerDb(), SWGSDRangel::SWGNFMDemodReport::setChannelSampleRate(), SWGSDRangel::SWGNFMDemodReport::setCtcssTone(), and SWGSDRangel::SWGNFMDemodReport::setSquelch().

Referenced by webapiReportGet().

829 {
830  double magsqAvg, magsqPeak;
831  int nbMagsqSamples;
832  getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples);
833 
834  response.getNfmDemodReport()->setChannelPowerDb(CalcDb::dbPower(magsqAvg));
836  response.getNfmDemodReport()->setSquelch(m_squelchOpen ? 1 : 0);
839 }
void getMagSqLevels(double &avg, double &peak, int &nbSamples)
Definition: nfmdemod.h:171
const Real * getToneSet() const
Definition: ctcssdetector.h:45
void setChannelSampleRate(qint32 channel_sample_rate)
static double dbPower(double magsq, double floor=1e-12)
Definition: db.cpp:22
uint32_t m_audioSampleRate
Definition: nfmdemod.h:215
void setAudioSampleRate(qint32 audio_sample_rate)
SWGNFMDemodReport * getNfmDemodReport()
bool m_squelchOpen
Definition: nfmdemod.h:234
NFMDemodSettings m_settings
Definition: nfmdemod.h:214
int m_ctcssIndex
Definition: nfmdemod.h:227
int m_inputSampleRate
Definition: nfmdemod.h:212
void setChannelPowerDb(float channel_power_db)
void setCtcssTone(float ctcss_tone)
CTCSSDetector m_ctcssDetector
Definition: nfmdemod.h:226
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiFormatChannelSettings()

void NFMDemod::webapiFormatChannelSettings ( SWGSDRangel::SWGChannelSettings response,
const NFMDemodSettings settings 
)
private

Definition at line 787 of file nfmdemod.cpp.

References SWGSDRangel::SWGNFMDemodSettings::getAudioDeviceName(), SWGSDRangel::SWGChannelSettings::getNfmDemodSettings(), SWGSDRangel::SWGNFMDemodSettings::getReverseApiAddress(), SWGSDRangel::SWGNFMDemodSettings::getTitle(), NFMDemodSettings::m_afBandwidth, NFMDemodSettings::m_audioDeviceName, NFMDemodSettings::m_audioMute, NFMDemodSettings::m_ctcssIndex, NFMDemodSettings::m_ctcssOn, NFMDemodSettings::m_deltaSquelch, NFMDemodSettings::m_fmDeviation, NFMDemodSettings::m_highPass, NFMDemodSettings::m_inputFrequencyOffset, NFMDemodSettings::m_reverseAPIAddress, NFMDemodSettings::m_reverseAPIChannelIndex, NFMDemodSettings::m_reverseAPIDeviceIndex, NFMDemodSettings::m_reverseAPIPort, NFMDemodSettings::m_rfBandwidth, NFMDemodSettings::m_rgbColor, NFMDemodSettings::m_squelch, NFMDemodSettings::m_squelchGate, NFMDemodSettings::m_title, NFMDemodSettings::m_useReverseAPI, NFMDemodSettings::m_volume, SWGSDRangel::SWGNFMDemodSettings::setAfBandwidth(), SWGSDRangel::SWGNFMDemodSettings::setAudioDeviceName(), SWGSDRangel::SWGNFMDemodSettings::setAudioMute(), SWGSDRangel::SWGNFMDemodSettings::setCtcssIndex(), SWGSDRangel::SWGNFMDemodSettings::setCtcssOn(), SWGSDRangel::SWGNFMDemodSettings::setDeltaSquelch(), SWGSDRangel::SWGNFMDemodSettings::setFmDeviation(), SWGSDRangel::SWGNFMDemodSettings::setHighPass(), SWGSDRangel::SWGNFMDemodSettings::setInputFrequencyOffset(), SWGSDRangel::SWGNFMDemodSettings::setReverseApiAddress(), SWGSDRangel::SWGNFMDemodSettings::setReverseApiChannelIndex(), SWGSDRangel::SWGNFMDemodSettings::setReverseApiDeviceIndex(), SWGSDRangel::SWGNFMDemodSettings::setReverseApiPort(), SWGSDRangel::SWGNFMDemodSettings::setRfBandwidth(), SWGSDRangel::SWGNFMDemodSettings::setRgbColor(), SWGSDRangel::SWGNFMDemodSettings::setSquelch(), SWGSDRangel::SWGNFMDemodSettings::setSquelchGate(), SWGSDRangel::SWGNFMDemodSettings::setTitle(), SWGSDRangel::SWGNFMDemodSettings::setUseReverseApi(), and SWGSDRangel::SWGNFMDemodSettings::setVolume().

Referenced by webapiSettingsGet(), and webapiSettingsPutPatch().

788 {
789  response.getNfmDemodSettings()->setAfBandwidth(settings.m_afBandwidth);
790  response.getNfmDemodSettings()->setAudioMute(settings.m_audioMute ? 1 : 0);
791  response.getNfmDemodSettings()->setHighPass(settings.m_highPass ? 1 : 0);
792  response.getNfmDemodSettings()->setCtcssIndex(settings.m_ctcssIndex);
793  response.getNfmDemodSettings()->setCtcssOn(settings.m_ctcssOn ? 1 : 0);
794  response.getNfmDemodSettings()->setDeltaSquelch(settings.m_deltaSquelch ? 1 : 0);
795  response.getNfmDemodSettings()->setFmDeviation(settings.m_fmDeviation);
797  response.getNfmDemodSettings()->setRfBandwidth(settings.m_rfBandwidth);
798  response.getNfmDemodSettings()->setRgbColor(settings.m_rgbColor);
799  response.getNfmDemodSettings()->setSquelch(settings.m_squelch);
800  response.getNfmDemodSettings()->setSquelchGate(settings.m_squelchGate);
801  response.getNfmDemodSettings()->setVolume(settings.m_volume);
802 
803  if (response.getNfmDemodSettings()->getTitle()) {
804  *response.getNfmDemodSettings()->getTitle() = settings.m_title;
805  } else {
806  response.getNfmDemodSettings()->setTitle(new QString(settings.m_title));
807  }
808 
809  if (response.getNfmDemodSettings()->getAudioDeviceName()) {
810  *response.getNfmDemodSettings()->getAudioDeviceName() = settings.m_audioDeviceName;
811  } else {
812  response.getNfmDemodSettings()->setAudioDeviceName(new QString(settings.m_audioDeviceName));
813  }
814 
815  response.getNfmDemodSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
816 
817  if (response.getNfmDemodSettings()->getReverseApiAddress()) {
819  } else {
820  response.getNfmDemodSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
821  }
822 
826 }
uint16_t m_reverseAPIPort
void setUseReverseApi(qint32 use_reverse_api)
void setAfBandwidth(float af_bandwidth)
SWGNFMDemodSettings * getNfmDemodSettings()
Real m_squelch
deci-Bels
QString m_reverseAPIAddress
void setInputFrequencyOffset(qint64 input_frequency_offset)
void setSquelchGate(qint32 squelch_gate)
uint16_t m_reverseAPIChannelIndex
void setDeltaSquelch(qint32 delta_squelch)
void setReverseApiAddress(QString *reverse_api_address)
void setRfBandwidth(float rf_bandwidth)
uint16_t m_reverseAPIDeviceIndex
void setAudioDeviceName(QString *audio_device_name)
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
int32_t m_inputFrequencyOffset
void setCtcssIndex(qint32 ctcss_index)
void setReverseApiPort(qint32 reverse_api_port)
void setFmDeviation(qint32 fm_deviation)
void setReverseApiChannelIndex(qint32 reverse_api_channel_index)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiReportGet()

int NFMDemod::webapiReportGet ( SWGSDRangel::SWGChannelReport response,
QString &  errorMessage 
)
virtual

Reimplemented from ChannelAPI.

Definition at line 776 of file nfmdemod.cpp.

References SWGSDRangel::SWGChannelReport::getNfmDemodReport(), SWGSDRangel::SWGNFMDemodReport::init(), SWGSDRangel::SWGChannelReport::setNfmDemodReport(), and webapiFormatChannelReport().

Referenced by getStreamCenterFrequency().

779 {
780  (void) errorMessage;
782  response.getNfmDemodReport()->init();
783  webapiFormatChannelReport(response);
784  return 200;
785 }
SWGNFMDemodReport * getNfmDemodReport()
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport &response)
Definition: nfmdemod.cpp:828
void setNfmDemodReport(SWGNFMDemodReport *nfm_demod_report)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiReverseSendSettings()

void NFMDemod::webapiReverseSendSettings ( QList< QString > &  channelSettingsKeys,
const NFMDemodSettings settings,
bool  force 
)
private

Definition at line 841 of file nfmdemod.cpp.

References SWGSDRangel::SWGChannelSettings::asJson(), ChannelAPI::getDeviceSetIndex(), ChannelAPI::getIndexInDeviceSet(), SWGSDRangel::SWGChannelSettings::getNfmDemodSettings(), NFMDemodSettings::m_afBandwidth, NFMDemodSettings::m_audioDeviceName, NFMDemodSettings::m_audioMute, NFMDemodSettings::m_ctcssIndex, NFMDemodSettings::m_ctcssOn, NFMDemodSettings::m_deltaSquelch, NFMDemodSettings::m_fmDeviation, NFMDemodSettings::m_highPass, NFMDemodSettings::m_inputFrequencyOffset, m_networkManager, m_networkRequest, NFMDemodSettings::m_reverseAPIAddress, NFMDemodSettings::m_reverseAPIChannelIndex, NFMDemodSettings::m_reverseAPIDeviceIndex, NFMDemodSettings::m_reverseAPIPort, NFMDemodSettings::m_rfBandwidth, NFMDemodSettings::m_rgbColor, NFMDemodSettings::m_squelch, NFMDemodSettings::m_squelchGate, NFMDemodSettings::m_title, NFMDemodSettings::m_volume, SWGSDRangel::SWGNFMDemodSettings::setAfBandwidth(), SWGSDRangel::SWGNFMDemodSettings::setAudioDeviceName(), SWGSDRangel::SWGNFMDemodSettings::setAudioMute(), SWGSDRangel::SWGChannelSettings::setChannelType(), SWGSDRangel::SWGNFMDemodSettings::setCtcssIndex(), SWGSDRangel::SWGNFMDemodSettings::setCtcssOn(), SWGSDRangel::SWGNFMDemodSettings::setDeltaSquelch(), SWGSDRangel::SWGChannelSettings::setDirection(), SWGSDRangel::SWGNFMDemodSettings::setFmDeviation(), SWGSDRangel::SWGNFMDemodSettings::setInputFrequencyOffset(), SWGSDRangel::SWGChannelSettings::setNfmDemodSettings(), SWGSDRangel::SWGChannelSettings::setOriginatorChannelIndex(), SWGSDRangel::SWGChannelSettings::setOriginatorDeviceSetIndex(), SWGSDRangel::SWGNFMDemodSettings::setRfBandwidth(), SWGSDRangel::SWGNFMDemodSettings::setRgbColor(), SWGSDRangel::SWGNFMDemodSettings::setSquelch(), SWGSDRangel::SWGNFMDemodSettings::setSquelchGate(), SWGSDRangel::SWGNFMDemodSettings::setTitle(), and SWGSDRangel::SWGNFMDemodSettings::setVolume().

Referenced by applySettings().

842 {
844  swgChannelSettings->setDirection(0); // single sink (Rx)
845  swgChannelSettings->setOriginatorChannelIndex(getIndexInDeviceSet());
846  swgChannelSettings->setOriginatorDeviceSetIndex(getDeviceSetIndex());
847  swgChannelSettings->setChannelType(new QString("NFMDemod"));
848  swgChannelSettings->setNfmDemodSettings(new SWGSDRangel::SWGNFMDemodSettings());
849  SWGSDRangel::SWGNFMDemodSettings *swgNFMDemodSettings = swgChannelSettings->getNfmDemodSettings();
850 
851  // transfer data that has been modified. When force is on transfer all data except reverse API data
852 
853  if (channelSettingsKeys.contains("afBandwidth") || force) {
854  swgNFMDemodSettings->setAfBandwidth(settings.m_afBandwidth);
855  }
856  if (channelSettingsKeys.contains("audioMute") || force) {
857  swgNFMDemodSettings->setAudioMute(settings.m_audioMute ? 1 : 0);
858  }
859  if (channelSettingsKeys.contains("highPass") || force) {
860  swgNFMDemodSettings->setAudioMute(settings.m_highPass ? 1 : 0);
861  }
862  if (channelSettingsKeys.contains("ctcssIndex") || force) {
863  swgNFMDemodSettings->setCtcssIndex(settings.m_ctcssIndex);
864  }
865  if (channelSettingsKeys.contains("ctcssOn") || force) {
866  swgNFMDemodSettings->setCtcssOn(settings.m_ctcssOn ? 1 : 0);
867  }
868  if (channelSettingsKeys.contains("deltaSquelch") || force) {
869  swgNFMDemodSettings->setDeltaSquelch(settings.m_deltaSquelch ? 1 : 0);
870  }
871  if (channelSettingsKeys.contains("fmDeviation") || force) {
872  swgNFMDemodSettings->setFmDeviation(settings.m_fmDeviation);
873  }
874  if (channelSettingsKeys.contains("inputFrequencyOffset") || force) {
875  swgNFMDemodSettings->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
876  }
877  if (channelSettingsKeys.contains("rfBandwidth") || force) {
878  swgNFMDemodSettings->setRfBandwidth(settings.m_rfBandwidth);
879  }
880  if (channelSettingsKeys.contains("rgbColor") || force) {
881  swgNFMDemodSettings->setRgbColor(settings.m_rgbColor);
882  }
883  if (channelSettingsKeys.contains("squelch") || force) {
884  swgNFMDemodSettings->setSquelch(settings.m_squelch);
885  }
886  if (channelSettingsKeys.contains("squelchGate") || force) {
887  swgNFMDemodSettings->setSquelchGate(settings.m_squelchGate);
888  }
889  if (channelSettingsKeys.contains("title") || force) {
890  swgNFMDemodSettings->setTitle(new QString(settings.m_title));
891  }
892  if (channelSettingsKeys.contains("volume") || force) {
893  swgNFMDemodSettings->setVolume(settings.m_volume);
894  }
895  if (channelSettingsKeys.contains("audioDeviceName") || force) {
896  swgNFMDemodSettings->setAudioDeviceName(new QString(settings.m_audioDeviceName));
897  }
898 
899  QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
900  .arg(settings.m_reverseAPIAddress)
901  .arg(settings.m_reverseAPIPort)
902  .arg(settings.m_reverseAPIDeviceIndex)
903  .arg(settings.m_reverseAPIChannelIndex);
904  m_networkRequest.setUrl(QUrl(channelSettingsURL));
905  m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
906 
907  QBuffer *buffer=new QBuffer();
908  buffer->open((QBuffer::ReadWrite));
909  buffer->write(swgChannelSettings->asJson().toUtf8());
910  buffer->seek(0);
911 
912  // Always use PATCH to avoid passing reverse API settings
913  m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
914 
915  delete swgChannelSettings;
916 }
void setOriginatorChannelIndex(qint32 originator_channel_index)
uint16_t m_reverseAPIPort
QNetworkRequest m_networkRequest
Definition: nfmdemod.h:256
void setAfBandwidth(float af_bandwidth)
SWGNFMDemodSettings * getNfmDemodSettings()
int getDeviceSetIndex() const
Definition: channelapi.h:89
void setNfmDemodSettings(SWGNFMDemodSettings *nfm_demod_settings)
Real m_squelch
deci-Bels
void setChannelType(QString *channel_type)
void setOriginatorDeviceSetIndex(qint32 originator_device_set_index)
QString m_reverseAPIAddress
void setInputFrequencyOffset(qint64 input_frequency_offset)
void setSquelchGate(qint32 squelch_gate)
uint16_t m_reverseAPIChannelIndex
void setDeltaSquelch(qint32 delta_squelch)
void setRfBandwidth(float rf_bandwidth)
virtual QString asJson() override
uint16_t m_reverseAPIDeviceIndex
QNetworkAccessManager * m_networkManager
Definition: nfmdemod.h:255
void setAudioDeviceName(QString *audio_device_name)
int32_t m_inputFrequencyOffset
int getIndexInDeviceSet() const
Definition: channelapi.h:87
void setCtcssIndex(qint32 ctcss_index)
void setFmDeviation(qint32 fm_deviation)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiSettingsGet()

int NFMDemod::webapiSettingsGet ( SWGSDRangel::SWGChannelSettings response,
QString &  errorMessage 
)
virtual

Reimplemented from ChannelAPI.

Definition at line 671 of file nfmdemod.cpp.

References SWGSDRangel::SWGChannelSettings::getNfmDemodSettings(), SWGSDRangel::SWGNFMDemodSettings::init(), m_settings, SWGSDRangel::SWGChannelSettings::setNfmDemodSettings(), and webapiFormatChannelSettings().

Referenced by getStreamCenterFrequency().

674 {
675  (void) errorMessage;
677  response.getNfmDemodSettings()->init();
679  return 200;
680 }
SWGNFMDemodSettings * getNfmDemodSettings()
void setNfmDemodSettings(SWGNFMDemodSettings *nfm_demod_settings)
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings &response, const NFMDemodSettings &settings)
Definition: nfmdemod.cpp:787
NFMDemodSettings m_settings
Definition: nfmdemod.h:214
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiSettingsPutPatch()

int NFMDemod::webapiSettingsPutPatch ( bool  force,
const QStringList &  channelSettingsKeys,
SWGSDRangel::SWGChannelSettings response,
QString &  errorMessage 
)
virtual

Reimplemented from ChannelAPI.

Definition at line 682 of file nfmdemod.cpp.

References NFMDemod::MsgConfigureNFMDemod::create(), NFMDemod::MsgConfigureChannelizer::create(), SWGSDRangel::SWGNFMDemodSettings::getAfBandwidth(), SWGSDRangel::SWGNFMDemodSettings::getAudioDeviceName(), SWGSDRangel::SWGNFMDemodSettings::getAudioMute(), SWGSDRangel::SWGNFMDemodSettings::getCtcssIndex(), SWGSDRangel::SWGNFMDemodSettings::getCtcssOn(), SWGSDRangel::SWGNFMDemodSettings::getDeltaSquelch(), SWGSDRangel::SWGNFMDemodSettings::getFmDeviation(), SWGSDRangel::SWGNFMDemodSettings::getHighPass(), SWGSDRangel::SWGNFMDemodSettings::getInputFrequencyOffset(), SWGSDRangel::SWGChannelSettings::getNfmDemodSettings(), SWGSDRangel::SWGNFMDemodSettings::getReverseApiAddress(), SWGSDRangel::SWGNFMDemodSettings::getReverseApiChannelIndex(), SWGSDRangel::SWGNFMDemodSettings::getReverseApiDeviceIndex(), SWGSDRangel::SWGNFMDemodSettings::getReverseApiPort(), SWGSDRangel::SWGNFMDemodSettings::getRfBandwidth(), SWGSDRangel::SWGNFMDemodSettings::getRgbColor(), SWGSDRangel::SWGNFMDemodSettings::getSquelch(), SWGSDRangel::SWGNFMDemodSettings::getSquelchGate(), SWGSDRangel::SWGNFMDemodSettings::getTitle(), SWGSDRangel::SWGNFMDemodSettings::getUseReverseApi(), SWGSDRangel::SWGNFMDemodSettings::getVolume(), NFMDemodSettings::m_afBandwidth, NFMDemodSettings::m_audioDeviceName, NFMDemodSettings::m_audioMute, m_audioSampleRate, NFMDemodSettings::m_ctcssIndex, NFMDemodSettings::m_ctcssOn, NFMDemodSettings::m_deltaSquelch, NFMDemodSettings::m_fmDeviation, BasebandSampleSink::m_guiMessageQueue, NFMDemodSettings::m_highPass, NFMDemodSettings::m_inputFrequencyOffset, BasebandSampleSink::m_inputMessageQueue, NFMDemodSettings::m_reverseAPIAddress, NFMDemodSettings::m_reverseAPIChannelIndex, NFMDemodSettings::m_reverseAPIDeviceIndex, NFMDemodSettings::m_reverseAPIPort, NFMDemodSettings::m_rfBandwidth, NFMDemodSettings::m_rgbColor, m_settings, NFMDemodSettings::m_squelch, NFMDemodSettings::m_squelchGate, NFMDemodSettings::m_title, NFMDemodSettings::m_useReverseAPI, NFMDemodSettings::m_volume, MessageQueue::push(), and webapiFormatChannelSettings().

Referenced by getStreamCenterFrequency().

687 {
688  (void) errorMessage;
689  NFMDemodSettings settings = m_settings;
690  bool frequencyOffsetChanged = false;
691 
692  if (channelSettingsKeys.contains("afBandwidth")) {
693  settings.m_afBandwidth = response.getNfmDemodSettings()->getAfBandwidth();
694  }
695  if (channelSettingsKeys.contains("audioMute")) {
696  settings.m_audioMute = response.getNfmDemodSettings()->getAudioMute() != 0;
697  }
698  if (channelSettingsKeys.contains("highPass")) {
699  settings.m_highPass = response.getNfmDemodSettings()->getHighPass() != 0;
700  }
701  if (channelSettingsKeys.contains("ctcssIndex")) {
702  settings.m_ctcssIndex = response.getNfmDemodSettings()->getCtcssIndex();
703  }
704  if (channelSettingsKeys.contains("ctcssOn")) {
705  settings.m_ctcssOn = response.getNfmDemodSettings()->getCtcssOn() != 0;
706  }
707  if (channelSettingsKeys.contains("deltaSquelch")) {
708  settings.m_deltaSquelch = response.getNfmDemodSettings()->getDeltaSquelch() != 0;
709  }
710  if (channelSettingsKeys.contains("fmDeviation")) {
711  settings.m_fmDeviation = response.getNfmDemodSettings()->getFmDeviation();
712  }
713  if (channelSettingsKeys.contains("inputFrequencyOffset"))
714  {
716  frequencyOffsetChanged = true;
717  }
718  if (channelSettingsKeys.contains("rfBandwidth")) {
719  settings.m_rfBandwidth = response.getNfmDemodSettings()->getRfBandwidth();
720  }
721  if (channelSettingsKeys.contains("rgbColor")) {
722  settings.m_rgbColor = response.getNfmDemodSettings()->getRgbColor();
723  }
724  if (channelSettingsKeys.contains("squelch")) {
725  settings.m_squelch = response.getNfmDemodSettings()->getSquelch();
726  }
727  if (channelSettingsKeys.contains("squelchGate")) {
728  settings.m_squelchGate = response.getNfmDemodSettings()->getSquelchGate();
729  }
730  if (channelSettingsKeys.contains("title")) {
731  settings.m_title = *response.getNfmDemodSettings()->getTitle();
732  }
733  if (channelSettingsKeys.contains("volume")) {
734  settings.m_volume = response.getNfmDemodSettings()->getVolume();
735  }
736  if (channelSettingsKeys.contains("audioDeviceName")) {
737  settings.m_audioDeviceName = *response.getNfmDemodSettings()->getAudioDeviceName();
738  }
739  if (channelSettingsKeys.contains("useReverseAPI")) {
740  settings.m_useReverseAPI = response.getNfmDemodSettings()->getUseReverseApi() != 0;
741  }
742  if (channelSettingsKeys.contains("reverseAPIAddress")) {
744  }
745  if (channelSettingsKeys.contains("reverseAPIPort")) {
746  settings.m_reverseAPIPort = response.getNfmDemodSettings()->getReverseApiPort();
747  }
748  if (channelSettingsKeys.contains("reverseAPIDeviceIndex")) {
750  }
751  if (channelSettingsKeys.contains("reverseAPIChannelIndex")) {
753  }
754 
755  if (frequencyOffsetChanged)
756  {
757  MsgConfigureChannelizer* channelConfigMsg = MsgConfigureChannelizer::create(
759  m_inputMessageQueue.push(channelConfigMsg);
760  }
761 
762  MsgConfigureNFMDemod *msg = MsgConfigureNFMDemod::create(settings, force);
764 
765  if (m_guiMessageQueue) // forward to GUI if any
766  {
767  MsgConfigureNFMDemod *msgToGUI = MsgConfigureNFMDemod::create(settings, force);
768  m_guiMessageQueue->push(msgToGUI);
769  }
770 
771  webapiFormatChannelSettings(response, settings);
772 
773  return 200;
774 }
uint16_t m_reverseAPIPort
void push(Message *message, bool emitSignal=true)
Push message onto queue.
SWGNFMDemodSettings * getNfmDemodSettings()
static MsgConfigureChannelizer * create(int sampleRate, int centerFrequency)
Definition: nfmdemod.h:83
uint32_t m_audioSampleRate
Definition: nfmdemod.h:215
static MsgConfigureNFMDemod * create(const NFMDemodSettings &settings, bool force)
Definition: nfmdemod.h:60
Real m_squelch
deci-Bels
MessageQueue m_inputMessageQueue
Queue for asynchronous inbound communication.
QString m_reverseAPIAddress
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
uint16_t m_reverseAPIChannelIndex
uint16_t m_reverseAPIDeviceIndex
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings &response, const NFMDemodSettings &settings)
Definition: nfmdemod.cpp:787
NFMDemodSettings m_settings
Definition: nfmdemod.h:214
int32_t m_inputFrequencyOffset
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ m_afSquelch

AFSquelch NFMDemod::m_afSquelch
private

Definition at line 243 of file nfmdemod.h.

Referenced by applyAudioSampleRate(), applySettings(), NFMDemod(), and processOneSample().

◆ m_afSquelchOpen

bool NFMDemod::m_afSquelchOpen
private

Definition at line 235 of file nfmdemod.h.

Referenced by processOneSample().

◆ m_agcLevel

Real NFMDemod::m_agcLevel
private

Definition at line 244 of file nfmdemod.h.

Referenced by NFMDemod().

◆ m_audioBuffer

AudioVector NFMDemod::m_audioBuffer
private

Definition at line 247 of file nfmdemod.h.

Referenced by NFMDemod(), and processOneSample().

◆ m_audioBufferFill

uint NFMDemod::m_audioBufferFill
private

Definition at line 248 of file nfmdemod.h.

Referenced by NFMDemod(), and processOneSample().

◆ m_audioFifo

AudioFifo NFMDemod::m_audioFifo
private

Definition at line 249 of file nfmdemod.h.

Referenced by applySettings(), NFMDemod(), processOneSample(), start(), and ~NFMDemod().

◆ m_audioSampleRate

uint32_t NFMDemod::m_audioSampleRate
private

◆ m_bandpass

Bandpass<Real> NFMDemod::m_bandpass
private

Definition at line 224 of file nfmdemod.h.

Referenced by applyAudioSampleRate(), applySettings(), and processOneSample().

◆ m_channelId

const QString NFMDemod::m_channelId = "NFMDemod"
static

Definition at line 190 of file nfmdemod.h.

Referenced by NFMPlugin::initPlugin(), and NFMDemod().

◆ m_channelIdURI

const QString NFMDemod::m_channelIdURI = "sdrangel.channel.nfmdemod"
static

Definition at line 189 of file nfmdemod.h.

Referenced by NFMPlugin::initPlugin(), and NFMDemodGUI::NFMDemodGUI().

◆ m_channelizer

DownChannelizer* NFMDemod::m_channelizer
private

Definition at line 210 of file nfmdemod.h.

Referenced by handleMessage(), and ~NFMDemod().

◆ m_ctcssDetector

CTCSSDetector NFMDemod::m_ctcssDetector
private

◆ m_ctcssIndex

int NFMDemod::m_ctcssIndex
private

Definition at line 227 of file nfmdemod.h.

Referenced by processOneSample(), and webapiFormatChannelReport().

◆ m_ctcssIndexSelected

int NFMDemod::m_ctcssIndexSelected
private

Definition at line 228 of file nfmdemod.h.

Referenced by processOneSample(), and setSelectedCtcssIndex().

◆ m_ctcssLowpass

Lowpass<Real> NFMDemod::m_ctcssLowpass
private

Definition at line 223 of file nfmdemod.h.

Referenced by applyAudioSampleRate(), and processOneSample().

◆ m_deviceAPI

DeviceAPI* NFMDemod::m_deviceAPI
private

Definition at line 208 of file nfmdemod.h.

Referenced by ~NFMDemod().

◆ m_discriCompensation

float NFMDemod::m_discriCompensation
private

compensation factor that depends on audio rate (1 for 48 kS/s)

Definition at line 216 of file nfmdemod.h.

Referenced by NFMDemod(), and processOneSample().

◆ m_inputFrequencyOffset

int NFMDemod::m_inputFrequencyOffset
private

Definition at line 213 of file nfmdemod.h.

Referenced by applyChannelSettings(), and start().

◆ m_inputSampleRate

int NFMDemod::m_inputSampleRate
private

◆ m_interpolator

Interpolator NFMDemod::m_interpolator
private

Definition at line 220 of file nfmdemod.h.

Referenced by applyAudioSampleRate(), applyChannelSettings(), applySettings(), and feed().

◆ m_interpolatorDistance

Real NFMDemod::m_interpolatorDistance
private

Definition at line 221 of file nfmdemod.h.

Referenced by applyAudioSampleRate(), applyChannelSettings(), applySettings(), and feed().

◆ m_interpolatorDistanceRemain

Real NFMDemod::m_interpolatorDistanceRemain
private

Definition at line 222 of file nfmdemod.h.

Referenced by applyAudioSampleRate(), applyChannelSettings(), applySettings(), and feed().

◆ m_lowpass

Lowpass<Real> NFMDemod::m_lowpass
private

Definition at line 225 of file nfmdemod.h.

Referenced by applyAudioSampleRate(), applySettings(), and processOneSample().

◆ m_magsq

double NFMDemod::m_magsq
private

displayed averaged value

Definition at line 236 of file nfmdemod.h.

Referenced by getMag(), and getMagSqLevels().

◆ m_magsqCount

int NFMDemod::m_magsqCount
private

Definition at line 239 of file nfmdemod.h.

Referenced by getMagSqLevels(), and processOneSample().

◆ m_magSqLevelStore

MagSqLevelsStore NFMDemod::m_magSqLevelStore
private

Definition at line 240 of file nfmdemod.h.

Referenced by getMagSqLevels().

◆ m_magsqPeak

double NFMDemod::m_magsqPeak
private

Definition at line 238 of file nfmdemod.h.

Referenced by getMagSqLevels(), and processOneSample().

◆ m_magsqSum

double NFMDemod::m_magsqSum
private

Definition at line 237 of file nfmdemod.h.

Referenced by getMagSqLevels(), and processOneSample().

◆ m_movingAverage

MovingAverageUtil<Real, double, 32> NFMDemod::m_movingAverage
private

Definition at line 242 of file nfmdemod.h.

Referenced by applySettings(), and processOneSample().

◆ m_nco

NCO NFMDemod::m_nco
private

Definition at line 219 of file nfmdemod.h.

Referenced by applyChannelSettings(), and feed().

◆ m_networkManager

QNetworkAccessManager* NFMDemod::m_networkManager
private

Definition at line 255 of file nfmdemod.h.

Referenced by webapiReverseSendSettings(), and ~NFMDemod().

◆ m_networkRequest

QNetworkRequest NFMDemod::m_networkRequest
private

Definition at line 256 of file nfmdemod.h.

Referenced by webapiReverseSendSettings().

◆ m_phaseDiscri

PhaseDiscriminators NFMDemod::m_phaseDiscri
private

Definition at line 253 of file nfmdemod.h.

Referenced by applySettings(), processOneSample(), and start().

◆ m_running

bool NFMDemod::m_running
private

Definition at line 217 of file nfmdemod.h.

Referenced by feed(), start(), and stop().

◆ m_sampleCount

int NFMDemod::m_sampleCount
private

Definition at line 229 of file nfmdemod.h.

Referenced by processOneSample().

◆ m_settings

NFMDemodSettings NFMDemod::m_settings
private

◆ m_settingsMutex

QMutex NFMDemod::m_settingsMutex
private

Definition at line 251 of file nfmdemod.h.

Referenced by applyAudioSampleRate(), applyChannelSettings(), applySettings(), and feed().

◆ m_squelchCount

int NFMDemod::m_squelchCount
private

Definition at line 230 of file nfmdemod.h.

Referenced by applyAudioSampleRate(), applySettings(), processOneSample(), and start().

◆ m_squelchDelayLine

DoubleBufferFIFO<Real> NFMDemod::m_squelchDelayLine
private

Definition at line 245 of file nfmdemod.h.

Referenced by processOneSample().

◆ m_squelchGate

int NFMDemod::m_squelchGate
private

Definition at line 231 of file nfmdemod.h.

Referenced by applyAudioSampleRate(), applySettings(), and processOneSample().

◆ m_squelchLevel

Real NFMDemod::m_squelchLevel
private

Definition at line 233 of file nfmdemod.h.

Referenced by applySettings(), and processOneSample().

◆ m_squelchOpen

bool NFMDemod::m_squelchOpen
private

Definition at line 234 of file nfmdemod.h.

Referenced by getSquelchOpen(), processOneSample(), and webapiFormatChannelReport().

◆ m_threadedChannelizer

ThreadedBasebandSampleSink* NFMDemod::m_threadedChannelizer
private

Definition at line 209 of file nfmdemod.h.

Referenced by ~NFMDemod().

◆ m_udpBlockSize

const int NFMDemod::m_udpBlockSize = 512
staticprivate

Definition at line 258 of file nfmdemod.h.


The documentation for this class was generated from the following files: