From 3583996c4a2a316c0e7683b67e1007d639718c37 Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 24 Aug 2017 11:49:47 +0200 Subject: [PATCH] Added UDP sink copy to audio buffer --- sdrbase/audio/audiofifo.cpp | 33 ++++++++++++++++++++------------- sdrbase/audio/audiofifo.h | 35 +++++++++++++++++++++-------------- sdrbase/util/udpsink.h | 35 ++++++++++++++++++++++++++++++++--- 3 files changed, 73 insertions(+), 30 deletions(-) diff --git a/sdrbase/audio/audiofifo.cpp b/sdrbase/audio/audiofifo.cpp index 0b6962b6a..ef8cdece2 100644 --- a/sdrbase/audio/audiofifo.cpp +++ b/sdrbase/audio/audiofifo.cpp @@ -22,7 +22,9 @@ #define MIN(x, y) ((x) < (y) ? (x) : (y)) AudioFifo::AudioFifo() : - m_fifo(0) + m_fifo(0), + m_udpSink(0), + m_copyToUDP(false) { m_size = 0; m_fill = 0; @@ -31,7 +33,7 @@ AudioFifo::AudioFifo() : m_sampleSize = 0; } -AudioFifo::AudioFifo(uint sampleSize, uint numSamples) : +AudioFifo::AudioFifo(uint32_t sampleSize, uint32_t numSamples) : m_fifo(0) { QMutexLocker mutexLocker(&m_mutex); @@ -55,19 +57,24 @@ AudioFifo::~AudioFifo() m_size = 0; } -bool AudioFifo::setSize(uint sampleSize, uint numSamples) +bool AudioFifo::setSize(uint32_t sampleSize, uint32_t numSamples) { QMutexLocker mutexLocker(&m_mutex); return create(sampleSize, numSamples); } -uint AudioFifo::write(const quint8* data, uint numSamples, int timeout_ms) +uint AudioFifo::write(const quint8* data, uint32_t numSamples, int timeout_ms) { QTime time; - uint total; - uint remaining; - uint copyLen; + uint32_t total; + uint32_t remaining; + uint32_t copyLen; + + if (m_copyToUDP && m_udpSink) + { + m_udpSink->write((qint16 *) data, numSamples); + } if(m_fifo == 0) { @@ -141,12 +148,12 @@ uint AudioFifo::write(const quint8* data, uint numSamples, int timeout_ms) return total; } -uint AudioFifo::read(quint8* data, uint numSamples, int timeout_ms) +uint AudioFifo::read(quint8* data, uint32_t numSamples, int timeout_ms) { QTime time; - uint total; - uint remaining; - uint copyLen; + uint32_t total; + uint32_t remaining; + uint32_t copyLen; if(m_fifo == 0) { @@ -220,7 +227,7 @@ uint AudioFifo::read(quint8* data, uint numSamples, int timeout_ms) return total; } -uint AudioFifo::drain(uint numSamples) +uint AudioFifo::drain(uint32_t numSamples) { QMutexLocker mutexLocker(&m_mutex); @@ -247,7 +254,7 @@ void AudioFifo::clear() m_writeWaitCondition.wakeOne(); } -bool AudioFifo::create(uint sampleSize, uint numSamples) +bool AudioFifo::create(uint32_t sampleSize, uint32_t numSamples) { if(m_fifo != 0) { diff --git a/sdrbase/audio/audiofifo.h b/sdrbase/audio/audiofifo.h index ce6b1ba89..f88552ca1 100644 --- a/sdrbase/audio/audiofifo.h +++ b/sdrbase/audio/audiofifo.h @@ -22,46 +22,53 @@ #include #include #include "util/export.h" +#include "util/udpsink.h" class SDRANGEL_API AudioFifo : public QObject { Q_OBJECT public: AudioFifo(); - AudioFifo(uint sampleSize, uint numSamples); + AudioFifo(uint32_t sampleSize, uint32_t numSamples); ~AudioFifo(); - bool setSize(uint sampleSize, uint numSamples); + bool setSize(uint32_t sampleSize, uint32_t numSamples); - uint write(const quint8* data, uint numSamples, int timeout_ms = INT_MAX); - uint read(quint8* data, uint numSamples, int timeout_ms = INT_MAX); + uint32_t write(const quint8* data, uint32_t numSamples, int timeout_ms = INT_MAX); + uint32_t read(quint8* data, uint32_t numSamples, int timeout_ms = INT_MAX); - uint drain(uint numSamples); + uint32_t drain(uint32_t numSamples); void clear(); - inline uint flush() { return drain(m_fill); } - inline uint fill() const { return m_fill; } + inline uint32_t flush() { return drain(m_fill); } + inline uint32_t fill() const { return m_fill; } inline bool isEmpty() const { return m_fill == 0; } inline bool isFull() const { return m_fill == m_size; } - inline uint size() const { return m_size; } + inline uint32_t size() const { return m_size; } + + void setUDPSink(UDPSink *udpSink) { m_udpSink = udpSink; } + void setCopyToUDP(bool copyToUDP) { m_copyToUDP = copyToUDP; } private: QMutex m_mutex; qint8* m_fifo; - uint m_sampleSize; + uint32_t m_sampleSize; - uint m_size; - uint m_fill; - uint m_head; - uint m_tail; + uint32_t m_size; + uint32_t m_fill; + uint32_t m_head; + uint32_t m_tail; QMutex m_writeWaitLock; QMutex m_readWaitLock; QWaitCondition m_writeWaitCondition; QWaitCondition m_readWaitCondition; - bool create(uint sampleSize, uint numSamples); + UDPSink *m_udpSink; + bool m_copyToUDP; + + bool create(uint32_t sampleSize, uint32_t numSamples); }; #endif // INCLUDE_AUDIOFIFO_H diff --git a/sdrbase/util/udpsink.h b/sdrbase/util/udpsink.h index d3bb6916e..9c95b09b2 100644 --- a/sdrbase/util/udpsink.h +++ b/sdrbase/util/udpsink.h @@ -62,6 +62,9 @@ public: void setAddress(QString& address) { m_address.setAddress(address); } void setPort(unsigned int port) { m_port = port; } + /** + * Write one sample + */ void write(T sample) { if (m_sampleBufferIndex < m_udpSamples) @@ -77,14 +80,40 @@ public: } } + /** + * Write a bunch of samples + */ + void write(T *samples, int nbSamples) + { + int samplesIndex = 0; + + if (m_sampleBufferIndex + nbSamples > m_udpSamples) // fill remainder of buffer and send it + { + memcpy(&m_sampleBuffer[m_sampleBufferIndex], &samples[samplesIndex], (m_udpSamples - m_sampleBufferIndex)*sizeof(T)); // fill remainder of buffer + m_socket->writeDatagram((const char*)&m_sampleBuffer[0], (qint64 ) m_udpSize, m_address, m_port); // send buffer + samplesIndex += (m_udpSamples - m_sampleBufferIndex); + nbSamples -= (m_udpSamples - m_sampleBufferIndex); + m_sampleBufferIndex = 0; + } + + while (nbSamples > m_udpSamples) // send directly from input without buffering + { + m_socket->writeDatagram((const char*)&samples[samplesIndex], (qint64 ) m_udpSize, m_address, m_port); + samplesIndex += m_udpSamples; + nbSamples -= m_udpSamples; + } + + memcpy(&m_sampleBuffer[m_sampleBufferIndex], &samples[samplesIndex], nbSamples*sizeof(T)); // copy remainder of input to buffer + } + private: - unsigned int m_udpSize; - unsigned int m_udpSamples; + int m_udpSize; + int m_udpSamples; QHostAddress m_address; unsigned int m_port; QUdpSocket *m_socket; T *m_sampleBuffer;; - uint32_t m_sampleBufferIndex; + int m_sampleBufferIndex; };