From b0b6aeac6c0eba9331eaa4f837803032acb93944 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 11 Jan 2017 16:16:35 -0800 Subject: [PATCH] Ken's feedback --- assignment-client/src/audio/AudioMixer.cpp | 13 ++++---- .../src/audio/AudioMixerClientData.h | 6 ---- .../src/audio/AudioMixerSlave.cpp | 7 ++--- assignment-client/src/audio/AudioMixerSlave.h | 2 +- interface/resources/qml/hifi/NameCard.qml | 30 ++++++++++++------- interface/resources/qml/hifi/Pal.qml | 6 ++-- libraries/audio/src/AudioHRTF.h | 2 +- libraries/networking/src/NodeList.cpp | 4 ++- .../src/UsersScriptingInterface.h | 3 +- 9 files changed, 41 insertions(+), 32 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index fddd2d641e..07639867eb 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -28,6 +28,7 @@ #include #include +#include "AudioHelpers.h" #include "AudioRingBuffer.h" #include "AudioMixerClientData.h" #include "AvatarAudioStream.h" @@ -188,7 +189,6 @@ void AudioMixer::handleNodeKilled(SharedNodePointer killedNode) { auto clientData = dynamic_cast(node->getLinkedData()); if (clientData) { QUuid killedUUID = killedNode->getUUID(); - clientData->removePerAvatarGain(killedUUID); clientData->removeHRTFsForNode(killedUUID); } }); @@ -246,11 +246,14 @@ void AudioMixer::handleNodeIgnoreRequestPacket(QSharedPointer p void AudioMixer::handlePerAvatarGainSetDataPacket(QSharedPointer packet, SharedNodePointer sendingNode) { auto clientData = dynamic_cast(sendingNode->getLinkedData()); if (clientData) { + QUuid listeningNodeUUID = sendingNode->getUUID(); // parse the UUID from the packet - QUuid ignoredUUID = QUuid::fromRfc4122(packet->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); - float gain; - packet->readPrimitive(&gain); - clientData->setPerAvatarGain(ignoredUUID, gain); + QUuid audioSourceUUID = QUuid::fromRfc4122(packet->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + uint8_t packedGain; + packet->readPrimitive(&packedGain); + float gain = unpackFloatGainFromByte(packedGain); + clientData->hrtfForStream(audioSourceUUID, QUuid()).setGainAdjustment(gain); + qDebug() << "Setting gain adjustment for hrtf[" << listeningNodeUUID << "][" << audioSourceUUID << "] to " << gain; } } diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index d7fbfe5112..e637fd0409 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -95,10 +95,6 @@ public: bool getRequestsDomainListData() { return _requestsDomainListData; } void setRequestsDomainListData(bool requesting) { _requestsDomainListData = requesting; } - float getPerAvatarGain(const QUuid& avatarID) { return (_perAvatarGain.count(avatarID) ? _perAvatarGain.at(avatarID) : 1.0f); } - void setPerAvatarGain(const QUuid& avatarID, float gain) { _perAvatarGain[avatarID] = gain; } - void removePerAvatarGain(const QUuid& avatarID) { _perAvatarGain.erase(avatarID); } - signals: void injectorStreamFinished(const QUuid& streamIdentifier); @@ -129,8 +125,6 @@ private: bool _shouldMuteClient { false }; bool _requestsDomainListData { false }; - - std::unordered_map _perAvatarGain; }; #endif // hifi_AudioMixerClientData_h diff --git a/assignment-client/src/audio/AudioMixerSlave.cpp b/assignment-client/src/audio/AudioMixerSlave.cpp index d502239341..28d3358eb5 100644 --- a/assignment-client/src/audio/AudioMixerSlave.cpp +++ b/assignment-client/src/audio/AudioMixerSlave.cpp @@ -252,13 +252,12 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& node) { // Enumerate the audio streams attached to the otherNode auto streamsCopy = otherData->getAudioStreams(); - float thisAvatarGain = nodeData->getPerAvatarGain(otherNode->getUUID()); for (auto& streamPair : streamsCopy) { auto otherNodeStream = streamPair.second; bool isSelfWithEcho = ((*otherNode == *node) && (otherNodeStream->shouldLoopbackForNode())); // Add all audio streams that should be added to the mix if (isSelfWithEcho || (!isSelfWithEcho && !insideIgnoreRadius)) { - addStreamToMix(*nodeData, otherNode->getUUID(), *nodeAudioStream, *otherNodeStream, thisAvatarGain); + addStreamToMix(*nodeData, otherNode->getUUID(), *nodeAudioStream, *otherNodeStream); } } } @@ -279,7 +278,7 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& node) { } void AudioMixerSlave::addStreamToMix(AudioMixerClientData& listenerNodeData, const QUuid& sourceNodeID, - const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd, float perAvatarGain) { + const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd) { // to reduce artifacts we calculate the gain and azimuth for every source for this listener // even if we are not going to end up mixing in this source @@ -296,7 +295,7 @@ void AudioMixerSlave::addStreamToMix(AudioMixerClientData& listenerNodeData, con float distance = glm::max(glm::length(relativePosition), EPSILON); // figure out the gain for this source at the listener - float gain = gainForSource(listeningNodeStream, streamToAdd, relativePosition, isEcho) * perAvatarGain; + float gain = gainForSource(listeningNodeStream, streamToAdd, relativePosition, isEcho); // figure out the azimuth to this source at the listener float azimuth = isEcho ? 0.0f : azimuthForSource(listeningNodeStream, listeningNodeStream, relativePosition); diff --git a/assignment-client/src/audio/AudioMixerSlave.h b/assignment-client/src/audio/AudioMixerSlave.h index 89aa70f99a..c4aabfbb4a 100644 --- a/assignment-client/src/audio/AudioMixerSlave.h +++ b/assignment-client/src/audio/AudioMixerSlave.h @@ -43,7 +43,7 @@ private: bool prepareMix(const SharedNodePointer& node); // add a stream to the mix void addStreamToMix(AudioMixerClientData& listenerData, const QUuid& streamerID, - const AvatarAudioStream& listenerStream, const PositionalAudioStream& streamer, float perAvatarGain); + const AvatarAudioStream& listenerStream, const PositionalAudioStream& streamer); float gainForSource(const AvatarAudioStream& listener, const PositionalAudioStream& streamer, const glm::vec3& relativePosition, bool isEcho); diff --git a/interface/resources/qml/hifi/NameCard.qml b/interface/resources/qml/hifi/NameCard.qml index 4b8ee6cbc3..3e8ee355c8 100644 --- a/interface/resources/qml/hifi/NameCard.qml +++ b/interface/resources/qml/hifi/NameCard.qml @@ -155,10 +155,10 @@ Row { visible: !isMyCard width: parent.width height: 18 - value: pal.gain[uuid] ? pal.gain[uuid] : 1.0 - minimumValue: 0.0 - maximumValue: 1.5 - stepSize: 0.1 + value: pal.gainSliderValueDB[uuid] ? pal.gainSliderValueDB[uuid] : 0.0 + minimumValue: -60.0 + maximumValue: 20.0 + stepSize: 2 updateValueWhileDragging: false onValueChanged: updateGainFromQML(uuid, value) style: SliderStyle { @@ -167,6 +167,12 @@ Row { implicitWidth: gainSlider.width implicitHeight: 4 radius: 2 + MouseArea { + anchors.fill: parent + onDoubleClicked: { + gainSlider.value = 0.0 + } + } } handle: Rectangle { anchors.centerIn: parent @@ -178,12 +184,14 @@ Row { } } - function updateGainFromQML(avatarUuid, gainValue) { - pal.gain[avatarUuid] = gainValue; - var data = { - sessionId: avatarUuid, - gain: (Math.pow(20, gainValue) - 1) / (20 - 1) - }; - pal.sendToScript({method: 'updateGain', params: data}); + function updateGainFromQML(avatarUuid, sliderValue) { + if (pal.gainSliderValueDB[avatarUuid] !== sliderValue) { + pal.gainSliderValueDB[avatarUuid] = sliderValue; + var data = { + sessionId: avatarUuid, + gain: sliderValue + }; + pal.sendToScript({method: 'updateGain', params: data}); + } } } diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index 039ab78baf..c74d8757f7 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -32,7 +32,9 @@ Rectangle { property var ignored: ({}); // Keep a local list of ignored avatars & their data. Necessary because HashMap is slow to respond after ignoring. property var userModelData: [] // This simple list is essentially a mirror of the userModel listModel without all the extra complexities. property bool iAmAdmin: false - property var gain: ({}); // Keep a local list of per-avatar gain. Far faster than keeping this data on the server. + // Keep a local list of per-avatar gainSliderValueDBs. Far faster than fetching this data from the server. + // NOTE: if another script modifies the per-avatar gain, this value won't be accurate! + property var gainSliderValueDB: ({}); // This is the container for the PAL Rectangle { @@ -497,7 +499,7 @@ Rectangle { break; case 'clearLocalQMLData': ignored = {}; - gain = {}; + gainSliderValueDB = {}; break; default: console.log('Unrecognized message:', JSON.stringify(message)); diff --git a/libraries/audio/src/AudioHRTF.h b/libraries/audio/src/AudioHRTF.h index c9d053bec4..6a17a2d3cc 100644 --- a/libraries/audio/src/AudioHRTF.h +++ b/libraries/audio/src/AudioHRTF.h @@ -45,7 +45,7 @@ public: void renderSilent(int16_t* input, float* output, int index, float azimuth, float distance, float gain, int numFrames); // - // HRTF local gain adjustment + // HRTF local gain adjustment in amplitude (1.0 == unity) // void setGainAdjustment(float gain) { _gainAdjust = HRTF_GAIN * gain; }; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 00f13dff3d..98a563c4e5 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -26,6 +26,7 @@ #include "AccountManager.h" #include "AddressManager.h" #include "Assignment.h" +#include "AudioHelpers.h" #include "HifiSockAddr.h" #include "FingerprintUtils.h" @@ -961,7 +962,8 @@ void NodeList::setAvatarGain(const QUuid& nodeID, float gain) { // write the node ID to the packet setAvatarGainPacket->write(nodeID.toRfc4122()); - setAvatarGainPacket->writePrimitive((gain < 5.0f ? gain : 5.0f)); + // We need to convert the gain in dB (from the script) to an amplitude before packing it. + setAvatarGainPacket->writePrimitive(packFloatGainToByte(fastExp2f(gain / 6.0206f))); qCDebug(networking) << "Sending Set Avatar Gain packet UUID: " << uuidStringWithoutCurlyBraces(nodeID) << "Gain:" << gain; diff --git a/libraries/script-engine/src/UsersScriptingInterface.h b/libraries/script-engine/src/UsersScriptingInterface.h index d2d77a6796..0b6b7855b5 100644 --- a/libraries/script-engine/src/UsersScriptingInterface.h +++ b/libraries/script-engine/src/UsersScriptingInterface.h @@ -63,9 +63,10 @@ public slots: /**jsdoc * Sets an avatar's gain for you and you only. + * Units are Decibels (dB) * @function Users.setAvatarGain * @param {nodeID} nodeID The node or session ID of the user whose gain you want to modify. - * @param {float} gain The gain of the avatar you'd like to set. + * @param {float} gain The gain of the avatar you'd like to set. Units are dB. */ void setAvatarGain(const QUuid& nodeID, float gain);