From 5e776596b5745d356577363a99800867c4b0b33e Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 27 Mar 2018 00:09:52 +0200 Subject: [PATCH] Multiple audio support: RTP rate is device sample rate --- sdrbase/audio/audiodevicemanager.cpp | 2 + sdrbase/audio/audionetsink.cpp | 5 ++ sdrbase/audio/audionetsink.h | 1 + sdrbase/audio/audiooutput.cpp | 11 +++-- sdrbase/audio/audiooutput.h | 1 + sdrbase/util/rtpsink.cpp | 70 +++++++++++++++++++++++++++- sdrbase/util/rtpsink.h | 1 + 7 files changed, 86 insertions(+), 5 deletions(-) diff --git a/sdrbase/audio/audiodevicemanager.cpp b/sdrbase/audio/audiodevicemanager.cpp index ddae0ba9a..d150b7244 100644 --- a/sdrbase/audio/audiodevicemanager.cpp +++ b/sdrbase/audio/audiodevicemanager.cpp @@ -573,6 +573,8 @@ void AudioDeviceManager::setOutputDeviceInfo(int outputDeviceIndex, const Output audioOutput->setUdpCopyToUDP(deviceInfo.copyToUDP); audioOutput->setUdpDestination(deviceInfo.udpAddress, deviceInfo.udpPort); audioOutput->setUdpUseRTP(deviceInfo.udpUseRTP); + audioOutput->setUdpChannelMode(deviceInfo.udpChannelMode); + audioOutput->setUdpChannelFormat(deviceInfo.udpChannelMode == AudioOutput::UDPChannelStereo, deviceInfo.sampleRate); } void AudioDeviceManager::unsetOutputDeviceInfo(int outputDeviceIndex) diff --git a/sdrbase/audio/audionetsink.cpp b/sdrbase/audio/audionetsink.cpp index 11b63c446..a8747ecdc 100644 --- a/sdrbase/audio/audionetsink.cpp +++ b/sdrbase/audio/audionetsink.cpp @@ -94,6 +94,11 @@ void AudioNetSink::setStereo(bool stereo) m_rtpBufferAudio->setPayloadType(stereo ? RTPSink::PayloadL16Stereo : RTPSink::PayloadL16Mono); } +void AudioNetSink::setParameters(bool stereo, int sampleRate) +{ + m_rtpBufferAudio->setPayloadInformation(stereo ? RTPSink::PayloadL16Stereo : RTPSink::PayloadL16Mono, sampleRate); +} + void AudioNetSink::write(qint16 sample) { if (m_type == SinkUDP) diff --git a/sdrbase/audio/audionetsink.h b/sdrbase/audio/audionetsink.h index 4d05e144f..3e7fe1a1c 100644 --- a/sdrbase/audio/audionetsink.h +++ b/sdrbase/audio/audionetsink.h @@ -44,6 +44,7 @@ public: void addDestination(const QString& address, uint16_t port); void deleteDestination(const QString& address, uint16_t port); void setStereo(bool stereo); + void setParameters(bool stereo, int sampleRate); void write(qint16 sample); void write(qint16 lSample, qint16 rSample); diff --git a/sdrbase/audio/audiooutput.cpp b/sdrbase/audio/audiooutput.cpp index e2da793a8..bf905e6ff 100644 --- a/sdrbase/audio/audiooutput.cpp +++ b/sdrbase/audio/audiooutput.cpp @@ -197,13 +197,16 @@ void AudioOutput::setUdpUseRTP(bool useRTP) void AudioOutput::setUdpChannelMode(UDPChannelMode udpChannelMode) { - if (m_audioNetSink) { - m_audioNetSink->setStereo(udpChannelMode == UDPChannelStereo); - } - m_udpChannelMode = udpChannelMode; } +void AudioOutput::setUdpChannelFormat(bool stereo, int sampleRate) +{ + if (m_audioNetSink) { + m_audioNetSink->setParameters(stereo, sampleRate); + } +} + qint64 AudioOutput::readData(char* data, qint64 maxLen) { //qDebug("AudioOutput::readData: %lld", maxLen); diff --git a/sdrbase/audio/audiooutput.h b/sdrbase/audio/audiooutput.h index 910407aa9..34da30f3e 100644 --- a/sdrbase/audio/audiooutput.h +++ b/sdrbase/audio/audiooutput.h @@ -58,6 +58,7 @@ public: void setUdpCopyToUDP(bool copyToUDP); void setUdpUseRTP(bool useRTP); void setUdpChannelMode(UDPChannelMode udpChannelMode); + void setUdpChannelFormat(bool stereo, int sampleRate); private: QMutex m_mutex; diff --git a/sdrbase/util/rtpsink.cpp b/sdrbase/util/rtpsink.cpp index b3cbf5871..7e2020f89 100644 --- a/sdrbase/util/rtpsink.cpp +++ b/sdrbase/util/rtpsink.cpp @@ -53,7 +53,7 @@ RTPSink::RTPSink(QUdpSocket *udpSocket, bool stereo) : qDebug("RTPSink::RTPSink: created session: %s", qrtplib::RTPGetErrorString(status).c_str()); } - setPayloadType(m_payloadType); + setPayloadInformation(m_payloadType, m_sampleRate); m_valid = true; uint32_t endianTest32 = 1; @@ -71,6 +71,74 @@ RTPSink::~RTPSink() } } +void RTPSink::setPayloadInformation(PayloadType payloadType, int sampleRate) +{ + uint32_t timestampinc; + QMutexLocker locker(&m_mutex); + + qDebug("RTPSink::setPayloadType: %d sampleRate: %d", payloadType, sampleRate); + + switch (payloadType) + { + case PayloadL16Stereo: + m_sampleBytes = 4; + m_rtpSession.SetDefaultPayloadType(96); + timestampinc = m_sampleRate / 100; + break; + case PayloadL16Mono: + default: + m_sampleBytes = 2; + m_rtpSession.SetDefaultPayloadType(96); + timestampinc = m_sampleRate / 50; + break; + } + + m_packetSamples = m_sampleRate/50; // 20ms packet samples + m_bufferSize = m_packetSamples * m_sampleBytes; + + if (m_byteBuffer) { + delete[] m_byteBuffer; + } + + m_byteBuffer = new uint8_t[m_bufferSize]; + m_sampleBufferIndex = 0; + m_payloadType = payloadType; + + int status = m_rtpSession.SetTimestampUnit(1.0 / (double) m_sampleRate); + + if (status < 0) { + qCritical("RTPSink::setPayloadType: cannot set timestamp unit: %s", qrtplib::RTPGetErrorString(status).c_str()); + } else { + qDebug("RTPSink::setPayloadType: timestamp unit set to %f: %s", + 1.0 / (double) m_sampleRate, + qrtplib::RTPGetErrorString(status).c_str()); + } + + status = m_rtpSession.SetDefaultMark(false); + + if (status < 0) { + qCritical("RTPSink::setPayloadType: cannot set default mark: %s", qrtplib::RTPGetErrorString(status).c_str()); + } else { + qDebug("RTPSink::setPayloadType: set default mark to false: %s", qrtplib::RTPGetErrorString(status).c_str()); + } + + status = m_rtpSession.SetDefaultTimestampIncrement(timestampinc); + + if (status < 0) { + qCritical("RTPSink::setPayloadType: cannot set default timestamp increment: %s", qrtplib::RTPGetErrorString(status).c_str()); + } else { + qDebug("RTPSink::setPayloadType: set default timestamp increment to %d: %s", timestampinc, qrtplib::RTPGetErrorString(status).c_str()); + } + + status = m_rtpSession.SetMaximumPacketSize(m_bufferSize+40); + + if (status < 0) { + qCritical("RTPSink::setPayloadType: cannot set maximum packet size: %s", qrtplib::RTPGetErrorString(status).c_str()); + } else { + qDebug("RTPSink::setPayloadType: set maximum packet size to %d bytes: %s", m_bufferSize+40, qrtplib::RTPGetErrorString(status).c_str()); + } +} + void RTPSink::setPayloadType(PayloadType payloadType) { uint32_t timestampinc; diff --git a/sdrbase/util/rtpsink.h b/sdrbase/util/rtpsink.h index 9ef8afc3f..e264ae52a 100644 --- a/sdrbase/util/rtpsink.h +++ b/sdrbase/util/rtpsink.h @@ -49,6 +49,7 @@ public: bool isValid() const { return m_valid; } void setPayloadType(PayloadType payloadType); + void setPayloadInformation(PayloadType payloadType, int sampleRate); void setDestination(const QString& address, uint16_t port); void deleteDestination(const QString& address, uint16_t port);