mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-05-29 05:22:25 -04:00
WFM demod: implement RTP over UDP for audio copy
This commit is contained in:
parent
b183a66d29
commit
7bf9252039
@ -25,6 +25,7 @@
|
|||||||
#include "dsp/threadedbasebandsamplesink.h"
|
#include "dsp/threadedbasebandsamplesink.h"
|
||||||
#include "device/devicesourceapi.h"
|
#include "device/devicesourceapi.h"
|
||||||
#include "audio/audiooutput.h"
|
#include "audio/audiooutput.h"
|
||||||
|
#include "audio/audionetsink.h"
|
||||||
#include "dsp/dspengine.h"
|
#include "dsp/dspengine.h"
|
||||||
#include "dsp/dspcommands.h"
|
#include "dsp/dspcommands.h"
|
||||||
|
|
||||||
@ -59,7 +60,8 @@ WFMDemod::WFMDemod(DeviceSourceAPI* deviceAPI) :
|
|||||||
m_audioBufferFill = 0;
|
m_audioBufferFill = 0;
|
||||||
|
|
||||||
DSPEngine::instance()->addAudioSink(&m_audioFifo);
|
DSPEngine::instance()->addAudioSink(&m_audioFifo);
|
||||||
m_udpBufferAudio = new UDPSink<qint16>(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_channelizer = new DownChannelizer(this);
|
||||||
m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this);
|
m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this);
|
||||||
@ -78,13 +80,17 @@ WFMDemod::~WFMDemod()
|
|||||||
}
|
}
|
||||||
|
|
||||||
DSPEngine::instance()->removeAudioSink(&m_audioFifo);
|
DSPEngine::instance()->removeAudioSink(&m_audioFifo);
|
||||||
|
delete m_audioNetSink;
|
||||||
|
|
||||||
m_deviceAPI->removeChannelAPI(this);
|
m_deviceAPI->removeChannelAPI(this);
|
||||||
m_deviceAPI->removeThreadedSink(m_threadedChannelizer);
|
m_deviceAPI->removeThreadedSink(m_threadedChannelizer);
|
||||||
delete m_threadedChannelizer;
|
delete m_threadedChannelizer;
|
||||||
delete m_channelizer;
|
delete m_channelizer;
|
||||||
|
}
|
||||||
|
|
||||||
delete m_udpBufferAudio;
|
bool WFMDemod::isAudioNetSinkRTPCapable() const
|
||||||
|
{
|
||||||
|
return m_audioNetSink && m_audioNetSink->isRTPCapable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst __attribute__((unused)))
|
void WFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst __attribute__((unused)))
|
||||||
@ -148,7 +154,9 @@ void WFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
|
|||||||
m_audioBuffer[m_audioBufferFill].l = sample;
|
m_audioBuffer[m_audioBufferFill].l = sample;
|
||||||
m_audioBuffer[m_audioBufferFill].r = 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);
|
||||||
|
}
|
||||||
|
|
||||||
++m_audioBufferFill;
|
++m_audioBufferFill;
|
||||||
|
|
||||||
@ -232,6 +240,14 @@ bool WFMDemod::handleMessage(const Message& cmd)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (BasebandSampleSink::MsgThreadedSink::match(cmd))
|
||||||
|
{
|
||||||
|
BasebandSampleSink::MsgThreadedSink& cfg = (BasebandSampleSink::MsgThreadedSink&) cmd;
|
||||||
|
const QThread *thread = cfg.getThread();
|
||||||
|
qDebug("WFMDemod::handleMessage: BasebandSampleSink::MsgThreadedSink: %p", thread);
|
||||||
|
m_audioNetSink->moveToThread(const_cast<QThread*>(thread)); // use the thread for udp sinks
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if (DSPSignalNotification::match(cmd))
|
else if (DSPSignalNotification::match(cmd))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -315,8 +331,27 @@ void WFMDemod::applySettings(const WFMDemodSettings& settings, bool force)
|
|||||||
if ((m_settings.m_udpAddress != settings.m_udpAddress)
|
if ((m_settings.m_udpAddress != settings.m_udpAddress)
|
||||||
|| (m_settings.m_udpPort != settings.m_udpPort) || force)
|
|| (m_settings.m_udpPort != settings.m_udpPort) || force)
|
||||||
{
|
{
|
||||||
m_udpBufferAudio->setAddress(const_cast<QString&>(settings.m_udpAddress));
|
m_audioNetSink->setDestination(settings.m_udpAddress, settings.m_udpPort);
|
||||||
m_udpBufferAudio->setPort(settings.m_udpPort);
|
}
|
||||||
|
|
||||||
|
if ((settings.m_copyAudioUseRTP != m_settings.m_copyAudioUseRTP) || force)
|
||||||
|
{
|
||||||
|
if (settings.m_copyAudioUseRTP)
|
||||||
|
{
|
||||||
|
if (m_audioNetSink->selectType(AudioNetSink::SinkRTP)) {
|
||||||
|
qDebug("WFMDemod::applySettings: set audio sink to RTP mode");
|
||||||
|
} else {
|
||||||
|
qWarning("WFMDemod::applySettings: RTP support for audio sink not available. Fall back too UDP");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_audioNetSink->selectType(AudioNetSink::SinkUDP)) {
|
||||||
|
qDebug("WFMDemod::applySettings: set audio sink to UDP mode");
|
||||||
|
} else {
|
||||||
|
qWarning("WFMDemod::applySettings: failed to set audio sink to UDP mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_settings = settings;
|
m_settings = settings;
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
class ThreadedBasebandSampleSink;
|
class ThreadedBasebandSampleSink;
|
||||||
class DownChannelizer;
|
class DownChannelizer;
|
||||||
class DeviceSourceAPI;
|
class DeviceSourceAPI;
|
||||||
|
class AudioNetSink;
|
||||||
|
|
||||||
class WFMDemod : public BasebandSampleSink, public ChannelSinkAPI {
|
class WFMDemod : public BasebandSampleSink, public ChannelSinkAPI {
|
||||||
public:
|
public:
|
||||||
@ -119,6 +120,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;
|
||||||
|
|
||||||
@ -155,7 +158,7 @@ private:
|
|||||||
|
|
||||||
AudioVector m_audioBuffer;
|
AudioVector m_audioBuffer;
|
||||||
uint m_audioBufferFill;
|
uint m_audioBufferFill;
|
||||||
UDPSink<qint16> *m_udpBufferAudio;
|
AudioNetSink *m_audioNetSink;
|
||||||
|
|
||||||
AudioFifo m_audioFifo;
|
AudioFifo m_audioFifo;
|
||||||
SampleVector m_sampleBuffer;
|
SampleVector m_sampleBuffer;
|
||||||
|
@ -137,6 +137,12 @@ void WFMDemodGUI::on_copyAudioToUDP_toggled(bool checked)
|
|||||||
applySettings();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WFMDemodGUI::on_useRTP_toggled(bool checked)
|
||||||
|
{
|
||||||
|
m_settings.m_copyAudioUseRTP = checked;
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
void WFMDemodGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused)))
|
void WFMDemodGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused)))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -207,6 +213,10 @@ WFMDemodGUI::WFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
|
|||||||
m_deviceUISet->addChannelMarker(&m_channelMarker);
|
m_deviceUISet->addChannelMarker(&m_channelMarker);
|
||||||
m_deviceUISet->addRollupWidget(this);
|
m_deviceUISet->addRollupWidget(this);
|
||||||
|
|
||||||
|
if (!m_wfmDemod->isAudioNetSinkRTPCapable()) {
|
||||||
|
ui->useRTP->hide();
|
||||||
|
}
|
||||||
|
|
||||||
connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
|
connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
|
||||||
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
|
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
|
||||||
|
|
||||||
@ -269,6 +279,10 @@ void WFMDemodGUI::displaySettings()
|
|||||||
ui->squelch->setValue(m_settings.m_squelch);
|
ui->squelch->setValue(m_settings.m_squelch);
|
||||||
ui->squelchText->setText(QString("%1 dB").arg(m_settings.m_squelch));
|
ui->squelchText->setText(QString("%1 dB").arg(m_settings.m_squelch));
|
||||||
|
|
||||||
|
if (m_wfmDemod->isAudioNetSinkRTPCapable()) {
|
||||||
|
ui->useRTP->setChecked(m_settings.m_copyAudioUseRTP);
|
||||||
|
}
|
||||||
|
|
||||||
blockApplySettings(false);
|
blockApplySettings(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ private slots:
|
|||||||
void on_squelch_valueChanged(int value);
|
void on_squelch_valueChanged(int value);
|
||||||
void on_audioMute_toggled(bool checked);
|
void on_audioMute_toggled(bool checked);
|
||||||
void on_copyAudioToUDP_toggled(bool copy);
|
void on_copyAudioToUDP_toggled(bool copy);
|
||||||
|
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 tick();
|
void tick();
|
||||||
|
@ -384,6 +384,16 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="useRTP">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Kiki koko kuku cacaboudin</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>R</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="audioMute">
|
<widget class="QToolButton" name="audioMute">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -44,6 +44,7 @@ void WFMDemodSettings::resetToDefaults()
|
|||||||
m_audioMute = false;
|
m_audioMute = false;
|
||||||
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 = 9999;
|
m_udpPort = 9999;
|
||||||
m_rgbColor = QColor(0, 0, 255).rgb();
|
m_rgbColor = QColor(0, 0, 255).rgb();
|
||||||
|
@ -32,6 +32,7 @@ struct WFMDemodSettings
|
|||||||
bool m_audioMute;
|
bool m_audioMute;
|
||||||
quint32 m_audioSampleRate;
|
quint32 m_audioSampleRate;
|
||||||
bool m_copyAudioToUDP;
|
bool m_copyAudioToUDP;
|
||||||
|
bool m_copyAudioUseRTP;
|
||||||
QString m_udpAddress;
|
QString m_udpAddress;
|
||||||
quint16 m_udpPort;
|
quint16 m_udpPort;
|
||||||
quint32 m_rgbColor;
|
quint32 m_rgbColor;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user