mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-02-03 09:44:01 -05:00
NFM demod: GUI button and setting to use RTP over UDP for copy to audio
This commit is contained in:
parent
cbf229c15c
commit
2beba446f3
@ -81,12 +81,6 @@ NFMDemod::NFMDemod(DeviceSourceAPI *devieAPI) :
|
|||||||
m_audioNetSink = new AudioNetSink(this);
|
m_audioNetSink = new AudioNetSink(this);
|
||||||
m_audioNetSink->setDestination(m_settings.m_udpAddress, m_settings.m_udpPort);
|
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_channelizer = new DownChannelizer(this);
|
||||||
m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this);
|
m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this);
|
||||||
m_deviceAPI->addThreadedSink(m_threadedChannelizer);
|
m_deviceAPI->addThreadedSink(m_threadedChannelizer);
|
||||||
@ -106,6 +100,11 @@ NFMDemod::~NFMDemod()
|
|||||||
delete m_channelizer;
|
delete m_channelizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NFMDemod::isAudioNetSinkRTPCapable() const
|
||||||
|
{
|
||||||
|
return m_audioNetSink && m_audioNetSink->isRTPCapable();
|
||||||
|
}
|
||||||
|
|
||||||
float arctan2(Real y, Real x)
|
float arctan2(Real y, Real x)
|
||||||
{
|
{
|
||||||
Real coeff_1 = M_PI / 4;
|
Real coeff_1 = M_PI / 4;
|
||||||
@ -479,6 +478,26 @@ void NFMDemod::applySettings(const NFMDemodSettings& settings, bool force)
|
|||||||
setSelectedCtcssIndex(settings.m_ctcssIndex);
|
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;
|
m_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,6 +556,9 @@ int NFMDemod::webapiSettingsPutPatch(
|
|||||||
if (channelSettingsKeys.contains("copyAudioToUDP")) {
|
if (channelSettingsKeys.contains("copyAudioToUDP")) {
|
||||||
settings.m_copyAudioToUDP = response.getNfmDemodSettings()->getCopyAudioToUdp() != 0;
|
settings.m_copyAudioToUDP = response.getNfmDemodSettings()->getCopyAudioToUdp() != 0;
|
||||||
}
|
}
|
||||||
|
if (channelSettingsKeys.contains("copyAudioUseRTP")) {
|
||||||
|
settings.m_copyAudioUseRTP = response.getNfmDemodSettings()->getCopyAudioUseRtp() != 0;
|
||||||
|
}
|
||||||
if (channelSettingsKeys.contains("ctcssIndex")) {
|
if (channelSettingsKeys.contains("ctcssIndex")) {
|
||||||
settings.m_ctcssIndex = response.getNfmDemodSettings()->getCtcssIndex();
|
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()->setAudioMute(settings.m_audioMute ? 1 : 0);
|
||||||
response.getNfmDemodSettings()->setAudioSampleRate(settings.m_audioSampleRate);
|
response.getNfmDemodSettings()->setAudioSampleRate(settings.m_audioSampleRate);
|
||||||
response.getNfmDemodSettings()->setCopyAudioToUdp(settings.m_copyAudioToUDP ? 1 : 0);
|
response.getNfmDemodSettings()->setCopyAudioToUdp(settings.m_copyAudioToUDP ? 1 : 0);
|
||||||
|
response.getNfmDemodSettings()->setCopyAudioUseRtp(settings.m_copyAudioUseRTP ? 1 : 0);
|
||||||
response.getNfmDemodSettings()->setCtcssIndex(settings.m_ctcssIndex);
|
response.getNfmDemodSettings()->setCtcssIndex(settings.m_ctcssIndex);
|
||||||
response.getNfmDemodSettings()->setCtcssOn(settings.m_ctcssOn ? 1 : 0);
|
response.getNfmDemodSettings()->setCtcssOn(settings.m_ctcssOn ? 1 : 0);
|
||||||
response.getNfmDemodSettings()->setDeltaSquelch(settings.m_deltaSquelch ? 1 : 0);
|
response.getNfmDemodSettings()->setDeltaSquelch(settings.m_deltaSquelch ? 1 : 0);
|
||||||
|
@ -159,6 +159,8 @@ public:
|
|||||||
m_magsqCount = 0;
|
m_magsqCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isAudioNetSinkRTPCapable() const;
|
||||||
|
|
||||||
static const QString m_channelIdURI;
|
static const QString m_channelIdURI;
|
||||||
static const QString m_channelId;
|
static const QString m_channelId;
|
||||||
|
|
||||||
|
@ -211,6 +211,12 @@ void NFMDemodGUI::on_copyAudioToUDP_toggled(bool checked)
|
|||||||
applySettings();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NFMDemodGUI::on_useRTP_toggled(bool checked)
|
||||||
|
{
|
||||||
|
m_settings.m_copyAudioUseRTP = checked;
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
void NFMDemodGUI::on_ctcss_currentIndexChanged(int index)
|
void NFMDemodGUI::on_ctcss_currentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
m_settings.m_ctcssIndex = index;
|
m_settings.m_ctcssIndex = index;
|
||||||
@ -314,6 +320,7 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
|
|||||||
|
|
||||||
QChar delta = QChar(0x94, 0x03);
|
QChar delta = QChar(0x94, 0x03);
|
||||||
ui->deltaSquelch->setText(delta);
|
ui->deltaSquelch->setText(delta);
|
||||||
|
ui->useRTP->setEnabled(m_nfmDemod->isAudioNetSinkRTPCapable());
|
||||||
|
|
||||||
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||||
|
|
||||||
@ -393,6 +400,10 @@ void NFMDemodGUI::displaySettings()
|
|||||||
|
|
||||||
ui->ctcss->setCurrentIndex(m_settings.m_ctcssIndex);
|
ui->ctcss->setCurrentIndex(m_settings.m_ctcssIndex);
|
||||||
|
|
||||||
|
if (m_nfmDemod->isAudioNetSinkRTPCapable()) {
|
||||||
|
ui->useRTP->setChecked(m_settings.m_copyAudioUseRTP);
|
||||||
|
}
|
||||||
|
|
||||||
blockApplySettings(false);
|
blockApplySettings(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ private slots:
|
|||||||
void on_ctcssOn_toggled(bool checked);
|
void on_ctcssOn_toggled(bool checked);
|
||||||
void on_audioMute_toggled(bool checked);
|
void on_audioMute_toggled(bool checked);
|
||||||
void on_copyAudioToUDP_toggled(bool checked);
|
void on_copyAudioToUDP_toggled(bool checked);
|
||||||
|
void on_useRTP_toggled(bool checked);
|
||||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||||
void onMenuDialogCalled(const QPoint& p);
|
void onMenuDialogCalled(const QPoint& p);
|
||||||
void handleInputMessages();
|
void handleInputMessages();
|
||||||
|
@ -611,6 +611,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="ButtonSwitch" name="useRTP">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Use RTP protocol for sending audio via UDP</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>R</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -51,6 +51,7 @@ void NFMDemodSettings::resetToDefaults()
|
|||||||
m_ctcssIndex = 0;
|
m_ctcssIndex = 0;
|
||||||
m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate();
|
m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate();
|
||||||
m_copyAudioToUDP = false;
|
m_copyAudioToUDP = false;
|
||||||
|
m_copyAudioUseRTP = false;
|
||||||
m_udpAddress = "127.0.0.1";
|
m_udpAddress = "127.0.0.1";
|
||||||
m_udpPort = 9998;
|
m_udpPort = 9998;
|
||||||
m_rgbColor = QColor(255, 0, 0).rgb();
|
m_rgbColor = QColor(255, 0, 0).rgb();
|
||||||
@ -77,6 +78,7 @@ QByteArray NFMDemodSettings::serialize() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.writeString(14, m_title);
|
s.writeString(14, m_title);
|
||||||
|
s.writeBool(15, m_copyAudioUseRTP);
|
||||||
|
|
||||||
return s.final();
|
return s.final();
|
||||||
}
|
}
|
||||||
@ -120,6 +122,7 @@ bool NFMDemodSettings::deserialize(const QByteArray& data)
|
|||||||
d.readS32(11, &m_squelchGate, 5);
|
d.readS32(11, &m_squelchGate, 5);
|
||||||
d.readBool(12, &m_deltaSquelch, false);
|
d.readBool(12, &m_deltaSquelch, false);
|
||||||
d.readString(14, &m_title, "NFM Demodulator");
|
d.readString(14, &m_title, "NFM Demodulator");
|
||||||
|
d.readBool(15, &m_copyAudioUseRTP, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ struct NFMDemodSettings
|
|||||||
int m_ctcssIndex;
|
int m_ctcssIndex;
|
||||||
uint32_t m_audioSampleRate;
|
uint32_t m_audioSampleRate;
|
||||||
bool m_copyAudioToUDP;
|
bool m_copyAudioToUDP;
|
||||||
|
bool m_copyAudioUseRTP;
|
||||||
QString m_udpAddress;
|
QString m_udpAddress;
|
||||||
uint16_t m_udpPort;
|
uint16_t m_udpPort;
|
||||||
quint32 m_rgbColor;
|
quint32 m_rgbColor;
|
||||||
|
@ -56,6 +56,15 @@ AudioNetSink::~AudioNetSink()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AudioNetSink::isRTPCapable() const
|
||||||
|
{
|
||||||
|
#ifdef HAS_JRTPLIB
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool AudioNetSink::selectType(SinkType type)
|
bool AudioNetSink::selectType(SinkType type)
|
||||||
{
|
{
|
||||||
if (type == SinkUDP)
|
if (type == SinkUDP)
|
||||||
|
@ -43,6 +43,7 @@ public:
|
|||||||
void write(qint16 sample);
|
void write(qint16 sample);
|
||||||
void write(const AudioSample& sample);
|
void write(const AudioSample& sample);
|
||||||
|
|
||||||
|
bool isRTPCapable() const;
|
||||||
bool selectType(SinkType type);
|
bool selectType(SinkType type);
|
||||||
|
|
||||||
static const int m_udpBlockSize;
|
static const int m_udpBlockSize;
|
||||||
|
@ -1371,6 +1371,9 @@ margin-bottom: 20px;
|
|||||||
"copyAudioToUDP" : {
|
"copyAudioToUDP" : {
|
||||||
"type" : "integer"
|
"type" : "integer"
|
||||||
},
|
},
|
||||||
|
"copyAudioUseRTP" : {
|
||||||
|
"type" : "integer"
|
||||||
|
},
|
||||||
"udpAddress" : {
|
"udpAddress" : {
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
},
|
},
|
||||||
@ -16921,7 +16924,7 @@ except ApiException as e:
|
|||||||
</div>
|
</div>
|
||||||
<div id="generator">
|
<div id="generator">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
Generated 2018-01-25T00:10:31.068+01:00
|
Generated 2018-02-05T00:57:57.193+01:00
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -32,6 +32,8 @@ NFMDemodSettings:
|
|||||||
type: integer
|
type: integer
|
||||||
copyAudioToUDP:
|
copyAudioToUDP:
|
||||||
type: integer
|
type: integer
|
||||||
|
copyAudioUseRTP:
|
||||||
|
type: integer
|
||||||
udpAddress:
|
udpAddress:
|
||||||
type: string
|
type: string
|
||||||
udpPort:
|
udpPort:
|
||||||
|
@ -32,6 +32,8 @@ NFMDemodSettings:
|
|||||||
type: integer
|
type: integer
|
||||||
copyAudioToUDP:
|
copyAudioToUDP:
|
||||||
type: integer
|
type: integer
|
||||||
|
copyAudioUseRTP:
|
||||||
|
type: integer
|
||||||
udpAddress:
|
udpAddress:
|
||||||
type: string
|
type: string
|
||||||
udpPort:
|
udpPort:
|
||||||
|
@ -1371,6 +1371,9 @@ margin-bottom: 20px;
|
|||||||
"copyAudioToUDP" : {
|
"copyAudioToUDP" : {
|
||||||
"type" : "integer"
|
"type" : "integer"
|
||||||
},
|
},
|
||||||
|
"copyAudioUseRTP" : {
|
||||||
|
"type" : "integer"
|
||||||
|
},
|
||||||
"udpAddress" : {
|
"udpAddress" : {
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
},
|
},
|
||||||
@ -16921,7 +16924,7 @@ except ApiException as e:
|
|||||||
</div>
|
</div>
|
||||||
<div id="generator">
|
<div id="generator">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
Generated 2018-01-25T00:10:31.068+01:00
|
Generated 2018-02-05T00:57:57.193+01:00
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -50,6 +50,7 @@ SWGNFMDemodSettings::init() {
|
|||||||
ctcss_index = 0;
|
ctcss_index = 0;
|
||||||
audio_sample_rate = 0;
|
audio_sample_rate = 0;
|
||||||
copy_audio_to_udp = 0;
|
copy_audio_to_udp = 0;
|
||||||
|
copy_audio_use_rtp = 0;
|
||||||
udp_address = new QString("");
|
udp_address = new QString("");
|
||||||
udp_port = 0;
|
udp_port = 0;
|
||||||
rgb_color = 0;
|
rgb_color = 0;
|
||||||
@ -72,6 +73,7 @@ SWGNFMDemodSettings::cleanup() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(udp_address != nullptr) {
|
if(udp_address != nullptr) {
|
||||||
delete udp_address;
|
delete udp_address;
|
||||||
}
|
}
|
||||||
@ -107,6 +109,7 @@ SWGNFMDemodSettings::fromJsonObject(QJsonObject &pJson) {
|
|||||||
::SWGSDRangel::setValue(&ctcss_index, pJson["ctcssIndex"], "qint32", "");
|
::SWGSDRangel::setValue(&ctcss_index, pJson["ctcssIndex"], "qint32", "");
|
||||||
::SWGSDRangel::setValue(&audio_sample_rate, pJson["audioSampleRate"], "qint32", "");
|
::SWGSDRangel::setValue(&audio_sample_rate, pJson["audioSampleRate"], "qint32", "");
|
||||||
::SWGSDRangel::setValue(©_audio_to_udp, pJson["copyAudioToUDP"], "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_address, pJson["udpAddress"], "QString", "QString");
|
||||||
::SWGSDRangel::setValue(&udp_port, pJson["udpPort"], "qint32", "");
|
::SWGSDRangel::setValue(&udp_port, pJson["udpPort"], "qint32", "");
|
||||||
::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
|
::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
|
||||||
@ -153,6 +156,8 @@ SWGNFMDemodSettings::asJsonObject() {
|
|||||||
|
|
||||||
obj->insert("copyAudioToUDP", QJsonValue(copy_audio_to_udp));
|
obj->insert("copyAudioToUDP", QJsonValue(copy_audio_to_udp));
|
||||||
|
|
||||||
|
obj->insert("copyAudioUseRTP", QJsonValue(copy_audio_use_rtp));
|
||||||
|
|
||||||
toJsonValue(QString("udpAddress"), udp_address, obj, QString("QString"));
|
toJsonValue(QString("udpAddress"), udp_address, obj, QString("QString"));
|
||||||
|
|
||||||
obj->insert("udpPort", QJsonValue(udp_port));
|
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;
|
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*
|
QString*
|
||||||
SWGNFMDemodSettings::getUdpAddress() {
|
SWGNFMDemodSettings::getUdpAddress() {
|
||||||
return udp_address;
|
return udp_address;
|
||||||
|
@ -81,6 +81,9 @@ public:
|
|||||||
qint32 getCopyAudioToUdp();
|
qint32 getCopyAudioToUdp();
|
||||||
void setCopyAudioToUdp(qint32 copy_audio_to_udp);
|
void setCopyAudioToUdp(qint32 copy_audio_to_udp);
|
||||||
|
|
||||||
|
qint32 getCopyAudioUseRtp();
|
||||||
|
void setCopyAudioUseRtp(qint32 copy_audio_use_rtp);
|
||||||
|
|
||||||
QString* getUdpAddress();
|
QString* getUdpAddress();
|
||||||
void setUdpAddress(QString* udp_address);
|
void setUdpAddress(QString* udp_address);
|
||||||
|
|
||||||
@ -108,6 +111,7 @@ private:
|
|||||||
qint32 ctcss_index;
|
qint32 ctcss_index;
|
||||||
qint32 audio_sample_rate;
|
qint32 audio_sample_rate;
|
||||||
qint32 copy_audio_to_udp;
|
qint32 copy_audio_to_udp;
|
||||||
|
qint32 copy_audio_use_rtp;
|
||||||
QString* udp_address;
|
QString* udp_address;
|
||||||
qint32 udp_port;
|
qint32 udp_port;
|
||||||
qint32 rgb_color;
|
qint32 rgb_color;
|
||||||
|
Loading…
Reference in New Issue
Block a user