diff --git a/sdrbase/audio/audiodevicemanager.cpp b/sdrbase/audio/audiodevicemanager.cpp index dc60cfff6..9bd5b9416 100644 --- a/sdrbase/audio/audiodevicemanager.cpp +++ b/sdrbase/audio/audiodevicemanager.cpp @@ -614,6 +614,7 @@ void AudioDeviceManager::setOutputDeviceInfo(int outputDeviceIndex, const Output audioOutput->setUdpUseRTP(deviceInfo.udpUseRTP); audioOutput->setUdpChannelMode(deviceInfo.udpChannelMode); audioOutput->setUdpChannelFormat(deviceInfo.udpChannelCodec, deviceInfo.udpChannelMode == AudioOutput::UDPChannelStereo, deviceInfo.sampleRate); + audioOutput->setUdpDecimation(deviceInfo.decimationFactor); qDebug("AudioDeviceManager::setOutputDeviceInfo: index: %d device: %s updated", outputDeviceIndex, qPrintable(deviceName)); diff --git a/sdrbase/audio/audionetsink.cpp b/sdrbase/audio/audionetsink.cpp index a5ebc4af8..3f7a61f01 100644 --- a/sdrbase/audio/audionetsink.cpp +++ b/sdrbase/audio/audionetsink.cpp @@ -27,6 +27,8 @@ AudioNetSink::AudioNetSink(QObject *parent) : m_type(SinkUDP), m_codec(CodecL16), m_rtpBufferAudio(0), + m_decimation(1), + m_decimationCount(0), m_bufferIndex(0), m_port(9998) { @@ -38,6 +40,8 @@ AudioNetSink::AudioNetSink(QObject *parent, int sampleRate, bool stereo) : m_type(SinkUDP), m_codec(CodecL16), m_rtpBufferAudio(0), + m_decimation(1), + m_decimationCount(0), m_bufferIndex(0), m_port(9998) { @@ -130,8 +134,33 @@ void AudioNetSink::setParameters(Codec codec, bool stereo, int sampleRate) } } -void AudioNetSink::write(qint16 sample) +void AudioNetSink::setDecimation(uint32_t decimation) { + m_decimation = decimation < 1 ? 1 : decimation > 6 ? 6 : decimation; + qDebug() << "AudioNetSink::setDecimation: " << m_decimation << " from: " << decimation; + m_decimationCount = 0; +} + +void AudioNetSink::write(qint16 isample) +{ + qint16& sample = isample; + + if (m_decimation > 1) + { + float lpSample = m_audioFilter.runLP(sample / 32768.0f); + + if (m_decimationCount >= m_decimation - 1) + { + sample = lpSample * 32768.0f; + m_decimationCount = 0; + } + else + { + m_decimationCount++; + return; + } + } + if (m_type == SinkUDP) { if (m_bufferIndex >= m_udpBlockSize) @@ -194,8 +223,29 @@ void AudioNetSink::write(qint16 sample) } } -void AudioNetSink::write(qint16 lSample, qint16 rSample) +void AudioNetSink::write(qint16 ilSample, qint16 irSample) { + qint16& lSample = ilSample; + qint16& rSample = irSample; + + if (m_decimation > 1) + { + float lpLSample = m_audioFilter.runLP(lSample / 32768.0f); + float lpRSample = m_audioFilter.runLP(rSample / 32768.0f); + + if (m_decimationCount >= m_decimation - 1) + { + lSample = lpLSample * 32768.0f; + rSample = lpRSample * 32768.0f; + m_decimationCount = 0; + } + else + { + m_decimationCount++; + return; + } + } + if (m_type == SinkUDP) { if (m_bufferIndex >= m_udpBlockSize) @@ -219,36 +269,6 @@ void AudioNetSink::write(qint16 lSample, qint16 rSample) } } -//void AudioNetSink::write(AudioSample* samples, uint32_t numSamples) -//{ -// if (m_type == SinkUDP) -// { -// int samplesIndex = 0; -// -// if (m_bufferIndex + numSamples*sizeof(AudioSample) >= m_udpBlockSize) // fill remainder of buffer and send it -// { -// memcpy(&m_data[m_bufferIndex], &samples[samplesIndex], m_udpBlockSize - m_bufferIndex); // fill remainder of buffer -// m_udpSocket->writeDatagram((const char*)m_data, (qint64 ) m_udpBlockSize, m_address, m_port); -// m_bufferIndex = 0; -// samplesIndex += (m_udpBlockSize - m_bufferIndex) / sizeof(AudioSample); -// numSamples -= (m_udpBlockSize - m_bufferIndex) / sizeof(AudioSample); -// } -// -// while (numSamples > m_udpBlockSize/sizeof(AudioSample)) // send directly from input without buffering -// { -// m_udpSocket->writeDatagram((const char*)&samples[samplesIndex], (qint64 ) m_udpBlockSize, m_address, m_port); -// samplesIndex += m_udpBlockSize/sizeof(AudioSample); -// numSamples -= m_udpBlockSize/sizeof(AudioSample); -// } -// -// memcpy(&m_data[m_bufferIndex], &samples[samplesIndex], numSamples*sizeof(AudioSample)); -// } -// else if (m_type == SinkRTP) -// { -// m_rtpBufferAudio->write((uint8_t *) samples, numSamples*2); // 2 x 16 bit sample -// } -//} - void AudioNetSink::moveToThread(QThread *thread) { m_udpSocket->moveToThread(thread); diff --git a/sdrbase/audio/audionetsink.h b/sdrbase/audio/audionetsink.h index 240565d7a..c3c4d3b3a 100644 --- a/sdrbase/audio/audionetsink.h +++ b/sdrbase/audio/audionetsink.h @@ -19,6 +19,7 @@ #define SDRBASE_AUDIO_AUDIONETSINK_H_ #include "dsp/dsptypes.h" +#include "audiofilter.h" #include "audiocompressor.h" #include "export.h" @@ -54,10 +55,10 @@ public: void addDestination(const QString& address, uint16_t port); void deleteDestination(const QString& address, uint16_t port); void setParameters(Codec codec, bool stereo, int sampleRate); + void setDecimation(uint32_t decimation); void write(qint16 sample); void write(qint16 lSample, qint16 rSample); - //void write(AudioSample* samples, uint32_t numSamples); bool isRTPCapable() const; bool selectType(SinkType type); @@ -72,6 +73,9 @@ protected: QUdpSocket *m_udpSocket; RTPSink *m_rtpBufferAudio; AudioCompressor m_audioCompressor; + AudioFilter m_audioFilter; + uint32_t m_decimation; + uint32_t m_decimationCount; char m_data[65536]; unsigned int m_bufferIndex; QHostAddress m_address; diff --git a/sdrbase/audio/audiooutput.cpp b/sdrbase/audio/audiooutput.cpp index 2155e4653..25fdfcc65 100644 --- a/sdrbase/audio/audiooutput.cpp +++ b/sdrbase/audio/audiooutput.cpp @@ -210,6 +210,13 @@ void AudioOutput::setUdpChannelFormat(UDPChannelCodec udpChannelCodec, bool ster } } +void AudioOutput::setUdpDecimation(uint32_t decimation) +{ + if (m_audioNetSink) { + m_audioNetSink->setDecimation(decimation); + } +} + 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 140e32397..5c389c731 100644 --- a/sdrbase/audio/audiooutput.h +++ b/sdrbase/audio/audiooutput.h @@ -67,6 +67,7 @@ public: void setUdpUseRTP(bool useRTP); void setUdpChannelMode(UDPChannelMode udpChannelMode); void setUdpChannelFormat(UDPChannelCodec udpChannelCodec, bool stereo, int sampleRate); + void setUdpDecimation(uint32_t decimation); private: QMutex m_mutex;