diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 59bc878cba..3b3d6549ee 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -191,9 +191,11 @@ void AudioMixerClientData::parsePerAvatarGainSet(ReceivedMessage& message, const float gain = unpackFloatGainFromByte(packedGain); if (avatarUuid.isNull()) { - // FIXME: change master gain, and reset hrtf gains for all active streams - qDebug() << "Setting MASTER avatar gain for [" << uuid << "] to " << gain; + // set the MASTER avatar gain + setMasterAvatarGain(gain); + qDebug() << "Setting MASTER avatar gain for " << uuid << " to " << gain; } else { + // set the per-source avatar gain hrtfForStream(avatarUuid, QUuid()).setGainAdjustment(gain); qDebug() << "Setting avatar gain adjustment for hrtf[" << uuid << "][" << avatarUuid << "] to " << gain; } diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index 7a8690d8cc..c3a31715ea 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -83,6 +83,9 @@ public: // uses randomization to have the AudioMixer send a stats packet to this node around every second bool shouldSendStats(int frameNumber); + float getMasterAvatarGain() const { return _masterAvatarGain; } + void setMasterAvatarGain(float gain) { _masterAvatarGain = gain; } + AudioLimiter audioLimiter; void setupCodec(CodecPluginPointer codec, const QString& codecName); @@ -175,6 +178,8 @@ private: int _frameToSendStats { 0 }; + float _masterAvatarGain { 1.0f }; // per-listener mixing gain, applied only to avatars + CodecPluginPointer _codec; QString _selectedCodecName; Encoder* _encoder{ nullptr }; // for outbound mixed stream diff --git a/assignment-client/src/audio/AudioMixerSlave.cpp b/assignment-client/src/audio/AudioMixerSlave.cpp index a131e266d2..86e6d21d66 100644 --- a/assignment-client/src/audio/AudioMixerSlave.cpp +++ b/assignment-client/src/audio/AudioMixerSlave.cpp @@ -48,8 +48,8 @@ void sendEnvironmentPacket(const SharedNodePointer& node, AudioMixerClientData& // mix helpers inline float approximateGain(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd, const glm::vec3& relativePosition); -inline float computeGain(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd, - const glm::vec3& relativePosition, bool isEcho); +inline float computeGain(AudioMixerClientData& listenerNodeData, const AvatarAudioStream& listeningNodeStream, + const PositionalAudioStream& streamToAdd, const glm::vec3& relativePosition, bool isEcho); inline float computeAzimuth(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd, const glm::vec3& relativePosition); @@ -266,7 +266,7 @@ void AudioMixerSlave::addStream(AudioMixerClientData& listenerNodeData, const QU glm::vec3 relativePosition = streamToAdd.getPosition() - listeningNodeStream.getPosition(); float distance = glm::max(glm::length(relativePosition), EPSILON); - float gain = computeGain(listeningNodeStream, streamToAdd, relativePosition, isEcho); + float gain = computeGain(listenerNodeData, listeningNodeStream, streamToAdd, relativePosition, isEcho); float azimuth = isEcho ? 0.0f : computeAzimuth(listeningNodeStream, listeningNodeStream, relativePosition); const int HRTF_DATASET_INDEX = 1; @@ -484,10 +484,12 @@ float approximateGain(const AvatarAudioStream& listeningNodeStream, const Positi // when throttling, as close streams are expected to be heard by a user float distance = glm::length(relativePosition); return gain / distance; + + // avatar: skip master gain - it is constant for all streams } -float computeGain(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd, - const glm::vec3& relativePosition, bool isEcho) { +float computeGain(AudioMixerClientData& listenerNodeData, const AvatarAudioStream& listeningNodeStream, + const PositionalAudioStream& streamToAdd, const glm::vec3& relativePosition, bool isEcho) { float gain = 1.0f; // injector: apply attenuation @@ -507,6 +509,9 @@ float computeGain(const AvatarAudioStream& listeningNodeStream, const Positional float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + (angleOfDelivery * (OFF_AXIS_ATTENUATION_STEP / PI_OVER_TWO)); gain *= offAxisCoefficient; + + // apply master gain, only to avatars + gain *= listenerNodeData.getMasterAvatarGain(); } auto& audioZones = AudioMixer::getAudioZones(); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 04699d8ad1..63ec460de8 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -990,10 +990,10 @@ void NodeList::setAvatarGain(const QUuid& nodeID, float gain) { setAvatarGainPacket->write(nodeID.toRfc4122()); // We need to convert the gain in dB (from the script) to an amplitude before packing it. - setAvatarGainPacket->writePrimitive(packFloatGainToByte(fastExp2f(gain / 6.0206f))); + setAvatarGainPacket->writePrimitive(packFloatGainToByte(fastExp2f(gain / 6.02059991f))); if (nodeID.isNull()) { - qCDebug(networking) << "Sending Set Avatar MASTER Gain packet with Gain:" << gain; + qCDebug(networking) << "Sending Set MASTER Avatar Gain packet with Gain:" << gain; } else { qCDebug(networking) << "Sending Set Avatar Gain packet with UUID: " << uuidStringWithoutCurlyBraces(nodeID) << "Gain:" << gain; }