add audio peak limiter to audio mixer

This commit is contained in:
Brad Hefta-Gaub 2016-05-28 20:34:27 -07:00
parent cb3dfa0457
commit 1e7cd06d0e
4 changed files with 24 additions and 11 deletions

View file

@ -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 // check for silent audio after the peak limitor has converted the samples
// also check if we ended up with a silent frame bool hasAudio = false;
for (int i = 0; i < AudioConstants::NETWORK_FRAME_SAMPLES_STEREO; ++i) { 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) { if (_clampedSamples[i] != 0.0f) {
++nonZeroSamples; hasAudio = true;
break;
} }
} }
return hasAudio;
return (nonZeroSamples > 0);
} }
void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) { void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) {

View file

@ -17,6 +17,8 @@
#include <udt/PacketHeaders.h> #include <udt/PacketHeaders.h>
#include <UUID.h> #include <UUID.h>
#include <AudioLimiter.h>;
#include "InjectedAudioStream.h" #include "InjectedAudioStream.h"
#include "AudioMixer.h" #include "AudioMixer.h"
@ -26,7 +28,8 @@
AudioMixerClientData::AudioMixerClientData(const QUuid& nodeID) : AudioMixerClientData::AudioMixerClientData(const QUuid& nodeID) :
NodeData(nodeID), NodeData(nodeID),
_outgoingMixedAudioSequenceNumber(0), _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 // 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 // this ensures we send out stats to this client around every second
@ -38,6 +41,10 @@ AudioMixerClientData::AudioMixerClientData(const QUuid& nodeID) :
_frameToSendStats = distribution(numberGenerator); _frameToSendStats = distribution(numberGenerator);
} }
void AudioMixerClientData::clampAudioSamples(float* input, int16_t* output, int numFrames) {
_audioLimiter->render(input, output, numFrames);
}
AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() { AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() {
QReadLocker readLocker { &_streamsLock }; QReadLocker readLocker { &_streamsLock };

View file

@ -21,6 +21,8 @@
#include "PositionalAudioStream.h" #include "PositionalAudioStream.h"
#include "AvatarAudioStream.h" #include "AvatarAudioStream.h"
class AudioLimiter;
class AudioMixerClientData : public NodeData { class AudioMixerClientData : public NodeData {
Q_OBJECT Q_OBJECT
public: public:
@ -61,6 +63,8 @@ public:
// uses randomization to have the AudioMixer send a stats packet to this node around every second // uses randomization to have the AudioMixer send a stats packet to this node around every second
bool shouldSendStats(int frameNumber); bool shouldSendStats(int frameNumber);
void clampAudioSamples(float* input, int16_t* output, int numFrames);
signals: signals:
void injectorStreamFinished(const QUuid& streamIdentifier); void injectorStreamFinished(const QUuid& streamIdentifier);
@ -77,6 +81,8 @@ private:
AudioStreamStats _downstreamAudioStreamStats; AudioStreamStats _downstreamAudioStreamStats;
int _frameToSendStats { 0 }; int _frameToSendStats { 0 };
std::unique_ptr<AudioLimiter> _audioLimiter;
}; };
#endif // hifi_AudioMixerClientData_h #endif // hifi_AudioMixerClientData_h

View file

@ -18,6 +18,9 @@
namespace AudioConstants { namespace AudioConstants {
const int SAMPLE_RATE = 24000; const int SAMPLE_RATE = 24000;
const int MONO = 1;
const int STEREO = 2;
typedef int16_t AudioSample; typedef int16_t AudioSample;