1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-09-05 14:47:50 -04:00

Added UDP sink copy to audio buffer

This commit is contained in:
f4exb 2017-08-24 11:49:47 +02:00
parent c46ad022b3
commit 3583996c4a
3 changed files with 73 additions and 30 deletions

View File

@ -22,7 +22,9 @@
#define MIN(x, y) ((x) < (y) ? (x) : (y)) #define MIN(x, y) ((x) < (y) ? (x) : (y))
AudioFifo::AudioFifo() : AudioFifo::AudioFifo() :
m_fifo(0) m_fifo(0),
m_udpSink(0),
m_copyToUDP(false)
{ {
m_size = 0; m_size = 0;
m_fill = 0; m_fill = 0;
@ -31,7 +33,7 @@ AudioFifo::AudioFifo() :
m_sampleSize = 0; m_sampleSize = 0;
} }
AudioFifo::AudioFifo(uint sampleSize, uint numSamples) : AudioFifo::AudioFifo(uint32_t sampleSize, uint32_t numSamples) :
m_fifo(0) m_fifo(0)
{ {
QMutexLocker mutexLocker(&m_mutex); QMutexLocker mutexLocker(&m_mutex);
@ -55,19 +57,24 @@ AudioFifo::~AudioFifo()
m_size = 0; m_size = 0;
} }
bool AudioFifo::setSize(uint sampleSize, uint numSamples) bool AudioFifo::setSize(uint32_t sampleSize, uint32_t numSamples)
{ {
QMutexLocker mutexLocker(&m_mutex); QMutexLocker mutexLocker(&m_mutex);
return create(sampleSize, numSamples); 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; QTime time;
uint total; uint32_t total;
uint remaining; uint32_t remaining;
uint copyLen; uint32_t copyLen;
if (m_copyToUDP && m_udpSink)
{
m_udpSink->write((qint16 *) data, numSamples);
}
if(m_fifo == 0) if(m_fifo == 0)
{ {
@ -141,12 +148,12 @@ uint AudioFifo::write(const quint8* data, uint numSamples, int timeout_ms)
return total; 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; QTime time;
uint total; uint32_t total;
uint remaining; uint32_t remaining;
uint copyLen; uint32_t copyLen;
if(m_fifo == 0) if(m_fifo == 0)
{ {
@ -220,7 +227,7 @@ uint AudioFifo::read(quint8* data, uint numSamples, int timeout_ms)
return total; return total;
} }
uint AudioFifo::drain(uint numSamples) uint AudioFifo::drain(uint32_t numSamples)
{ {
QMutexLocker mutexLocker(&m_mutex); QMutexLocker mutexLocker(&m_mutex);
@ -247,7 +254,7 @@ void AudioFifo::clear()
m_writeWaitCondition.wakeOne(); m_writeWaitCondition.wakeOne();
} }
bool AudioFifo::create(uint sampleSize, uint numSamples) bool AudioFifo::create(uint32_t sampleSize, uint32_t numSamples)
{ {
if(m_fifo != 0) if(m_fifo != 0)
{ {

View File

@ -22,46 +22,53 @@
#include <QMutex> #include <QMutex>
#include <QWaitCondition> #include <QWaitCondition>
#include "util/export.h" #include "util/export.h"
#include "util/udpsink.h"
class SDRANGEL_API AudioFifo : public QObject { class SDRANGEL_API AudioFifo : public QObject {
Q_OBJECT Q_OBJECT
public: public:
AudioFifo(); AudioFifo();
AudioFifo(uint sampleSize, uint numSamples); AudioFifo(uint32_t sampleSize, uint32_t numSamples);
~AudioFifo(); ~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); uint32_t write(const quint8* data, uint32_t numSamples, int timeout_ms = INT_MAX);
uint read(quint8* data, uint 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(); void clear();
inline uint flush() { return drain(m_fill); } inline uint32_t flush() { return drain(m_fill); }
inline uint fill() const { return m_fill; } inline uint32_t fill() const { return m_fill; }
inline bool isEmpty() const { return m_fill == 0; } inline bool isEmpty() const { return m_fill == 0; }
inline bool isFull() const { return m_fill == m_size; } 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<qint16> *udpSink) { m_udpSink = udpSink; }
void setCopyToUDP(bool copyToUDP) { m_copyToUDP = copyToUDP; }
private: private:
QMutex m_mutex; QMutex m_mutex;
qint8* m_fifo; qint8* m_fifo;
uint m_sampleSize; uint32_t m_sampleSize;
uint m_size; uint32_t m_size;
uint m_fill; uint32_t m_fill;
uint m_head; uint32_t m_head;
uint m_tail; uint32_t m_tail;
QMutex m_writeWaitLock; QMutex m_writeWaitLock;
QMutex m_readWaitLock; QMutex m_readWaitLock;
QWaitCondition m_writeWaitCondition; QWaitCondition m_writeWaitCondition;
QWaitCondition m_readWaitCondition; QWaitCondition m_readWaitCondition;
bool create(uint sampleSize, uint numSamples); UDPSink<qint16> *m_udpSink;
bool m_copyToUDP;
bool create(uint32_t sampleSize, uint32_t numSamples);
}; };
#endif // INCLUDE_AUDIOFIFO_H #endif // INCLUDE_AUDIOFIFO_H

View File

@ -62,6 +62,9 @@ public:
void setAddress(QString& address) { m_address.setAddress(address); } void setAddress(QString& address) { m_address.setAddress(address); }
void setPort(unsigned int port) { m_port = port; } void setPort(unsigned int port) { m_port = port; }
/**
* Write one sample
*/
void write(T sample) void write(T sample)
{ {
if (m_sampleBufferIndex < m_udpSamples) 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: private:
unsigned int m_udpSize; int m_udpSize;
unsigned int m_udpSamples; int m_udpSamples;
QHostAddress m_address; QHostAddress m_address;
unsigned int m_port; unsigned int m_port;
QUdpSocket *m_socket; QUdpSocket *m_socket;
T *m_sampleBuffer;; T *m_sampleBuffer;;
uint32_t m_sampleBufferIndex; int m_sampleBufferIndex;
}; };