From 1e7cd06d0e5ed13497977cc30e89519a08393e51 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sat, 28 May 2016 20:34:27 -0700 Subject: [PATCH] add audio peak limiter to audio mixer --- assignment-client/src/audio/AudioMixer.cpp | 17 +++++++---------- .../src/audio/AudioMixerClientData.cpp | 9 ++++++++- .../src/audio/AudioMixerClientData.h | 6 ++++++ libraries/audio/src/AudioConstants.h | 3 +++ 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 0f51bd00b1..1832c29d1e 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -339,21 +339,18 @@ bool AudioMixer::prepareMixForListeningNode(Node* node) { } }); - int nonZeroSamples = 0; + // use the per listner AudioLimiter to render the mixed data... + listenerNodeData->clampAudioSamples(_mixedSamples, _clampedSamples, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); - // enumerate the mixed samples and clamp any samples outside the min/max - // also check if we ended up with a silent frame + // check for silent audio after the peak limitor has converted the samples + bool hasAudio = false; for (int i = 0; i < AudioConstants::NETWORK_FRAME_SAMPLES_STEREO; ++i) { - - _clampedSamples[i] = int16_t(glm::clamp(int(_mixedSamples[i] * AudioConstants::MAX_SAMPLE_VALUE), - AudioConstants::MIN_SAMPLE_VALUE, - AudioConstants::MAX_SAMPLE_VALUE)); if (_clampedSamples[i] != 0.0f) { - ++nonZeroSamples; + hasAudio = true; + break; } } - - return (nonZeroSamples > 0); + return hasAudio; } void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) { diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 93a51b1df2..6a25027310 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -17,6 +17,8 @@ #include #include +#include ; + #include "InjectedAudioStream.h" #include "AudioMixer.h" @@ -26,7 +28,8 @@ AudioMixerClientData::AudioMixerClientData(const QUuid& nodeID) : NodeData(nodeID), _outgoingMixedAudioSequenceNumber(0), - _downstreamAudioStreamStats() + _downstreamAudioStreamStats(), + _audioLimiter(new AudioLimiter(AudioConstants::SAMPLE_RATE, AudioConstants::STEREO)) { // of the ~94 blocks in a second of audio sent from the AudioMixer, pick a random one to send out a stats packet on // this ensures we send out stats to this client around every second @@ -38,6 +41,10 @@ AudioMixerClientData::AudioMixerClientData(const QUuid& nodeID) : _frameToSendStats = distribution(numberGenerator); } +void AudioMixerClientData::clampAudioSamples(float* input, int16_t* output, int numFrames) { + _audioLimiter->render(input, output, numFrames); +} + AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() { QReadLocker readLocker { &_streamsLock }; diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index ff4143cf08..e543c51b0c 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -21,6 +21,8 @@ #include "PositionalAudioStream.h" #include "AvatarAudioStream.h" +class AudioLimiter; + class AudioMixerClientData : public NodeData { Q_OBJECT public: @@ -61,6 +63,8 @@ public: // uses randomization to have the AudioMixer send a stats packet to this node around every second bool shouldSendStats(int frameNumber); + void clampAudioSamples(float* input, int16_t* output, int numFrames); + signals: void injectorStreamFinished(const QUuid& streamIdentifier); @@ -77,6 +81,8 @@ private: AudioStreamStats _downstreamAudioStreamStats; int _frameToSendStats { 0 }; + + std::unique_ptr _audioLimiter; }; #endif // hifi_AudioMixerClientData_h diff --git a/libraries/audio/src/AudioConstants.h b/libraries/audio/src/AudioConstants.h index 38fead87f1..dbbe434915 100644 --- a/libraries/audio/src/AudioConstants.h +++ b/libraries/audio/src/AudioConstants.h @@ -18,6 +18,9 @@ namespace AudioConstants { const int SAMPLE_RATE = 24000; + const int MONO = 1; + const int STEREO = 2; + typedef int16_t AudioSample;