From c6b58431feac7ffe39192123a3d4880eb42ffff7 Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 17 Aug 2017 20:23:17 +0200 Subject: [PATCH] UDPSrc plugin: partial squelch implementation --- plugins/channelrx/udpsrc/udpsrc.cpp | 24 ++++++-- plugins/channelrx/udpsrc/udpsrc.h | 31 ++++++++-- plugins/channelrx/udpsrc/udpsrcgui.cpp | 28 ++++++++- plugins/channelrx/udpsrc/udpsrcgui.h | 2 + plugins/channelrx/udpsrc/udpsrcgui.ui | 77 ++++++++++++++++++++++++ plugins/channeltx/udpsink/udpsink.cpp | 6 +- plugins/channeltx/udpsink/udpsink.h | 11 +++- plugins/channeltx/udpsink/udpsinkgui.cpp | 13 +++- plugins/channeltx/udpsink/udpsinkgui.ui | 2 +- 9 files changed, 177 insertions(+), 17 deletions(-) diff --git a/plugins/channelrx/udpsrc/udpsrc.cpp b/plugins/channelrx/udpsrc/udpsrc.cpp index d446f54be..9d4e44aa1 100644 --- a/plugins/channelrx/udpsrc/udpsrc.cpp +++ b/plugins/channelrx/udpsrc/udpsrc.cpp @@ -35,6 +35,8 @@ UDPSrc::UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, BasebandSampl m_audioStereo(false), m_volume(20), m_fmDeviation(2500), + m_outMovingAverage(480, 1e-10), + m_inMovingAverage(480, 1e-10), m_audioFifo(4, 24000), m_settingsMutex(QMutex::Recursive) { @@ -67,6 +69,7 @@ UDPSrc::UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, BasebandSampl m_this = 0; m_scale = 0; m_magsq = 0; + m_inMagsq = 0; UDPFilter = new fftfilt(0.0, (m_rfBandwidth / 2.0) / m_outputSampleRate, udpBlockSize); m_phaseDiscri.setFMScaling((float) m_outputSampleRate / (2.0f * m_fmDeviation)); @@ -117,13 +120,17 @@ void UDPSrc::configureImmediate(MessageQueue* messageQueue, bool audioActive, bool audioStereo, Real boost, - int volume) + int volume, + Real squelchDB, + bool squelchEnabled) { Message* cmd = MsgUDPSrcConfigureImmediate::create( audioActive, audioStereo, boost, - volume); + volume, + squelchDB, + squelchEnabled); messageQueue->push(cmd); } @@ -149,7 +156,13 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector: if(m_interpolator.decimate(&m_sampleDistanceRemain, c, &ci)) { - m_magsq = ((ci.real()*ci.real() + ci.imag()*ci.imag())*m_gain*m_gain) / (1<<30); + double inMagSq = ci.real()*ci.real() + ci.imag()*ci.imag(); + //m_magsq = (inMagSq*m_gain*m_gain) / (1<<30); + m_outMovingAverage.feed((inMagSq*m_gain*m_gain) / (1<<30)); + m_inMovingAverage.feed(inMagSq / (1<<30)); + m_magsq = m_outMovingAverage.average(); + m_inMagsq = m_inMovingAverage.average(); + Sample s(ci.real() * m_gain, ci.imag() * m_gain); m_sampleBuffer.push_back(s); m_sampleDistanceRemain += m_inputSampleRate / m_outputSampleRate; @@ -220,7 +233,7 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector: } else if (m_sampleFormat == FormatAMMono) { - FixReal demod = (FixReal) (32768.0f * sqrt(m_magsq)); + FixReal demod = (FixReal) (32768.0f * sqrt(inMagSq) * m_gain); m_udpBufferMono->write(demod); } else // Raw I/Q samples @@ -371,6 +384,9 @@ bool UDPSrc::handleMessage(const Message& cmd) m_sampleDistanceRemain = m_inputSampleRate / m_outputSampleRate; UDPFilter->create_filter(0.0, (m_rfBandwidth / 2.0) / m_outputSampleRate); + m_inMovingAverage.resize(m_inputSampleRate * 0.01, 1e-10); // 10 ms + m_outMovingAverage.resize(m_outputSampleRate * 0.01, 1e-10); // 10 ms + m_settingsMutex.unlock(); qDebug() << "UDPSrc::handleMessage: MsgUDPSrcConfigure: m_sampleFormat: " << m_sampleFormat diff --git a/plugins/channelrx/udpsrc/udpsrc.h b/plugins/channelrx/udpsrc/udpsrc.h index a957a36c4..0eb363841 100644 --- a/plugins/channelrx/udpsrc/udpsrc.h +++ b/plugins/channelrx/udpsrc/udpsrc.h @@ -25,6 +25,7 @@ #include "dsp/fftfilt.h" #include "dsp/interpolator.h" #include "dsp/phasediscri.h" +#include "dsp/movingaverage.h" #include "util/udpsink.h" #include "util/message.h" #include "audio/audiofifo.h" @@ -71,9 +72,12 @@ public: bool audioActive, bool audioStereo, Real gain, - int volume); + int volume, + Real squelchDB, + bool squelchEnabled); void setSpectrum(MessageQueue* messageQueue, bool enabled); double getMagSq() const { return m_magsq; } + double getInMagSq() const { return m_inMagsq; } virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly); virtual void start(); @@ -151,36 +155,48 @@ protected: int getVolume() const { return m_volume; } bool getAudioActive() const { return m_audioActive; } bool getAudioStereo() const { return m_audioStereo; } + Real getSquelchDB() const { return m_squelchDB; } + bool getSquelchEnabled() const { return m_squelchEnabled; } static MsgUDPSrcConfigureImmediate* create( bool audioActive, bool audioStereo, int boost, - int volume) + int volume, + Real squelchDB, + bool squelchEnabled) { return new MsgUDPSrcConfigureImmediate( audioActive, audioStereo, boost, - volume); + volume, + squelchDB, + squelchEnabled); } private: Real m_gain; - int m_volume; + int m_volume; bool m_audioActive; bool m_audioStereo; + Real m_squelchDB; + bool m_squelchEnabled; MsgUDPSrcConfigureImmediate( bool audioActive, bool audioStereo, Real gain, - int volume) : + int volume, + Real squelchDB, + bool squelchEnabled) : Message(), m_gain(gain), m_volume(volume), m_audioActive(audioActive), - m_audioStereo(audioStereo) + m_audioStereo(audioStereo), + m_squelchDB(squelchDB), + m_squelchEnabled(squelchEnabled) { } }; @@ -222,6 +238,9 @@ protected: int m_volume; int m_fmDeviation; double m_magsq; + double m_inMagsq; + MovingAverage m_outMovingAverage; + MovingAverage m_inMovingAverage; Real m_scale; Complex m_last, m_this; diff --git a/plugins/channelrx/udpsrc/udpsrcgui.cpp b/plugins/channelrx/udpsrc/udpsrcgui.cpp index a804251df..d6c895433 100644 --- a/plugins/channelrx/udpsrc/udpsrcgui.cpp +++ b/plugins/channelrx/udpsrc/udpsrcgui.cpp @@ -105,6 +105,7 @@ QByteArray UDPSrcGUI::serialize() const s.writeS32(13, m_audioPort); s.writeBool(14, m_audioStereo); s.writeS32(15, m_fmDeviation); + s.writeS32(16, ui->squelch->value()); return s.final(); } @@ -189,6 +190,9 @@ bool UDPSrcGUI::deserialize(const QByteArray& data) ui->audioStereo->setChecked(booltmp); d.readS32(15, &s32tmp, 2500); ui->fmDeviation->setText(QString("%1").arg(s32tmp)); + d.readS32(16, &s32tmp, -60); + ui->squelch->setValue(s32tmp); + ui->squelchText->setText(tr("%1").arg(s32tmp*1.0, 0, 'f', 0)); blockApplySettings(false); m_channelMarker.blockSignals(false); @@ -222,6 +226,9 @@ void UDPSrcGUI::tick() m_channelPowerAvg.feed(m_udpSrc->getMagSq()); double powDb = CalcDb::dbPower(m_channelPowerAvg.average()); ui->channelPower->setText(QString::number(powDb, 'f', 1)); + m_inPowerAvg.feed(m_udpSrc->getInMagSq()); + double inPowDb = CalcDb::dbPower(m_inPowerAvg.average()); + ui->inputPower->setText(QString::number(inPowDb, 'f', 1)); } m_tickCount++; @@ -235,6 +242,7 @@ UDPSrcGUI::UDPSrcGUI(PluginAPI* pluginAPI, DeviceSourceAPI *deviceAPI, QWidget* m_udpSrc(0), m_channelMarker(this), m_channelPowerAvg(4, 1e-10), + m_inPowerAvg(4, 1e-10), m_tickCount(0), m_gain(1.0), m_volume(20), @@ -307,6 +315,7 @@ void UDPSrcGUI::displaySettings() { ui->gainText->setText(tr("%1").arg(ui->gain->value()/10.0, 0, 'f', 1)); ui->volumeText->setText(QString("%1").arg(ui->volume->value())); + ui->squelchText->setText(tr("%1").arg(ui->squelch->value()*1.0, 0, 'f', 0)); } void UDPSrcGUI::applySettingsImmediate() @@ -322,7 +331,9 @@ void UDPSrcGUI::applySettingsImmediate() m_audioActive, m_audioStereo, m_gain, - m_volume); + m_volume, + ui->squelch->value() * 1.0f, + ui->squelch->value() != -100); } } @@ -518,11 +529,24 @@ void UDPSrcGUI::on_gain_valueChanged(int value) void UDPSrcGUI::on_volume_valueChanged(int value) { - ui->volume->setValue(value); ui->volumeText->setText(QString("%1").arg(value)); applySettingsImmediate(); } +void UDPSrcGUI::on_squelch_valueChanged(int value) +{ + if (value == -100) // means disabled + { + ui->squelchText->setText("---"); + } + else + { + ui->squelchText->setText(tr("%1").arg(value*1.0, 0, 'f', 0)); + } + + applySettingsImmediate(); +} + void UDPSrcGUI::onWidgetRolled(QWidget* widget, bool rollDown) { if ((widget == ui->spectrumBox) && (m_udpSrc != 0)) diff --git a/plugins/channelrx/udpsrc/udpsrcgui.h b/plugins/channelrx/udpsrc/udpsrcgui.h index cca6050d5..c7bcc019d 100644 --- a/plugins/channelrx/udpsrc/udpsrcgui.h +++ b/plugins/channelrx/udpsrc/udpsrcgui.h @@ -74,6 +74,7 @@ private slots: void onMenuDoubleClicked(); void on_gain_valueChanged(int value); void on_volume_valueChanged(int value); + void on_squelch_valueChanged(int value); void tick(); private: @@ -83,6 +84,7 @@ private: UDPSrc* m_udpSrc; ChannelMarker m_channelMarker; MovingAverage m_channelPowerAvg; + MovingAverage m_inPowerAvg; uint32_t m_tickCount; // settings diff --git a/plugins/channelrx/udpsrc/udpsrcgui.ui b/plugins/channelrx/udpsrc/udpsrcgui.ui index 9e9649f21..dc678e3cc 100644 --- a/plugins/channelrx/udpsrc/udpsrcgui.ui +++ b/plugins/channelrx/udpsrc/udpsrcgui.ui @@ -580,6 +580,83 @@ + + + + + + + 0 + 22 + + + + Sq + + + + + + + Power squelch threshold (dB) + + + -100 + + + 0 + + + 1 + + + -60 + + + Qt::Horizontal + + + + + + + + 22 + 0 + + + + Power squelch threshold (dB) + + + -00 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 40 + 0 + + + + Input power (dB) to which squelch applies + + + -100.0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + diff --git a/plugins/channeltx/udpsink/udpsink.cpp b/plugins/channeltx/udpsink/udpsink.cpp index b227bf2cd..83239f2b5 100644 --- a/plugins/channeltx/udpsink/udpsink.cpp +++ b/plugins/channeltx/udpsink/udpsink.cpp @@ -232,6 +232,7 @@ bool UDPSink::handleMessage(const Message& cmd) m_config.m_channelMute = cfg.getChannelMute(); m_config.m_gain = cfg.getGain(); m_config.m_squelch = CalcDb::powerFromdB(cfg.getSquelchDB()); + m_config.m_squelchEnabled = cfg.getSquelchEnabled(); apply(cfg.getForce()); @@ -245,7 +246,8 @@ bool UDPSink::handleMessage(const Message& cmd) << " m_channelMute: " << m_config.m_channelMute << " m_gain: " << m_config.m_gain << " squelchDB: " << cfg.getSquelchDB() - << " m_squelch: " << m_config.m_squelch; + << " m_squelch: " << m_config.m_squelch + << " m_squelchEnabled: " << m_config.m_squelchEnabled; return true; } @@ -332,6 +334,7 @@ void UDPSink::configure(MessageQueue* messageQueue, bool channelMute, Real gain, Real squelchDB, + bool squelchEnabled, bool force) { Message* cmd = MsgUDPSinkConfigure::create(sampleFormat, @@ -343,6 +346,7 @@ void UDPSink::configure(MessageQueue* messageQueue, channelMute, gain, squelchDB, + squelchEnabled, force); messageQueue->push(cmd); } diff --git a/plugins/channeltx/udpsink/udpsink.h b/plugins/channeltx/udpsink/udpsink.h index bf31d44b8..0c9dd2b4a 100644 --- a/plugins/channeltx/udpsink/udpsink.h +++ b/plugins/channeltx/udpsink/udpsink.h @@ -69,6 +69,7 @@ public: bool channelMute, Real gain, Real squelchDB, + bool squelchEnabled, bool force = false); void setSpectrum(MessageQueue* messageQueue, bool enabled); @@ -95,6 +96,7 @@ private: bool getChannelMute() const { return m_channelMute; } Real getGain() const { return m_gain; } Real getSquelchDB() const { return m_squelchDB; } + bool getSquelchEnabled() const { return m_squelchEnabled; } bool getForce() const { return m_force; } static MsgUDPSinkConfigure* create(SampleFormat @@ -107,6 +109,7 @@ private: bool channelMute, Real gain, Real squelchDB, + bool squelchEnabled, bool force) { return new MsgUDPSinkConfigure(sampleFormat, @@ -118,6 +121,7 @@ private: channelMute, gain, squelchDB, + squelchEnabled, force); } @@ -131,6 +135,7 @@ private: bool m_channelMute; Real m_gain; Real m_squelchDB; + bool m_squelchEnabled; bool m_force; MsgUDPSinkConfigure(SampleFormat sampleFormat, @@ -142,6 +147,7 @@ private: bool channelMute, Real gain, Real squelchDB, + bool squelchEnabled, bool force) : Message(), m_sampleFormat(sampleFormat), @@ -153,6 +159,7 @@ private: m_channelMute(channelMute), m_gain(gain), m_squelchDB(squelchDB), + m_squelchEnabled(squelchEnabled), m_force(force) { } }; @@ -188,6 +195,7 @@ private: bool m_channelMute; Real m_gain; Real m_squelch; //!< squared magnitude + bool m_squelchEnabled; QString m_udpAddressStr; quint16 m_udpPort; @@ -203,6 +211,7 @@ private: m_channelMute(false), m_gain(1.0), m_squelch(-50.0), + m_squelchEnabled(true), m_udpAddressStr("127.0.0.1"), m_udpPort(9999) {} @@ -258,7 +267,7 @@ private: inline void calculateSquelch(double value) { - if (value > m_running.m_squelch) + if ((!m_running.m_squelchEnabled) || (value > m_running.m_squelch)) { if (m_squelchOpenCount < m_squelchThreshold) { m_squelchOpenCount++; diff --git a/plugins/channeltx/udpsink/udpsinkgui.cpp b/plugins/channeltx/udpsink/udpsinkgui.cpp index 5a157e5c5..45dec33f6 100644 --- a/plugins/channeltx/udpsink/udpsinkgui.cpp +++ b/plugins/channeltx/udpsink/udpsinkgui.cpp @@ -177,7 +177,7 @@ bool UDPSinkGUI::deserialize(const QByteArray& data) m_channelMarker.setTitle(strtmp); this->setWindowTitle(m_channelMarker.getTitle()); - d.readS32(14, &s32tmp, 10); + d.readS32(14, &s32tmp, -60); ui->squelch->setValue(s32tmp); ui->squelchText->setText(tr("%1").arg(s32tmp*1.0, 0, 'f', 0)); @@ -398,6 +398,7 @@ void UDPSinkGUI::applySettings(bool force) ui->channelMute->isChecked(), ui->gain->value() / 10.0f, ui->squelch->value() * 1.0f, + ui->squelch->value() != -100, force); ui->applyBtn->setEnabled(false); @@ -465,7 +466,15 @@ void UDPSinkGUI::on_gain_valueChanged(int value) void UDPSinkGUI::on_squelch_valueChanged(int value) { - ui->squelchText->setText(tr("%1").arg(value*1.0, 0, 'f', 0)); + if (value == -100) // means disabled + { + ui->squelchText->setText("---"); + } + else + { + ui->squelchText->setText(tr("%1").arg(value*1.0, 0, 'f', 0)); + } + applySettings(); } diff --git a/plugins/channeltx/udpsink/udpsinkgui.ui b/plugins/channeltx/udpsink/udpsinkgui.ui index 805d90a2e..7a35f66f0 100644 --- a/plugins/channeltx/udpsink/udpsinkgui.ui +++ b/plugins/channeltx/udpsink/udpsinkgui.ui @@ -43,7 +43,7 @@ 2 2 340 - 142 + 141