From 3e5c6f62b1a6534aec053b12def76cfaf2db540a Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 14 Aug 2017 10:59:05 +0200 Subject: [PATCH] UDPSink plugin: interim state (1) --- plugins/channeltx/udpsink/udpsink.cpp | 87 ++++++++++++++++++++++-- plugins/channeltx/udpsink/udpsink.h | 42 +++++++++--- plugins/channeltx/udpsink/udpsinkgui.cpp | 3 +- plugins/channeltx/udpsink/udpsinkgui.ui | 18 +++++ 4 files changed, 135 insertions(+), 15 deletions(-) diff --git a/plugins/channeltx/udpsink/udpsink.cpp b/plugins/channeltx/udpsink/udpsink.cpp index d42f01e20..632dbd460 100644 --- a/plugins/channeltx/udpsink/udpsink.cpp +++ b/plugins/channeltx/udpsink/udpsink.cpp @@ -27,6 +27,9 @@ UDPSink::UDPSink(MessageQueue* uiMessageQueue, UDPSinkGUI* udpSinkGUI, BasebandS m_spectrum(spectrum), m_settingsMutex(QMutex::Recursive) { + setObjectName("UDPSink"); + + apply(true); } UDPSink::~UDPSink() @@ -43,8 +46,48 @@ void UDPSink::stop() void UDPSink::pull(Sample& sample) { - sample.m_real = 0.0f; - sample.m_imag = 0.0f; + if (m_running.m_channelMute) + { + sample.m_real = 0.0f; + sample.m_imag = 0.0f; + return; + } + + Complex ci; + + m_settingsMutex.lock(); + + if (m_interpolatorDistance > 1.0f) // decimate + { + modulateSample(); + + while (!m_interpolator.decimate(&m_interpolatorDistanceRemain, m_modSample, &ci)) + { + modulateSample(); + } + } + else + { + if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, m_modSample, &ci)) + { + modulateSample(); + } + } + + m_interpolatorDistanceRemain += m_interpolatorDistance; + + ci *= m_carrierNco.nextIQ(); // shift to carrier frequency + + m_settingsMutex.unlock(); + + sample.m_real = (FixReal) ci.real(); + sample.m_imag = (FixReal) ci.imag(); +} + +void UDPSink::modulateSample() +{ + m_modSample.real(0.0f); // TODO + m_modSample.imag(0.0f); } bool UDPSink::handleMessage(const Message& cmd) @@ -82,9 +125,19 @@ bool UDPSink::handleMessage(const Message& cmd) m_config.m_fmDeviation = cfg.getFMDeviation(); m_config.m_udpAddressStr = cfg.getUDPAddress(); m_config.m_udpPort = cfg.getUDPPort(); + m_config.m_channelMute = cfg.getChannelMute(); m_settingsMutex.unlock(); + qDebug() << "UDPSink::handleMessage: MsgUDPSinkConfigure:" + << " m_sampleFormat: " << m_config.m_sampleFormat + << " m_inputSampleRate: " << m_config.m_inputSampleRate + << " m_rfBandwidth: " << m_config.m_rfBandwidth + << " m_fmDeviation: " << m_config.m_fmDeviation + << " m_udpAddressStr: " << m_config.m_udpAddressStr + << " m_udpPort: " << m_config.m_udpPort + << " m_channelMute: " << m_config.m_channelMute; + return true; } else @@ -99,14 +152,40 @@ void UDPSink::configure(MessageQueue* messageQueue, Real rfBandwidth, int fmDeviation, QString& udpAddress, - int udpPort) + int udpPort, + bool channelMute) { Message* cmd = MsgUDPSinkConfigure::create(sampleFormat, outputSampleRate, rfBandwidth, fmDeviation, udpAddress, - udpPort); + udpPort, + channelMute); messageQueue->push(cmd); } +void UDPSink::apply(bool force) +{ + if ((m_config.m_inputFrequencyOffset != m_running.m_inputFrequencyOffset) || + (m_config.m_outputSampleRate != m_running.m_outputSampleRate) || force) + { + m_settingsMutex.lock(); + m_carrierNco.setFreq(m_config.m_inputFrequencyOffset, m_config.m_outputSampleRate); + m_settingsMutex.unlock(); + } + + if((m_config.m_outputSampleRate != m_running.m_outputSampleRate) || + (m_config.m_rfBandwidth != m_running.m_rfBandwidth) || + (m_config.m_inputSampleRate != m_running.m_inputSampleRate) || force) + { + m_settingsMutex.lock(); + m_interpolatorDistanceRemain = 0; + m_interpolatorConsumed = false; + m_interpolatorDistance = (Real) m_config.m_inputSampleRate / (Real) m_config.m_outputSampleRate; + m_interpolator.create(48, m_config.m_inputSampleRate, m_config.m_rfBandwidth / 2.2, 3.0); + m_settingsMutex.unlock(); + } + + m_running = m_config; +} diff --git a/plugins/channeltx/udpsink/udpsink.h b/plugins/channeltx/udpsink/udpsink.h index 775fab659..ed7972aa6 100644 --- a/plugins/channeltx/udpsink/udpsink.h +++ b/plugins/channeltx/udpsink/udpsink.h @@ -21,6 +21,8 @@ #include "dsp/basebandsamplesource.h" #include "dsp/basebandsamplesink.h" +#include "dsp/interpolator.h" +#include "dsp/nco.h" #include "util/message.h" class UDPSinkGUI; @@ -55,7 +57,8 @@ public: Real rfBandwidth, int fmDeviation, QString& udpAddress, - int udpPort); + int udpPort, + bool channelMute); private: class MsgUDPSinkConfigure : public Message { @@ -68,6 +71,7 @@ private: int getFMDeviation() const { return m_fmDeviation; } const QString& getUDPAddress() const { return m_udpAddress; } int getUDPPort() const { return m_udpPort; } + bool getChannelMute() const { return m_channelMute; } static MsgUDPSinkConfigure* create(SampleFormat sampleFormat, @@ -75,14 +79,16 @@ private: Real rfBandwidth, int fmDeviation, QString& udpAddress, - int udpPort) + int udpPort, + bool channelMute) { return new MsgUDPSinkConfigure(sampleFormat, inputSampleRate, rfBandwidth, fmDeviation, udpAddress, - udpPort); + udpPort, + channelMute); } private: @@ -92,20 +98,23 @@ private: int m_fmDeviation; QString m_udpAddress; int m_udpPort; + bool m_channelMute; MsgUDPSinkConfigure(SampleFormat sampleFormat, Real inputSampleRate, Real rfBandwidth, int fmDeviation, QString& udpAddress, - int udpPort) : + int udpPort, + bool channelMute) : Message(), m_sampleFormat(sampleFormat), m_inputSampleRate(inputSampleRate), m_rfBandwidth(rfBandwidth), m_fmDeviation(fmDeviation), m_udpAddress(udpAddress), - m_udpPort(udpPort) + m_udpPort(udpPort), + m_channelMute(channelMute) { } }; @@ -117,18 +126,20 @@ private: qint64 m_inputFrequencyOffset; Real m_rfBandwidth; int m_fmDeviation; + bool m_channelMute; QString m_udpAddressStr; quint16 m_udpPort; Config() : - m_basebandSampleRate(0), - m_outputSampleRate(0), + m_basebandSampleRate(48000), + m_outputSampleRate(48000), m_sampleFormat(0), - m_inputSampleRate(0), + m_inputSampleRate(48000), m_inputFrequencyOffset(0), - m_rfBandwidth(0), - m_fmDeviation(0), + m_rfBandwidth(12500), + m_fmDeviation(1.0), + m_channelMute(false), m_udpAddressStr("127.0.0.1"), m_udpPort(9999) {} @@ -137,11 +148,22 @@ private: Config m_config; Config m_running; + NCO m_carrierNco; + Complex m_modSample; + MessageQueue* m_uiMessageQueue; UDPSinkGUI* m_udpSinkGUI; BasebandSampleSink* m_spectrum; + Interpolator m_interpolator; + Real m_interpolatorDistance; + Real m_interpolatorDistanceRemain; + bool m_interpolatorConsumed; + QMutex m_settingsMutex; + + void apply(bool force); + void modulateSample(); }; diff --git a/plugins/channeltx/udpsink/udpsinkgui.cpp b/plugins/channeltx/udpsink/udpsinkgui.cpp index 762e42ae0..c39bfa292 100644 --- a/plugins/channeltx/udpsink/udpsinkgui.cpp +++ b/plugins/channeltx/udpsink/udpsinkgui.cpp @@ -367,7 +367,8 @@ void UDPSinkGUI::applySettings() rfBandwidth, fmDeviation, m_udpAddress, - udpPort); + udpPort, + ui->channelMute->isChecked()); ui->applyBtn->setEnabled(false); } diff --git a/plugins/channeltx/udpsink/udpsinkgui.ui b/plugins/channeltx/udpsink/udpsinkgui.ui index 4b028368e..2eea039c5 100644 --- a/plugins/channeltx/udpsink/udpsinkgui.ui +++ b/plugins/channeltx/udpsink/udpsinkgui.ui @@ -157,6 +157,24 @@ + + + + Mute/Unmute channel + + + + + + + :/txon.png + :/txoff.png:/txon.png + + + true + + +