mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 12:08:54 +02:00
first pass audio mixer automatic muting of noisy streams, tour guide improvements, new lightExample.js, hair hangs over cone 'body'
This commit is contained in:
parent
a6c8fb7449
commit
688bd0f34f
12 changed files with 121 additions and 26 deletions
|
@ -61,8 +61,7 @@
|
||||||
|
|
||||||
const float LOUDNESS_TO_DISTANCE_RATIO = 0.00001f;
|
const float LOUDNESS_TO_DISTANCE_RATIO = 0.00001f;
|
||||||
const float DEFAULT_ATTENUATION_PER_DOUBLING_IN_DISTANCE = 0.18;
|
const float DEFAULT_ATTENUATION_PER_DOUBLING_IN_DISTANCE = 0.18;
|
||||||
const float DEFAULT_NOISE_MUTING_THRESHOLD = 100.0f;
|
const float DEFAULT_NOISE_MUTING_THRESHOLD = 0.003f;
|
||||||
|
|
||||||
const QString AUDIO_MIXER_LOGGING_TARGET_NAME = "audio-mixer";
|
const QString AUDIO_MIXER_LOGGING_TARGET_NAME = "audio-mixer";
|
||||||
const QString AUDIO_ENV_GROUP_KEY = "audio_env";
|
const QString AUDIO_ENV_GROUP_KEY = "audio_env";
|
||||||
const QString AUDIO_BUFFER_GROUP_KEY = "audio_buffer";
|
const QString AUDIO_BUFFER_GROUP_KEY = "audio_buffer";
|
||||||
|
@ -81,7 +80,6 @@ bool AudioMixer::_enableFilter = true;
|
||||||
|
|
||||||
bool AudioMixer::shouldMute(float quietestFrame, float loudestFrame) {
|
bool AudioMixer::shouldMute(float quietestFrame, float loudestFrame) {
|
||||||
return (quietestFrame > _noiseMutingThreshold);
|
return (quietestFrame > _noiseMutingThreshold);
|
||||||
qDebug() << "Muting, quiestest frame = " << quietestFrame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioMixer::AudioMixer(const QByteArray& packet) :
|
AudioMixer::AudioMixer(const QByteArray& packet) :
|
||||||
|
@ -1015,7 +1013,17 @@ void AudioMixer::parseSettingsObject(const QJsonObject &settingsObject) {
|
||||||
qDebug() << "Attenuation per doubling in distance changed to" << _attenuationPerDoublingInDistance;
|
qDebug() << "Attenuation per doubling in distance changed to" << _attenuationPerDoublingInDistance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString NOISE_MUTING_THRESHOLD = "noise_muting_threshold";
|
||||||
|
if (audioEnvGroupObject[NOISE_MUTING_THRESHOLD].isString()) {
|
||||||
|
bool ok = false;
|
||||||
|
float noiseMutingThreshold = audioEnvGroupObject[NOISE_MUTING_THRESHOLD].toString().toFloat(&ok);
|
||||||
|
if (ok) {
|
||||||
|
_noiseMutingThreshold = noiseMutingThreshold;
|
||||||
|
qDebug() << "Noise muting threshold changed to" << _noiseMutingThreshold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const QString FILTER_KEY = "enable_filter";
|
const QString FILTER_KEY = "enable_filter";
|
||||||
if (audioEnvGroupObject[FILTER_KEY].isBool()) {
|
if (audioEnvGroupObject[FILTER_KEY].isBool()) {
|
||||||
_enableFilter = audioEnvGroupObject[FILTER_KEY].toBool();
|
_enableFilter = audioEnvGroupObject[FILTER_KEY].toBool();
|
||||||
|
|
|
@ -89,6 +89,14 @@
|
||||||
"default": "0.18",
|
"default": "0.18",
|
||||||
"advanced": false
|
"advanced": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "noise_muting_threshold",
|
||||||
|
"label": "Noise Muting Threshold",
|
||||||
|
"help": "Loudness value for noise background between 0 and 1.0 (0: mute everyone, 1.0: never mute)",
|
||||||
|
"placeholder": "0.003",
|
||||||
|
"default": "0.003",
|
||||||
|
"advanced": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "enable_filter",
|
"name": "enable_filter",
|
||||||
"type": "checkbox",
|
"type": "checkbox",
|
||||||
|
|
|
@ -12,6 +12,8 @@ var MIN_CHANGE = 2.0;
|
||||||
var LANDING_DISTANCE = 2.0;
|
var LANDING_DISTANCE = 2.0;
|
||||||
var LANDING_RANDOM = 0.2;
|
var LANDING_RANDOM = 0.2;
|
||||||
|
|
||||||
|
var relativePosition;
|
||||||
|
|
||||||
function update(deltaTime) {
|
function update(deltaTime) {
|
||||||
|
|
||||||
if (Math.random() < deltaTime) {
|
if (Math.random() < deltaTime) {
|
||||||
|
@ -26,20 +28,15 @@ function update(deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (guide) {
|
if (guide) {
|
||||||
|
relativePosition = Vec3.subtract(MyAvatar.position, lastGuidePosition);
|
||||||
// Check whether guide has moved, update if so
|
// Check whether guide has moved, update if so
|
||||||
if (Vec3.length(lastGuidePosition) == 0.0) {
|
if (Vec3.length(lastGuidePosition) == 0.0) {
|
||||||
lastGuidePosition = guide.position;
|
lastGuidePosition = guide.position;
|
||||||
} else {
|
} else {
|
||||||
if (Vec3.length(Vec3.subtract(lastGuidePosition, guide.position)) > MIN_CHANGE) {
|
if (Vec3.length(Vec3.subtract(lastGuidePosition, guide.position)) > MIN_CHANGE) {
|
||||||
var meToGuide = Vec3.multiply(Vec3.normalize(Vec3.subtract(guide.position, MyAvatar.position)), LANDING_DISTANCE);
|
var newPosition = Vec3.sum(guide.position, relativePosition);
|
||||||
var newPosition = Vec3.subtract(guide.position, meToGuide);
|
|
||||||
newPosition = Vec3.sum(newPosition, { x: Math.random() * LANDING_RANDOM - LANDING_RANDOM / 2.0,
|
|
||||||
y: 0,
|
|
||||||
z: Math.random() * LANDING_RANDOM - LANDING_RANDOM / 2.0 });
|
|
||||||
MyAvatar.position = newPosition;
|
MyAvatar.position = newPosition;
|
||||||
|
|
||||||
lastGuidePosition = guide.position;
|
lastGuidePosition = guide.position;
|
||||||
MyAvatar.orientation = guide.orientation;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
46
examples/lightExample.js
Normal file
46
examples/lightExample.js
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
//
|
||||||
|
// spotlightExample.js
|
||||||
|
// examples
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 10/28/14.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// This is an example script that demonstrates creating and editing a particle
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
var position = Vec3.sum(MyAvatar.position, Quat.getFront(Camera.getOrientation()));
|
||||||
|
|
||||||
|
var sphereID = Entities.addEntity({
|
||||||
|
type: "Sphere",
|
||||||
|
position: position,
|
||||||
|
dimensions: { x: 0.1, y: 0.1, z: 0.1 },
|
||||||
|
color: { red: 255, green: 255, blue: 0 }
|
||||||
|
});
|
||||||
|
|
||||||
|
var lightID = Entities.addEntity({
|
||||||
|
type: "Light",
|
||||||
|
position: position,
|
||||||
|
dimensions: { x: 1, y: 1, z: 1 },
|
||||||
|
angularVelocity: { x: 0, y: 0, z: 0 },
|
||||||
|
angularDamping: 0,
|
||||||
|
|
||||||
|
isSpotlight: false,
|
||||||
|
diffuseColor: { red: 255, green: 255, blue: 0 },
|
||||||
|
ambientColor: { red: 0, green: 0, blue: 0 },
|
||||||
|
specularColor: { red: 255, green: 255, blue: 255 },
|
||||||
|
|
||||||
|
constantAttenuation: 0,
|
||||||
|
linearAttenuation: 1,
|
||||||
|
quadraticAttenuation: 0,
|
||||||
|
exponent: 0,
|
||||||
|
cutoff: 180, // in degrees
|
||||||
|
});
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(function() {
|
||||||
|
print("Deleted sphere and light");
|
||||||
|
Entities.deleteEntity(sphereID);
|
||||||
|
Entities.deleteEntity(lightID);
|
||||||
|
});
|
|
@ -728,9 +728,8 @@ void Audio::handleAudioInput() {
|
||||||
_loudestFrame = _lastInputLoudness;
|
_loudestFrame = _lastInputLoudness;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int FRAMES_FOR_NOISE_DETECTION = 300;
|
const int FRAMES_FOR_NOISE_DETECTION = 400;
|
||||||
if (_inputFrameCounter++ > FRAMES_FOR_NOISE_DETECTION) {
|
if (_inputFrameCounter++ > FRAMES_FOR_NOISE_DETECTION) {
|
||||||
qDebug() << "Quietest/loudest frame: " << _quietestFrame << " / " << _loudestFrame << " NGfloor: " << _noiseGateMeasuredFloor;
|
|
||||||
_quietestFrame = std::numeric_limits<float>::max();
|
_quietestFrame = std::numeric_limits<float>::max();
|
||||||
_loudestFrame = 0.0f;
|
_loudestFrame = 0.0f;
|
||||||
_inputFrameCounter = 0;
|
_inputFrameCounter = 0;
|
||||||
|
|
|
@ -52,12 +52,10 @@ Hair::Hair(int strands,
|
||||||
glm::vec3 thisVertex;
|
glm::vec3 thisVertex;
|
||||||
for (int strand = 0; strand < _strands; strand++) {
|
for (int strand = 0; strand < _strands; strand++) {
|
||||||
float strandAngle = randFloat() * PI;
|
float strandAngle = randFloat() * PI;
|
||||||
float azimuth;
|
|
||||||
float elevation = - (randFloat() * PI);
|
float azimuth = (float)strand / (float)_strands * PI * 2.0f;
|
||||||
azimuth = PI_OVER_TWO;
|
float elevation = 0.0f;
|
||||||
if (randFloat() < 0.5f) {
|
|
||||||
azimuth *= -1.0f;
|
|
||||||
}
|
|
||||||
glm::vec3 thisStrand(sinf(azimuth) * cosf(elevation), sinf(elevation), -cosf(azimuth) * cosf(elevation));
|
glm::vec3 thisStrand(sinf(azimuth) * cosf(elevation), sinf(elevation), -cosf(azimuth) * cosf(elevation));
|
||||||
thisStrand *= _radius;
|
thisStrand *= _radius;
|
||||||
|
|
||||||
|
@ -115,11 +113,22 @@ void Hair::simulate(float deltaTime) {
|
||||||
glm::vec3 diff = thisPosition - _hairLastPosition[vertexIndex];
|
glm::vec3 diff = thisPosition - _hairLastPosition[vertexIndex];
|
||||||
_hairPosition[vertexIndex] += diff * HAIR_DAMPING;
|
_hairPosition[vertexIndex] += diff * HAIR_DAMPING;
|
||||||
|
|
||||||
|
/*
|
||||||
// Resolve collisions with sphere
|
// Resolve collisions with sphere
|
||||||
if (glm::length(_hairPosition[vertexIndex]) < _radius) {
|
if (glm::length(_hairPosition[vertexIndex]) < _radius) {
|
||||||
_hairPosition[vertexIndex] += glm::normalize(_hairPosition[vertexIndex]) *
|
_hairPosition[vertexIndex] += glm::normalize(_hairPosition[vertexIndex]) *
|
||||||
(_radius - glm::length(_hairPosition[vertexIndex]));
|
(_radius - glm::length(_hairPosition[vertexIndex]));
|
||||||
|
} */
|
||||||
|
|
||||||
|
// Collide with a conical body descending from the root of the hair
|
||||||
|
glm::vec3 thisVertex = _hairPosition[vertexIndex];
|
||||||
|
float depth = -thisVertex.y;
|
||||||
|
thisVertex.y = 0.0f;
|
||||||
|
const float BODY_CONE_ANGLE = 0.30;
|
||||||
|
if (glm::length(thisVertex) < depth * BODY_CONE_ANGLE) {
|
||||||
|
_hairPosition[vertexIndex] += glm::normalize(thisVertex) * (depth * BODY_CONE_ANGLE - glm::length(thisVertex));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add random thing driven by loudness
|
// Add random thing driven by loudness
|
||||||
float loudnessFactor = (_loudness > SOUND_THRESHOLD) ? logf(_loudness - SOUND_THRESHOLD) / 2000.0f : 0.0f;
|
float loudnessFactor = (_loudness > SOUND_THRESHOLD) ? logf(_loudness - SOUND_THRESHOLD) / 2000.0f : 0.0f;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//
|
//
|
||||||
// EntityTreeRenderer.cpp
|
// EntityTreeRenderer.cpp
|
||||||
// interface/src
|
// interface/src
|
||||||
//
|
//
|
||||||
|
|
|
@ -26,7 +26,8 @@ AudioInjector::AudioInjector(QObject* parent) :
|
||||||
_sound(NULL),
|
_sound(NULL),
|
||||||
_options(),
|
_options(),
|
||||||
_shouldStop(false),
|
_shouldStop(false),
|
||||||
_currentSendPosition(0)
|
_currentSendPosition(0),
|
||||||
|
_loudness(0.0f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +35,8 @@ AudioInjector::AudioInjector(Sound* sound, const AudioInjectorOptions& injectorO
|
||||||
_sound(sound),
|
_sound(sound),
|
||||||
_options(injectorOptions),
|
_options(injectorOptions),
|
||||||
_shouldStop(false),
|
_shouldStop(false),
|
||||||
_currentSendPosition(0)
|
_currentSendPosition(0),
|
||||||
|
_loudness(0.0f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +44,10 @@ void AudioInjector::setOptions(AudioInjectorOptions& options) {
|
||||||
_options = options;
|
_options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float AudioInjector::getLoudness() {
|
||||||
|
return _loudness;
|
||||||
|
}
|
||||||
|
|
||||||
const uchar MAX_INJECTOR_VOLUME = 0xFF;
|
const uchar MAX_INJECTOR_VOLUME = 0xFF;
|
||||||
|
|
||||||
void AudioInjector::injectAudio() {
|
void AudioInjector::injectAudio() {
|
||||||
|
@ -113,6 +119,15 @@ void AudioInjector::injectAudio() {
|
||||||
|
|
||||||
int bytesToCopy = std::min(((_options.isStereo()) ? 2 : 1) * NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL,
|
int bytesToCopy = std::min(((_options.isStereo()) ? 2 : 1) * NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL,
|
||||||
soundByteArray.size() - _currentSendPosition);
|
soundByteArray.size() - _currentSendPosition);
|
||||||
|
|
||||||
|
// Measure the loudness of this frame
|
||||||
|
_loudness = 0.0f;
|
||||||
|
for (int i = 0; i < bytesToCopy; i += sizeof(int16_t)) {
|
||||||
|
_loudness += abs(*reinterpret_cast<int16_t*>(soundByteArray.data() + _currentSendPosition + i)) /
|
||||||
|
(MAX_SAMPLE_VALUE / 2.0f);
|
||||||
|
}
|
||||||
|
_loudness /= (float)(bytesToCopy / sizeof(int16_t));
|
||||||
|
|
||||||
memcpy(injectAudioPacket.data() + positionOptionOffset,
|
memcpy(injectAudioPacket.data() + positionOptionOffset,
|
||||||
&_options.getPosition(),
|
&_options.getPosition(),
|
||||||
sizeof(_options.getPosition()));
|
sizeof(_options.getPosition()));
|
||||||
|
|
|
@ -33,6 +33,8 @@ public slots:
|
||||||
void stop() { _shouldStop = true; }
|
void stop() { _shouldStop = true; }
|
||||||
void setOptions(AudioInjectorOptions& options);
|
void setOptions(AudioInjectorOptions& options);
|
||||||
void setCurrentSendPosition(int currentSendPosition) { _currentSendPosition = currentSendPosition; }
|
void setCurrentSendPosition(int currentSendPosition) { _currentSendPosition = currentSendPosition; }
|
||||||
|
float getLoudness();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void finished();
|
void finished();
|
||||||
private:
|
private:
|
||||||
|
@ -40,6 +42,7 @@ private:
|
||||||
AudioInjectorOptions _options;
|
AudioInjectorOptions _options;
|
||||||
bool _shouldStop;
|
bool _shouldStop;
|
||||||
int _currentSendPosition;
|
int _currentSendPosition;
|
||||||
|
float _loudness;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(AudioInjector*)
|
Q_DECLARE_METATYPE(AudioInjector*)
|
||||||
|
|
|
@ -45,7 +45,15 @@ bool AudioScriptingInterface::isInjectorPlaying(AudioInjector* injector) {
|
||||||
return (injector != NULL);
|
return (injector != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioScriptingInterface::startDrumSound(float volume, float frequency, float duration, float decay,
|
float AudioScriptingInterface::getLoudness(AudioInjector* injector) {
|
||||||
|
if (injector) {
|
||||||
|
return injector->getLoudness();
|
||||||
|
} else {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioScriptingInterface::startDrumSound(float volume, float frequency, float duration, float decay,
|
||||||
const AudioInjectorOptions* injectorOptions) {
|
const AudioInjectorOptions* injectorOptions) {
|
||||||
|
|
||||||
Sound* sound = new Sound(volume, frequency, duration, decay);
|
Sound* sound = new Sound(volume, frequency, duration, decay);
|
||||||
|
|
|
@ -23,6 +23,7 @@ public slots:
|
||||||
static AudioInjector* playSound(Sound* sound, const AudioInjectorOptions* injectorOptions = NULL);
|
static AudioInjector* playSound(Sound* sound, const AudioInjectorOptions* injectorOptions = NULL);
|
||||||
static void stopInjector(AudioInjector* injector);
|
static void stopInjector(AudioInjector* injector);
|
||||||
static bool isInjectorPlaying(AudioInjector* injector);
|
static bool isInjectorPlaying(AudioInjector* injector);
|
||||||
|
static float getLoudness(AudioInjector* injector);
|
||||||
static void startDrumSound(float volume, float frequency, float duration, float decay,
|
static void startDrumSound(float volume, float frequency, float duration, float decay,
|
||||||
const AudioInjectorOptions* injectorOptions = NULL);
|
const AudioInjectorOptions* injectorOptions = NULL);
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,9 @@ void PositionalAudioStream::resetStats() {
|
||||||
void PositionalAudioStream::updateLastPopOutputLoudnessAndTrailingLoudness() {
|
void PositionalAudioStream::updateLastPopOutputLoudnessAndTrailingLoudness() {
|
||||||
_lastPopOutputLoudness = _ringBuffer.getFrameLoudness(_lastPopOutput);
|
_lastPopOutputLoudness = _ringBuffer.getFrameLoudness(_lastPopOutput);
|
||||||
|
|
||||||
const int TRAILING_AVERAGE_FRAMES = 100;
|
const int TRAILING_MUTE_THRESHOLD_FRAMES = 400;
|
||||||
const float CURRENT_FRAME_RATIO = 1.0f / TRAILING_AVERAGE_FRAMES;
|
const int TRAILING_LOUDNESS_FRAMES = 200;
|
||||||
|
const float CURRENT_FRAME_RATIO = 1.0f / TRAILING_LOUDNESS_FRAMES;
|
||||||
const float PREVIOUS_FRAMES_RATIO = 1.0f - CURRENT_FRAME_RATIO;
|
const float PREVIOUS_FRAMES_RATIO = 1.0f - CURRENT_FRAME_RATIO;
|
||||||
const float LOUDNESS_EPSILON = 0.000001f;
|
const float LOUDNESS_EPSILON = 0.000001f;
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ void PositionalAudioStream::updateLastPopOutputLoudnessAndTrailingLoudness() {
|
||||||
_lastPopOutputTrailingLoudness = 0;
|
_lastPopOutputTrailingLoudness = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_frameCounter++ == TRAILING_AVERAGE_FRAMES) {
|
if (_frameCounter++ == TRAILING_MUTE_THRESHOLD_FRAMES) {
|
||||||
_frameCounter = 0;
|
_frameCounter = 0;
|
||||||
_quietestTrailingFrameLoudness = std::numeric_limits<float>::max();
|
_quietestTrailingFrameLoudness = std::numeric_limits<float>::max();
|
||||||
_loudestTrailingFrameLoudness = 0.0f;
|
_loudestTrailingFrameLoudness = 0.0f;
|
||||||
|
|
Loading…
Reference in a new issue