diff --git a/sdrbase/audio/audionetsink.cpp b/sdrbase/audio/audionetsink.cpp
index d0dbb372c..7de15b3ee 100644
--- a/sdrbase/audio/audionetsink.cpp
+++ b/sdrbase/audio/audionetsink.cpp
@@ -15,6 +15,8 @@
// along with this program. If not, see . //
///////////////////////////////////////////////////////////////////////////////////
+#include
+
#include "audionetsink.h"
#include "util/rtpsink.h"
@@ -33,7 +35,7 @@ AudioNetSink::AudioNetSink(QObject *parent) :
m_bufferIndex(0),
m_port(9998)
{
- memset(m_data, 0, 65536);
+ std::fill(m_data, m_data+m_dataBlockSize, 0);
m_udpSocket = new QUdpSocket(parent);
}
@@ -47,7 +49,7 @@ AudioNetSink::AudioNetSink(QObject *parent, int sampleRate, bool stereo) :
m_bufferIndex(0),
m_port(9998)
{
- memset(m_data, 0, 65536);
+ std::fill(m_data, m_data+m_dataBlockSize, 0);
m_udpSocket = new QUdpSocket(parent);
m_rtpBufferAudio = new RTPSink(m_udpSocket, sampleRate, stereo);
}
@@ -130,6 +132,9 @@ void AudioNetSink::setParameters(Codec codec, bool stereo, int sampleRate)
case CodecL8:
m_rtpBufferAudio->setPayloadInformation(RTPSink::PayloadL8, sampleRate);
break;
+ case CodecG722:
+ m_rtpBufferAudio->setPayloadInformation(RTPSink::PayloadG722, sampleRate/2);
+ break;
case CodecL16: // actually no codec
default:
m_rtpBufferAudio->setPayloadInformation(stereo ? RTPSink::PayloadL16Stereo : RTPSink::PayloadL16Mono, sampleRate);
@@ -173,35 +178,44 @@ void AudioNetSink::write(qint16 isample)
m_udpSocket->writeDatagram((const char*)m_data, (qint64 ) m_udpBlockSize, m_address, m_port);
m_bufferIndex = 0;
}
- else
+
+ switch(m_codec)
{
- switch(m_codec)
- {
- case CodecPCMA:
- case CodecPCMU:
- {
- qint8 *p = (qint8*) &m_data[m_bufferIndex];
- *p = m_audioCompressor.compress8(sample);
- m_bufferIndex += sizeof(qint8);
- }
- break;
- case CodecL8:
- {
- qint8 *p = (qint8*) &m_data[m_bufferIndex];
- *p = sample / 256;
- m_bufferIndex += sizeof(qint8);
- }
- break;
- case CodecL16:
- default:
- {
- qint16 *p = (qint16*) &m_data[m_bufferIndex];
- *p = sample;
- m_bufferIndex += sizeof(qint16);
- }
- break;
+ case CodecPCMA:
+ case CodecPCMU:
+ {
+ qint8 *p = (qint8*) &m_data[m_bufferIndex];
+ *p = m_audioCompressor.compress8(sample);
+ m_bufferIndex += sizeof(qint8);
+ }
+ break;
+ case CodecL8:
+ {
+ qint8 *p = (qint8*) &m_data[m_bufferIndex];
+ *p = sample / 256;
+ m_bufferIndex += sizeof(qint8);
+ }
+ break;
+ case CodecG722:
+ {
+ qint16 *p = (qint16*) &m_data[m_udpBlockSize + 2*m_bufferIndex];
+ *p = sample;
+ m_bufferIndex += 1;
+
+ if (m_bufferIndex == m_udpBlockSize) {
+ m_g722.encode((uint8_t *) m_data, (const int16_t*) &m_data[3*m_udpBlockSize], m_udpBlockSize);
}
}
+ break;
+ case CodecL16:
+ default:
+ {
+ qint16 *p = (qint16*) &m_data[m_bufferIndex];
+ *p = sample;
+ m_bufferIndex += sizeof(qint16);
+ }
+ break;
+ }
}
else if (m_type == SinkRTP)
{
@@ -220,6 +234,22 @@ void AudioNetSink::write(qint16 isample)
m_rtpBufferAudio->write((uint8_t *) &p);
}
break;
+ case CodecG722:
+ {
+ if (m_bufferIndex >= m_g722BlockSize)
+ {
+ static const int sz = m_g722BlockSize / sizeof(int16_t);
+ uint8_t g722_data[sz];
+ m_g722.encode(g722_data, (const int16_t*) m_data, sz);
+ m_rtpBufferAudio->write(g722_data, sz);
+ m_bufferIndex = 0;
+ }
+
+ qint16 *p = (qint16*) &m_data[m_bufferIndex];
+ *p = sample;
+ m_bufferIndex += sizeof(qint16);
+ }
+ break;
case CodecL16:
default:
m_rtpBufferAudio->write((uint8_t *) &sample);
diff --git a/sdrbase/audio/audionetsink.h b/sdrbase/audio/audionetsink.h
index 02db8e709..b60ebdaf4 100644
--- a/sdrbase/audio/audionetsink.h
+++ b/sdrbase/audio/audionetsink.h
@@ -21,6 +21,7 @@
#include "dsp/dsptypes.h"
#include "audiofilter.h"
#include "audiocompressor.h"
+#include "audiog722.h"
#include "export.h"
#include
@@ -44,7 +45,8 @@ public:
CodecL16, //!< Linear 16 bit samples (no formatting)
CodecL8, //!< Linear 8 bit samples
CodecPCMA, //!< PCM A-law 8 bit samples
- CodecPCMU //!< PCM Mu-law 8 bit samples
+ CodecPCMU, //!< PCM Mu-law 8 bit samples
+ CodecG722 //!< G722 compressed 8 bit samples 16kS/s in 8kS/s out
} Codec;
AudioNetSink(QObject *parent); //!< without RTP
@@ -66,6 +68,8 @@ public:
void moveToThread(QThread *thread);
static const int m_udpBlockSize;
+ static const int m_dataBlockSize = 65536;
+ static const int m_g722BlockSize = 1024; // size in bytes
protected:
SinkType m_type;
@@ -73,11 +77,12 @@ protected:
QUdpSocket *m_udpSocket;
RTPSink *m_rtpBufferAudio;
AudioCompressor m_audioCompressor;
+ AudioG722 m_g722;
AudioFilter m_audioFilter;
int m_sampleRate;
uint32_t m_decimation;
uint32_t m_decimationCount;
- char m_data[65536];
+ char m_data[m_dataBlockSize];
unsigned int m_bufferIndex;
QHostAddress m_address;
unsigned int m_port;
diff --git a/sdrbase/audio/audiooutput.h b/sdrbase/audio/audiooutput.h
index 5c389c731..e5fea5926 100644
--- a/sdrbase/audio/audiooutput.h
+++ b/sdrbase/audio/audiooutput.h
@@ -46,7 +46,8 @@ public:
UDPCodecL16, //!< Linear 16 bit (no codec)
UDPCodecL8, //!< Linear 8 bit
UDPCodecALaw, //!< PCM A-law 8 bit
- UDPCodecULaw //!< PCM Mu-law 8 bit
+ UDPCodecULaw, //!< PCM Mu-law 8 bit
+ UDPCodecG722 //!< G722 compression
};
AudioOutput();
diff --git a/sdrbase/util/rtpsink.cpp b/sdrbase/util/rtpsink.cpp
index 999b16679..9e92793c7 100644
--- a/sdrbase/util/rtpsink.cpp
+++ b/sdrbase/util/rtpsink.cpp
@@ -104,6 +104,12 @@ void RTPSink::setPayloadInformation(PayloadType payloadType, int sampleRate)
m_packetSamples = m_sampleRate / 50; // 20ms packet samples
timestampinc = m_sampleRate / 100; // 2 channels
break;
+ case PayloadG722:
+ m_sampleBytes = 1;
+ m_rtpSession.SetDefaultPayloadType(9);
+ m_packetSamples = m_sampleRate / 50; // 20ms packet samples
+ timestampinc = m_sampleRate / 50; // 1 channel
+ break;
case PayloadL16Mono:
default:
m_sampleBytes = 2;
@@ -226,10 +232,10 @@ void RTPSink::write(const uint8_t *sampleByte)
qCritical("RTPSink::write: cannot write packet: %s", qrtplib::RTPGetErrorString(status).c_str());
}
- writeNetBuf(&m_byteBuffer[0],
- sampleByte,
- elemLength(m_payloadType),
- m_sampleBytes,
+ writeNetBuf(&m_byteBuffer[0],
+ sampleByte,
+ elemLength(m_payloadType),
+ m_sampleBytes,
m_endianReverse);
m_sampleBufferIndex = 1;
}
diff --git a/sdrbase/util/rtpsink.h b/sdrbase/util/rtpsink.h
index ea69b4549..8f6a421ac 100644
--- a/sdrbase/util/rtpsink.h
+++ b/sdrbase/util/rtpsink.h
@@ -44,7 +44,8 @@ public:
PayloadL16Stereo,
PayloadL8,
PayloadPCMA8,
- PayloadPCMU8
+ PayloadPCMU8,
+ PayloadG722
} PayloadType;
RTPSink(QUdpSocket *udpSocket, int sampleRate, bool stereo);
diff --git a/sdrgui/gui/audiodialog.cpp b/sdrgui/gui/audiodialog.cpp
index 2b59d3af0..167184f84 100644
--- a/sdrgui/gui/audiodialog.cpp
+++ b/sdrgui/gui/audiodialog.cpp
@@ -1,10 +1,29 @@
-#include "audiodialog.h"
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2015-2019 F4EXB //
+// written by Edouard Griffiths //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
-#include