Merge branch 'master' of https://github.com/highfidelity/hifi into metavoxels

This commit is contained in:
Andrzej Kapolka 2014-11-17 16:46:51 -08:00
commit 4308a45028
10 changed files with 116 additions and 54 deletions

View file

@ -776,25 +776,8 @@ 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) {
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);
nodeData->getAvatarAudioStream()->setLastMutedNow();
free(packet);
}
QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeNoisyMute);
nodeList->writeDatagram(packet, node);
}
if (node->getType() == NodeType::Agent && node->getActiveSocket()

View file

@ -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)
{
}

View file

@ -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

View file

@ -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) {

View file

@ -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);
};
})

View file

@ -565,9 +565,9 @@ 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;
float dryFraction = (noEcho) ? 0.0f : (1.0f - wetFraction);
float lValue,rValue;
for (int sample = 0; sample < numSamples; sample += audioFormat.channelCount()) {
@ -579,11 +579,13 @@ 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] * 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] * dryFraction + rValue * wetFraction),
MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
samplesData[j] = (int16_t)rResult;
} else {
// ignore channels above 2
@ -622,23 +624,10 @@ void Audio::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
}
if (hasLocalReverb) {
QByteArray loopbackCopy;
if (!hasEcho) {
loopbackCopy = loopBackByteArray;
}
int16_t* loopbackSamples = reinterpret_cast<int16_t*>(loopBackByteArray.data());
int numLoopbackSamples = loopBackByteArray.size() / sizeof(int16_t);
updateGverbOptions();
addReverb(loopbackSamples, numLoopbackSamples, _outputFormat);
if (!hasEcho) {
int16_t* loopbackCopySamples = reinterpret_cast<int16_t*>(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) {

View file

@ -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);

View file

@ -141,17 +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();
if (incomingType == PacketTypeMuteEnvironment) {
AudioScriptingInterface::getInstance().environmentMuted();
} else {
AudioScriptingInterface::getInstance().mutedByMixer();
}
}
break;
}

View file

@ -37,6 +37,10 @@ public slots:
void injectorStopped();
signals:
void mutedByMixer();
void environmentMuted();
private:
AudioScriptingInterface();
QList< QPointer<AudioInjector> > _activeInjectors;

View file

@ -54,7 +54,7 @@ enum PacketType {
UNUSED_2,
UNUSED_3,
UNUSED_4,
UNUSED_5,
PacketTypeNoisyMute,
PacketTypeMetavoxelData,
PacketTypeAvatarIdentity,
PacketTypeAvatarBillboard,