From f297298adba41e4a9e9b23f2f4b68442fb966c64 Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 3 Dec 2015 04:02:21 +0100 Subject: [PATCH] UDP source: basic audio return via UDP --- plugins/channel/udpsrc/udpsrc.cpp | 75 +++++++++++++++++++++++++++++-- plugins/channel/udpsrc/udpsrc.h | 18 ++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/plugins/channel/udpsrc/udpsrc.cpp b/plugins/channel/udpsrc/udpsrc.cpp index 008cdb2d6..14e8c60c5 100644 --- a/plugins/channel/udpsrc/udpsrc.cpp +++ b/plugins/channel/udpsrc/udpsrc.cpp @@ -18,18 +18,25 @@ #include #include +#include #include "dsp/channelizer.h" +#include "dsp/dspengine.h" #include "udpsrcgui.h" MESSAGE_CLASS_DEFINITION(UDPSrc::MsgUDPSrcConfigure, Message) MESSAGE_CLASS_DEFINITION(UDPSrc::MsgUDPSrcSpectrum, Message) UDPSrc::UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, SampleSink* spectrum) : - m_settingsMutex(QMutex::Recursive) + m_settingsMutex(QMutex::Recursive), + m_audioFifo(4, 24000) { setObjectName("UDPSrc"); m_socket = new QUdpSocket(this); + m_audioSocket = new QUdpSocket(this); + + m_audioBuffer.resize(1<<9); + m_audioBufferFill = 0; m_inputSampleRate = 96000; m_sampleFormat = FormatSSB; @@ -53,13 +60,26 @@ UDPSrc::UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, SampleSink* s m_magsq = 0; m_sampleBufferSSB.resize(udpFftLen); UDPFilter = new fftfilt(0.3 / 48.0, 16.0 / 48.0, udpFftLen); - // if (!TCPFilter) segfault; + + if (m_audioSocket->bind(QHostAddress::LocalHost, m_udpPort-1)) + { + qDebug("UDPSrc::UDPSrc: bind audio socket to port %d", m_udpPort - 1); + connect(m_audioSocket, SIGNAL(readyRead()), this, SLOT(audioReadyRead())); + } + else + { + qWarning("UDPSrc::UDPSrc: cannot bind audio port"); + } + + DSPEngine::instance()->addAudioSink(&m_audioFifo); } UDPSrc::~UDPSrc() { + delete m_audioSocket; delete m_socket; if (UDPFilter) delete UDPFilter; + DSPEngine::instance()->removeAudioSink(&m_audioFifo); } void UDPSrc::configure(MessageQueue* messageQueue, SampleFormat sampleFormat, Real outputSampleRate, Real rfBandwidth, QString& udpAddress, int udpPort, int boost) @@ -215,6 +235,11 @@ bool UDPSrc::handleMessage(const Message& cmd) if (cfg.getUDPPort() != m_udpPort) { m_udpPort = cfg.getUDPPort(); + + if (!m_audioSocket->bind(QHostAddress::Any, m_udpPort-1)) + { + qWarning("UDPSrc::handleMessage: cannot bind audio socket"); + } } m_boost = cfg.getBoost(); @@ -232,7 +257,7 @@ bool UDPSrc::handleMessage(const Message& cmd) m_settingsMutex.unlock(); - qDebug() << " - MsgUDPSrcConfigure: m_sampleFormat: " << m_sampleFormat + qDebug() << "UDPSrc::handleMessage: MsgUDPSrcConfigure: m_sampleFormat: " << m_sampleFormat << " m_outputSampleRate: " << m_outputSampleRate << " m_rfBandwidth: " << m_rfBandwidth << " m_boost: " << m_boost @@ -247,7 +272,7 @@ bool UDPSrc::handleMessage(const Message& cmd) m_spectrumEnabled = spc.getEnabled(); - qDebug() << " - MsgUDPSrcSpectrum: m_spectrumEnabled: " << m_spectrumEnabled; + qDebug() << "UDPSrc::handleMessage: MsgUDPSrcSpectrum: m_spectrumEnabled: " << m_spectrumEnabled; return true; } @@ -263,3 +288,45 @@ bool UDPSrc::handleMessage(const Message& cmd) } } } + +void UDPSrc::audioReadyRead() +{ + QByteArray buffer; + + while (m_audioSocket->hasPendingDatagrams()) + { + buffer.resize(m_audioSocket->pendingDatagramSize()); + m_audioSocket->readDatagram(buffer.data(), buffer.size(), 0, 0); + //qDebug("UDPSrc::audioReadyRead: %d", buffer.size()); + + for (int i = 0; i < buffer.size() - 3; i += 4) + { + qint16 l_sample = (qint16) *(&buffer.data()[i]); + qint16 r_sample = (qint16) *(&buffer.data()[i+2]); + m_audioBuffer[m_audioBufferFill].l = l_sample * 100; + m_audioBuffer[m_audioBufferFill].r = r_sample * 100; + ++m_audioBufferFill; + + if (m_audioBufferFill >= m_audioBuffer.size()) + { + uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1); + + if (res != m_audioBufferFill) + { + qDebug("UDPSrc::audioReadyRead: lost %u samples", m_audioBufferFill - res); + } + + m_audioBufferFill = 0; + } + } + + if (m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 0) != m_audioBufferFill) + { + qDebug("UDPSrc::audioReadyRead: lost samples"); + } + + m_audioBufferFill = 0; + } + + //qDebug("UDPSrc::audioReadyRead: done"); +} diff --git a/plugins/channel/udpsrc/udpsrc.h b/plugins/channel/udpsrc/udpsrc.h index ddb1e9e57..c50a7fb78 100644 --- a/plugins/channel/udpsrc/udpsrc.h +++ b/plugins/channel/udpsrc/udpsrc.h @@ -8,6 +8,8 @@ #include "dsp/fftfilt.h" #include "dsp/interpolator.h" #include "util/message.h" +#include "audio/audiofifo.h" + #define udpFftLen 2048 @@ -25,6 +27,13 @@ public: FormatNone }; + struct AudioSample { + qint16 l; + qint16 r; + }; + + typedef std::vector AudioVector; + UDPSrc(MessageQueue* uiMessageQueue, UDPSrcGUI* udpSrcGUI, SampleSink* spectrum); virtual ~UDPSrc(); @@ -37,6 +46,9 @@ public: virtual void stop(); virtual bool handleMessage(const Message& cmd); +public slots: + void audioReadyRead(); + protected: class MsgUDPSrcConfigure : public Message { MESSAGE_CLASS_DECLARATION @@ -95,6 +107,7 @@ protected: MessageQueue* m_uiMessageQueue; UDPSrcGUI* m_udpSrcGUI; QUdpSocket *m_socket; + QUdpSocket *m_audioSocket; int m_inputSampleRate; @@ -116,6 +129,11 @@ protected: SampleVector m_sampleBuffer; SampleVector m_sampleBufferSSB; + + AudioVector m_audioBuffer; + uint m_audioBufferFill; + AudioFifo m_audioFifo; + SampleSink* m_spectrum; bool m_spectrumEnabled;