diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 0f51bd00b1..03bb32cd53 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->audioLimiter.render(_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; + if (_clampedSamples[i] != 0) { + 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..20003ba10d 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -25,6 +25,7 @@ AudioMixerClientData::AudioMixerClientData(const QUuid& nodeID) : NodeData(nodeID), + audioLimiter(AudioConstants::SAMPLE_RATE, AudioConstants::STEREO), _outgoingMixedAudioSequenceNumber(0), _downstreamAudioStreamStats() { diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index ff4143cf08..17274a1519 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -16,11 +16,13 @@ #include #include +#include #include #include "PositionalAudioStream.h" #include "AvatarAudioStream.h" + 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); + AudioLimiter audioLimiter; + signals: void injectorStreamFinished(const QUuid& streamIdentifier); 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; diff --git a/script-archive/tests/audio/testPeakLimiter.js b/script-archive/tests/audio/testPeakLimiter.js new file mode 100644 index 0000000000..d56126b912 --- /dev/null +++ b/script-archive/tests/audio/testPeakLimiter.js @@ -0,0 +1,19 @@ +var audioOptions = { + volume: 1.0, + loop: true, + position: MyAvatar.position +} + +//var sineWave = Script.resolvePath("./1760sine.wav"); // use relative file +var sineWave = "https://s3-us-west-1.amazonaws.com/highfidelity-dev/1760sine.wav"; // use file from S3 +var sound = SoundCache.getSound(sineWave); +var injectorCount = 0; +var MAX_INJECTOR_COUNT = 40; + +Script.update.connect(function() { + if (sound.downloaded && injectorCount < MAX_INJECTOR_COUNT) { + injectorCount++; + print("stating injector:" + injectorCount); + Audio.playSound(sound, audioOptions); + } +}); \ No newline at end of file