mirror of
https://github.com/lubosz/overte.git
synced 2025-04-08 07:22:43 +02:00
Merge pull request #14797 from kencooke/audio-injector-stereo-distattn-bugfix2
case 20805: RC78.1 to master: Fix the distance attenuation of stereo local injectors
This commit is contained in:
commit
72d3eb9d33
8 changed files with 60 additions and 26 deletions
|
@ -4194,7 +4194,9 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
if (!isShifted && !isMeta && !isOption && !event->isAutoRepeat()) {
|
||||
AudioInjectorOptions options;
|
||||
options.localOnly = true;
|
||||
options.positionSet = false; // system sound
|
||||
options.stereo = true;
|
||||
|
||||
Setting::Handle<bool> notificationSounds{ MenuOption::NotificationSounds, true };
|
||||
Setting::Handle<bool> notificationSoundSnapshot{ MenuOption::NotificationSoundsSnapshot, true };
|
||||
if (notificationSounds.get() && notificationSoundSnapshot.get()) {
|
||||
|
|
|
@ -1310,10 +1310,17 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) {
|
|||
memset(_localScratchBuffer, 0, bytesToRead);
|
||||
if (0 < injectorBuffer->readData((char*)_localScratchBuffer, bytesToRead)) {
|
||||
|
||||
float gain = injector->getVolume();
|
||||
|
||||
if (injector->isAmbisonic()) {
|
||||
|
||||
// no distance attenuation
|
||||
float gain = injector->getVolume();
|
||||
if (injector->isPositionSet()) {
|
||||
|
||||
// distance attenuation
|
||||
glm::vec3 relativePosition = injector->getPosition() - _positionGetter();
|
||||
float distance = glm::max(glm::length(relativePosition), EPSILON);
|
||||
gain = gainForSource(distance, gain);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate the soundfield orientation relative to the listener.
|
||||
|
@ -1327,33 +1334,49 @@ bool AudioClient::mixLocalAudioInjectors(float* mixBuffer) {
|
|||
float qy = -relativeOrientation.x;
|
||||
float qz = relativeOrientation.y;
|
||||
|
||||
// Ambisonic gets spatialized into mixBuffer
|
||||
// spatialize into mixBuffer
|
||||
injector->getLocalFOA().render(_localScratchBuffer, mixBuffer, HRTF_DATASET_INDEX,
|
||||
qw, qx, qy, qz, gain, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL);
|
||||
|
||||
} else if (injector->isStereo()) {
|
||||
|
||||
// calculate distance, gain
|
||||
glm::vec3 relativePosition = injector->getPosition() - _positionGetter();
|
||||
float distance = glm::max(glm::length(relativePosition), EPSILON);
|
||||
float gain = gainForSource(distance, injector->getVolume());
|
||||
if (injector->isPositionSet()) {
|
||||
|
||||
// stereo gets directly mixed into mixBuffer
|
||||
for (int i = 0; i < AudioConstants::NETWORK_FRAME_SAMPLES_STEREO; i++) {
|
||||
mixBuffer[i] += convertToFloat(_localScratchBuffer[i]) * gain;
|
||||
// distance attenuation
|
||||
glm::vec3 relativePosition = injector->getPosition() - _positionGetter();
|
||||
float distance = glm::max(glm::length(relativePosition), EPSILON);
|
||||
gain = gainForSource(distance, gain);
|
||||
}
|
||||
|
||||
} else {
|
||||
// direct mix into mixBuffer
|
||||
for (int i = 0; i < AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL; i++) {
|
||||
mixBuffer[2*i+0] += convertToFloat(_localScratchBuffer[2*i+0]) * gain;
|
||||
mixBuffer[2*i+1] += convertToFloat(_localScratchBuffer[2*i+1]) * gain;
|
||||
}
|
||||
|
||||
// calculate distance, gain and azimuth for hrtf
|
||||
glm::vec3 relativePosition = injector->getPosition() - _positionGetter();
|
||||
float distance = glm::max(glm::length(relativePosition), EPSILON);
|
||||
float gain = gainForSource(distance, injector->getVolume());
|
||||
float azimuth = azimuthForSource(relativePosition);
|
||||
} else { // injector is mono
|
||||
|
||||
// mono gets spatialized into mixBuffer
|
||||
injector->getLocalHRTF().render(_localScratchBuffer, mixBuffer, HRTF_DATASET_INDEX,
|
||||
azimuth, distance, gain, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL);
|
||||
if (injector->isPositionSet()) {
|
||||
|
||||
// distance attenuation
|
||||
glm::vec3 relativePosition = injector->getPosition() - _positionGetter();
|
||||
float distance = glm::max(glm::length(relativePosition), EPSILON);
|
||||
gain = gainForSource(distance, gain);
|
||||
|
||||
float azimuth = azimuthForSource(relativePosition);
|
||||
|
||||
// spatialize into mixBuffer
|
||||
injector->getLocalHRTF().render(_localScratchBuffer, mixBuffer, HRTF_DATASET_INDEX,
|
||||
azimuth, distance, gain, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL);
|
||||
} else {
|
||||
|
||||
// direct mix into mixBuffer
|
||||
for (int i = 0; i < AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL; i++) {
|
||||
float sample = convertToFloat(_localScratchBuffer[i]) * gain;
|
||||
mixBuffer[2*i+0] += sample;
|
||||
mixBuffer[2*i+1] += sample;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
|
||||
bool isLocalOnly() const { return _options.localOnly; }
|
||||
float getVolume() const { return _options.volume; }
|
||||
bool isPositionSet() const { return _options.positionSet; }
|
||||
glm::vec3 getPosition() const { return _options.position; }
|
||||
glm::quat getOrientation() const { return _options.orientation; }
|
||||
bool isStereo() const { return _options.stereo; }
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
AudioInjectorOptions::AudioInjectorOptions() :
|
||||
position(0.0f, 0.0f, 0.0f),
|
||||
positionSet(true), // default to legacy behavior
|
||||
volume(1.0f),
|
||||
loop(false),
|
||||
orientation(glm::vec3(0.0f, 0.0f, 0.0f)),
|
||||
|
@ -29,12 +30,13 @@ AudioInjectorOptions::AudioInjectorOptions() :
|
|||
secondOffset(0.0f),
|
||||
pitch(1.0f)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QScriptValue injectorOptionsToScriptValue(QScriptEngine* engine, const AudioInjectorOptions& injectorOptions) {
|
||||
QScriptValue obj = engine->newObject();
|
||||
obj.setProperty("position", vec3ToScriptValue(engine, injectorOptions.position));
|
||||
if (injectorOptions.positionSet) {
|
||||
obj.setProperty("position", vec3ToScriptValue(engine, injectorOptions.position));
|
||||
}
|
||||
obj.setProperty("volume", injectorOptions.volume);
|
||||
obj.setProperty("loop", injectorOptions.loop);
|
||||
obj.setProperty("orientation", quatToScriptValue(engine, injectorOptions.orientation));
|
||||
|
@ -68,12 +70,18 @@ void injectorOptionsFromScriptValue(const QScriptValue& object, AudioInjectorOpt
|
|||
return;
|
||||
}
|
||||
|
||||
if (injectorOptions.positionSet == false) {
|
||||
qWarning() << "Audio injector options: injectorOptionsFromScriptValue() called more than once?";
|
||||
}
|
||||
injectorOptions.positionSet = false;
|
||||
|
||||
QScriptValueIterator it(object);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
|
||||
if (it.name() == "position") {
|
||||
vec3FromScriptValue(object.property("position"), injectorOptions.position);
|
||||
injectorOptions.positionSet = true;
|
||||
} else if (it.name() == "orientation") {
|
||||
quatFromScriptValue(object.property("orientation"), injectorOptions.orientation);
|
||||
} else if (it.name() == "volume") {
|
||||
|
|
|
@ -21,6 +21,7 @@ class AudioInjectorOptions {
|
|||
public:
|
||||
AudioInjectorOptions();
|
||||
glm::vec3 position;
|
||||
bool positionSet;
|
||||
float volume;
|
||||
bool loop;
|
||||
glm::quat orientation;
|
||||
|
|
|
@ -38,10 +38,10 @@ void AudioScriptingInterface::setLocalAudioInterface(AbstractAudioInterface* aud
|
|||
}
|
||||
}
|
||||
|
||||
ScriptAudioInjector* AudioScriptingInterface::playSystemSound(SharedSoundPointer sound, const QVector3D& position) {
|
||||
ScriptAudioInjector* AudioScriptingInterface::playSystemSound(SharedSoundPointer sound) {
|
||||
AudioInjectorOptions options;
|
||||
options.position = glm::vec3(position.x(), position.y(), position.z());
|
||||
options.localOnly = true;
|
||||
options.positionSet = false; // system sound
|
||||
return playSound(sound, options);
|
||||
}
|
||||
|
||||
|
|
|
@ -102,11 +102,9 @@ protected:
|
|||
* @function Audio.playSystemSound
|
||||
* @param {SoundObject} sound - The content of an audio file, loaded using {@link SoundCache.getSound}. See
|
||||
* {@link SoundObject} for supported formats.
|
||||
* @param {Vec3} position - The position in the domain to play the sound.
|
||||
* @returns {AudioInjector} The audio injector that plays the audio file.
|
||||
*/
|
||||
// FIXME: there is no way to play a positionless sound
|
||||
Q_INVOKABLE ScriptAudioInjector* playSystemSound(SharedSoundPointer sound, const QVector3D& position);
|
||||
Q_INVOKABLE ScriptAudioInjector* playSystemSound(SharedSoundPointer sound);
|
||||
|
||||
/**jsdoc
|
||||
* Set whether or not the audio input should be used in stereo. If the audio input does not support stereo then setting a
|
||||
|
|
|
@ -210,6 +210,7 @@ void TabletScriptingInterface::playSound(TabletAudioEvents aEvent) {
|
|||
options.stereo = sound->isStereo();
|
||||
options.ambisonic = sound->isAmbisonic();
|
||||
options.localOnly = true;
|
||||
options.positionSet = false; // system sound
|
||||
|
||||
AudioInjectorPointer injector = AudioInjector::playSoundAndDelete(sound, options);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue