diff --git a/plugins/channelrx/demodam/amdemod.cpp b/plugins/channelrx/demodam/amdemod.cpp index 2e075ad84..7b9d2f7e0 100644 --- a/plugins/channelrx/demodam/amdemod.cpp +++ b/plugins/channelrx/demodam/amdemod.cpp @@ -187,6 +187,14 @@ bool AMDemod::handleMessage(const Message& cmd) return true; } + else if (BasebandSampleSink::MsgThreadedSink::match(cmd)) + { + BasebandSampleSink::MsgThreadedSink& cfg = (BasebandSampleSink::MsgThreadedSink&) cmd; + const QThread *thread = cfg.getThread(); + qDebug("AMDemod::handleMessage: BasebandSampleSink::MsgThreadedSink: %p", thread); + m_audioNetSink->moveToThread(const_cast(thread)); // use the thread for udp sinks + return true; + } else if (DSPSignalNotification::match(cmd)) { return true; diff --git a/plugins/channelrx/demodam/amdemod.h b/plugins/channelrx/demodam/amdemod.h index 8d20b7456..5fec9042f 100644 --- a/plugins/channelrx/demodam/amdemod.h +++ b/plugins/channelrx/demodam/amdemod.h @@ -28,9 +28,9 @@ #include "dsp/agc.h" #include "dsp/bandpass.h" #include "audio/audiofifo.h" +#include "audio/audionetsink.h" #include "util/message.h" #include "amdemodsettings.h" -#include "audio/audionetsink.h" class DeviceSourceAPI; class DownChannelizer; diff --git a/plugins/channelrx/demodssb/ssbdemod.cpp b/plugins/channelrx/demodssb/ssbdemod.cpp index 84d92bd8a..5e90d4252 100644 --- a/plugins/channelrx/demodssb/ssbdemod.cpp +++ b/plugins/channelrx/demodssb/ssbdemod.cpp @@ -22,6 +22,7 @@ #include #include "audio/audiooutput.h" +#include "audio/audionetsink.h" #include "dsp/dspengine.h" #include "dsp/downchannelizer.h" #include "dsp/threadedbasebandsamplesink.h" @@ -85,7 +86,8 @@ SSBDemod::SSBDemod(DeviceSourceAPI *deviceAPI) : DSBFilter = new fftfilt((2.0f * m_Bandwidth) / m_audioSampleRate, 2 * ssbFftLen); DSPEngine::instance()->addAudioSink(&m_audioFifo); - m_udpBufferAudio = new UDPSink(this, m_udpBlockSize, m_settings.m_udpPort); + m_audioNetSink = new AudioNetSink(0); // parent thread allocated dynamically + m_audioNetSink->setDestination(m_settings.m_udpAddress, m_settings.m_udpPort); m_channelizer = new DownChannelizer(this); m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this); @@ -101,13 +103,17 @@ SSBDemod::~SSBDemod() if (SSBFilter) delete SSBFilter; if (DSBFilter) delete DSBFilter; DSPEngine::instance()->removeAudioSink(&m_audioFifo); + delete m_audioNetSink; m_deviceAPI->removeChannelAPI(this); m_deviceAPI->removeThreadedSink(m_threadedChannelizer); delete m_threadedChannelizer; delete m_channelizer; +} - delete m_udpBufferAudio; +bool SSBDemod::isAudioNetSinkRTPCapable() const +{ + return m_audioNetSink && m_audioNetSink->isRTPCapable(); } void SSBDemod::configure(MessageQueue* messageQueue, @@ -219,7 +225,7 @@ void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto m_audioBuffer[m_audioBufferFill].r = 0; m_audioBuffer[m_audioBufferFill].l = 0; - if (m_settings.m_copyAudioToUDP) { m_udpBufferAudio->write(0); } + if (m_settings.m_copyAudioToUDP) { m_audioNetSink->write(0); } } else { @@ -236,7 +242,7 @@ void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto m_audioBuffer[m_audioBufferFill].l = (qint16)(sideband[i].imag() * m_volume * agcVal); } - if (m_settings.m_copyAudioToUDP) { m_udpBufferAudio->write(m_audioBuffer[m_audioBufferFill].r + m_audioBuffer[m_audioBufferFill].l); } + if (m_settings.m_copyAudioToUDP) { m_audioNetSink->write(m_audioBuffer[m_audioBufferFill].r + m_audioBuffer[m_audioBufferFill].l); } } else { @@ -245,7 +251,7 @@ void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto m_audioBuffer[m_audioBufferFill].l = sample; m_audioBuffer[m_audioBufferFill].r = sample; - if (m_settings.m_copyAudioToUDP) { m_udpBufferAudio->write(sample); } + if (m_settings.m_copyAudioToUDP) { m_audioNetSink->write(sample); } } } @@ -325,6 +331,14 @@ bool SSBDemod::handleMessage(const Message& cmd) return true; } + else if (BasebandSampleSink::MsgThreadedSink::match(cmd)) + { + BasebandSampleSink::MsgThreadedSink& cfg = (BasebandSampleSink::MsgThreadedSink&) cmd; + const QThread *thread = cfg.getThread(); + qDebug("SSBDemod::handleMessage: BasebandSampleSink::MsgThreadedSink: %p", thread); + m_audioNetSink->moveToThread(const_cast(thread)); // use the thread for udp sinks + return true; + } else if (DSPSignalNotification::match(cmd)) { return true; @@ -380,6 +394,7 @@ void SSBDemod::applySettings(const SSBDemodSettings& settings, bool force) << " m_dsb: " << settings.m_dsb << " m_audioMute: " << settings.m_audioMute << " m_copyAudioToUDP: " << settings.m_copyAudioToUDP + << " m_copyAudioUseRTP: " << settings.m_copyAudioUseRTP << " m_agcActive: " << settings.m_agc << " m_agcClamping: " << settings.m_agcClamping << " m_agcTimeLog2: " << settings.m_agcTimeLog2 @@ -476,8 +491,27 @@ void SSBDemod::applySettings(const SSBDemodSettings& settings, bool force) if ((m_settings.m_udpAddress != settings.m_udpAddress) || (m_settings.m_udpPort != settings.m_udpPort) || force) { - m_udpBufferAudio->setAddress(const_cast(settings.m_udpAddress)); - m_udpBufferAudio->setPort(settings.m_udpPort); + m_audioNetSink->setDestination(settings.m_udpAddress, settings.m_udpPort); + } + + if ((settings.m_copyAudioUseRTP != m_settings.m_copyAudioUseRTP) || force) + { + if (settings.m_copyAudioUseRTP) + { + if (m_audioNetSink->selectType(AudioNetSink::SinkRTP)) { + qDebug("NFMDemod::applySettings: set audio sink to RTP mode"); + } else { + qWarning("NFMDemod::applySettings: RTP support for audio sink not available. Fall back too UDP"); + } + } + else + { + if (m_audioNetSink->selectType(AudioNetSink::SinkUDP)) { + qDebug("NFMDemod::applySettings: set audio sink to UDP mode"); + } else { + qWarning("NFMDemod::applySettings: failed to set audio sink to UDP mode"); + } + } } m_spanLog2 = settings.m_spanLog2; diff --git a/plugins/channelrx/demodssb/ssbdemod.h b/plugins/channelrx/demodssb/ssbdemod.h index a8fa5e0d9..c71698e01 100644 --- a/plugins/channelrx/demodssb/ssbdemod.h +++ b/plugins/channelrx/demodssb/ssbdemod.h @@ -38,6 +38,7 @@ class DeviceSourceAPI; class ThreadedBasebandSampleSink; class DownChannelizer; +class AudioNetSink; class SSBDemod : public BasebandSampleSink, public ChannelSinkAPI { public: @@ -133,6 +134,8 @@ public: m_magsqCount = 0; } + bool isAudioNetSinkRTPCapable() const; + static const QString m_channelIdURI; static const QString m_channelId; @@ -274,7 +277,7 @@ private: uint m_audioBufferFill; AudioFifo m_audioFifo; quint32 m_audioSampleRate; - UDPSink *m_udpBufferAudio; + AudioNetSink *m_audioNetSink; static const int m_udpBlockSize; QMutex m_settingsMutex; diff --git a/plugins/channelrx/demodssb/ssbdemodgui.cpp b/plugins/channelrx/demodssb/ssbdemodgui.cpp index 2e07bc7c1..eb9c63e0e 100644 --- a/plugins/channelrx/demodssb/ssbdemodgui.cpp +++ b/plugins/channelrx/demodssb/ssbdemodgui.cpp @@ -203,6 +203,12 @@ void SSBDemodGUI::on_copyAudioToUDP_toggled(bool checked) applySettings(); } +void SSBDemodGUI::on_useRTP_toggled(bool checked) +{ + m_settings.m_copyAudioUseRTP = checked; + applySettings(); +} + void SSBDemodGUI::onMenuDialogCalled(const QPoint &p) { BasicChannelSettingsDialog dialog(&m_channelMarker, this); @@ -282,6 +288,9 @@ SSBDemodGUI::SSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban m_deviceUISet->addChannelMarker(&m_channelMarker); m_deviceUISet->addRollupWidget(this); + if (!m_ssbDemod->isAudioNetSinkRTPCapable()) { + ui->useRTP->hide(); + } connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor())); connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor())); @@ -514,6 +523,10 @@ void SSBDemodGUI::displaySettings() ui->agcThresholdGateText->setText(s); ui->copyAudioToUDP->setChecked(m_settings.m_copyAudioToUDP); + if (m_ssbDemod->isAudioNetSinkRTPCapable()) { + ui->useRTP->setChecked(m_settings.m_copyAudioUseRTP); + } + blockApplySettings(false); } diff --git a/plugins/channelrx/demodssb/ssbdemodgui.h b/plugins/channelrx/demodssb/ssbdemodgui.h index 79c15f4fa..52b2a9cd5 100644 --- a/plugins/channelrx/demodssb/ssbdemodgui.h +++ b/plugins/channelrx/demodssb/ssbdemodgui.h @@ -96,6 +96,7 @@ private slots: void on_spanLog2_valueChanged(int value); void on_flipSidebands_clicked(bool checked); void on_copyAudioToUDP_toggled(bool copy); + void on_useRTP_toggled(bool checked); void onWidgetRolled(QWidget* widget, bool rollDown); void onMenuDialogCalled(const QPoint& p); void tick(); diff --git a/plugins/channelrx/demodssb/ssbdemodgui.ui b/plugins/channelrx/demodssb/ssbdemodgui.ui index df8594703..4fd0a4800 100644 --- a/plugins/channelrx/demodssb/ssbdemodgui.ui +++ b/plugins/channelrx/demodssb/ssbdemodgui.ui @@ -6,7 +6,7 @@ 0 0 - 400 + 413 190 @@ -36,13 +36,13 @@ 0 0 - 398 + 410 171 - 398 + 410 0 @@ -873,6 +873,16 @@ + + + + Use RTP protocol for audio copy to UDP + + + R + + + diff --git a/plugins/channelrx/demodssb/ssbdemodsettings.cpp b/plugins/channelrx/demodssb/ssbdemodsettings.cpp index b1f805e6b..2cebdd11e 100644 --- a/plugins/channelrx/demodssb/ssbdemodsettings.cpp +++ b/plugins/channelrx/demodssb/ssbdemodsettings.cpp @@ -45,6 +45,7 @@ void SSBDemodSettings::resetToDefaults() m_agc = false; m_agcClamping = false; m_copyAudioToUDP = false; + m_copyAudioUseRTP = false; m_agcPowerThreshold = -40; m_agcThresholdGate = 4; m_agcTimeLog2 = 7; @@ -83,6 +84,7 @@ QByteArray SSBDemodSettings::serialize() const s.writeS32(14, m_agcThresholdGate); s.writeBool(15, m_agcClamping); s.writeString(16, m_title); + s.writeBool(17, m_copyAudioUseRTP); return s.final(); } @@ -127,6 +129,7 @@ bool SSBDemodSettings::deserialize(const QByteArray& data) d.readS32(14, &m_agcThresholdGate, 4); d.readBool(15, &m_agcClamping, false); d.readString(16, &m_title, "SSB Demodulator"); + d.readBool(17, &m_copyAudioUseRTP, false); return true; } diff --git a/plugins/channelrx/demodssb/ssbdemodsettings.h b/plugins/channelrx/demodssb/ssbdemodsettings.h index fda0e1fad..a13232797 100644 --- a/plugins/channelrx/demodssb/ssbdemodsettings.h +++ b/plugins/channelrx/demodssb/ssbdemodsettings.h @@ -34,6 +34,7 @@ struct SSBDemodSettings bool m_dsb; bool m_audioMute; bool m_copyAudioToUDP; + bool m_copyAudioUseRTP; bool m_agc; bool m_agcClamping; int m_agcTimeLog2; diff --git a/sdrbase/audio/audionetsink.h b/sdrbase/audio/audionetsink.h index a1781de8c..33456a50e 100644 --- a/sdrbase/audio/audionetsink.h +++ b/sdrbase/audio/audionetsink.h @@ -18,10 +18,12 @@ #ifndef SDRBASE_AUDIO_AUDIONETSINK_H_ #define SDRBASE_AUDIO_AUDIONETSINK_H_ -#include #include "dsp/dsptypes.h" #include "util/export.h" +#include +#include + template class UDPSink; class RTPSink; class QThread;