diff --git a/plugins/channelrx/demodnfm/nfmdemod.cpp b/plugins/channelrx/demodnfm/nfmdemod.cpp index 96f5a392b..2d1ab13cf 100644 --- a/plugins/channelrx/demodnfm/nfmdemod.cpp +++ b/plugins/channelrx/demodnfm/nfmdemod.cpp @@ -81,12 +81,6 @@ NFMDemod::NFMDemod(DeviceSourceAPI *devieAPI) : m_audioNetSink = new AudioNetSink(this); m_audioNetSink->setDestination(m_settings.m_udpAddress, m_settings.m_udpPort); - if (m_audioNetSink->selectType(AudioNetSink::SinkRTP)) { - qDebug("NFMDemod::NFMDemod: set audio sink to RTP mode"); - } else { - qWarning("NFMDemod::NFMDemod: RTP support for audio sink not available. Fall back too UDP"); - } - m_channelizer = new DownChannelizer(this); m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this); m_deviceAPI->addThreadedSink(m_threadedChannelizer); @@ -106,6 +100,11 @@ NFMDemod::~NFMDemod() delete m_channelizer; } +bool NFMDemod::isAudioNetSinkRTPCapable() const +{ + return m_audioNetSink && m_audioNetSink->isRTPCapable(); +} + float arctan2(Real y, Real x) { Real coeff_1 = M_PI / 4; @@ -479,6 +478,26 @@ void NFMDemod::applySettings(const NFMDemodSettings& settings, bool force) setSelectedCtcssIndex(settings.m_ctcssIndex); } + 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_settings = settings; } @@ -537,6 +556,9 @@ int NFMDemod::webapiSettingsPutPatch( if (channelSettingsKeys.contains("copyAudioToUDP")) { settings.m_copyAudioToUDP = response.getNfmDemodSettings()->getCopyAudioToUdp() != 0; } + if (channelSettingsKeys.contains("copyAudioUseRTP")) { + settings.m_copyAudioUseRTP = response.getNfmDemodSettings()->getCopyAudioUseRtp() != 0; + } if (channelSettingsKeys.contains("ctcssIndex")) { settings.m_ctcssIndex = response.getNfmDemodSettings()->getCtcssIndex(); } @@ -606,6 +628,7 @@ void NFMDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& resp response.getNfmDemodSettings()->setAudioMute(settings.m_audioMute ? 1 : 0); response.getNfmDemodSettings()->setAudioSampleRate(settings.m_audioSampleRate); response.getNfmDemodSettings()->setCopyAudioToUdp(settings.m_copyAudioToUDP ? 1 : 0); + response.getNfmDemodSettings()->setCopyAudioUseRtp(settings.m_copyAudioUseRTP ? 1 : 0); response.getNfmDemodSettings()->setCtcssIndex(settings.m_ctcssIndex); response.getNfmDemodSettings()->setCtcssOn(settings.m_ctcssOn ? 1 : 0); response.getNfmDemodSettings()->setDeltaSquelch(settings.m_deltaSquelch ? 1 : 0); diff --git a/plugins/channelrx/demodnfm/nfmdemod.h b/plugins/channelrx/demodnfm/nfmdemod.h index ac5bfeae7..490481ea0 100644 --- a/plugins/channelrx/demodnfm/nfmdemod.h +++ b/plugins/channelrx/demodnfm/nfmdemod.h @@ -159,6 +159,8 @@ public: m_magsqCount = 0; } + bool isAudioNetSinkRTPCapable() const; + static const QString m_channelIdURI; static const QString m_channelId; diff --git a/plugins/channelrx/demodnfm/nfmdemodgui.cpp b/plugins/channelrx/demodnfm/nfmdemodgui.cpp index a2fad4346..5e209e4ca 100644 --- a/plugins/channelrx/demodnfm/nfmdemodgui.cpp +++ b/plugins/channelrx/demodnfm/nfmdemodgui.cpp @@ -211,6 +211,12 @@ void NFMDemodGUI::on_copyAudioToUDP_toggled(bool checked) applySettings(); } +void NFMDemodGUI::on_useRTP_toggled(bool checked) +{ + m_settings.m_copyAudioUseRTP = checked; + applySettings(); +} + void NFMDemodGUI::on_ctcss_currentIndexChanged(int index) { m_settings.m_ctcssIndex = index; @@ -314,6 +320,7 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban QChar delta = QChar(0x94, 0x03); ui->deltaSquelch->setText(delta); + ui->useRTP->setEnabled(m_nfmDemod->isAudioNetSinkRTPCapable()); connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); @@ -393,6 +400,10 @@ void NFMDemodGUI::displaySettings() ui->ctcss->setCurrentIndex(m_settings.m_ctcssIndex); + if (m_nfmDemod->isAudioNetSinkRTPCapable()) { + ui->useRTP->setChecked(m_settings.m_copyAudioUseRTP); + } + blockApplySettings(false); } diff --git a/plugins/channelrx/demodnfm/nfmdemodgui.h b/plugins/channelrx/demodnfm/nfmdemodgui.h index 4920c7b54..3b4b0e68d 100644 --- a/plugins/channelrx/demodnfm/nfmdemodgui.h +++ b/plugins/channelrx/demodnfm/nfmdemodgui.h @@ -79,6 +79,7 @@ private slots: void on_ctcssOn_toggled(bool checked); void on_audioMute_toggled(bool checked); void on_copyAudioToUDP_toggled(bool checked); + void on_useRTP_toggled(bool checked); void onWidgetRolled(QWidget* widget, bool rollDown); void onMenuDialogCalled(const QPoint& p); void handleInputMessages(); diff --git a/plugins/channelrx/demodnfm/nfmdemodgui.ui b/plugins/channelrx/demodnfm/nfmdemodgui.ui index 0abea44fa..c798abb3f 100644 --- a/plugins/channelrx/demodnfm/nfmdemodgui.ui +++ b/plugins/channelrx/demodnfm/nfmdemodgui.ui @@ -611,6 +611,19 @@ + + + + Use RTP protocol for sending audio via UDP + + + R + + + true + + + diff --git a/plugins/channelrx/demodnfm/nfmdemodsettings.cpp b/plugins/channelrx/demodnfm/nfmdemodsettings.cpp index 6699524da..c1efda589 100644 --- a/plugins/channelrx/demodnfm/nfmdemodsettings.cpp +++ b/plugins/channelrx/demodnfm/nfmdemodsettings.cpp @@ -51,6 +51,7 @@ void NFMDemodSettings::resetToDefaults() m_ctcssIndex = 0; m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate(); m_copyAudioToUDP = false; + m_copyAudioUseRTP = false; m_udpAddress = "127.0.0.1"; m_udpPort = 9998; m_rgbColor = QColor(255, 0, 0).rgb(); @@ -77,6 +78,7 @@ QByteArray NFMDemodSettings::serialize() const } s.writeString(14, m_title); + s.writeBool(15, m_copyAudioUseRTP); return s.final(); } @@ -120,6 +122,7 @@ bool NFMDemodSettings::deserialize(const QByteArray& data) d.readS32(11, &m_squelchGate, 5); d.readBool(12, &m_deltaSquelch, false); d.readString(14, &m_title, "NFM Demodulator"); + d.readBool(15, &m_copyAudioUseRTP, false); return true; } diff --git a/plugins/channelrx/demodnfm/nfmdemodsettings.h b/plugins/channelrx/demodnfm/nfmdemodsettings.h index a758edb58..578f7cdd6 100644 --- a/plugins/channelrx/demodnfm/nfmdemodsettings.h +++ b/plugins/channelrx/demodnfm/nfmdemodsettings.h @@ -40,6 +40,7 @@ struct NFMDemodSettings int m_ctcssIndex; uint32_t m_audioSampleRate; bool m_copyAudioToUDP; + bool m_copyAudioUseRTP; QString m_udpAddress; uint16_t m_udpPort; quint32 m_rgbColor; diff --git a/sdrbase/audio/audionetsink.cpp b/sdrbase/audio/audionetsink.cpp index 76415347d..042557e3f 100644 --- a/sdrbase/audio/audionetsink.cpp +++ b/sdrbase/audio/audionetsink.cpp @@ -56,6 +56,15 @@ AudioNetSink::~AudioNetSink() #endif } +bool AudioNetSink::isRTPCapable() const +{ +#ifdef HAS_JRTPLIB + return true; +#else + return false; +#endif +} + bool AudioNetSink::selectType(SinkType type) { if (type == SinkUDP) diff --git a/sdrbase/audio/audionetsink.h b/sdrbase/audio/audionetsink.h index d1b1218e0..08dc27618 100644 --- a/sdrbase/audio/audionetsink.h +++ b/sdrbase/audio/audionetsink.h @@ -43,6 +43,7 @@ public: void write(qint16 sample); void write(const AudioSample& sample); + bool isRTPCapable() const; bool selectType(SinkType type); static const int m_udpBlockSize; diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html index 7879d98fd..fb2087c12 100644 --- a/sdrbase/resources/webapi/doc/html2/index.html +++ b/sdrbase/resources/webapi/doc/html2/index.html @@ -1371,6 +1371,9 @@ margin-bottom: 20px; "copyAudioToUDP" : { "type" : "integer" }, + "copyAudioUseRTP" : { + "type" : "integer" + }, "udpAddress" : { "type" : "string" }, @@ -16921,7 +16924,7 @@ except ApiException as e:
- Generated 2018-01-25T00:10:31.068+01:00 + Generated 2018-02-05T00:57:57.193+01:00
diff --git a/sdrbase/resources/webapi/doc/swagger/include/NFMDemod.yaml b/sdrbase/resources/webapi/doc/swagger/include/NFMDemod.yaml index e644936fe..c83d72e4e 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/NFMDemod.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/NFMDemod.yaml @@ -32,6 +32,8 @@ NFMDemodSettings: type: integer copyAudioToUDP: type: integer + copyAudioUseRTP: + type: integer udpAddress: type: string udpPort: diff --git a/swagger/sdrangel/api/swagger/include/NFMDemod.yaml b/swagger/sdrangel/api/swagger/include/NFMDemod.yaml index e644936fe..c83d72e4e 100644 --- a/swagger/sdrangel/api/swagger/include/NFMDemod.yaml +++ b/swagger/sdrangel/api/swagger/include/NFMDemod.yaml @@ -32,6 +32,8 @@ NFMDemodSettings: type: integer copyAudioToUDP: type: integer + copyAudioUseRTP: + type: integer udpAddress: type: string udpPort: diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html index 7879d98fd..fb2087c12 100644 --- a/swagger/sdrangel/code/html2/index.html +++ b/swagger/sdrangel/code/html2/index.html @@ -1371,6 +1371,9 @@ margin-bottom: 20px; "copyAudioToUDP" : { "type" : "integer" }, + "copyAudioUseRTP" : { + "type" : "integer" + }, "udpAddress" : { "type" : "string" }, @@ -16921,7 +16924,7 @@ except ApiException as e:
- Generated 2018-01-25T00:10:31.068+01:00 + Generated 2018-02-05T00:57:57.193+01:00
diff --git a/swagger/sdrangel/code/qt5/client/SWGNFMDemodSettings.cpp b/swagger/sdrangel/code/qt5/client/SWGNFMDemodSettings.cpp index 5e1bd88b8..d323c99c6 100644 --- a/swagger/sdrangel/code/qt5/client/SWGNFMDemodSettings.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGNFMDemodSettings.cpp @@ -50,6 +50,7 @@ SWGNFMDemodSettings::init() { ctcss_index = 0; audio_sample_rate = 0; copy_audio_to_udp = 0; + copy_audio_use_rtp = 0; udp_address = new QString(""); udp_port = 0; rgb_color = 0; @@ -72,6 +73,7 @@ SWGNFMDemodSettings::cleanup() { + if(udp_address != nullptr) { delete udp_address; } @@ -107,6 +109,7 @@ SWGNFMDemodSettings::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&ctcss_index, pJson["ctcssIndex"], "qint32", ""); ::SWGSDRangel::setValue(&audio_sample_rate, pJson["audioSampleRate"], "qint32", ""); ::SWGSDRangel::setValue(©_audio_to_udp, pJson["copyAudioToUDP"], "qint32", ""); + ::SWGSDRangel::setValue(©_audio_use_rtp, pJson["copyAudioUseRTP"], "qint32", ""); ::SWGSDRangel::setValue(&udp_address, pJson["udpAddress"], "QString", "QString"); ::SWGSDRangel::setValue(&udp_port, pJson["udpPort"], "qint32", ""); ::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", ""); @@ -153,6 +156,8 @@ SWGNFMDemodSettings::asJsonObject() { obj->insert("copyAudioToUDP", QJsonValue(copy_audio_to_udp)); + obj->insert("copyAudioUseRTP", QJsonValue(copy_audio_use_rtp)); + toJsonValue(QString("udpAddress"), udp_address, obj, QString("QString")); obj->insert("udpPort", QJsonValue(udp_port)); @@ -281,6 +286,15 @@ SWGNFMDemodSettings::setCopyAudioToUdp(qint32 copy_audio_to_udp) { this->copy_audio_to_udp = copy_audio_to_udp; } +qint32 +SWGNFMDemodSettings::getCopyAudioUseRtp() { + return copy_audio_use_rtp; +} +void +SWGNFMDemodSettings::setCopyAudioUseRtp(qint32 copy_audio_use_rtp) { + this->copy_audio_use_rtp = copy_audio_use_rtp; +} + QString* SWGNFMDemodSettings::getUdpAddress() { return udp_address; diff --git a/swagger/sdrangel/code/qt5/client/SWGNFMDemodSettings.h b/swagger/sdrangel/code/qt5/client/SWGNFMDemodSettings.h index d030653e5..619bad4c3 100644 --- a/swagger/sdrangel/code/qt5/client/SWGNFMDemodSettings.h +++ b/swagger/sdrangel/code/qt5/client/SWGNFMDemodSettings.h @@ -81,6 +81,9 @@ public: qint32 getCopyAudioToUdp(); void setCopyAudioToUdp(qint32 copy_audio_to_udp); + qint32 getCopyAudioUseRtp(); + void setCopyAudioUseRtp(qint32 copy_audio_use_rtp); + QString* getUdpAddress(); void setUdpAddress(QString* udp_address); @@ -108,6 +111,7 @@ private: qint32 ctcss_index; qint32 audio_sample_rate; qint32 copy_audio_to_udp; + qint32 copy_audio_use_rtp; QString* udp_address; qint32 udp_port; qint32 rgb_color;