From 25850136155dfb0126b85a83c212d20dcd93a7c0 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 09:54:43 -0800 Subject: [PATCH 01/11] JS signal when AM mutes client --- interface/src/DatagramProcessor.cpp | 1 + libraries/audio/src/AudioScriptingInterface.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 6f9f4cae68..5d034c1c17 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -152,6 +152,7 @@ void DatagramProcessor::processDatagrams() { if (glm::distance(Application::getInstance()->getAvatar()->getPosition(), position) < radius && !Application::getInstance()->getAudio()->getMuted()) { Application::getInstance()->getAudio()->toggleMute(); + AudioScriptingInterface::getInstance().mutedByMixer(); } break; } diff --git a/libraries/audio/src/AudioScriptingInterface.h b/libraries/audio/src/AudioScriptingInterface.h index 0017806b40..7a60577042 100644 --- a/libraries/audio/src/AudioScriptingInterface.h +++ b/libraries/audio/src/AudioScriptingInterface.h @@ -37,6 +37,9 @@ public slots: void injectorStopped(); +signals: + void mutedByMixer(); + private: AudioScriptingInterface(); QList< QPointer > _activeInjectors; From 46eebe9d40a3b270bcdae8277a500fcc2e5325d4 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 10:26:47 -0800 Subject: [PATCH 02/11] Give noisy mutes their own packet type --- assignment-client/src/audio/AudioMixer.cpp | 16 ++--------- interface/src/DatagramProcessor.cpp | 27 +++++++++++++------ libraries/audio/src/AudioScriptingInterface.h | 1 + libraries/networking/src/PacketHeaders.h | 2 +- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 6c8a4fd1c2..81bfe7a734 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -779,21 +779,9 @@ void AudioMixer::run() { static const int TIME_BETWEEN_MUTES = 5; // in secs if (usecTimestampNow() - nodeData->getAvatarAudioStream()->getLastMuted() > TIME_BETWEEN_MUTES * USECS_PER_SECOND) { - int headerSize = numBytesForPacketHeaderGivenPacketType(PacketTypeMuteEnvironment); - int packetSize = headerSize + sizeof(glm::vec3) + sizeof(float); - - // Fake data to force mute - glm::vec3 position = nodeData->getAvatarAudioStream()->getPosition(); - float radius = 1.0f; - - char* packet = (char*)malloc(packetSize); - populatePacketHeader(packet, PacketTypeMuteEnvironment); - memcpy(packet + headerSize, &position, sizeof(glm::vec3)); - memcpy(packet + headerSize + sizeof(glm::vec3), &radius, sizeof(float)); - - nodeList->writeDatagram(packet, packetSize, node); + QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeNoisyMute); + nodeList->writeDatagram(packet, node); nodeData->getAvatarAudioStream()->setLastMutedNow(); - free(packet); } } diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 5d034c1c17..96680423ed 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -141,18 +141,29 @@ void DatagramProcessor::processDatagrams() { AccountManager::getInstance().checkAndSignalForAccessToken(); break; } + case PacketTypeNoisyMute: case PacketTypeMuteEnvironment: { - glm::vec3 position; - float radius; + bool mute = !Application::getInstance()->getAudio()->getMuted(); - int headerSize = numBytesForPacketHeaderGivenPacketType(PacketTypeMuteEnvironment); - memcpy(&position, incomingPacket.constData() + headerSize, sizeof(glm::vec3)); - memcpy(&radius, incomingPacket.constData() + headerSize + sizeof(glm::vec3), sizeof(float)); + if (incomingType == PacketTypeMuteEnvironment) { + glm::vec3 position; + float radius, distance; + + int headerSize = numBytesForPacketHeaderGivenPacketType(PacketTypeMuteEnvironment); + memcpy(&position, incomingPacket.constData() + headerSize, sizeof(glm::vec3)); + memcpy(&radius, incomingPacket.constData() + headerSize + sizeof(glm::vec3), sizeof(float)); + distance = glm::distance(Application::getInstance()->getAvatar()->getPosition(), position); + + mute = mute && (distance < radius); + } - if (glm::distance(Application::getInstance()->getAvatar()->getPosition(), position) < radius - && !Application::getInstance()->getAudio()->getMuted()) { + if (mute) { Application::getInstance()->getAudio()->toggleMute(); - AudioScriptingInterface::getInstance().mutedByMixer(); + if (incomingType == PacketTypeMuteEnvironment) { + AudioScriptingInterface::getInstance().environmentMuted(); + } else { + AudioScriptingInterface::getInstance().mutedByMixer(); + } } break; } diff --git a/libraries/audio/src/AudioScriptingInterface.h b/libraries/audio/src/AudioScriptingInterface.h index 7a60577042..5b67666a97 100644 --- a/libraries/audio/src/AudioScriptingInterface.h +++ b/libraries/audio/src/AudioScriptingInterface.h @@ -39,6 +39,7 @@ public slots: signals: void mutedByMixer(); + void environmentMuted(); private: AudioScriptingInterface(); diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h index d617f2243a..6cca5b505d 100644 --- a/libraries/networking/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -54,7 +54,7 @@ enum PacketType { UNUSED_2, UNUSED_3, UNUSED_4, - UNUSED_5, + PacketTypeNoisyMute, PacketTypeMetavoxelData, PacketTypeAvatarIdentity, PacketTypeAvatarBillboard, From 4615afe034577dcdd1db6463dd99f6c6a0b85171 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 10:32:28 -0800 Subject: [PATCH 03/11] Remove lastMuted member in AvatarAudioStream --- assignment-client/src/audio/AudioMixer.cpp | 10 +++------- assignment-client/src/audio/AvatarAudioStream.cpp | 3 +-- assignment-client/src/audio/AvatarAudioStream.h | 5 ----- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 81bfe7a734..ab4524cb71 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -776,13 +776,9 @@ void AudioMixer::run() { // if the stream should be muted, send mute packet if (nodeData->getAvatarAudioStream() && shouldMute(nodeData->getAvatarAudioStream()->getQuietestFrameLoudness())) { - static const int TIME_BETWEEN_MUTES = 5; // in secs - if (usecTimestampNow() - nodeData->getAvatarAudioStream()->getLastMuted() > - TIME_BETWEEN_MUTES * USECS_PER_SECOND) { - QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeNoisyMute); - nodeList->writeDatagram(packet, node); - nodeData->getAvatarAudioStream()->setLastMutedNow(); - } + QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeNoisyMute); + nodeList->writeDatagram(packet, node); + nodeData->getAvatarAudioStream()->setLastMutedNow(); } if (node->getType() == NodeType::Agent && node->getActiveSocket() diff --git a/assignment-client/src/audio/AvatarAudioStream.cpp b/assignment-client/src/audio/AvatarAudioStream.cpp index cd67722a2e..90dcefa09d 100644 --- a/assignment-client/src/audio/AvatarAudioStream.cpp +++ b/assignment-client/src/audio/AvatarAudioStream.cpp @@ -14,8 +14,7 @@ #include "AvatarAudioStream.h" AvatarAudioStream::AvatarAudioStream(bool isStereo, const InboundAudioStream::Settings& settings) : - PositionalAudioStream(PositionalAudioStream::Microphone, isStereo, settings), - _lastMuted(usecTimestampNow()) + PositionalAudioStream(PositionalAudioStream::Microphone, isStereo, settings) { } diff --git a/assignment-client/src/audio/AvatarAudioStream.h b/assignment-client/src/audio/AvatarAudioStream.h index e1fb6dd486..482c6fd538 100644 --- a/assignment-client/src/audio/AvatarAudioStream.h +++ b/assignment-client/src/audio/AvatarAudioStream.h @@ -20,17 +20,12 @@ class AvatarAudioStream : public PositionalAudioStream { public: AvatarAudioStream(bool isStereo, const InboundAudioStream::Settings& settings); - qint64 getLastMuted() const { return _lastMuted; } - void setLastMutedNow() { _lastMuted = usecTimestampNow(); } - private: // disallow copying of AvatarAudioStream objects AvatarAudioStream(const AvatarAudioStream&); AvatarAudioStream& operator= (const AvatarAudioStream&); int parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples); - - qint64 _lastMuted; }; #endif // hifi_AvatarAudioStream_h From 0528a9ff9b21009f95661ca71496ded5f21e1646 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 10:49:35 -0800 Subject: [PATCH 04/11] Remove forgotten setLastMuted --- assignment-client/src/audio/AudioMixer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index ab4524cb71..32447d1d61 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -778,7 +778,6 @@ void AudioMixer::run() { && shouldMute(nodeData->getAvatarAudioStream()->getQuietestFrameLoudness())) { QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeNoisyMute); nodeList->writeDatagram(packet, node); - nodeData->getAvatarAudioStream()->setLastMutedNow(); } if (node->getType() == NodeType::Agent && node->getActiveSocket() From 3f3eae9350498bc25e0fd821557f5581482c3e64 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 17 Nov 2014 12:02:09 -0800 Subject: [PATCH 05/11] Adjusted distances for new avatar sizes. --- interface/src/Application.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index dc1ec96321..2c70249b32 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -115,15 +115,15 @@ static const float NODE_KILLED_BLUE = 0.0f; static const QString SNAPSHOT_EXTENSION = ".jpg"; static const float BILLBOARD_FIELD_OF_VIEW = 30.0f; // degrees -static const float BILLBOARD_DISTANCE = 5.0f; // meters +static const float BILLBOARD_DISTANCE = 5.56f; // meters static const int MIRROR_VIEW_TOP_PADDING = 5; static const int MIRROR_VIEW_LEFT_PADDING = 10; static const int MIRROR_VIEW_WIDTH = 265; static const int MIRROR_VIEW_HEIGHT = 215; -static const float MIRROR_FULLSCREEN_DISTANCE = 0.35f; -static const float MIRROR_REARVIEW_DISTANCE = 0.65f; -static const float MIRROR_REARVIEW_BODY_DISTANCE = 2.3f; +static const float MIRROR_FULLSCREEN_DISTANCE = 0.389f; +static const float MIRROR_REARVIEW_DISTANCE = 0.722f; +static const float MIRROR_REARVIEW_BODY_DISTANCE = 2.56f; static const float MIRROR_FIELD_OF_VIEW = 30.0f; static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS_PER_SECOND; From de2b86957b4af5dc9b5cf7a82d7ba40cd4a79e2e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 12:04:45 -0800 Subject: [PATCH 06/11] Proportional dry fraction --- interface/src/Audio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 2dc94e6027..c7de0788a3 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -566,8 +566,8 @@ void Audio::setReverbOptions(const AudioEffectOptions* options) { } void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioFormat) { - float dryFraction = DB_CO(_reverbOptions->getDryLevel()); float wetFraction = DB_CO(_reverbOptions->getWetLevel()); + float dryFraction = 1.0f - wetFraction; float lValue,rValue; for (int sample = 0; sample < numSamples; sample += audioFormat.channelCount()) { From 9fac84a9378371468a8ba1415080116a7ed8608d Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Mon, 17 Nov 2014 12:58:54 -0800 Subject: [PATCH 07/11] Changed the Alpha on the editmodels overlay Changed the Alpha on the editmodels overlay --- examples/editModels.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/editModels.js b/examples/editModels.js index 69976e03a1..3f1863fef2 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -2479,7 +2479,7 @@ function Tooltip() { margin: this.margin, text: "", color: { red: 228, green: 228, blue: 228 }, - alpha: 0.5, + alpha: 0.8, visible: false }); this.show = function (doShow) { From 082b9ff59f3aa8c590a9d26104e3c555f922d25f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 13:43:55 -0800 Subject: [PATCH 08/11] Faster and better Local reverb / no echo --- interface/src/Audio.cpp | 25 ++++++++----------------- interface/src/Audio.h | 2 +- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index c7de0788a3..99039829e7 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -565,7 +565,7 @@ void Audio::setReverbOptions(const AudioEffectOptions* options) { } } -void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioFormat) { +void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioFormat, bool noEcho) { float wetFraction = DB_CO(_reverbOptions->getWetLevel()); float dryFraction = 1.0f - wetFraction; @@ -579,11 +579,15 @@ void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioF for (int j = sample; j < sample + audioFormat.channelCount(); j++) { if (j == sample) { // left channel - int lResult = glm::clamp((int)(samplesData[j] * dryFraction + lValue * wetFraction), MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); + int lResult = glm::clamp((int)(samplesData[j] * ((noEcho) ? 0.0f : dryFraction) + + lValue * wetFraction), + MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); samplesData[j] = (int16_t)lResult; } else if (j == (sample + 1)) { // right channel - int rResult = glm::clamp((int)(samplesData[j] * dryFraction + rValue * wetFraction), MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); + int rResult = glm::clamp((int)(samplesData[j] * ((noEcho) ? 0.0f : dryFraction) + + rValue * wetFraction), + MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); samplesData[j] = (int16_t)rResult; } else { // ignore channels above 2 @@ -622,23 +626,10 @@ void Audio::handleLocalEchoAndReverb(QByteArray& inputByteArray) { } if (hasLocalReverb) { - QByteArray loopbackCopy; - if (!hasEcho) { - loopbackCopy = loopBackByteArray; - } - int16_t* loopbackSamples = reinterpret_cast(loopBackByteArray.data()); int numLoopbackSamples = loopBackByteArray.size() / sizeof(int16_t); updateGverbOptions(); - addReverb(loopbackSamples, numLoopbackSamples, _outputFormat); - - if (!hasEcho) { - int16_t* loopbackCopySamples = reinterpret_cast(loopbackCopy.data()); - for (int i = 0; i < numLoopbackSamples; ++i) { - loopbackSamples[i] = glm::clamp((int)loopbackSamples[i] - loopbackCopySamples[i], - MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); - } - } + addReverb(loopbackSamples, numLoopbackSamples, _outputFormat, !hasEcho); } if (_loopbackOutputDevice) { diff --git a/interface/src/Audio.h b/interface/src/Audio.h index d8e5c5386c..913524d8e5 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -269,7 +269,7 @@ private: // Adds Reverb void initGverb(); void updateGverbOptions(); - void addReverb(int16_t* samples, int numSamples, QAudioFormat& format); + void addReverb(int16_t* samples, int numSamples, QAudioFormat& format, bool noEcho = false); void handleLocalEchoAndReverb(QByteArray& inputByteArray); From a8c38aab64f5c30d3185be17021ec270b978c3da Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 14:47:20 -0800 Subject: [PATCH 09/11] dryFraction factorisation --- interface/src/Audio.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 99039829e7..2eb751868e 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -567,7 +567,7 @@ void Audio::setReverbOptions(const AudioEffectOptions* options) { void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioFormat, bool noEcho) { float wetFraction = DB_CO(_reverbOptions->getWetLevel()); - float dryFraction = 1.0f - wetFraction; + float dryFraction = (noEcho) ? 0.0f : (1.0f - wetFraction); float lValue,rValue; for (int sample = 0; sample < numSamples; sample += audioFormat.channelCount()) { @@ -579,14 +579,12 @@ void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioF for (int j = sample; j < sample + audioFormat.channelCount(); j++) { if (j == sample) { // left channel - int lResult = glm::clamp((int)(samplesData[j] * ((noEcho) ? 0.0f : dryFraction) + - lValue * wetFraction), + int lResult = glm::clamp((int)(samplesData[j] * dryFraction + lValue * wetFraction), MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); samplesData[j] = (int16_t)lResult; } else if (j == (sample + 1)) { // right channel - int rResult = glm::clamp((int)(samplesData[j] * ((noEcho) ? 0.0f : dryFraction) + - rValue * wetFraction), + int rResult = glm::clamp((int)(samplesData[j] * dryFraction + rValue * wetFraction), MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); samplesData[j] = (int16_t)rResult; } else { From 1ac9f2f5633070f456ac73da2f64f6cc867e2065 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 17 Nov 2014 14:51:46 -0800 Subject: [PATCH 10/11] first cut at movable entities script --- examples/entityScripts/movable.js | 80 +++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 examples/entityScripts/movable.js diff --git a/examples/entityScripts/movable.js b/examples/entityScripts/movable.js new file mode 100644 index 0000000000..432a0be3f0 --- /dev/null +++ b/examples/entityScripts/movable.js @@ -0,0 +1,80 @@ +// +// movable.js +// examples/entityScripts +// +// Created by Brad Hefta-Gaub on 11/17/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +(function(){ + + this.entityID = null; + this.properties = null; + this.graboffset = null; + + // Pr, Vr are respectively the Ray's Point of origin and Vector director + // Pp, Np are respectively the Plane's Point of origin and Normal vector + this.rayPlaneIntersection = function(Pr, Vr, Pp, Np) { + var d = -Vec3.dot(Pp, Np); + var t = -(Vec3.dot(Pr, Np) + d) / Vec3.dot(Vr, Np); + return Vec3.sum(Pr, Vec3.multiply(t, Vr)); + }; + + // updates the piece position based on mouse input + this.updatePosition = function(mouseEvent) { + var pickRay = Camera.computePickRay(mouseEvent.x, mouseEvent.y) + var upVector = { x: 0, y: 1, z: 0 }; + var intersection = this.rayPlaneIntersection(pickRay.origin, pickRay.direction, + this.properties.position, upVector); + + var newPosition = Vec3.sum(intersection, this.graboffset); + Entities.editEntity(this.entityID, { position: newPosition }); + }; + + this.grab = function(mouseEvent) { + // first calculate the offset + var pickRay = Camera.computePickRay(mouseEvent.x, mouseEvent.y) + var upVector = { x: 0, y: 1, z: 0 }; + var intersection = this.rayPlaneIntersection(pickRay.origin, pickRay.direction, + this.properties.position, upVector); + this.graboffset = Vec3.subtract(this.properties.position, intersection); + this.updatePosition(mouseEvent); + }; + + this.move = function(mouseEvent) { + this.updatePosition(mouseEvent); + }; + + this.release = function(mouseEvent) { + this.updatePosition(mouseEvent); + }; + + // All callbacks start by updating the properties + this.updateProperties = function(entityID) { + if (this.entityID === null || !this.entityID.isKnownID) { + this.entityID = Entities.identifyEntity(entityID); + } + this.properties = Entities.getEntityProperties(this.entityID); + }; + + this.preload = function(entityID) { + this.updateProperties(entityID); // All callbacks start by updating the properties + }; + + this.clickDownOnEntity = function(entityID, mouseEvent) { + this.updateProperties(entityID); // All callbacks start by updating the properties + this.grab(mouseEvent); + }; + + this.holdingClickOnEntity = function(entityID, mouseEvent) { + this.updateProperties(entityID); // All callbacks start by updating the properties + this.move(mouseEvent); + }; + this.clickReleaseOnEntity = function(entityID, mouseEvent) { + this.updateProperties(entityID); // All callbacks start by updating the properties + this.release(mouseEvent); + }; + +}) From 5eac93dcfd72cff6ba7e6cfb14d656e6c6da4c27 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 16:59:23 -0800 Subject: [PATCH 11/11] User separate gverb instance for local reverb --- interface/src/Audio.cpp | 22 +++++++++++++++++----- interface/src/Audio.h | 3 ++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 2eb751868e..b7076b6c1a 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -99,6 +99,7 @@ Audio::Audio(QObject* parent) : _muted(false), _reverb(false), _reverbOptions(&_scriptReverbOptions), + _gverbLocal(NULL), _gverb(NULL), _iconColor(1.0f), _iconPulseTimeReference(usecTimestampNow()), @@ -504,12 +505,23 @@ bool Audio::switchOutputToAudioDevice(const QString& outputDeviceName) { void Audio::initGverb() { // Initialize a new gverb instance + _gverbLocal = gverb_new(_outputFormat.sampleRate(), _reverbOptions->getMaxRoomSize(), _reverbOptions->getRoomSize(), + _reverbOptions->getReverbTime(), _reverbOptions->getDamping(), _reverbOptions->getSpread(), + _reverbOptions->getInputBandwidth(), _reverbOptions->getEarlyLevel(), + _reverbOptions->getTailLevel()); _gverb = gverb_new(_outputFormat.sampleRate(), _reverbOptions->getMaxRoomSize(), _reverbOptions->getRoomSize(), _reverbOptions->getReverbTime(), _reverbOptions->getDamping(), _reverbOptions->getSpread(), _reverbOptions->getInputBandwidth(), _reverbOptions->getEarlyLevel(), _reverbOptions->getTailLevel()); - + // Configure the instance (these functions are not super well named - they actually set several internal variables) + gverb_set_roomsize(_gverbLocal, _reverbOptions->getRoomSize()); + gverb_set_revtime(_gverbLocal, _reverbOptions->getReverbTime()); + gverb_set_damping(_gverbLocal, _reverbOptions->getDamping()); + gverb_set_inputbandwidth(_gverbLocal, _reverbOptions->getInputBandwidth()); + gverb_set_earlylevel(_gverbLocal, DB_CO(_reverbOptions->getEarlyLevel())); + gverb_set_taillevel(_gverbLocal, DB_CO(_reverbOptions->getTailLevel())); + gverb_set_roomsize(_gverb, _reverbOptions->getRoomSize()); gverb_set_revtime(_gverb, _reverbOptions->getReverbTime()); gverb_set_damping(_gverb, _reverbOptions->getDamping()); @@ -565,7 +577,7 @@ void Audio::setReverbOptions(const AudioEffectOptions* options) { } } -void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioFormat, bool noEcho) { +void Audio::addReverb(ty_gverb* gverb, int16_t* samplesData, int numSamples, QAudioFormat& audioFormat, bool noEcho) { float wetFraction = DB_CO(_reverbOptions->getWetLevel()); float dryFraction = (noEcho) ? 0.0f : (1.0f - wetFraction); @@ -573,7 +585,7 @@ void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioF for (int sample = 0; sample < numSamples; sample += audioFormat.channelCount()) { // Run GVerb float value = (float)samplesData[sample]; - gverb_do(_gverb, value, &lValue, &rValue); + gverb_do(gverb, value, &lValue, &rValue); // Mix, accounting for clipping, the left and right channels. Ignore the rest. for (int j = sample; j < sample + audioFormat.channelCount(); j++) { @@ -627,7 +639,7 @@ void Audio::handleLocalEchoAndReverb(QByteArray& inputByteArray) { int16_t* loopbackSamples = reinterpret_cast(loopBackByteArray.data()); int numLoopbackSamples = loopBackByteArray.size() / sizeof(int16_t); updateGverbOptions(); - addReverb(loopbackSamples, numLoopbackSamples, _outputFormat, !hasEcho); + addReverb(_gverbLocal, loopbackSamples, numLoopbackSamples, _outputFormat, !hasEcho); } if (_loopbackOutputDevice) { @@ -1018,7 +1030,7 @@ void Audio::processReceivedSamples(const QByteArray& inputBuffer, QByteArray& ou if(_reverb || _receivedAudioStream.hasReverb()) { updateGverbOptions(); - addReverb((int16_t*)outputBuffer.data(), numDeviceOutputSamples, _outputFormat); + addReverb(_gverb, (int16_t*)outputBuffer.data(), numDeviceOutputSamples, _outputFormat); } } diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 913524d8e5..127c2e3332 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -248,6 +248,7 @@ private: AudioEffectOptions _scriptReverbOptions; AudioEffectOptions _zoneReverbOptions; AudioEffectOptions* _reverbOptions; + ty_gverb* _gverbLocal; ty_gverb* _gverb; GLuint _micTextureId; GLuint _muteTextureId; @@ -269,7 +270,7 @@ private: // Adds Reverb void initGverb(); void updateGverbOptions(); - void addReverb(int16_t* samples, int numSamples, QAudioFormat& format, bool noEcho = false); + void addReverb(ty_gverb* gverb, int16_t* samples, int numSamples, QAudioFormat& format, bool noEcho = false); void handleLocalEchoAndReverb(QByteArray& inputByteArray);