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 Slots | Private Member Functions | Private Attributes | List of all members
SSBDemod Class Reference

#include <ssbdemod.h>

+ Inheritance diagram for SSBDemod:
+ Collaboration diagram for SSBDemod:

Classes

struct  MagSqLevelsStore
 
class  MsgConfigureChannelizer
 
class  MsgConfigureSSBDemod
 
class  MsgConfigureSSBDemodPrivate
 

Public Member Functions

 SSBDemod (DeviceAPI *deviceAPI)
 
virtual ~SSBDemod ()
 
virtual void destroy ()
 
void setSampleSink (BasebandSampleSink *sampleSink)
 
void configure (MessageQueue *messageQueue, Real Bandwidth, Real LowCutoff, Real volume, int spanLog2, bool audioBinaural, bool audioFlipChannels, bool dsb, bool audioMute, bool agc, bool agcClamping, int agcTimeLog2, int agcPowerThreshold, int agcThresholdGate)
 
virtual void feed (const SampleVector::const_iterator &begin, const SampleVector::const_iterator &end, bool positiveOnly)
 
virtual void start ()
 
virtual void stop ()
 
virtual bool handleMessage (const Message &cmd)
 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
 
uint32_t getAudioSampleRate () const
 
uint32_t getInputSampleRate () const
 
double getMagSq () const
 
bool getAudioActive () const
 
void getMagSqLevels (double &avg, double &peak, int &nbSamples)
 
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)
 
- 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.ssbdemod"
 
static const QString m_channelId = "SSBDemod"
 

Private Slots

void networkManagerFinished (QNetworkReply *reply)
 

Private Member Functions

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

Private Attributes

DeviceAPIm_deviceAPI
 
ThreadedBasebandSampleSinkm_threadedChannelizer
 
DownChannelizerm_channelizer
 
SSBDemodSettings m_settings
 
Real m_Bandwidth
 
Real m_LowCutoff
 
Real m_volume
 
int m_spanLog2
 
fftfilt::cmplx m_sum
 
int m_undersampleCount
 
int m_inputSampleRate
 
int m_inputFrequencyOffset
 
bool m_audioBinaual
 
bool m_audioFlipChannels
 
bool m_usb
 
bool m_dsb
 
bool m_audioMute
 
double m_magsq
 
double m_magsqSum
 
double m_magsqPeak
 
int m_magsqCount
 
MagSqLevelsStore m_magSqLevelStore
 
MagAGC m_agc
 
bool m_agcActive
 
bool m_agcClamping
 
int m_agcNbSamples
 number of audio (48 kHz) samples for AGC averaging More...
 
double m_agcPowerThreshold
 AGC power threshold (linear) More...
 
int m_agcThresholdGate
 Gate length in number of samples befor threshold triggers. More...
 
DoubleBufferFIFO< fftfilt::cmplxm_squelchDelayLine
 
bool m_audioActive
 True if an audio signal is produced (no AGC or AGC and above threshold) More...
 
NCOF m_nco
 
Interpolator m_interpolator
 
Real m_interpolatorDistance
 
Real m_interpolatorDistanceRemain
 
fftfiltSSBFilter
 
fftfiltDSBFilter
 
BasebandSampleSinkm_sampleSink
 
SampleVector m_sampleBuffer
 
AudioVector m_audioBuffer
 
uint m_audioBufferFill
 
AudioFifo m_audioFifo
 
quint32 m_audioSampleRate
 
QNetworkAccessManager * m_networkManager
 
QNetworkRequest m_networkRequest
 
QMutex m_settingsMutex
 

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 48 of file ssbdemod.h.

Constructor & Destructor Documentation

◆ SSBDemod()

SSBDemod::SSBDemod ( DeviceAPI deviceAPI)

Definition at line 51 of file ssbdemod.cpp.

References AudioDeviceManager::addAudioSink(), DeviceAPI::addChannelSink(), DeviceAPI::addChannelSinkAPI(), applyChannelSettings(), applySettings(), DSBFilter, DSPEngine::getAudioDeviceManager(), BasebandSampleSink::getInputMessageQueue(), AudioDeviceManager::getOutputSampleRate(), DSPEngine::instance(), m_agc, m_agcClamping, m_audioBuffer, m_audioBufferFill, m_audioFifo, m_audioSampleRate, m_Bandwidth, m_channelId, m_channelizer, m_deviceAPI, m_inputFrequencyOffset, m_inputSampleRate, m_LowCutoff, m_magsq, m_magsqCount, m_magsqPeak, m_magsqSum, m_networkManager, m_settings, m_spanLog2, m_sum, m_threadedChannelizer, m_undersampleCount, m_usb, m_volume, networkManagerFinished(), SDR_RX_SCALED, MagAGC::setClamping(), MagAGC::setClampMax(), ssbFftLen, and SSBFilter.

Referenced by SSBDemod::MsgConfigureChannelizer::MsgConfigureChannelizer().

51  :
53  m_deviceAPI(deviceAPI),
54  m_audioBinaual(false),
55  m_audioFlipChannels(false),
56  m_dsb(false),
57  m_audioMute(false),
58  m_agc(12000, agcTarget, 1e-2),
59  m_agcActive(false),
60  m_agcClamping(false),
61  m_agcNbSamples(12000),
62  m_agcPowerThreshold(1e-2),
64  m_squelchDelayLine(2*48000),
65  m_audioActive(false),
66  m_sampleSink(0),
67  m_audioFifo(24000),
68  m_settingsMutex(QMutex::Recursive)
69 {
70  setObjectName(m_channelId);
71 
72  m_Bandwidth = 5000;
73  m_LowCutoff = 300;
74  m_volume = 2.0;
75  m_spanLog2 = 3;
76  m_inputSampleRate = 48000;
78 
81 
82  m_audioBuffer.resize(1<<14);
85  m_sum = 0;
86 
87  m_usb = true;
88  m_magsq = 0.0f;
89  m_magsqSum = 0.0f;
90  m_magsqPeak = 0.0f;
91  m_magsqCount = 0;
92 
95 
98 
100  applySettings(m_settings, true);
101 
102  m_channelizer = new DownChannelizer(this);
106 
107  m_networkManager = new QNetworkAccessManager();
108  connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
109 }
void addAudioSink(AudioFifo *audioFifo, MessageQueue *sampleSinkMessageQueue, int outputDeviceIndex=-1)
Add the audio sink.
static const QString m_channelId
Definition: ssbdemod.h:177
int getOutputSampleRate(int outputDeviceIndex=-1)
int m_agcThresholdGate
Gate length in number of samples befor threshold triggers.
Definition: ssbdemod.h:311
bool m_audioBinaual
Definition: ssbdemod.h:296
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force=false)
Definition: ssbdemod.cpp:385
fftfilt * SSBFilter
Definition: ssbdemod.h:319
void addChannelSinkAPI(ChannelAPI *channelAPI, int streamIndex=0)
Definition: deviceapi.cpp:156
bool m_dsb
Definition: ssbdemod.h:299
double m_magsqPeak
Definition: ssbdemod.h:303
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
static const QString m_channelIdURI
Definition: ssbdemod.h:176
Real m_Bandwidth
Definition: ssbdemod.h:288
double m_magsq
Definition: ssbdemod.h:301
int m_magsqCount
Definition: ssbdemod.h:304
Real m_LowCutoff
Definition: ssbdemod.h:289
void networkManagerFinished(QNetworkReply *reply)
Definition: ssbdemod.cpp:931
QMutex m_settingsMutex
Definition: ssbdemod.h:333
BasebandSampleSink * m_sampleSink
Definition: ssbdemod.h:322
bool m_audioMute
Definition: ssbdemod.h:300
static DSPEngine * instance()
Definition: dspengine.cpp:51
fftfilt * DSBFilter
Definition: ssbdemod.h:320
fftfilt::cmplx m_sum
Definition: ssbdemod.h:292
ChannelAPI(const QString &name, StreamType streamType)
Definition: channelapi.cpp:23
void setClampMax(double clampMax)
Definition: agc.h:52
#define agcTarget
Definition: freedvdemod.h:40
int m_undersampleCount
Definition: ssbdemod.h:293
bool m_agcClamping
Definition: ssbdemod.h:308
double m_magsqSum
Definition: ssbdemod.h:302
int m_agcNbSamples
number of audio (48 kHz) samples for AGC averaging
Definition: ssbdemod.h:309
int m_inputFrequencyOffset
Definition: ssbdemod.h:295
bool m_audioActive
True if an audio signal is produced (no AGC or AGC and above threshold)
Definition: ssbdemod.h:313
int m_inputSampleRate
Definition: ssbdemod.h:294
DeviceAPI * m_deviceAPI
Definition: ssbdemod.h:283
bool m_usb
Definition: ssbdemod.h:298
DoubleBufferFIFO< fftfilt::cmplx > m_squelchDelayLine
Definition: ssbdemod.h:312
int m_spanLog2
Definition: ssbdemod.h:291
Exposes a single sink stream (input, Rx)
Definition: channelapi.h:41
MagAGC m_agc
Definition: ssbdemod.h:306
SSBDemodSettings m_settings
Definition: ssbdemod.h:286
AudioVector m_audioBuffer
Definition: ssbdemod.h:325
DownChannelizer * m_channelizer
Definition: ssbdemod.h:285
AudioDeviceManager * getAudioDeviceManager()
Definition: dspengine.h:55
void addChannelSink(ThreadedBasebandSampleSink *sink, int streamIndex=0)
Add a channel sink (Rx)
Definition: deviceapi.cpp:118
Real m_volume
Definition: ssbdemod.h:290
bool m_agcActive
Definition: ssbdemod.h:307
void applySettings(const SSBDemodSettings &settings, bool force=false)
Definition: ssbdemod.cpp:458
ThreadedBasebandSampleSink * m_threadedChannelizer
Definition: ssbdemod.h:284
double m_agcPowerThreshold
AGC power threshold (linear)
Definition: ssbdemod.h:310
void setClamping(bool clamping)
Definition: agc.h:51
QNetworkAccessManager * m_networkManager
Definition: ssbdemod.h:330
AudioFifo m_audioFifo
Definition: ssbdemod.h:327
bool m_audioFlipChannels
Definition: ssbdemod.h:297
quint32 m_audioSampleRate
Definition: ssbdemod.h:328
uint m_audioBufferFill
Definition: ssbdemod.h:326
#define SDR_RX_SCALED
Definition: dsptypes.h:34
#define ssbFftLen
Definition: chanalyzer.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ~SSBDemod()

SSBDemod::~SSBDemod ( )
virtual

Definition at line 111 of file ssbdemod.cpp.

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

Referenced by SSBDemod::MsgConfigureChannelizer::MsgConfigureChannelizer().

112 {
113  disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
114  delete m_networkManager;
116 
119  delete m_threadedChannelizer;
120  delete m_channelizer;
121  delete SSBFilter;
122  delete DSBFilter;
123 }
void removeChannelSinkAPI(ChannelAPI *channelAPI, int streamIndex=0)
Definition: deviceapi.cpp:163
fftfilt * SSBFilter
Definition: ssbdemod.h:319
void removeAudioSink(AudioFifo *audioFifo)
Remove the audio sink.
void networkManagerFinished(QNetworkReply *reply)
Definition: ssbdemod.cpp:931
static DSPEngine * instance()
Definition: dspengine.cpp:51
fftfilt * DSBFilter
Definition: ssbdemod.h:320
void removeChannelSink(ThreadedBasebandSampleSink *sink, int streamIndex=0)
Remove a channel sink (Rx)
Definition: deviceapi.cpp:127
DeviceAPI * m_deviceAPI
Definition: ssbdemod.h:283
DownChannelizer * m_channelizer
Definition: ssbdemod.h:285
AudioDeviceManager * getAudioDeviceManager()
Definition: dspengine.h:55
ThreadedBasebandSampleSink * m_threadedChannelizer
Definition: ssbdemod.h:284
QNetworkAccessManager * m_networkManager
Definition: ssbdemod.h:330
AudioFifo m_audioFifo
Definition: ssbdemod.h:327
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Function Documentation

◆ applyAudioSampleRate()

void SSBDemod::applyAudioSampleRate ( int  sampleRate)
private

Definition at line 411 of file ssbdemod.cpp.

References agcTarget, DSPConfigureAudio::AudioOutput, Interpolator::create(), SSBDemod::MsgConfigureChannelizer::create(), fftfilt::create_dsb_filter(), fftfilt::create_filter(), DSBFilter, m_agc, m_agcNbSamples, SSBDemodSettings::m_agcThresholdGate, m_agcThresholdGate, SSBDemodSettings::m_agcTimeLog2, m_audioFifo, m_audioSampleRate, m_Bandwidth, BasebandSampleSink::m_guiMessageQueue, SSBDemodSettings::m_inputFrequencyOffset, BasebandSampleSink::m_inputMessageQueue, m_inputSampleRate, m_interpolator, m_interpolatorDistance, m_interpolatorDistanceRemain, m_LowCutoff, m_settings, m_settingsMutex, MessageQueue::push(), MagAGC::resize(), MagAGC::setGate(), AudioFifo::setSize(), MagAGC::setStepDownDelay(), and SSBFilter.

Referenced by applySettings(), and handleMessage().

412 {
413  qDebug("SSBDemod::applyAudioSampleRate: %d", sampleRate);
414 
415  MsgConfigureChannelizer* channelConfigMsg = MsgConfigureChannelizer::create(
416  sampleRate, m_settings.m_inputFrequencyOffset);
417  m_inputMessageQueue.push(channelConfigMsg);
418 
419  m_settingsMutex.lock();
420 
421  Real interpolatorBandwidth = (m_Bandwidth * 1.5f) > m_inputSampleRate ? m_inputSampleRate : (m_Bandwidth * 1.5f);
422  m_interpolator.create(16, m_inputSampleRate, interpolatorBandwidth, 2.0f);
425 
426  SSBFilter->create_filter(m_LowCutoff / (float) sampleRate, m_Bandwidth / (float) sampleRate);
427  DSBFilter->create_dsb_filter((2.0f * m_Bandwidth) / (float) sampleRate);
428 
429  int agcNbSamples = (sampleRate / 1000) * (1<<m_settings.m_agcTimeLog2);
430  int agcThresholdGate = (sampleRate / 1000) * m_settings.m_agcThresholdGate; // ms
431 
432  if (m_agcNbSamples != agcNbSamples)
433  {
434  m_agc.resize(agcNbSamples, agcNbSamples/2, agcTarget);
435  m_agc.setStepDownDelay(agcNbSamples);
436  m_agcNbSamples = agcNbSamples;
437  }
438 
439  if (m_agcThresholdGate != agcThresholdGate)
440  {
441  m_agc.setGate(agcThresholdGate);
442  m_agcThresholdGate = agcThresholdGate;
443  }
444 
445  m_audioFifo.setSize(sampleRate);
446 
447  m_settingsMutex.unlock();
448 
449  m_audioSampleRate = sampleRate;
450 
451  if (m_guiMessageQueue) // forward to GUI if any
452  {
454  m_guiMessageQueue->push(cfg);
455  }
456 }
int m_agcThresholdGate
Gate length in number of samples befor threshold triggers.
Definition: ssbdemod.h:311
void push(Message *message, bool emitSignal=true)
Push message onto queue.
fftfilt * SSBFilter
Definition: ssbdemod.h:319
void create(int phaseSteps, double sampleRate, double cutoff, double nbTapsPerPhase=4.5)
Real m_interpolatorDistance
Definition: ssbdemod.h:317
static MsgConfigureChannelizer * create(int sampleRate, int centerFrequency)
Definition: ssbdemod.h:81
Real m_Bandwidth
Definition: ssbdemod.h:288
MessageQueue m_inputMessageQueue
Queue for asynchronous inbound communication.
Real m_LowCutoff
Definition: ssbdemod.h:289
QMutex m_settingsMutex
Definition: ssbdemod.h:333
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
void resize(int historySize, int stepLength, Real R)
Definition: agc.cpp:65
void create_filter(float f1, float f2)
Definition: fftfilt.cpp:107
fftfilt * DSBFilter
Definition: ssbdemod.h:320
#define agcTarget
Definition: freedvdemod.h:40
int m_agcNbSamples
number of audio (48 kHz) samples for AGC averaging
Definition: ssbdemod.h:309
int m_inputSampleRate
Definition: ssbdemod.h:294
MagAGC m_agc
Definition: ssbdemod.h:306
SSBDemodSettings m_settings
Definition: ssbdemod.h:286
qint32 m_inputFrequencyOffset
bool setSize(uint32_t numSamples)
Definition: audiofifo.cpp:59
AudioFifo m_audioFifo
Definition: ssbdemod.h:327
void setStepDownDelay(int stepDownDelay)
Definition: agc.h:50
void setGate(int gate)
Definition: agc.h:49
quint32 m_audioSampleRate
Definition: ssbdemod.h:328
Real m_interpolatorDistanceRemain
Definition: ssbdemod.h:318
float Real
Definition: dsptypes.h:42
void create_dsb_filter(float f2)
Definition: fftfilt.cpp:148
Interpolator m_interpolator
Definition: ssbdemod.h:316
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ applyChannelSettings()

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

Definition at line 385 of file ssbdemod.cpp.

References Interpolator::create(), m_audioSampleRate, m_Bandwidth, m_inputFrequencyOffset, m_inputSampleRate, m_interpolator, m_interpolatorDistance, m_interpolatorDistanceRemain, m_nco, m_settingsMutex, and NCOF::setFreq().

Referenced by handleMessage(), SSBDemod(), and start().

386 {
387  qDebug() << "SSBDemod::applyChannelSettings:"
388  << " inputSampleRate: " << inputSampleRate
389  << " inputFrequencyOffset: " << inputFrequencyOffset;
390 
391  if ((m_inputFrequencyOffset != inputFrequencyOffset) ||
392  (m_inputSampleRate != inputSampleRate) || force)
393  {
394  m_nco.setFreq(-inputFrequencyOffset, inputSampleRate);
395  }
396 
397  if ((m_inputSampleRate != inputSampleRate) || force)
398  {
399  m_settingsMutex.lock();
400  Real interpolatorBandwidth = (m_Bandwidth * 1.5f) > inputSampleRate ? inputSampleRate : (m_Bandwidth * 1.5f);
401  m_interpolator.create(16, inputSampleRate, interpolatorBandwidth, 2.0f);
403  m_interpolatorDistance = (Real) inputSampleRate / (Real) m_audioSampleRate;
404  m_settingsMutex.unlock();
405  }
406 
407  m_inputSampleRate = inputSampleRate;
408  m_inputFrequencyOffset = inputFrequencyOffset;
409 }
void create(int phaseSteps, double sampleRate, double cutoff, double nbTapsPerPhase=4.5)
Real m_interpolatorDistance
Definition: ssbdemod.h:317
NCOF m_nco
Definition: ssbdemod.h:315
Real m_Bandwidth
Definition: ssbdemod.h:288
QMutex m_settingsMutex
Definition: ssbdemod.h:333
int m_inputFrequencyOffset
Definition: ssbdemod.h:295
int m_inputSampleRate
Definition: ssbdemod.h:294
void setFreq(Real freq, Real sampleRate)
Definition: ncof.cpp:51
quint32 m_audioSampleRate
Definition: ssbdemod.h:328
Real m_interpolatorDistanceRemain
Definition: ssbdemod.h:318
float Real
Definition: dsptypes.h:42
Interpolator m_interpolator
Definition: ssbdemod.h:316
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ applySettings()

void SSBDemod::applySettings ( const SSBDemodSettings settings,
bool  force = false 
)
private

Definition at line 458 of file ssbdemod.cpp.

References AudioDeviceManager::addAudioSink(), agcTarget, applyAudioSampleRate(), Interpolator::create(), fftfilt::create_dsb_filter(), fftfilt::create_filter(), DSBFilter, DSPEngine::getAudioDeviceManager(), BasebandSampleSink::getInputMessageQueue(), AudioDeviceManager::getOutputDeviceIndex(), AudioDeviceManager::getOutputSampleRate(), DSPEngine::instance(), SSBDemodSettings::m_agc, m_agc, m_agcActive, SSBDemodSettings::m_agcClamping, m_agcClamping, m_agcNbSamples, SSBDemodSettings::m_agcPowerThreshold, m_agcPowerThreshold, SSBDemodSettings::m_agcThresholdGate, m_agcThresholdGate, SSBDemodSettings::m_agcTimeLog2, m_audioBinaual, SSBDemodSettings::m_audioBinaural, SSBDemodSettings::m_audioDeviceName, m_audioFifo, SSBDemodSettings::m_audioFlipChannels, m_audioFlipChannels, SSBDemodSettings::m_audioMute, m_audioMute, m_audioSampleRate, m_Bandwidth, SSBDemodSettings::m_dsb, m_dsb, SSBDemodSettings::m_inputFrequencyOffset, m_inputSampleRate, m_interpolator, m_interpolatorDistance, m_interpolatorDistanceRemain, SSBDemodSettings::m_lowCutoff, m_LowCutoff, SSBDemodSettings::m_minPowerThresholdDB, SSBDemodSettings::m_reverseAPIAddress, SSBDemodSettings::m_reverseAPIChannelIndex, SSBDemodSettings::m_reverseAPIDeviceIndex, SSBDemodSettings::m_reverseAPIPort, SSBDemodSettings::m_rfBandwidth, m_settings, m_settingsMutex, SSBDemodSettings::m_spanLog2, m_spanLog2, m_usb, SSBDemodSettings::m_useReverseAPI, SSBDemodSettings::m_volume, m_volume, CalcDb::powerFromdB(), MagAGC::resize(), SDR_RX_SCALED, MagAGC::setClamping(), MagAGC::setGate(), MagAGC::setStepDownDelay(), MagAGC::setThreshold(), MagAGC::setThresholdEnable(), SSBFilter, and webapiReverseSendSettings().

Referenced by handleMessage(), and SSBDemod().

459 {
460  qDebug() << "SSBDemod::applySettings:"
461  << " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
462  << " m_rfBandwidth: " << settings.m_rfBandwidth
463  << " m_lowCutoff: " << settings.m_lowCutoff
464  << " m_volume: " << settings.m_volume
465  << " m_spanLog2: " << settings.m_spanLog2
466  << " m_audioBinaual: " << settings.m_audioBinaural
467  << " m_audioFlipChannels: " << settings.m_audioFlipChannels
468  << " m_dsb: " << settings.m_dsb
469  << " m_audioMute: " << settings.m_audioMute
470  << " m_agcActive: " << settings.m_agc
471  << " m_agcClamping: " << settings.m_agcClamping
472  << " m_agcTimeLog2: " << settings.m_agcTimeLog2
473  << " agcPowerThreshold: " << settings.m_agcPowerThreshold
474  << " agcThresholdGate: " << settings.m_agcThresholdGate
475  << " m_audioDeviceName: " << settings.m_audioDeviceName
476  << " m_useReverseAPI: " << settings.m_useReverseAPI
477  << " m_reverseAPIAddress: " << settings.m_reverseAPIAddress
478  << " m_reverseAPIPort: " << settings.m_reverseAPIPort
479  << " m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex
480  << " m_reverseAPIChannelIndex: " << settings.m_reverseAPIChannelIndex
481  << " force: " << force;
482 
483  QList<QString> reverseAPIKeys;
484 
485  if((m_settings.m_inputFrequencyOffset != settings.m_inputFrequencyOffset) || force) {
486  reverseAPIKeys.append("inputFrequencyOffset");
487  }
488  if((m_settings.m_rfBandwidth != settings.m_rfBandwidth) || force) {
489  reverseAPIKeys.append("rfBandwidth");
490  }
491  if((m_settings.m_lowCutoff != settings.m_lowCutoff) || force) {
492  reverseAPIKeys.append("lowCutoff");
493  }
494 
495  if((m_settings.m_rfBandwidth != settings.m_rfBandwidth) ||
496  (m_settings.m_lowCutoff != settings.m_lowCutoff) || force)
497  {
498  float band, lowCutoff;
499 
500  band = settings.m_rfBandwidth;
501  lowCutoff = settings.m_lowCutoff;
502 
503  if (band < 0) {
504  band = -band;
505  lowCutoff = -lowCutoff;
506  m_usb = false;
507  } else {
508  m_usb = true;
509  }
510 
511  if (band < 100.0f)
512  {
513  band = 100.0f;
514  lowCutoff = 0;
515  }
516 
517  m_Bandwidth = band;
518  m_LowCutoff = lowCutoff;
519 
520  m_settingsMutex.lock();
521  Real interpolatorBandwidth = (m_Bandwidth * 1.5f) > m_inputSampleRate ? m_inputSampleRate : (m_Bandwidth * 1.5f);
522  m_interpolator.create(16, m_inputSampleRate, interpolatorBandwidth, 2.0f);
525  SSBFilter->create_filter(m_LowCutoff / (float) m_audioSampleRate, m_Bandwidth / (float) m_audioSampleRate);
526  DSBFilter->create_dsb_filter((2.0f * m_Bandwidth) / (float) m_audioSampleRate);
527  m_settingsMutex.unlock();
528  }
529 
530  if ((m_settings.m_volume != settings.m_volume) || force)
531  {
532  reverseAPIKeys.append("volume");
533  m_volume = settings.m_volume;
534  m_volume /= 4.0; // for 3276.8
535  }
536 
537  if ((m_settings.m_agcTimeLog2 != settings.m_agcTimeLog2) || force) {
538  reverseAPIKeys.append("agcTimeLog2");
539  }
540  if ((m_settings.m_agcPowerThreshold != settings.m_agcPowerThreshold) || force) {
541  reverseAPIKeys.append("agcPowerThreshold");
542  }
543  if ((m_settings.m_agcThresholdGate != settings.m_agcThresholdGate) || force) {
544  reverseAPIKeys.append("agcThresholdGate");
545  }
546  if ((m_settings.m_agcClamping != settings.m_agcClamping) || force) {
547  reverseAPIKeys.append("agcClamping");
548  }
549 
550  if ((m_settings.m_agcTimeLog2 != settings.m_agcTimeLog2) ||
553  (m_settings.m_agcClamping != settings.m_agcClamping) || force)
554  {
555  int agcNbSamples = (m_audioSampleRate / 1000) * (1<<settings.m_agcTimeLog2);
557  double agcPowerThreshold = CalcDb::powerFromdB(settings.m_agcPowerThreshold) * (SDR_RX_SCALED*SDR_RX_SCALED);
558  int agcThresholdGate = (m_audioSampleRate / 1000) * settings.m_agcThresholdGate; // ms
559  bool agcClamping = settings.m_agcClamping;
560 
561  if (m_agcNbSamples != agcNbSamples)
562  {
563  m_settingsMutex.lock();
564  m_agc.resize(agcNbSamples, agcNbSamples/2, agcTarget);
565  m_agc.setStepDownDelay(agcNbSamples);
566  m_agcNbSamples = agcNbSamples;
567  m_settingsMutex.unlock();
568  }
569 
570  if (m_agcPowerThreshold != agcPowerThreshold)
571  {
572  m_agc.setThreshold(agcPowerThreshold);
573  m_agcPowerThreshold = agcPowerThreshold;
574  }
575 
576  if (m_agcThresholdGate != agcThresholdGate)
577  {
578  m_agc.setGate(agcThresholdGate);
579  m_agcThresholdGate = agcThresholdGate;
580  }
581 
582  if (m_agcClamping != agcClamping)
583  {
584  m_agc.setClamping(agcClamping);
585  m_agcClamping = agcClamping;
586  }
587 
588  qDebug() << "SBDemod::applySettings: AGC:"
589  << " agcNbSamples: " << agcNbSamples
590  << " agcPowerThreshold: " << agcPowerThreshold
591  << " agcThresholdGate: " << agcThresholdGate
592  << " agcClamping: " << agcClamping;
593  }
594 
595  if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
596  {
597  reverseAPIKeys.append("audioDeviceName");
599  int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName);
600  audioDeviceManager->addAudioSink(&m_audioFifo, getInputMessageQueue(), audioDeviceIndex);
601  uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
602 
603  if (m_audioSampleRate != audioSampleRate) {
604  applyAudioSampleRate(audioSampleRate);
605  }
606  }
607 
608  if ((m_settings.m_spanLog2 != settings.m_spanLog2) || force) {
609  reverseAPIKeys.append("spanLog2");
610  }
611  if ((m_settings.m_audioBinaural != settings.m_audioBinaural) || force) {
612  reverseAPIKeys.append("audioBinaural");
613  }
614  if ((m_settings.m_audioFlipChannels != settings.m_audioFlipChannels) || force) {
615  reverseAPIKeys.append("audioFlipChannels");
616  }
617  if ((m_settings.m_dsb != settings.m_dsb) || force) {
618  reverseAPIKeys.append("dsb");
619  }
620  if ((m_settings.m_audioMute != settings.m_audioMute) || force) {
621  reverseAPIKeys.append("audioMute");
622  }
623  if ((m_settings.m_agc != settings.m_agc) || force) {
624  reverseAPIKeys.append("agc");
625  }
626 
627  m_spanLog2 = settings.m_spanLog2;
628  m_audioBinaual = settings.m_audioBinaural;
630  m_dsb = settings.m_dsb;
631  m_audioMute = settings.m_audioMute;
632  m_agcActive = settings.m_agc;
633 
634  if (settings.m_useReverseAPI)
635  {
636  bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
641  webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
642  }
643 
644  m_settings = settings;
645 }
void webapiReverseSendSettings(QList< QString > &channelSettingsKeys, const SSBDemodSettings &settings, bool force)
Definition: ssbdemod.cpp:848
void addAudioSink(AudioFifo *audioFifo, MessageQueue *sampleSinkMessageQueue, int outputDeviceIndex=-1)
Add the audio sink.
int getOutputSampleRate(int outputDeviceIndex=-1)
int m_agcThresholdGate
Gate length in number of samples befor threshold triggers.
Definition: ssbdemod.h:311
uint16_t m_reverseAPIPort
bool m_audioBinaual
Definition: ssbdemod.h:296
fftfilt * SSBFilter
Definition: ssbdemod.h:319
void setThresholdEnable(bool enable)
Definition: agc.cpp:83
bool m_dsb
Definition: ssbdemod.h:299
void create(int phaseSteps, double sampleRate, double cutoff, double nbTapsPerPhase=4.5)
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
Real m_interpolatorDistance
Definition: ssbdemod.h:317
int getOutputDeviceIndex(const QString &deviceName) const
Real m_Bandwidth
Definition: ssbdemod.h:288
static const int m_minPowerThresholdDB
Real m_LowCutoff
Definition: ssbdemod.h:289
unsigned int uint32_t
Definition: rtptypes_win.h:46
QMutex m_settingsMutex
Definition: ssbdemod.h:333
void applyAudioSampleRate(int sampleRate)
Definition: ssbdemod.cpp:411
void resize(int historySize, int stepLength, Real R)
Definition: agc.cpp:65
bool m_audioMute
Definition: ssbdemod.h:300
void create_filter(float f1, float f2)
Definition: fftfilt.cpp:107
static DSPEngine * instance()
Definition: dspengine.cpp:51
fftfilt * DSBFilter
Definition: ssbdemod.h:320
#define agcTarget
Definition: freedvdemod.h:40
bool m_agcClamping
Definition: ssbdemod.h:308
int m_agcNbSamples
number of audio (48 kHz) samples for AGC averaging
Definition: ssbdemod.h:309
int m_inputSampleRate
Definition: ssbdemod.h:294
bool m_usb
Definition: ssbdemod.h:298
int m_spanLog2
Definition: ssbdemod.h:291
uint16_t m_reverseAPIDeviceIndex
MagAGC m_agc
Definition: ssbdemod.h:306
SSBDemodSettings m_settings
Definition: ssbdemod.h:286
AudioDeviceManager * getAudioDeviceManager()
Definition: dspengine.h:55
uint16_t m_reverseAPIChannelIndex
qint32 m_inputFrequencyOffset
Real m_volume
Definition: ssbdemod.h:290
bool m_agcActive
Definition: ssbdemod.h:307
double m_agcPowerThreshold
AGC power threshold (linear)
Definition: ssbdemod.h:310
QString m_reverseAPIAddress
void setClamping(bool clamping)
Definition: agc.h:51
void setThreshold(double threshold)
Definition: agc.h:47
AudioFifo m_audioFifo
Definition: ssbdemod.h:327
void setStepDownDelay(int stepDownDelay)
Definition: agc.h:50
bool m_audioFlipChannels
Definition: ssbdemod.h:297
void setGate(int gate)
Definition: agc.h:49
quint32 m_audioSampleRate
Definition: ssbdemod.h:328
Real m_interpolatorDistanceRemain
Definition: ssbdemod.h:318
#define SDR_RX_SCALED
Definition: dsptypes.h:34
float Real
Definition: dsptypes.h:42
static double powerFromdB(double powerdB)
Definition: db.cpp:36
void create_dsb_filter(float f2)
Definition: fftfilt.cpp:148
Interpolator m_interpolator
Definition: ssbdemod.h:316
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ configure()

void SSBDemod::configure ( MessageQueue messageQueue,
Real  Bandwidth,
Real  LowCutoff,
Real  volume,
int  spanLog2,
bool  audioBinaural,
bool  audioFlipChannels,
bool  dsb,
bool  audioMute,
bool  agc,
bool  agcClamping,
int  agcTimeLog2,
int  agcPowerThreshold,
int  agcThresholdGate 
)

Definition at line 125 of file ssbdemod.cpp.

References SSBDemod::MsgConfigureSSBDemodPrivate::create(), and MessageQueue::push().

Referenced by setSampleSink().

139 {
141  Bandwidth,
142  LowCutoff,
143  volume,
144  spanLog2,
145  audioBinaural,
146  audioFlipChannel,
147  dsb,
148  audioMute,
149  agc,
150  agcClamping,
151  agcTimeLog2,
152  agcPowerThreshold,
153  agcThresholdGate);
154  messageQueue->push(cmd);
155 }
static MsgConfigureSSBDemodPrivate * create(Real Bandwidth, Real LowCutoff, Real volume, int spanLog2, bool audioBinaural, bool audioFlipChannels, bool dsb, bool audioMute, bool agc, bool agcClamping, int agcTimeLog2, int agcPowerThreshold, int agcThresholdGate)
Definition: ssbdemod.h:208
void push(Message *message, bool emitSignal=true)
Push message onto queue.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ deserialize()

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

Implements ChannelAPI.

Definition at line 652 of file ssbdemod.cpp.

References SSBDemod::MsgConfigureSSBDemod::create(), SSBDemodSettings::deserialize(), BasebandSampleSink::m_inputMessageQueue, m_settings, MessageQueue::push(), and SSBDemodSettings::resetToDefaults().

Referenced by getCenterFrequency().

653 {
654  if (m_settings.deserialize(data))
655  {
656  MsgConfigureSSBDemod *msg = MsgConfigureSSBDemod::create(m_settings, true);
658  return true;
659  }
660  else
661  {
663  MsgConfigureSSBDemod *msg = MsgConfigureSSBDemod::create(m_settings, true);
665  return false;
666  }
667 }
void push(Message *message, bool emitSignal=true)
Push message onto queue.
MessageQueue m_inputMessageQueue
Queue for asynchronous inbound communication.
bool deserialize(const QByteArray &data)
SSBDemodSettings m_settings
Definition: ssbdemod.h:286
static MsgConfigureSSBDemod * create(const SSBDemodSettings &settings, bool force)
Definition: ssbdemod.h:58
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ destroy()

virtual void SSBDemod::destroy ( )
inlinevirtual

Implements ChannelAPI.

Definition at line 99 of file ssbdemod.h.

99 { delete this; }

◆ feed()

void SSBDemod::feed ( const SampleVector::const_iterator &  begin,
const SampleVector::const_iterator &  end,
bool  positiveOnly 
)
virtual

Implements BasebandSampleSink.

Definition at line 157 of file ssbdemod.cpp.

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

Referenced by setSampleSink().

158 {
159  (void) positiveOnly;
160  Complex ci;
161  m_settingsMutex.lock();
162 
163  for(SampleVector::const_iterator it = begin; it < end; ++it)
164  {
165  Complex c(it->real(), it->imag());
166  c *= m_nco.nextIQ();
167 
168  if (m_interpolatorDistance < 1.0f) // interpolate
169  {
171  {
172  processOneSample(ci);
174  }
175  }
176  else
177  {
179  {
180  processOneSample(ci);
182  }
183  }
184  }
185 
186  m_settingsMutex.unlock();
187 }
bool decimate(Real *distance, const Complex &next, Complex *result)
Definition: interpolator.h:38
bool interpolate(Real *distance, const Complex &next, Complex *result)
Definition: interpolator.h:53
Real m_interpolatorDistance
Definition: ssbdemod.h:317
NCOF m_nco
Definition: ssbdemod.h:315
Complex nextIQ()
Return next complex sample.
Definition: ncof.cpp:63
QMutex m_settingsMutex
Definition: ssbdemod.h:333
void processOneSample(Complex &ci)
Definition: ssbdemod.cpp:189
std::complex< Real > Complex
Definition: dsptypes.h:43
Real m_interpolatorDistanceRemain
Definition: ssbdemod.h:318
Interpolator m_interpolator
Definition: ssbdemod.h:316
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getAudioActive()

bool SSBDemod::getAudioActive ( ) const
inline

Definition at line 142 of file ssbdemod.h.

References m_audioActive.

Referenced by SSBDemodGUI::tick().

142 { return m_audioActive; }
bool m_audioActive
True if an audio signal is produced (no AGC or AGC and above threshold)
Definition: ssbdemod.h:313
+ Here is the caller graph for this function:

◆ getAudioSampleRate()

uint32_t SSBDemod::getAudioSampleRate ( ) const
inline

Definition at line 139 of file ssbdemod.h.

References m_audioSampleRate.

Referenced by SSBDemodGUI::applyBandwidths(), SSBDemodGUI::applySettings(), SSBDemodGUI::handleMessage(), and SSBDemodGUI::spanLog2Limit().

139 { return m_audioSampleRate; }
quint32 m_audioSampleRate
Definition: ssbdemod.h:328
+ Here is the caller graph for this function:

◆ getCenterFrequency()

virtual qint64 SSBDemod::getCenterFrequency ( ) const
inlinevirtual

Applies to a default stream.

Implements ChannelAPI.

Definition at line 124 of file ssbdemod.h.

References deserialize(), SSBDemodSettings::m_inputFrequencyOffset, SSBDemod::MsgConfigureSSBDemod::m_settings, and serialize().

SSBDemodSettings m_settings
Definition: ssbdemod.h:286
qint32 m_inputFrequencyOffset
+ Here is the call graph for this function:

◆ getIdentifier()

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

Implements ChannelAPI.

Definition at line 122 of file ssbdemod.h.

122 { id = objectName(); }

◆ getInputSampleRate()

uint32_t SSBDemod::getInputSampleRate ( ) const
inline

Definition at line 140 of file ssbdemod.h.

References m_inputSampleRate.

Referenced by SSBDemodGUI::applyBandwidths(), and SSBDemodGUI::spanLog2Limit().

140 { return m_inputSampleRate; }
int m_inputSampleRate
Definition: ssbdemod.h:294
+ Here is the caller graph for this function:

◆ getMagSq()

double SSBDemod::getMagSq ( ) const
inline

Definition at line 141 of file ssbdemod.h.

References m_magsq.

141 { return m_magsq; }
double m_magsq
Definition: ssbdemod.h:301

◆ getMagSqLevels()

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

Definition at line 144 of file ssbdemod.h.

References SSBDemod::MagSqLevelsStore::m_magsq, m_magsq, m_magsqCount, m_magSqLevelStore, SSBDemod::MagSqLevelsStore::m_magsqPeak, m_magsqPeak, m_magsqSum, webapiReportGet(), webapiSettingsGet(), and webapiSettingsPutPatch().

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

145  {
146  if (m_magsqCount > 0)
147  {
151  }
152 
155  nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount;
156 
157  m_magsqSum = 0.0f;
158  m_magsqPeak = 0.0f;
159  m_magsqCount = 0;
160  }
double m_magsqPeak
Definition: ssbdemod.h:303
double m_magsq
Definition: ssbdemod.h:301
int m_magsqCount
Definition: ssbdemod.h:304
double m_magsqSum
Definition: ssbdemod.h:302
MagSqLevelsStore m_magSqLevelStore
Definition: ssbdemod.h:305
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getNbSinkStreams()

virtual int SSBDemod::getNbSinkStreams ( ) const
inlinevirtual

Implements ChannelAPI.

Definition at line 129 of file ssbdemod.h.

129 { return 1; }

◆ getNbSourceStreams()

virtual int SSBDemod::getNbSourceStreams ( ) const
inlinevirtual

Implements ChannelAPI.

Definition at line 130 of file ssbdemod.h.

130 { return 0; }

◆ getStreamCenterFrequency()

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

Implements ChannelAPI.

Definition at line 132 of file ssbdemod.h.

References SSBDemodSettings::m_inputFrequencyOffset, and SSBDemod::MsgConfigureSSBDemod::m_settings.

133  {
134  (void) streamIndex;
135  (void) sinkElseSource;
137  }
SSBDemodSettings m_settings
Definition: ssbdemod.h:286
qint32 m_inputFrequencyOffset

◆ getTitle()

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

Implements ChannelAPI.

Definition at line 123 of file ssbdemod.h.

References SSBDemod::MsgConfigureSSBDemod::m_settings, and SSBDemodSettings::m_title.

123 { title = m_settings.m_title; }
SSBDemodSettings m_settings
Definition: ssbdemod.h:286

◆ handleMessage()

bool SSBDemod::handleMessage ( const Message cmd)
virtual

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

Implements BasebandSampleSink.

Definition at line 315 of file ssbdemod.cpp.

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

Referenced by setSampleSink().

316 {
318  {
320  qDebug("SSBDemod::handleMessage: MsgChannelizerNotification: m_sampleRate");
321 
323 
324  return true;
325  }
326  else if (MsgConfigureChannelizer::match(cmd))
327  {
328  MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
329  qDebug() << "SSBDemod::handleMessage: MsgConfigureChannelizer: sampleRate: " << cfg.getSampleRate()
330  << " centerFrequency: " << cfg.getCenterFrequency();
331 
333  cfg.getSampleRate(),
334  cfg.getCenterFrequency());
335 
336  return true;
337  }
338  else if (MsgConfigureSSBDemod::match(cmd))
339  {
340  MsgConfigureSSBDemod& cfg = (MsgConfigureSSBDemod&) cmd;
341  qDebug("SSBDemod::handleMessage: MsgConfigureSSBDemod");
342 
343  applySettings(cfg.getSettings(), cfg.getForce());
344 
345  return true;
346  }
348  {
350  const QThread *thread = cfg.getThread();
351  qDebug("SSBDemod::handleMessage: BasebandSampleSink::MsgThreadedSink: %p", thread);
352  return true;
353  }
354  else if (DSPConfigureAudio::match(cmd))
355  {
356  DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
357  uint32_t sampleRate = cfg.getSampleRate();
358 
359  qDebug() << "SSBDemod::handleMessage: DSPConfigureAudio:"
360  << " sampleRate: " << sampleRate;
361 
362  if (sampleRate != m_audioSampleRate) {
363  applyAudioSampleRate(sampleRate);
364  }
365 
366  return true;
367  }
368  else if (DSPSignalNotification::match(cmd))
369  {
370  return true;
371  }
372  else
373  {
374  if(m_sampleSink != 0)
375  {
376  return m_sampleSink->handleMessage(cmd);
377  }
378  else
379  {
380  return false;
381  }
382  }
383 }
void configure(MessageQueue *messageQueue, int sampleRate, int centerFrequency)
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force=false)
Definition: ssbdemod.cpp:385
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
unsigned int uint32_t
Definition: rtptypes_win.h:46
BasebandSampleSink * m_sampleSink
Definition: ssbdemod.h:322
void applyAudioSampleRate(int sampleRate)
Definition: ssbdemod.cpp:411
virtual bool handleMessage(const Message &cmd)=0
Processing of a message. Returns true if message has actually been processed.
int getSampleRate() const
Definition: dspcommands.h:390
static bool match(const Message *message)
Definition: message.cpp:45
DownChannelizer * m_channelizer
Definition: ssbdemod.h:285
void applySettings(const SSBDemodSettings &settings, bool force=false)
Definition: ssbdemod.cpp:458
quint32 m_audioSampleRate
Definition: ssbdemod.h:328
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ networkManagerFinished

void SSBDemod::networkManagerFinished ( QNetworkReply *  reply)
privateslot

Definition at line 931 of file ssbdemod.cpp.

Referenced by SSBDemod(), and ~SSBDemod().

932 {
933  QNetworkReply::NetworkError replyError = reply->error();
934 
935  if (replyError)
936  {
937  qWarning() << "SSBDemod::networkManagerFinished:"
938  << " error(" << (int) replyError
939  << "): " << replyError
940  << ": " << reply->errorString();
941  return;
942  }
943 
944  QString answer = reply->readAll();
945  answer.chop(1); // remove last \n
946  qDebug("SSBDemod::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
947 }
+ Here is the caller graph for this function:

◆ processOneSample()

void SSBDemod::processOneSample ( Complex ci)
private

Definition at line 189 of file ssbdemod.cpp.

References DSBFilter, BasebandSampleSink::feed(), MagAGC::feedAndGetValue(), MagAGC::getStepDownDelay(), MagAGC::getStepValue(), i, m_agc, m_agcActive, m_audioActive, m_audioBinaual, m_audioBuffer, m_audioBufferFill, m_audioFifo, m_audioFlipChannels, m_audioMute, m_dsb, m_magsq, m_magsqCount, m_magsqPeak, m_magsqSum, m_sampleBuffer, m_sampleSink, m_spanLog2, m_squelchDelayLine, m_sum, m_undersampleCount, m_usb, m_volume, DoubleBufferFIFO< T >::readBack(), fftfilt::runDSB(), fftfilt::runSSB(), SDR_RX_SCALED, SSBFilter, AudioFifo::write(), and DoubleBufferFIFO< T >::write().

Referenced by feed().

190 {
191  fftfilt::cmplx *sideband;
192  int n_out = 0;
193  int decim = 1<<(m_spanLog2 - 1);
194  unsigned char decim_mask = decim - 1; // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1)
195 
196  if (m_dsb) {
197  n_out = DSBFilter->runDSB(ci, &sideband);
198  } else {
199  n_out = SSBFilter->runSSB(ci, &sideband, m_usb);
200  }
201 
202  for (int i = 0; i < n_out; i++)
203  {
204  // Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display
205  // smart decimation with bit gain using float arithmetic (23 bits significand)
206 
207  m_sum += sideband[i];
208 
209  if (!(m_undersampleCount++ & decim_mask))
210  {
211  Real avgr = m_sum.real() / decim;
212  Real avgi = m_sum.imag() / decim;
213  m_magsq = (avgr * avgr + avgi * avgi) / (SDR_RX_SCALED*SDR_RX_SCALED);
214 
215  m_magsqSum += m_magsq;
216 
217  if (m_magsq > m_magsqPeak)
218  {
220  }
221 
222  m_magsqCount++;
223 
224  if (!m_dsb & !m_usb)
225  { // invert spectrum for LSB
226  m_sampleBuffer.push_back(Sample(avgi, avgr));
227  }
228  else
229  {
230  m_sampleBuffer.push_back(Sample(avgr, avgi));
231  }
232 
233  m_sum.real(0.0);
234  m_sum.imag(0.0);
235  }
236 
237  float agcVal = m_agcActive ? m_agc.feedAndGetValue(sideband[i]) : 0.1;
239  m_audioActive = delayedSample.real() != 0.0;
240  m_squelchDelayLine.write(sideband[i]*agcVal);
241 
242  if (m_audioMute)
243  {
246  }
247  else
248  {
249  fftfilt::cmplx z = m_agcActive ? delayedSample * m_agc.getStepValue() : delayedSample;
250 
251  if (m_audioBinaual)
252  {
254  {
255  m_audioBuffer[m_audioBufferFill].r = (qint16)(z.imag() * m_volume);
256  m_audioBuffer[m_audioBufferFill].l = (qint16)(z.real() * m_volume);
257  }
258  else
259  {
260  m_audioBuffer[m_audioBufferFill].r = (qint16)(z.real() * m_volume);
261  m_audioBuffer[m_audioBufferFill].l = (qint16)(z.imag() * m_volume);
262  }
263  }
264  else
265  {
266  Real demod = (z.real() + z.imag()) * 0.7;
267  qint16 sample = (qint16)(demod * m_volume);
268  m_audioBuffer[m_audioBufferFill].l = sample;
269  m_audioBuffer[m_audioBufferFill].r = sample;
270  }
271  }
272 
274 
275  if (m_audioBufferFill >= m_audioBuffer.size())
276  {
277  uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill);
278 
279  if (res != m_audioBufferFill)
280  {
281  qDebug("SSBDemod::feed: %u/%u samples written", res, m_audioBufferFill);
282  }
283 
284  m_audioBufferFill = 0;
285  }
286  }
287 
288  uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill);
289 
290  if (res != m_audioBufferFill)
291  {
292  qDebug("SSBDemod::feed: %u/%u tail samples written", res, m_audioBufferFill);
293  }
294 
295  m_audioBufferFill = 0;
296 
297  if (m_sampleSink != 0)
298  {
300  }
301 
302  m_sampleBuffer.clear();
303 
304 }
bool m_audioBinaual
Definition: ssbdemod.h:296
fftfilt * SSBFilter
Definition: ssbdemod.h:319
bool m_dsb
Definition: ssbdemod.h:299
double m_magsqPeak
Definition: ssbdemod.h:303
double m_magsq
Definition: ssbdemod.h:301
int m_magsqCount
Definition: ssbdemod.h:304
virtual void feed(const SampleVector::const_iterator &begin, const SampleVector::const_iterator &end, bool positiveOnly)=0
double feedAndGetValue(const Complex &ci)
Definition: agc.cpp:108
std::complex< float > cmplx
Definition: fftfilt.h:21
void write(const T &element)
BasebandSampleSink * m_sampleSink
Definition: ssbdemod.h:322
bool m_audioMute
Definition: ssbdemod.h:300
fftfilt * DSBFilter
Definition: ssbdemod.h:320
fftfilt::cmplx m_sum
Definition: ssbdemod.h:292
int32_t i
Definition: decimators.h:244
int m_undersampleCount
Definition: ssbdemod.h:293
double m_magsqSum
Definition: ssbdemod.h:302
bool m_audioActive
True if an audio signal is produced (no AGC or AGC and above threshold)
Definition: ssbdemod.h:313
bool m_usb
Definition: ssbdemod.h:298
DoubleBufferFIFO< fftfilt::cmplx > m_squelchDelayLine
Definition: ssbdemod.h:312
int m_spanLog2
Definition: ssbdemod.h:291
MagAGC m_agc
Definition: ssbdemod.h:306
AudioVector m_audioBuffer
Definition: ssbdemod.h:325
int getStepDownDelay() const
Definition: agc.h:53
T & readBack(int delay)
Real m_volume
Definition: ssbdemod.h:290
bool m_agcActive
Definition: ssbdemod.h:307
int runSSB(const cmplx &in, cmplx **out, bool usb, bool getDC=true)
Definition: fftfilt.cpp:284
SampleVector m_sampleBuffer
Definition: ssbdemod.h:323
AudioFifo m_audioFifo
Definition: ssbdemod.h:327
bool m_audioFlipChannels
Definition: ssbdemod.h:297
float getStepValue() const
Definition: agc.cpp:199
uint m_audioBufferFill
Definition: ssbdemod.h:326
#define SDR_RX_SCALED
Definition: dsptypes.h:34
int runDSB(const cmplx &in, cmplx **out, bool getDC=true)
Definition: fftfilt.cpp:327
float Real
Definition: dsptypes.h:42
uint32_t write(const quint8 *data, uint32_t numSamples)
Definition: audiofifo.cpp:66
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ serialize()

QByteArray SSBDemod::serialize ( ) const
virtual

Implements ChannelAPI.

Definition at line 647 of file ssbdemod.cpp.

References m_settings, and SSBDemodSettings::serialize().

Referenced by getCenterFrequency().

648 {
649  return m_settings.serialize();
650 }
QByteArray serialize() const
SSBDemodSettings m_settings
Definition: ssbdemod.h:286
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setSampleSink()

void SSBDemod::setSampleSink ( BasebandSampleSink sampleSink)
inline

Definition at line 100 of file ssbdemod.h.

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

Referenced by SSBDemodGUI::SSBDemodGUI().

100 { m_sampleSink = sampleSink; }
BasebandSampleSink * m_sampleSink
Definition: ssbdemod.h:322
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ start()

void SSBDemod::start ( )
virtual

Implements BasebandSampleSink.

Definition at line 306 of file ssbdemod.cpp.

References applyChannelSettings(), m_inputFrequencyOffset, and m_inputSampleRate.

Referenced by setSampleSink().

307 {
309 }
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force=false)
Definition: ssbdemod.cpp:385
int m_inputFrequencyOffset
Definition: ssbdemod.h:295
int m_inputSampleRate
Definition: ssbdemod.h:294
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ stop()

void SSBDemod::stop ( )
virtual

Implements BasebandSampleSink.

Definition at line 311 of file ssbdemod.cpp.

Referenced by setSampleSink().

312 {
313 }
+ Here is the caller graph for this function:

◆ webapiFormatChannelReport()

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

Definition at line 836 of file ssbdemod.cpp.

References CalcDb::dbPower(), getMagSqLevels(), SWGSDRangel::SWGChannelReport::getSsbDemodReport(), m_audioActive, m_audioSampleRate, m_inputSampleRate, SWGSDRangel::SWGSSBDemodReport::setAudioSampleRate(), SWGSDRangel::SWGSSBDemodReport::setChannelPowerDb(), SWGSDRangel::SWGSSBDemodReport::setChannelSampleRate(), and SWGSDRangel::SWGSSBDemodReport::setSquelch().

Referenced by webapiReportGet().

837 {
838  double magsqAvg, magsqPeak;
839  int nbMagsqSamples;
840  getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples);
841 
842  response.getSsbDemodReport()->setChannelPowerDb(CalcDb::dbPower(magsqAvg));
843  response.getSsbDemodReport()->setSquelch(m_audioActive ? 1 : 0);
846 }
SWGSSBDemodReport * getSsbDemodReport()
static double dbPower(double magsq, double floor=1e-12)
Definition: db.cpp:22
void setAudioSampleRate(qint32 audio_sample_rate)
void getMagSqLevels(double &avg, double &peak, int &nbSamples)
Definition: ssbdemod.h:144
bool m_audioActive
True if an audio signal is produced (no AGC or AGC and above threshold)
Definition: ssbdemod.h:313
void setChannelSampleRate(qint32 channel_sample_rate)
int m_inputSampleRate
Definition: ssbdemod.h:294
quint32 m_audioSampleRate
Definition: ssbdemod.h:328
void setChannelPowerDb(float channel_power_db)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiFormatChannelSettings()

void SSBDemod::webapiFormatChannelSettings ( SWGSDRangel::SWGChannelSettings response,
const SSBDemodSettings settings 
)
private

Definition at line 792 of file ssbdemod.cpp.

References SWGSDRangel::SWGSSBDemodSettings::getAudioDeviceName(), SWGSDRangel::SWGSSBDemodSettings::getReverseApiAddress(), SWGSDRangel::SWGChannelSettings::getSsbDemodSettings(), SWGSDRangel::SWGSSBDemodSettings::getTitle(), SSBDemodSettings::m_agc, SSBDemodSettings::m_agcClamping, SSBDemodSettings::m_agcPowerThreshold, SSBDemodSettings::m_agcThresholdGate, SSBDemodSettings::m_agcTimeLog2, SSBDemodSettings::m_audioBinaural, SSBDemodSettings::m_audioDeviceName, SSBDemodSettings::m_audioFlipChannels, SSBDemodSettings::m_audioMute, SSBDemodSettings::m_dsb, SSBDemodSettings::m_inputFrequencyOffset, SSBDemodSettings::m_lowCutoff, SSBDemodSettings::m_reverseAPIAddress, SSBDemodSettings::m_reverseAPIChannelIndex, SSBDemodSettings::m_reverseAPIDeviceIndex, SSBDemodSettings::m_reverseAPIPort, SSBDemodSettings::m_rfBandwidth, SSBDemodSettings::m_rgbColor, SSBDemodSettings::m_spanLog2, SSBDemodSettings::m_title, SSBDemodSettings::m_useReverseAPI, SSBDemodSettings::m_volume, SWGSDRangel::SWGSSBDemodSettings::setAgc(), SWGSDRangel::SWGSSBDemodSettings::setAgcClamping(), SWGSDRangel::SWGSSBDemodSettings::setAgcPowerThreshold(), SWGSDRangel::SWGSSBDemodSettings::setAgcThresholdGate(), SWGSDRangel::SWGSSBDemodSettings::setAgcTimeLog2(), SWGSDRangel::SWGSSBDemodSettings::setAudioBinaural(), SWGSDRangel::SWGSSBDemodSettings::setAudioDeviceName(), SWGSDRangel::SWGSSBDemodSettings::setAudioFlipChannels(), SWGSDRangel::SWGSSBDemodSettings::setAudioMute(), SWGSDRangel::SWGSSBDemodSettings::setDsb(), SWGSDRangel::SWGSSBDemodSettings::setInputFrequencyOffset(), SWGSDRangel::SWGSSBDemodSettings::setLowCutoff(), SWGSDRangel::SWGSSBDemodSettings::setReverseApiAddress(), SWGSDRangel::SWGSSBDemodSettings::setReverseApiChannelIndex(), SWGSDRangel::SWGSSBDemodSettings::setReverseApiDeviceIndex(), SWGSDRangel::SWGSSBDemodSettings::setReverseApiPort(), SWGSDRangel::SWGSSBDemodSettings::setRfBandwidth(), SWGSDRangel::SWGSSBDemodSettings::setRgbColor(), SWGSDRangel::SWGSSBDemodSettings::setSpanLog2(), SWGSDRangel::SWGSSBDemodSettings::setTitle(), SWGSDRangel::SWGSSBDemodSettings::setUseReverseApi(), and SWGSDRangel::SWGSSBDemodSettings::setVolume().

Referenced by webapiSettingsGet(), and webapiSettingsPutPatch().

793 {
794  response.getSsbDemodSettings()->setAudioMute(settings.m_audioMute ? 1 : 0);
796  response.getSsbDemodSettings()->setRfBandwidth(settings.m_rfBandwidth);
797  response.getSsbDemodSettings()->setLowCutoff(settings.m_lowCutoff);
798  response.getSsbDemodSettings()->setVolume(settings.m_volume);
799  response.getSsbDemodSettings()->setSpanLog2(settings.m_spanLog2);
800  response.getSsbDemodSettings()->setAudioBinaural(settings.m_audioBinaural ? 1 : 0);
801  response.getSsbDemodSettings()->setAudioFlipChannels(settings.m_audioFlipChannels ? 1 : 0);
802  response.getSsbDemodSettings()->setDsb(settings.m_dsb ? 1 : 0);
803  response.getSsbDemodSettings()->setAudioMute(settings.m_audioMute ? 1 : 0);
804  response.getSsbDemodSettings()->setAgc(settings.m_agc ? 1 : 0);
805  response.getSsbDemodSettings()->setAgcClamping(settings.m_agcClamping ? 1 : 0);
806  response.getSsbDemodSettings()->setAgcTimeLog2(settings.m_agcTimeLog2);
809  response.getSsbDemodSettings()->setRgbColor(settings.m_rgbColor);
810 
811  if (response.getSsbDemodSettings()->getTitle()) {
812  *response.getSsbDemodSettings()->getTitle() = settings.m_title;
813  } else {
814  response.getSsbDemodSettings()->setTitle(new QString(settings.m_title));
815  }
816 
817  if (response.getSsbDemodSettings()->getAudioDeviceName()) {
818  *response.getSsbDemodSettings()->getAudioDeviceName() = settings.m_audioDeviceName;
819  } else {
820  response.getSsbDemodSettings()->setAudioDeviceName(new QString(settings.m_audioDeviceName));
821  }
822 
823  response.getSsbDemodSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
824 
825  if (response.getSsbDemodSettings()->getReverseApiAddress()) {
827  } else {
828  response.getSsbDemodSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
829  }
830 
834 }
void setInputFrequencyOffset(qint64 input_frequency_offset)
uint16_t m_reverseAPIPort
void setAudioBinaural(qint32 audio_binaural)
void setReverseApiChannelIndex(qint32 reverse_api_channel_index)
void setAgcClamping(qint32 agc_clamping)
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
void setAudioDeviceName(QString *audio_device_name)
void setAgcThresholdGate(qint32 agc_threshold_gate)
void setAgcPowerThreshold(qint32 agc_power_threshold)
void setRfBandwidth(float rf_bandwidth)
uint16_t m_reverseAPIDeviceIndex
uint16_t m_reverseAPIChannelIndex
qint32 m_inputFrequencyOffset
SWGSSBDemodSettings * getSsbDemodSettings()
void setUseReverseApi(qint32 use_reverse_api)
void setAudioFlipChannels(qint32 audio_flip_channels)
QString m_reverseAPIAddress
void setAgcTimeLog2(qint32 agc_time_log2)
void setReverseApiAddress(QString *reverse_api_address)
void setReverseApiPort(qint32 reverse_api_port)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiReportGet()

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

Reimplemented from ChannelAPI.

Definition at line 781 of file ssbdemod.cpp.

References SWGSDRangel::SWGChannelReport::getSsbDemodReport(), SWGSDRangel::SWGSSBDemodReport::init(), SWGSDRangel::SWGChannelReport::setSsbDemodReport(), and webapiFormatChannelReport().

Referenced by getMagSqLevels().

784 {
785  (void) errorMessage;
787  response.getSsbDemodReport()->init();
788  webapiFormatChannelReport(response);
789  return 200;
790 }
SWGSSBDemodReport * getSsbDemodReport()
void setSsbDemodReport(SWGSSBDemodReport *ssb_demod_report)
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport &response)
Definition: ssbdemod.cpp:836
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiReverseSendSettings()

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

Definition at line 848 of file ssbdemod.cpp.

References SWGSDRangel::SWGChannelSettings::asJson(), ChannelAPI::getDeviceSetIndex(), ChannelAPI::getIndexInDeviceSet(), SWGSDRangel::SWGChannelSettings::getSsbDemodSettings(), SSBDemodSettings::m_agc, SSBDemodSettings::m_agcClamping, SSBDemodSettings::m_agcPowerThreshold, SSBDemodSettings::m_agcThresholdGate, SSBDemodSettings::m_agcTimeLog2, SSBDemodSettings::m_audioBinaural, SSBDemodSettings::m_audioDeviceName, SSBDemodSettings::m_audioFlipChannels, SSBDemodSettings::m_audioMute, SSBDemodSettings::m_dsb, SSBDemodSettings::m_inputFrequencyOffset, SSBDemodSettings::m_lowCutoff, m_networkManager, m_networkRequest, SSBDemodSettings::m_reverseAPIAddress, SSBDemodSettings::m_reverseAPIChannelIndex, SSBDemodSettings::m_reverseAPIDeviceIndex, SSBDemodSettings::m_reverseAPIPort, SSBDemodSettings::m_rfBandwidth, SSBDemodSettings::m_rgbColor, SSBDemodSettings::m_spanLog2, SSBDemodSettings::m_title, SSBDemodSettings::m_volume, SWGSDRangel::SWGSSBDemodSettings::setAgc(), SWGSDRangel::SWGSSBDemodSettings::setAgcClamping(), SWGSDRangel::SWGSSBDemodSettings::setAgcPowerThreshold(), SWGSDRangel::SWGSSBDemodSettings::setAgcThresholdGate(), SWGSDRangel::SWGSSBDemodSettings::setAgcTimeLog2(), SWGSDRangel::SWGSSBDemodSettings::setAudioBinaural(), SWGSDRangel::SWGSSBDemodSettings::setAudioDeviceName(), SWGSDRangel::SWGSSBDemodSettings::setAudioFlipChannels(), SWGSDRangel::SWGSSBDemodSettings::setAudioMute(), SWGSDRangel::SWGChannelSettings::setChannelType(), SWGSDRangel::SWGChannelSettings::setDirection(), SWGSDRangel::SWGSSBDemodSettings::setDsb(), SWGSDRangel::SWGSSBDemodSettings::setInputFrequencyOffset(), SWGSDRangel::SWGSSBDemodSettings::setLowCutoff(), SWGSDRangel::SWGChannelSettings::setOriginatorChannelIndex(), SWGSDRangel::SWGChannelSettings::setOriginatorDeviceSetIndex(), SWGSDRangel::SWGSSBDemodSettings::setRfBandwidth(), SWGSDRangel::SWGSSBDemodSettings::setRgbColor(), SWGSDRangel::SWGSSBDemodSettings::setSpanLog2(), SWGSDRangel::SWGChannelSettings::setSsbDemodSettings(), SWGSDRangel::SWGSSBDemodSettings::setTitle(), and SWGSDRangel::SWGSSBDemodSettings::setVolume().

Referenced by applySettings().

849 {
851  swgChannelSettings->setDirection(0); // single sink (Rx)
852  swgChannelSettings->setOriginatorChannelIndex(getIndexInDeviceSet());
853  swgChannelSettings->setOriginatorDeviceSetIndex(getDeviceSetIndex());
854  swgChannelSettings->setChannelType(new QString("SSBDemod"));
855  swgChannelSettings->setSsbDemodSettings(new SWGSDRangel::SWGSSBDemodSettings());
856  SWGSDRangel::SWGSSBDemodSettings *swgSSBDemodSettings = swgChannelSettings->getSsbDemodSettings();
857 
858  // transfer data that has been modified. When force is on transfer all data except reverse API data
859 
860  if (channelSettingsKeys.contains("inputFrequencyOffset") || force) {
861  swgSSBDemodSettings->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
862  }
863  if (channelSettingsKeys.contains("rfBandwidth") || force) {
864  swgSSBDemodSettings->setRfBandwidth(settings.m_rfBandwidth);
865  }
866  if (channelSettingsKeys.contains("lowCutoff") || force) {
867  swgSSBDemodSettings->setLowCutoff(settings.m_lowCutoff);
868  }
869  if (channelSettingsKeys.contains("volume") || force) {
870  swgSSBDemodSettings->setVolume(settings.m_volume);
871  }
872  if (channelSettingsKeys.contains("spanLog2") || force) {
873  swgSSBDemodSettings->setSpanLog2(settings.m_spanLog2);
874  }
875  if (channelSettingsKeys.contains("audioBinaural") || force) {
876  swgSSBDemodSettings->setAudioBinaural(settings.m_audioBinaural ? 1 : 0);
877  }
878  if (channelSettingsKeys.contains("audioFlipChannels") || force) {
879  swgSSBDemodSettings->setAudioFlipChannels(settings.m_audioFlipChannels ? 1 : 0);
880  }
881  if (channelSettingsKeys.contains("dsb") || force) {
882  swgSSBDemodSettings->setDsb(settings.m_dsb ? 1 : 0);
883  }
884  if (channelSettingsKeys.contains("audioMute") || force) {
885  swgSSBDemodSettings->setAudioMute(settings.m_audioMute ? 1 : 0);
886  }
887  if (channelSettingsKeys.contains("agc") || force) {
888  swgSSBDemodSettings->setAgc(settings.m_agc ? 1 : 0);
889  }
890  if (channelSettingsKeys.contains("agcClamping") || force) {
891  swgSSBDemodSettings->setAgcClamping(settings.m_agcClamping ? 1 : 0);
892  }
893  if (channelSettingsKeys.contains("agcTimeLog2") || force) {
894  swgSSBDemodSettings->setAgcTimeLog2(settings.m_agcTimeLog2);
895  }
896  if (channelSettingsKeys.contains("agcPowerThreshold") || force) {
897  swgSSBDemodSettings->setAgcPowerThreshold(settings.m_agcPowerThreshold);
898  }
899  if (channelSettingsKeys.contains("agcThresholdGate") || force) {
900  swgSSBDemodSettings->setAgcThresholdGate(settings.m_agcThresholdGate);
901  }
902  if (channelSettingsKeys.contains("rgbColor") || force) {
903  swgSSBDemodSettings->setRgbColor(settings.m_rgbColor);
904  }
905  if (channelSettingsKeys.contains("title") || force) {
906  swgSSBDemodSettings->setTitle(new QString(settings.m_title));
907  }
908  if (channelSettingsKeys.contains("audioDeviceName") || force) {
909  swgSSBDemodSettings->setAudioDeviceName(new QString(settings.m_audioDeviceName));
910  }
911 
912  QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
913  .arg(settings.m_reverseAPIAddress)
914  .arg(settings.m_reverseAPIPort)
915  .arg(settings.m_reverseAPIDeviceIndex)
916  .arg(settings.m_reverseAPIChannelIndex);
917  m_networkRequest.setUrl(QUrl(channelSettingsURL));
918  m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
919 
920  QBuffer *buffer=new QBuffer();
921  buffer->open((QBuffer::ReadWrite));
922  buffer->write(swgChannelSettings->asJson().toUtf8());
923  buffer->seek(0);
924 
925  // Always use PATCH to avoid passing reverse API settings
926  m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
927 
928  delete swgChannelSettings;
929 }
void setOriginatorChannelIndex(qint32 originator_channel_index)
void setSsbDemodSettings(SWGSSBDemodSettings *ssb_demod_settings)
void setInputFrequencyOffset(qint64 input_frequency_offset)
uint16_t m_reverseAPIPort
void setAudioBinaural(qint32 audio_binaural)
int getDeviceSetIndex() const
Definition: channelapi.h:89
void setAgcClamping(qint32 agc_clamping)
void setChannelType(QString *channel_type)
void setOriginatorDeviceSetIndex(qint32 originator_device_set_index)
void setAudioDeviceName(QString *audio_device_name)
void setAgcThresholdGate(qint32 agc_threshold_gate)
void setAgcPowerThreshold(qint32 agc_power_threshold)
void setRfBandwidth(float rf_bandwidth)
virtual QString asJson() override
uint16_t m_reverseAPIDeviceIndex
uint16_t m_reverseAPIChannelIndex
qint32 m_inputFrequencyOffset
SWGSSBDemodSettings * getSsbDemodSettings()
void setAudioFlipChannels(qint32 audio_flip_channels)
QString m_reverseAPIAddress
QNetworkAccessManager * m_networkManager
Definition: ssbdemod.h:330
void setAgcTimeLog2(qint32 agc_time_log2)
int getIndexInDeviceSet() const
Definition: channelapi.h:87
QNetworkRequest m_networkRequest
Definition: ssbdemod.h:331
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiSettingsGet()

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

Reimplemented from ChannelAPI.

Definition at line 669 of file ssbdemod.cpp.

References SWGSDRangel::SWGChannelSettings::getSsbDemodSettings(), SWGSDRangel::SWGSSBDemodSettings::init(), m_settings, SWGSDRangel::SWGChannelSettings::setSsbDemodSettings(), and webapiFormatChannelSettings().

Referenced by getMagSqLevels().

672 {
673  (void) errorMessage;
675  response.getSsbDemodSettings()->init();
677  return 200;
678 }
void setSsbDemodSettings(SWGSSBDemodSettings *ssb_demod_settings)
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings &response, const SSBDemodSettings &settings)
Definition: ssbdemod.cpp:792
SSBDemodSettings m_settings
Definition: ssbdemod.h:286
SWGSSBDemodSettings * getSsbDemodSettings()
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiSettingsPutPatch()

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

Reimplemented from ChannelAPI.

Definition at line 680 of file ssbdemod.cpp.

References SSBDemod::MsgConfigureSSBDemod::create(), SSBDemod::MsgConfigureChannelizer::create(), SWGSDRangel::SWGSSBDemodSettings::getAgc(), SWGSDRangel::SWGSSBDemodSettings::getAgcClamping(), SWGSDRangel::SWGSSBDemodSettings::getAgcPowerThreshold(), SWGSDRangel::SWGSSBDemodSettings::getAgcThresholdGate(), SWGSDRangel::SWGSSBDemodSettings::getAgcTimeLog2(), SWGSDRangel::SWGSSBDemodSettings::getAudioBinaural(), SWGSDRangel::SWGSSBDemodSettings::getAudioDeviceName(), SWGSDRangel::SWGSSBDemodSettings::getAudioFlipChannels(), SWGSDRangel::SWGSSBDemodSettings::getAudioMute(), SWGSDRangel::SWGSSBDemodSettings::getDsb(), SWGSDRangel::SWGSSBDemodSettings::getInputFrequencyOffset(), SWGSDRangel::SWGSSBDemodSettings::getLowCutoff(), SWGSDRangel::SWGSSBDemodSettings::getReverseApiAddress(), SWGSDRangel::SWGSSBDemodSettings::getReverseApiChannelIndex(), SWGSDRangel::SWGSSBDemodSettings::getReverseApiDeviceIndex(), SWGSDRangel::SWGSSBDemodSettings::getReverseApiPort(), SWGSDRangel::SWGSSBDemodSettings::getRfBandwidth(), SWGSDRangel::SWGSSBDemodSettings::getRgbColor(), SWGSDRangel::SWGSSBDemodSettings::getSpanLog2(), SWGSDRangel::SWGChannelSettings::getSsbDemodSettings(), SWGSDRangel::SWGSSBDemodSettings::getTitle(), SWGSDRangel::SWGSSBDemodSettings::getUseReverseApi(), SWGSDRangel::SWGSSBDemodSettings::getVolume(), SSBDemodSettings::m_agc, SSBDemodSettings::m_agcClamping, SSBDemodSettings::m_agcPowerThreshold, SSBDemodSettings::m_agcThresholdGate, SSBDemodSettings::m_agcTimeLog2, SSBDemodSettings::m_audioBinaural, SSBDemodSettings::m_audioDeviceName, SSBDemodSettings::m_audioFlipChannels, SSBDemodSettings::m_audioMute, m_audioSampleRate, SSBDemodSettings::m_dsb, BasebandSampleSink::m_guiMessageQueue, SSBDemodSettings::m_inputFrequencyOffset, BasebandSampleSink::m_inputMessageQueue, SSBDemodSettings::m_lowCutoff, SSBDemodSettings::m_reverseAPIAddress, SSBDemodSettings::m_reverseAPIChannelIndex, SSBDemodSettings::m_reverseAPIDeviceIndex, SSBDemodSettings::m_reverseAPIPort, SSBDemodSettings::m_rfBandwidth, SSBDemodSettings::m_rgbColor, m_settings, SSBDemodSettings::m_spanLog2, SSBDemodSettings::m_title, SSBDemodSettings::m_useReverseAPI, SSBDemodSettings::m_volume, MessageQueue::push(), and webapiFormatChannelSettings().

Referenced by getMagSqLevels().

685 {
686  (void) errorMessage;
687  SSBDemodSettings settings = m_settings;
688  bool frequencyOffsetChanged = false;
689 
690  if (channelSettingsKeys.contains("inputFrequencyOffset"))
691  {
693  frequencyOffsetChanged = true;
694  }
695  if (channelSettingsKeys.contains("rfBandwidth")) {
696  settings.m_rfBandwidth = response.getSsbDemodSettings()->getRfBandwidth();
697  }
698  if (channelSettingsKeys.contains("lowCutoff")) {
699  settings.m_lowCutoff = response.getSsbDemodSettings()->getLowCutoff();
700  }
701  if (channelSettingsKeys.contains("volume")) {
702  settings.m_volume = response.getSsbDemodSettings()->getVolume();
703  }
704  if (channelSettingsKeys.contains("spanLog2")) {
705  settings.m_spanLog2 = response.getSsbDemodSettings()->getSpanLog2();
706  }
707  if (channelSettingsKeys.contains("audioBinaural")) {
708  settings.m_audioBinaural = response.getSsbDemodSettings()->getAudioBinaural() != 0;
709  }
710  if (channelSettingsKeys.contains("audioFlipChannels")) {
711  settings.m_audioFlipChannels = response.getSsbDemodSettings()->getAudioFlipChannels() != 0;
712  }
713  if (channelSettingsKeys.contains("dsb")) {
714  settings.m_dsb = response.getSsbDemodSettings()->getDsb() != 0;
715  }
716  if (channelSettingsKeys.contains("audioMute")) {
717  settings.m_audioMute = response.getSsbDemodSettings()->getAudioMute() != 0;
718  }
719  if (channelSettingsKeys.contains("agc")) {
720  settings.m_agc = response.getSsbDemodSettings()->getAgc() != 0;
721  }
722  if (channelSettingsKeys.contains("agcClamping")) {
723  settings.m_agcClamping = response.getSsbDemodSettings()->getAgcClamping() != 0;
724  }
725  if (channelSettingsKeys.contains("agcTimeLog2")) {
726  settings.m_agcTimeLog2 = response.getSsbDemodSettings()->getAgcTimeLog2();
727  }
728  if (channelSettingsKeys.contains("agcPowerThreshold")) {
730  }
731  if (channelSettingsKeys.contains("agcThresholdGate")) {
733  }
734  if (channelSettingsKeys.contains("rgbColor")) {
735  settings.m_rgbColor = response.getSsbDemodSettings()->getRgbColor();
736  }
737  if (channelSettingsKeys.contains("title")) {
738  settings.m_title = *response.getSsbDemodSettings()->getTitle();
739  }
740  if (channelSettingsKeys.contains("audioDeviceName")) {
741  settings.m_audioDeviceName = *response.getSsbDemodSettings()->getAudioDeviceName();
742  }
743  if (channelSettingsKeys.contains("useReverseAPI")) {
744  settings.m_useReverseAPI = response.getSsbDemodSettings()->getUseReverseApi() != 0;
745  }
746  if (channelSettingsKeys.contains("reverseAPIAddress")) {
748  }
749  if (channelSettingsKeys.contains("reverseAPIPort")) {
750  settings.m_reverseAPIPort = response.getSsbDemodSettings()->getReverseApiPort();
751  }
752  if (channelSettingsKeys.contains("reverseAPIDeviceIndex")) {
754  }
755  if (channelSettingsKeys.contains("reverseAPIChannelIndex")) {
757  }
758 
759  if (frequencyOffsetChanged)
760  {
761  MsgConfigureChannelizer* channelConfigMsg = MsgConfigureChannelizer::create(
763  m_inputMessageQueue.push(channelConfigMsg);
764  }
765 
766  MsgConfigureSSBDemod *msg = MsgConfigureSSBDemod::create(settings, force);
768 
769  qDebug("SSBDemod::webapiSettingsPutPatch: forward to GUI: %p", m_guiMessageQueue);
770  if (m_guiMessageQueue) // forward to GUI if any
771  {
772  MsgConfigureSSBDemod *msgToGUI = MsgConfigureSSBDemod::create(settings, force);
773  m_guiMessageQueue->push(msgToGUI);
774  }
775 
776  webapiFormatChannelSettings(response, settings);
777 
778  return 200;
779 }
uint16_t m_reverseAPIPort
void push(Message *message, bool emitSignal=true)
Push message onto queue.
static MsgConfigureChannelizer * create(int sampleRate, int centerFrequency)
Definition: ssbdemod.h:81
MessageQueue m_inputMessageQueue
Queue for asynchronous inbound communication.
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings &response, const SSBDemodSettings &settings)
Definition: ssbdemod.cpp:792
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
uint16_t m_reverseAPIDeviceIndex
SSBDemodSettings m_settings
Definition: ssbdemod.h:286
uint16_t m_reverseAPIChannelIndex
qint32 m_inputFrequencyOffset
SWGSSBDemodSettings * getSsbDemodSettings()
QString m_reverseAPIAddress
quint32 m_audioSampleRate
Definition: ssbdemod.h:328
static MsgConfigureSSBDemod * create(const SSBDemodSettings &settings, bool force)
Definition: ssbdemod.h:58
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ DSBFilter

fftfilt* SSBDemod::DSBFilter
private

◆ m_agc

MagAGC SSBDemod::m_agc
private

◆ m_agcActive

bool SSBDemod::m_agcActive
private

Definition at line 307 of file ssbdemod.h.

Referenced by applySettings(), and processOneSample().

◆ m_agcClamping

bool SSBDemod::m_agcClamping
private

◆ m_agcNbSamples

int SSBDemod::m_agcNbSamples
private

number of audio (48 kHz) samples for AGC averaging

Definition at line 309 of file ssbdemod.h.

Referenced by applyAudioSampleRate(), and applySettings().

◆ m_agcPowerThreshold

double SSBDemod::m_agcPowerThreshold
private

AGC power threshold (linear)

Definition at line 310 of file ssbdemod.h.

Referenced by applySettings(), and SSBDemod::MsgConfigureSSBDemodPrivate::getAGCPowerThershold().

◆ m_agcThresholdGate

int SSBDemod::m_agcThresholdGate
private

Gate length in number of samples befor threshold triggers.

Definition at line 311 of file ssbdemod.h.

Referenced by applyAudioSampleRate(), applySettings(), and SSBDemod::MsgConfigureSSBDemodPrivate::getAGCThersholdGate().

◆ m_audioActive

bool SSBDemod::m_audioActive
private

True if an audio signal is produced (no AGC or AGC and above threshold)

Definition at line 313 of file ssbdemod.h.

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

◆ m_audioBinaual

bool SSBDemod::m_audioBinaual
private

Definition at line 296 of file ssbdemod.h.

Referenced by applySettings(), and processOneSample().

◆ m_audioBuffer

AudioVector SSBDemod::m_audioBuffer
private

Definition at line 325 of file ssbdemod.h.

Referenced by processOneSample(), and SSBDemod().

◆ m_audioBufferFill

uint SSBDemod::m_audioBufferFill
private

Definition at line 326 of file ssbdemod.h.

Referenced by processOneSample(), and SSBDemod().

◆ m_audioFifo

AudioFifo SSBDemod::m_audioFifo
private

◆ m_audioFlipChannels

bool SSBDemod::m_audioFlipChannels
private

◆ m_audioMute

bool SSBDemod::m_audioMute
private

◆ m_audioSampleRate

quint32 SSBDemod::m_audioSampleRate
private

◆ m_Bandwidth

Real SSBDemod::m_Bandwidth
private

◆ m_channelId

const QString SSBDemod::m_channelId = "SSBDemod"
static

Definition at line 177 of file ssbdemod.h.

Referenced by SSBPlugin::initPlugin(), and SSBDemod().

◆ m_channelIdURI

const QString SSBDemod::m_channelIdURI = "sdrangel.channel.ssbdemod"
static

Definition at line 176 of file ssbdemod.h.

Referenced by SSBPlugin::initPlugin(), and SSBDemodGUI::SSBDemodGUI().

◆ m_channelizer

DownChannelizer* SSBDemod::m_channelizer
private

Definition at line 285 of file ssbdemod.h.

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

◆ m_deviceAPI

DeviceAPI* SSBDemod::m_deviceAPI
private

Definition at line 283 of file ssbdemod.h.

Referenced by SSBDemod(), and ~SSBDemod().

◆ m_dsb

bool SSBDemod::m_dsb
private

◆ m_inputFrequencyOffset

int SSBDemod::m_inputFrequencyOffset
private

Definition at line 295 of file ssbdemod.h.

Referenced by applyChannelSettings(), SSBDemod(), and start().

◆ m_inputSampleRate

int SSBDemod::m_inputSampleRate
private

◆ m_interpolator

Interpolator SSBDemod::m_interpolator
private

Definition at line 316 of file ssbdemod.h.

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

◆ m_interpolatorDistance

Real SSBDemod::m_interpolatorDistance
private

Definition at line 317 of file ssbdemod.h.

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

◆ m_interpolatorDistanceRemain

Real SSBDemod::m_interpolatorDistanceRemain
private

Definition at line 318 of file ssbdemod.h.

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

◆ m_LowCutoff

Real SSBDemod::m_LowCutoff
private

◆ m_magsq

double SSBDemod::m_magsq
private

Definition at line 301 of file ssbdemod.h.

Referenced by getMagSq(), getMagSqLevels(), processOneSample(), and SSBDemod().

◆ m_magsqCount

int SSBDemod::m_magsqCount
private

Definition at line 304 of file ssbdemod.h.

Referenced by getMagSqLevels(), processOneSample(), and SSBDemod().

◆ m_magSqLevelStore

MagSqLevelsStore SSBDemod::m_magSqLevelStore
private

Definition at line 305 of file ssbdemod.h.

Referenced by getMagSqLevels().

◆ m_magsqPeak

double SSBDemod::m_magsqPeak
private

Definition at line 303 of file ssbdemod.h.

Referenced by getMagSqLevels(), processOneSample(), and SSBDemod().

◆ m_magsqSum

double SSBDemod::m_magsqSum
private

Definition at line 302 of file ssbdemod.h.

Referenced by getMagSqLevels(), processOneSample(), and SSBDemod().

◆ m_nco

NCOF SSBDemod::m_nco
private

Definition at line 315 of file ssbdemod.h.

Referenced by applyChannelSettings(), and feed().

◆ m_networkManager

QNetworkAccessManager* SSBDemod::m_networkManager
private

Definition at line 330 of file ssbdemod.h.

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

◆ m_networkRequest

QNetworkRequest SSBDemod::m_networkRequest
private

Definition at line 331 of file ssbdemod.h.

Referenced by webapiReverseSendSettings().

◆ m_sampleBuffer

SampleVector SSBDemod::m_sampleBuffer
private

Definition at line 323 of file ssbdemod.h.

Referenced by processOneSample().

◆ m_sampleSink

BasebandSampleSink* SSBDemod::m_sampleSink
private

Definition at line 322 of file ssbdemod.h.

Referenced by handleMessage(), processOneSample(), and setSampleSink().

◆ m_settings

SSBDemodSettings SSBDemod::m_settings
private

◆ m_settingsMutex

QMutex SSBDemod::m_settingsMutex
private

Definition at line 333 of file ssbdemod.h.

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

◆ m_spanLog2

int SSBDemod::m_spanLog2
private

◆ m_squelchDelayLine

DoubleBufferFIFO<fftfilt::cmplx> SSBDemod::m_squelchDelayLine
private

Definition at line 312 of file ssbdemod.h.

Referenced by processOneSample().

◆ m_sum

fftfilt::cmplx SSBDemod::m_sum
private

Definition at line 292 of file ssbdemod.h.

Referenced by processOneSample(), and SSBDemod().

◆ m_threadedChannelizer

ThreadedBasebandSampleSink* SSBDemod::m_threadedChannelizer
private

Definition at line 284 of file ssbdemod.h.

Referenced by SSBDemod(), and ~SSBDemod().

◆ m_undersampleCount

int SSBDemod::m_undersampleCount
private

Definition at line 293 of file ssbdemod.h.

Referenced by processOneSample(), and SSBDemod().

◆ m_usb

bool SSBDemod::m_usb
private

Definition at line 298 of file ssbdemod.h.

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

◆ m_volume

Real SSBDemod::m_volume
private

◆ SSBFilter

fftfilt* SSBDemod::SSBFilter
private

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