Implement master avatar gain in the audio-mixer

This commit is contained in:
Ken Cooke 2017-10-31 11:18:03 -07:00
parent 3a2780bdf6
commit cfba6ae819
4 changed files with 21 additions and 9 deletions

View file

@ -191,9 +191,11 @@ void AudioMixerClientData::parsePerAvatarGainSet(ReceivedMessage& message, const
float gain = unpackFloatGainFromByte(packedGain); float gain = unpackFloatGainFromByte(packedGain);
if (avatarUuid.isNull()) { if (avatarUuid.isNull()) {
// FIXME: change master gain, and reset hrtf gains for all active streams // set the MASTER avatar gain
qDebug() << "Setting MASTER avatar gain for [" << uuid << "] to " << gain; setMasterAvatarGain(gain);
qDebug() << "Setting MASTER avatar gain for " << uuid << " to " << gain;
} else { } else {
// set the per-source avatar gain
hrtfForStream(avatarUuid, QUuid()).setGainAdjustment(gain); hrtfForStream(avatarUuid, QUuid()).setGainAdjustment(gain);
qDebug() << "Setting avatar gain adjustment for hrtf[" << uuid << "][" << avatarUuid << "] to " << gain; qDebug() << "Setting avatar gain adjustment for hrtf[" << uuid << "][" << avatarUuid << "] to " << gain;
} }

View file

@ -83,6 +83,9 @@ 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);
float getMasterAvatarGain() const { return _masterAvatarGain; }
void setMasterAvatarGain(float gain) { _masterAvatarGain = gain; }
AudioLimiter audioLimiter; AudioLimiter audioLimiter;
void setupCodec(CodecPluginPointer codec, const QString& codecName); void setupCodec(CodecPluginPointer codec, const QString& codecName);
@ -175,6 +178,8 @@ private:
int _frameToSendStats { 0 }; int _frameToSendStats { 0 };
float _masterAvatarGain { 1.0f }; // per-listener mixing gain, applied only to avatars
CodecPluginPointer _codec; CodecPluginPointer _codec;
QString _selectedCodecName; QString _selectedCodecName;
Encoder* _encoder{ nullptr }; // for outbound mixed stream Encoder* _encoder{ nullptr }; // for outbound mixed stream

View file

@ -48,8 +48,8 @@ void sendEnvironmentPacket(const SharedNodePointer& node, AudioMixerClientData&
// mix helpers // mix helpers
inline float approximateGain(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd, inline float approximateGain(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd,
const glm::vec3& relativePosition); const glm::vec3& relativePosition);
inline float computeGain(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd, inline float computeGain(AudioMixerClientData& listenerNodeData, const AvatarAudioStream& listeningNodeStream,
const glm::vec3& relativePosition, bool isEcho); const PositionalAudioStream& streamToAdd, const glm::vec3& relativePosition, bool isEcho);
inline float computeAzimuth(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd, inline float computeAzimuth(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd,
const glm::vec3& relativePosition); const glm::vec3& relativePosition);
@ -266,7 +266,7 @@ void AudioMixerSlave::addStream(AudioMixerClientData& listenerNodeData, const QU
glm::vec3 relativePosition = streamToAdd.getPosition() - listeningNodeStream.getPosition(); glm::vec3 relativePosition = streamToAdd.getPosition() - listeningNodeStream.getPosition();
float distance = glm::max(glm::length(relativePosition), EPSILON); 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); float azimuth = isEcho ? 0.0f : computeAzimuth(listeningNodeStream, listeningNodeStream, relativePosition);
const int HRTF_DATASET_INDEX = 1; 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 // when throttling, as close streams are expected to be heard by a user
float distance = glm::length(relativePosition); float distance = glm::length(relativePosition);
return gain / distance; return gain / distance;
// avatar: skip master gain - it is constant for all streams
} }
float computeGain(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd, float computeGain(AudioMixerClientData& listenerNodeData, const AvatarAudioStream& listeningNodeStream,
const glm::vec3& relativePosition, bool isEcho) { const PositionalAudioStream& streamToAdd, const glm::vec3& relativePosition, bool isEcho) {
float gain = 1.0f; float gain = 1.0f;
// injector: apply attenuation // 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)); float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + (angleOfDelivery * (OFF_AXIS_ATTENUATION_STEP / PI_OVER_TWO));
gain *= offAxisCoefficient; gain *= offAxisCoefficient;
// apply master gain, only to avatars
gain *= listenerNodeData.getMasterAvatarGain();
} }
auto& audioZones = AudioMixer::getAudioZones(); auto& audioZones = AudioMixer::getAudioZones();

View file

@ -990,10 +990,10 @@ void NodeList::setAvatarGain(const QUuid& nodeID, float gain) {
setAvatarGainPacket->write(nodeID.toRfc4122()); setAvatarGainPacket->write(nodeID.toRfc4122());
// We need to convert the gain in dB (from the script) to an amplitude before packing it. // 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()) { 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 { } else {
qCDebug(networking) << "Sending Set Avatar Gain packet with UUID: " << uuidStringWithoutCurlyBraces(nodeID) << "Gain:" << gain; qCDebug(networking) << "Sending Set Avatar Gain packet with UUID: " << uuidStringWithoutCurlyBraces(nodeID) << "Gain:" << gain;
} }