Merge branch 'master' of https://github.com/worklist/hifi into more_events

This commit is contained in:
ZappoMan 2014-02-09 10:32:14 -08:00
commit 3bf8dd87e8
9 changed files with 256 additions and 88 deletions

170
examples/editVoxels.js Normal file
View file

@ -0,0 +1,170 @@
//
// editVoxels.js
// hifi
//
// Created by Philip Rosedale on February 8, 2014
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
//
// Captures mouse clicks and edits voxels accordingly.
//
// click = create a new voxel on this face, same color as old
// Alt + click = delete this voxel
// shift + click = recolor this voxel
//
// Click and drag to create more new voxels in the same direction
//
function vLength(v) {
return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}
var key_alt = false;
var key_shift = false;
var isAdding = false;
var lastVoxelPosition = { x: 0, y: 0, z: 0 };
var lastVoxelColor = { red: 0, green: 0, blue: 0 };
var lastVoxelScale = 0;
var dragStart = { x: 0, y: 0 };
// Create a table of the different colors you can choose
var colors = new Array();
colors[0] = { red: 237, green: 175, blue: 0 };
colors[1] = { red: 61, green: 211, blue: 72 };
colors[2] = { red: 51, green: 204, blue: 204 };
colors[3] = { red: 63, green: 169, blue: 245 };
colors[4] = { red: 193, green: 99, blue: 122 };
colors[5] = { red: 255, green: 54, blue: 69 };
colors[6] = { red: 124, green: 36, blue: 36 };
colors[7] = { red: 63, green: 35, blue: 19 };
var numColors = 6;
var whichColor = 0;
// Create sounds for adding, deleting, recoloring voxels
var addSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Electronic/ElectronicBurst1.raw");
var deleteSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Bubbles/bubbles1.raw");
var changeColorSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Electronic/ElectronicBurst6.raw");
var audioOptions = new AudioInjectionOptions();
function mousePressEvent(event) {
var pickRay = Camera.computePickRay(event.x, event.y);
var intersection = Voxels.findRayIntersection(pickRay);
audioOptions.volume = 1.0;
audioOptions.position = { x: intersection.voxel.x, y: intersection.voxel.y, z: intersection.voxel.z };
if (intersection.intersects) {
if (key_alt) {
// Delete voxel
Voxels.eraseVoxel(intersection.voxel.x, intersection.voxel.y, intersection.voxel.z, intersection.voxel.s);
Audio.playSound(deleteSound, audioOptions);
} else if (key_shift) {
// Recolor Voxel
whichColor++;
if (whichColor == numColors) whichColor = 0;
Voxels.setVoxel(intersection.voxel.x,
intersection.voxel.y,
intersection.voxel.z,
intersection.voxel.s,
colors[whichColor].red, colors[whichColor].green, colors[whichColor].blue);
Audio.playSound(changeColorSound, audioOptions);
} else {
// Add voxel on face
var newVoxel = {
x: intersection.voxel.x,
y: intersection.voxel.y,
z: intersection.voxel.z,
s: intersection.voxel.s,
red: intersection.voxel.red,
green: intersection.voxel.green,
blue: intersection.voxel.blue };
if (intersection.face == "MIN_X_FACE") {
newVoxel.x -= newVoxel.s;
} else if (intersection.face == "MAX_X_FACE") {
newVoxel.x += newVoxel.s;
} else if (intersection.face == "MIN_Y_FACE") {
newVoxel.y -= newVoxel.s;
} else if (intersection.face == "MAX_Y_FACE") {
newVoxel.y += newVoxel.s;
} else if (intersection.face == "MIN_Z_FACE") {
newVoxel.z -= newVoxel.s;
} else if (intersection.face == "MAX_Z_FACE") {
newVoxel.z += newVoxel.s;
}
Voxels.setVoxel(newVoxel.x, newVoxel.y, newVoxel.z, newVoxel.s, newVoxel.red, newVoxel.green, newVoxel.blue);
lastVoxelPosition = { x: newVoxel.x, y: newVoxel.y, z: newVoxel.z };
lastVoxelColor = { red: newVoxel.red, green: newVoxel.green, blue: newVoxel.blue };
lastVoxelScale = newVoxel.s;
Audio.playSound(addSound, audioOptions);
dragStart = { x: event.x, y: event.y };
isAdding = true;
}
}
}
function keyPressEvent(event) {
key_alt = event.isAlt;
key_shift = event.isShifted;
}
function keyReleaseEvent(event) {
key_alt = false;
key_shift = false;
}
function mouseMoveEvent(event) {
if (isAdding) {
var pickRay = Camera.computePickRay(event.x, event.y);
var lastVoxelDistance = { x: pickRay.origin.x - lastVoxelPosition.x,
y: pickRay.origin.y - lastVoxelPosition.y,
z: pickRay.origin.z - lastVoxelPosition.z };
var distance = vLength(lastVoxelDistance);
var mouseSpot = { x: pickRay.direction.x * distance, y: pickRay.direction.y * distance, z: pickRay.direction.z * distance };
mouseSpot.x += pickRay.origin.x;
mouseSpot.y += pickRay.origin.y;
mouseSpot.z += pickRay.origin.z;
var dx = mouseSpot.x - lastVoxelPosition.x;
var dy = mouseSpot.y - lastVoxelPosition.y;
var dz = mouseSpot.z - lastVoxelPosition.z;
if (dx > lastVoxelScale) {
lastVoxelPosition.x += lastVoxelScale;
Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z,
lastVoxelScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue);
} else if (dx < -lastVoxelScale) {
lastVoxelPosition.x -= lastVoxelScale;
Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z,
lastVoxelScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue);
} else if (dy > lastVoxelScale) {
lastVoxelPosition.y += lastVoxelScale;
Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z,
lastVoxelScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue);
} else if (dy < -lastVoxelScale) {
lastVoxelPosition.y -= lastVoxelScale;
Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z,
lastVoxelScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue);
} else if (dz > lastVoxelScale) {
lastVoxelPosition.z += lastVoxelScale;
Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z,
lastVoxelScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue);
} else if (dz < -lastVoxelScale) {
lastVoxelPosition.z -= lastVoxelScale;
Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z,
lastVoxelScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue);
}
}
}
function mouseReleaseEvent(event) {
isAdding = false;
}
Controller.mousePressEvent.connect(mousePressEvent);
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
Controller.mouseMoveEvent.connect(mouseMoveEvent);
Controller.keyPressEvent.connect(keyPressEvent);
Controller.keyReleaseEvent.connect(keyReleaseEvent);
function scriptEnding() {
}
Script.scriptEnding.connect(scriptEnding);

View file

@ -4,6 +4,7 @@
// //
// This sample script moves a voxel around like a bird and sometimes makes tweeting noises // This sample script moves a voxel around like a bird and sometimes makes tweeting noises
// //
function vLength(v) { function vLength(v) {
return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z); return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
} }
@ -15,20 +16,24 @@ function randVector(a, b) {
var rval = { x: a + Math.random() * (b - a), y: a + Math.random() * (b - a), z: a + Math.random() * (b - a) }; var rval = { x: a + Math.random() * (b - a), y: a + Math.random() * (b - a), z: a + Math.random() * (b - a) };
return rval; return rval;
} }
function vMinus(a, b) { function vMinus(a, b) {
var rval = { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z }; var rval = { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };
return rval; return rval;
} }
function vPlus(a, b) { function vPlus(a, b) {
var rval = { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z }; var rval = { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
return rval; return rval;
} }
function vCopy(a, b) { function vCopy(a, b) {
a.x = b.x; a.x = b.x;
a.y = b.y; a.y = b.y;
a.z = b.z; a.z = b.z;
return; return;
} }
// Returns a vector which is fraction of the way between a and b // Returns a vector which is fraction of the way between a and b
function vInterpolate(a, b, fraction) { function vInterpolate(a, b, fraction) {
var rval = { x: a.x + (b.x - a.x) * fraction, y: a.y + (b.y - a.y) * fraction, z: a.z + (b.z - a.z) * fraction }; var rval = { x: a.x + (b.x - a.x) * fraction, y: a.y + (b.y - a.y) * fraction, z: a.z + (b.z - a.z) * fraction };
@ -62,6 +67,7 @@ if (which < 0.2) {
size = 0.15; size = 0.15;
} }
var startTimeInSeconds = new Date().getTime() / 1000; var startTimeInSeconds = new Date().getTime() / 1000;
var birdLifetime = 20; // lifetime of the bird in seconds! var birdLifetime = 20; // lifetime of the bird in seconds!
@ -72,15 +78,19 @@ var frame = 0;
var moving = false; var moving = false;
var tweeting = 0; var tweeting = 0;
var moved = false; var moved = false;
var CHANCE_OF_MOVING = 0.05;
var CHANCE_OF_MOVING = 0.00;
var CHANCE_OF_FLAPPING = 0.05;
var CHANCE_OF_TWEETING = 0.05; var CHANCE_OF_TWEETING = 0.05;
var START_HEIGHT_ABOVE_ME = 1.5; var START_HEIGHT_ABOVE_ME = 1.5;
var BIRD_GRAVITY = -0.1;
var BIRD_FLAP = 1.0;
var myPosition = MyAvatar.position; var myPosition = MyAvatar.position;
var properties = { var properties = {
lifetime: birdLifetime, lifetime: birdLifetime,
position: { x: myPosition.x, y: myPosition.y + START_HEIGHT_ABOVE_ME, z: myPosition.z }, position: { x: myPosition.x, y: myPosition.y + START_HEIGHT_ABOVE_ME, z: myPosition.z },
velocity: { x: 0, y: 0, z: 0 }, velocity: { x: 0, y: Math.random() * BIRD_FLAP, z: 0 },
gravity: { x: 0, y: 0, z: 0 }, gravity: { x: 0, y: BIRD_GRAVITY, z: 0 },
radius : 0.1, radius : 0.1,
color: { red: 0, color: { red: 0,
green: 255, green: 255,
@ -94,6 +104,7 @@ function moveBird() {
// check to see if we've been running long enough that our bird is dead // check to see if we've been running long enough that our bird is dead
var nowTimeInSeconds = new Date().getTime() / 1000; var nowTimeInSeconds = new Date().getTime() / 1000;
if ((nowTimeInSeconds - startTimeInSeconds) >= birdLifetime) { if ((nowTimeInSeconds - startTimeInSeconds) >= birdLifetime) {
print("our bird is dying, stop our script"); print("our bird is dying, stop our script");
Script.stop(); Script.stop();
return; return;
@ -115,11 +126,22 @@ function moveBird() {
} else { } else {
tweeting -= 1; tweeting -= 1;
} }
if (Math.random() < CHANCE_OF_FLAPPING) {
// Add a little upward impulse to our bird
// TODO: Get velocity
//
var newProperties = {
velocity: { x:0.0, y: Math.random() * BIRD_FLAP, z: 0.0 }
};
Particles.editParticle(particleID, newProperties);
print("flap!");
}
// Moving behavior // Moving behavior
if (moving == false) { if (moving == false) {
if (Math.random() < CHANCE_OF_MOVING) { if (Math.random() < CHANCE_OF_MOVING) {
targetPosition = randVector(- range, range); targetPosition = randVector(-range, range);
targetPosition = vPlus(targetPosition, myPosition); targetPosition = vPlus(targetPosition, myPosition);
if (targetPosition.x < 0) { if (targetPosition.x < 0) {
targetPosition.x = 0; targetPosition.x = 0;
} }
@ -170,5 +192,6 @@ function moveBird() {
} }
} }
} }
// register the call back so it fires before each data send // register the call back so it fires before each data send
Script.willSendVisualDataCallback.connect(moveBird); Script.willSendVisualDataCallback.connect(moveBird);

View file

@ -135,7 +135,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_isTouchPressed(false), _isTouchPressed(false),
_mousePressed(false), _mousePressed(false),
_isHoverVoxel(false), _isHoverVoxel(false),
_isHoverVoxelSounding(false),
_mouseVoxelScale(1.0f / 1024.0f), _mouseVoxelScale(1.0f / 1024.0f),
_mouseVoxelScaleInitialized(false), _mouseVoxelScaleInitialized(false),
_justEditedVoxel(false), _justEditedVoxel(false),
@ -1199,7 +1198,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
return; return;
} }
if (_isHoverVoxel) { if (_isHoverVoxel) {
_myAvatar->orbit(getMouseVoxelWorldCoordinates(_hoverVoxel), deltaX, deltaY); //_myAvatar->orbit(getMouseVoxelWorldCoordinates(_hoverVoxel), deltaX, deltaY);
return; return;
} }
} }
@ -1219,11 +1218,6 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
} }
} }
const bool MAKE_SOUND_ON_VOXEL_HOVER = false;
const bool MAKE_SOUND_ON_VOXEL_CLICK = true;
const float HOVER_VOXEL_FREQUENCY = 7040.f;
const float HOVER_VOXEL_DECAY = 0.999f;
void Application::mousePressEvent(QMouseEvent* event) { void Application::mousePressEvent(QMouseEvent* event) {
_controllerScriptingInterface.emitMousePressEvent(event); // send events to any registered scripts _controllerScriptingInterface.emitMousePressEvent(event); // send events to any registered scripts
@ -1263,37 +1257,6 @@ void Application::mousePressEvent(QMouseEvent* event) {
pasteVoxels(); pasteVoxels();
} }
if (!Menu::getInstance()->isOptionChecked(MenuOption::VoxelDeleteMode) &&
MAKE_SOUND_ON_VOXEL_CLICK && _isHoverVoxel && !_isHoverVoxelSounding) {
_hoverVoxelOriginalColor[0] = _hoverVoxel.red;
_hoverVoxelOriginalColor[1] = _hoverVoxel.green;
_hoverVoxelOriginalColor[2] = _hoverVoxel.blue;
_hoverVoxelOriginalColor[3] = 1;
const float RED_CLICK_FREQUENCY = 1000.f;
const float GREEN_CLICK_FREQUENCY = 1250.f;
const float BLUE_CLICK_FREQUENCY = 1330.f;
const float MIDDLE_A_FREQUENCY = 440.f;
float frequency = MIDDLE_A_FREQUENCY +
(_hoverVoxel.red / 255.f * RED_CLICK_FREQUENCY +
_hoverVoxel.green / 255.f * GREEN_CLICK_FREQUENCY +
_hoverVoxel.blue / 255.f * BLUE_CLICK_FREQUENCY) / 3.f;
_audio.startCollisionSound(1.0, frequency, 0.0, HOVER_VOXEL_DECAY, false);
_isHoverVoxelSounding = true;
const float PERCENTAGE_TO_MOVE_TOWARD = 0.90f;
glm::vec3 newTarget = getMouseVoxelWorldCoordinates(_hoverVoxel);
glm::vec3 myPosition = _myAvatar->getPosition();
// If there is not an action tool set (add, delete, color), move to this voxel
if (Menu::getInstance()->isOptionChecked(MenuOption::ClickToFly) &&
!(Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode) ||
Menu::getInstance()->isOptionChecked(MenuOption::VoxelDeleteMode) ||
Menu::getInstance()->isOptionChecked(MenuOption::VoxelColorMode))) {
_myAvatar->setMoveTarget(myPosition + (newTarget - myPosition) * PERCENTAGE_TO_MOVE_TOWARD);
}
}
} else if (event->button() == Qt::RightButton && Menu::getInstance()->isVoxelModeActionChecked()) { } else if (event->button() == Qt::RightButton && Menu::getInstance()->isVoxelModeActionChecked()) {
deleteVoxelUnderCursor(); deleteVoxelUnderCursor();
} }
@ -2044,44 +2007,11 @@ void Application::updateHoverVoxels(float deltaTime, float& distance, BoxFace& f
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels()"); PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels()");
// If we have clicked on a voxel, update it's color // Check for a new hover voxel
if (_isHoverVoxelSounding) { if (!_mousePressed) {
VoxelTreeElement* hoveredNode = _voxels.getVoxelAt(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s); {
if (hoveredNode) { PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels() _voxels.findRayIntersection()");
float bright = _audio.getCollisionSoundMagnitude(); _isHoverVoxel = _voxels.findRayIntersection(_mouseRayOrigin, _mouseRayDirection, _hoverVoxel, distance, face);
nodeColor clickColor = { 255 * bright + _hoverVoxelOriginalColor[0] * (1.f - bright),
_hoverVoxelOriginalColor[1] * (1.f - bright),
_hoverVoxelOriginalColor[2] * (1.f - bright), 1 };
hoveredNode->setColor(clickColor);
if (bright < 0.01f) {
hoveredNode->setColor(_hoverVoxelOriginalColor);
_isHoverVoxelSounding = false;
}
} else {
// Voxel is not found, clear all
_isHoverVoxelSounding = false;
_isHoverVoxel = false;
}
} else {
// Check for a new hover voxel
glm::vec4 oldVoxel(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s);
// only do this work if MAKE_SOUND_ON_VOXEL_HOVER or MAKE_SOUND_ON_VOXEL_CLICK is enabled,
// and make sure the tree is not already busy... because otherwise you'll have to wait.
if (!_mousePressed) {
{
PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels() _voxels.findRayIntersection()");
_isHoverVoxel = _voxels.findRayIntersection(_mouseRayOrigin, _mouseRayDirection, _hoverVoxel, distance, face);
}
if (MAKE_SOUND_ON_VOXEL_HOVER && _isHoverVoxel &&
glm::vec4(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s) != oldVoxel) {
_hoverVoxelOriginalColor[0] = _hoverVoxel.red;
_hoverVoxelOriginalColor[1] = _hoverVoxel.green;
_hoverVoxelOriginalColor[2] = _hoverVoxel.blue;
_hoverVoxelOriginalColor[3] = 1;
_audio.startCollisionSound(1.0, HOVER_VOXEL_FREQUENCY * _hoverVoxel.s * TREE_SCALE, 0.0, HOVER_VOXEL_DECAY, false);
_isHoverVoxelSounding = true;
}
} }
} }
} }

View file

@ -419,8 +419,6 @@ private:
VoxelDetail _hoverVoxel; // Stuff about the voxel I am hovering or clicking VoxelDetail _hoverVoxel; // Stuff about the voxel I am hovering or clicking
bool _isHoverVoxel; bool _isHoverVoxel;
bool _isHoverVoxelSounding;
nodeColor _hoverVoxelOriginalColor;
VoxelDetail _mouseVoxel; // details of the voxel to be edited VoxelDetail _mouseVoxel; // details of the voxel to be edited
float _mouseVoxelScale; // the scale for adding/removing voxels float _mouseVoxelScale; // the scale for adding/removing voxels

View file

@ -65,6 +65,10 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples, QObject* p
_measuredJitter(0), _measuredJitter(0),
_jitterBufferSamples(initialJitterBufferSamples), _jitterBufferSamples(initialJitterBufferSamples),
_lastInputLoudness(0), _lastInputLoudness(0),
_averageInputLoudness(0),
_noiseGateOpen(false),
_noiseGateEnabled(true),
_noiseGateFramesToClose(0),
_lastVelocity(0), _lastVelocity(0),
_lastAcceleration(0), _lastAcceleration(0),
_totalPacketsReceived(0), _totalPacketsReceived(0),
@ -348,12 +352,40 @@ void Audio::handleAudioInput() {
_inputFormat, _desiredInputFormat); _inputFormat, _desiredInputFormat);
float loudness = 0; float loudness = 0;
float thisSample = 0;
int samplesOverNoiseGate = 0;
const float NOISE_GATE_HEIGHT = 3.f;
const int NOISE_GATE_WIDTH = 5;
const int NOISE_GATE_CLOSE_FRAME_DELAY = 30;
for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) { for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) {
loudness += fabsf(monoAudioSamples[i]); thisSample = fabsf(monoAudioSamples[i]);
loudness += thisSample;
// Noise Reduction: Count peaks above the average loudness
if (thisSample > (_averageInputLoudness * NOISE_GATE_HEIGHT)) {
samplesOverNoiseGate++;
}
} }
_lastInputLoudness = loudness / NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; _lastInputLoudness = loudness / NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
const float LOUDNESS_AVERAGING_FRAMES = 1000.f; // This will be about 10 seconds
_averageInputLoudness = (1.f - 1.f / LOUDNESS_AVERAGING_FRAMES) * _averageInputLoudness + (1.f / LOUDNESS_AVERAGING_FRAMES) * _lastInputLoudness;
if (_noiseGateEnabled) {
if (samplesOverNoiseGate > NOISE_GATE_WIDTH) {
_noiseGateOpen = true;
_noiseGateFramesToClose = NOISE_GATE_CLOSE_FRAME_DELAY;
} else {
if (--_noiseGateFramesToClose == 0) {
_noiseGateOpen = false;
}
}
if (!_noiseGateOpen) {
for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) {
monoAudioSamples[i] = 0;
}
}
}
// add input data just written to the scope // add input data just written to the scope
QMetaObject::invokeMethod(_scope, "addSamples", Qt::QueuedConnection, QMetaObject::invokeMethod(_scope, "addSamples", Qt::QueuedConnection,
@ -524,6 +556,10 @@ void Audio::toggleMute() {
muteToggled(); muteToggled();
} }
void Audio::toggleAudioNoiseReduction() {
_noiseGateEnabled = !_noiseGateEnabled;
}
void Audio::render(int screenWidth, int screenHeight) { void Audio::render(int screenWidth, int screenHeight) {
if (_audioInput && _audioOutput) { if (_audioInput && _audioOutput) {
glLineWidth(2.0); glLineWidth(2.0);

View file

@ -45,7 +45,9 @@ public:
void render(int screenWidth, int screenHeight); void render(int screenWidth, int screenHeight);
float getLastInputLoudness() const { return _lastInputLoudness; } float getLastInputLoudness() const { return glm::max(_lastInputLoudness - _averageInputLoudness, 0.f); }
void setNoiseGateEnabled(bool noiseGateEnabled) { _noiseGateEnabled = noiseGateEnabled; }
void setLastAcceleration(const glm::vec3 lastAcceleration) { _lastAcceleration = lastAcceleration; } void setLastAcceleration(const glm::vec3 lastAcceleration) { _lastAcceleration = lastAcceleration; }
void setLastVelocity(const glm::vec3 lastVelocity) { _lastVelocity = lastVelocity; } void setLastVelocity(const glm::vec3 lastVelocity) { _lastVelocity = lastVelocity; }
@ -73,6 +75,7 @@ public slots:
void handleAudioInput(); void handleAudioInput();
void reset(); void reset();
void toggleMute(); void toggleMute();
void toggleAudioNoiseReduction();
virtual void handleAudioByteArray(const QByteArray& audioByteArray); virtual void handleAudioByteArray(const QByteArray& audioByteArray);
@ -106,6 +109,10 @@ private:
float _measuredJitter; float _measuredJitter;
int16_t _jitterBufferSamples; int16_t _jitterBufferSamples;
float _lastInputLoudness; float _lastInputLoudness;
float _averageInputLoudness;
bool _noiseGateOpen;
bool _noiseGateEnabled;
int _noiseGateFramesToClose;
glm::vec3 _lastVelocity; glm::vec3 _lastVelocity;
glm::vec3 _lastAcceleration; glm::vec3 _lastAcceleration;
int _totalPacketsReceived; int _totalPacketsReceived;

View file

@ -457,6 +457,11 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P); addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P);
QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools"); QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioNoiseReduction,
0,
true,
appInstance->getAudio(),
SLOT(toggleAudioNoiseReduction()));
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio);
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio);
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::MuteAudio, addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::MuteAudio,

View file

@ -187,6 +187,7 @@ namespace MenuOption {
const QString Enable3DTVMode = "Enable 3DTV Mode"; const QString Enable3DTVMode = "Enable 3DTV Mode";
const QString EnableOcclusionCulling = "Enable Occlusion Culling"; const QString EnableOcclusionCulling = "Enable Occlusion Culling";
const QString EnableVoxelPacketCompression = "Enable Voxel Packet Compression"; const QString EnableVoxelPacketCompression = "Enable Voxel Packet Compression";
const QString AudioNoiseReduction = "Audio Noise Reduction";
const QString EchoServerAudio = "Echo Server Audio"; const QString EchoServerAudio = "Echo Server Audio";
const QString EchoLocalAudio = "Echo Local Audio"; const QString EchoLocalAudio = "Echo Local Audio";
const QString MuteAudio = "Mute Microphone"; const QString MuteAudio = "Mute Microphone";

View file

@ -107,7 +107,6 @@ QByteArray AvatarData::toByteArray() {
destinationBuffer += sizeof(_headData->_lookAtPosition); destinationBuffer += sizeof(_headData->_lookAtPosition);
// Instantaneous audio loudness (used to drive facial animation) // Instantaneous audio loudness (used to drive facial animation)
//destinationBuffer += packFloatToByte(destinationBuffer, std::min(MAX_AUDIO_LOUDNESS, _audioLoudness), MAX_AUDIO_LOUDNESS);
memcpy(destinationBuffer, &_headData->_audioLoudness, sizeof(float)); memcpy(destinationBuffer, &_headData->_audioLoudness, sizeof(float));
destinationBuffer += sizeof(float); destinationBuffer += sizeof(float);
@ -215,7 +214,6 @@ int AvatarData::parseData(const QByteArray& packet) {
sourceBuffer += sizeof(_headData->_lookAtPosition); sourceBuffer += sizeof(_headData->_lookAtPosition);
// Instantaneous audio loudness (used to drive facial animation) // Instantaneous audio loudness (used to drive facial animation)
//sourceBuffer += unpackFloatFromByte(sourceBuffer, _audioLoudness, MAX_AUDIO_LOUDNESS);
memcpy(&_headData->_audioLoudness, sourceBuffer, sizeof(float)); memcpy(&_headData->_audioLoudness, sourceBuffer, sizeof(float));
sourceBuffer += sizeof(float); sourceBuffer += sizeof(float);