mirror of
https://github.com/overte-org/overte.git
synced 2025-08-05 19:39:43 +02:00
Add master injector gain to audio-mixer
This commit is contained in:
parent
de5b5301d6
commit
1057166418
3 changed files with 43 additions and 23 deletions
|
@ -84,6 +84,8 @@ public:
|
||||||
|
|
||||||
float getMasterAvatarGain() const { return _masterAvatarGain; }
|
float getMasterAvatarGain() const { return _masterAvatarGain; }
|
||||||
void setMasterAvatarGain(float gain) { _masterAvatarGain = gain; }
|
void setMasterAvatarGain(float gain) { _masterAvatarGain = gain; }
|
||||||
|
float getMasterInjectorGain() const { return _masterInjectorGain; }
|
||||||
|
void setMasterInjectorGain(float gain) { _masterInjectorGain = gain; }
|
||||||
|
|
||||||
AudioLimiter audioLimiter;
|
AudioLimiter audioLimiter;
|
||||||
|
|
||||||
|
@ -189,6 +191,7 @@ private:
|
||||||
int _frameToSendStats { 0 };
|
int _frameToSendStats { 0 };
|
||||||
|
|
||||||
float _masterAvatarGain { 1.0f }; // per-listener mixing gain, applied only to avatars
|
float _masterAvatarGain { 1.0f }; // per-listener mixing gain, applied only to avatars
|
||||||
|
float _masterInjectorGain { 1.0f }; // per-listener mixing gain, applied only to injectors
|
||||||
|
|
||||||
CodecPluginPointer _codec;
|
CodecPluginPointer _codec;
|
||||||
QString _selectedCodecName;
|
QString _selectedCodecName;
|
||||||
|
|
|
@ -50,7 +50,7 @@ void sendEnvironmentPacket(const SharedNodePointer& node, AudioMixerClientData&
|
||||||
|
|
||||||
// mix helpers
|
// mix helpers
|
||||||
inline float approximateGain(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd);
|
inline float approximateGain(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd);
|
||||||
inline float computeGain(float masterListenerGain, const AvatarAudioStream& listeningNodeStream,
|
inline float computeGain(float masterAvatarGain, float masterInjectorGain, const AvatarAudioStream& listeningNodeStream,
|
||||||
const PositionalAudioStream& streamToAdd, const glm::vec3& relativePosition, float distance, bool isEcho);
|
const PositionalAudioStream& streamToAdd, const glm::vec3& relativePosition, float distance, bool isEcho);
|
||||||
inline float computeAzimuth(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd,
|
inline float computeAzimuth(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd,
|
||||||
const glm::vec3& relativePosition);
|
const glm::vec3& relativePosition);
|
||||||
|
@ -338,8 +338,8 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isThrottling) {
|
if (!isThrottling) {
|
||||||
updateHRTFParameters(stream, *listenerAudioStream,
|
updateHRTFParameters(stream, *listenerAudioStream, listenerData->getMasterAvatarGain(),
|
||||||
listenerData->getMasterAvatarGain());
|
listenerData->getMasterInjectorGain());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
@ -363,8 +363,8 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isThrottling) {
|
if (!isThrottling) {
|
||||||
updateHRTFParameters(stream, *listenerAudioStream,
|
updateHRTFParameters(stream, *listenerAudioStream, listenerData->getMasterAvatarGain(),
|
||||||
listenerData->getMasterAvatarGain());
|
listenerData->getMasterInjectorGain());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
@ -381,13 +381,13 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
|
||||||
stream.approximateVolume = approximateVolume(stream, listenerAudioStream);
|
stream.approximateVolume = approximateVolume(stream, listenerAudioStream);
|
||||||
} else {
|
} else {
|
||||||
if (shouldBeSkipped(stream, *listener, *listenerAudioStream, *listenerData)) {
|
if (shouldBeSkipped(stream, *listener, *listenerAudioStream, *listenerData)) {
|
||||||
addStream(stream, *listenerAudioStream, 0.0f, isSoloing);
|
addStream(stream, *listenerAudioStream, 0.0f, 0.0f, isSoloing);
|
||||||
streams.skipped.push_back(move(stream));
|
streams.skipped.push_back(move(stream));
|
||||||
++stats.activeToSkipped;
|
++stats.activeToSkipped;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
addStream(stream, *listenerAudioStream, listenerData->getMasterAvatarGain(),
|
addStream(stream, *listenerAudioStream, listenerData->getMasterAvatarGain(), listenerData->getMasterInjectorGain(),
|
||||||
isSoloing);
|
isSoloing);
|
||||||
|
|
||||||
if (shouldBeInactive(stream)) {
|
if (shouldBeInactive(stream)) {
|
||||||
|
@ -423,7 +423,7 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
addStream(stream, *listenerAudioStream, listenerData->getMasterAvatarGain(),
|
addStream(stream, *listenerAudioStream, listenerData->getMasterAvatarGain(), listenerData->getMasterInjectorGain(),
|
||||||
isSoloing);
|
isSoloing);
|
||||||
|
|
||||||
if (shouldBeInactive(stream)) {
|
if (shouldBeInactive(stream)) {
|
||||||
|
@ -491,7 +491,9 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
|
||||||
|
|
||||||
void AudioMixerSlave::addStream(AudioMixerClientData::MixableStream& mixableStream,
|
void AudioMixerSlave::addStream(AudioMixerClientData::MixableStream& mixableStream,
|
||||||
AvatarAudioStream& listeningNodeStream,
|
AvatarAudioStream& listeningNodeStream,
|
||||||
float masterListenerGain, bool isSoloing) {
|
float masterAvatarGain,
|
||||||
|
float masterInjectorGain,
|
||||||
|
bool isSoloing) {
|
||||||
++stats.totalMixes;
|
++stats.totalMixes;
|
||||||
|
|
||||||
auto streamToAdd = mixableStream.positionalStream;
|
auto streamToAdd = mixableStream.positionalStream;
|
||||||
|
@ -504,9 +506,10 @@ void AudioMixerSlave::addStream(AudioMixerClientData::MixableStream& mixableStre
|
||||||
float distance = glm::max(glm::length(relativePosition), EPSILON);
|
float distance = glm::max(glm::length(relativePosition), EPSILON);
|
||||||
float azimuth = isEcho ? 0.0f : computeAzimuth(listeningNodeStream, listeningNodeStream, relativePosition);
|
float azimuth = isEcho ? 0.0f : computeAzimuth(listeningNodeStream, listeningNodeStream, relativePosition);
|
||||||
|
|
||||||
float gain = masterListenerGain;
|
float gain = masterAvatarGain;
|
||||||
if (!isSoloing) {
|
if (!isSoloing) {
|
||||||
gain = computeGain(masterListenerGain, listeningNodeStream, *streamToAdd, relativePosition, distance, isEcho);
|
gain = computeGain(masterAvatarGain, masterInjectorGain, listeningNodeStream, *streamToAdd, relativePosition,
|
||||||
|
distance, isEcho);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int HRTF_DATASET_INDEX = 1;
|
const int HRTF_DATASET_INDEX = 1;
|
||||||
|
@ -585,8 +588,9 @@ void AudioMixerSlave::addStream(AudioMixerClientData::MixableStream& mixableStre
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioMixerSlave::updateHRTFParameters(AudioMixerClientData::MixableStream& mixableStream,
|
void AudioMixerSlave::updateHRTFParameters(AudioMixerClientData::MixableStream& mixableStream,
|
||||||
AvatarAudioStream& listeningNodeStream,
|
AvatarAudioStream& listeningNodeStream,
|
||||||
float masterListenerGain) {
|
float masterAvatarGain,
|
||||||
|
float masterInjectorGain) {
|
||||||
auto streamToAdd = mixableStream.positionalStream;
|
auto streamToAdd = mixableStream.positionalStream;
|
||||||
|
|
||||||
// check if this is a server echo of a source back to itself
|
// check if this is a server echo of a source back to itself
|
||||||
|
@ -595,7 +599,8 @@ void AudioMixerSlave::updateHRTFParameters(AudioMixerClientData::MixableStream&
|
||||||
glm::vec3 relativePosition = streamToAdd->getPosition() - listeningNodeStream.getPosition();
|
glm::vec3 relativePosition = streamToAdd->getPosition() - listeningNodeStream.getPosition();
|
||||||
|
|
||||||
float distance = glm::max(glm::length(relativePosition), EPSILON);
|
float distance = glm::max(glm::length(relativePosition), EPSILON);
|
||||||
float gain = computeGain(masterListenerGain, listeningNodeStream, *streamToAdd, relativePosition, distance, isEcho);
|
float gain = computeGain(masterAvatarGain, masterInjectorGain, listeningNodeStream, *streamToAdd, relativePosition,
|
||||||
|
distance, isEcho);
|
||||||
float azimuth = isEcho ? 0.0f : computeAzimuth(listeningNodeStream, listeningNodeStream, relativePosition);
|
float azimuth = isEcho ? 0.0f : computeAzimuth(listeningNodeStream, listeningNodeStream, relativePosition);
|
||||||
|
|
||||||
mixableStream.hrtf->setParameterHistory(azimuth, distance, gain);
|
mixableStream.hrtf->setParameterHistory(azimuth, distance, gain);
|
||||||
|
@ -720,6 +725,7 @@ float approximateGain(const AvatarAudioStream& listeningNodeStream, const Positi
|
||||||
// injector: apply attenuation
|
// injector: apply attenuation
|
||||||
if (streamToAdd.getType() == PositionalAudioStream::Injector) {
|
if (streamToAdd.getType() == PositionalAudioStream::Injector) {
|
||||||
gain *= reinterpret_cast<const InjectedAudioStream*>(&streamToAdd)->getAttenuationRatio();
|
gain *= reinterpret_cast<const InjectedAudioStream*>(&streamToAdd)->getAttenuationRatio();
|
||||||
|
// injector: skip master gain
|
||||||
}
|
}
|
||||||
|
|
||||||
// avatar: skip attenuation - it is too costly to approximate
|
// avatar: skip attenuation - it is too costly to approximate
|
||||||
|
@ -729,16 +735,23 @@ float approximateGain(const AvatarAudioStream& listeningNodeStream, const Positi
|
||||||
float distance = glm::length(relativePosition);
|
float distance = glm::length(relativePosition);
|
||||||
return gain / distance;
|
return gain / distance;
|
||||||
|
|
||||||
// avatar: skip master gain - it is constant for all streams
|
// avatar: skip master gain
|
||||||
}
|
}
|
||||||
|
|
||||||
float computeGain(float masterListenerGain, const AvatarAudioStream& listeningNodeStream,
|
float computeGain(float masterAvatarGain,
|
||||||
const PositionalAudioStream& streamToAdd, const glm::vec3& relativePosition, float distance, bool isEcho) {
|
float masterInjectorGain,
|
||||||
|
const AvatarAudioStream& listeningNodeStream,
|
||||||
|
const PositionalAudioStream& streamToAdd,
|
||||||
|
const glm::vec3& relativePosition,
|
||||||
|
float distance,
|
||||||
|
bool isEcho) {
|
||||||
float gain = 1.0f;
|
float gain = 1.0f;
|
||||||
|
|
||||||
// injector: apply attenuation
|
// injector: apply attenuation
|
||||||
if (streamToAdd.getType() == PositionalAudioStream::Injector) {
|
if (streamToAdd.getType() == PositionalAudioStream::Injector) {
|
||||||
gain *= reinterpret_cast<const InjectedAudioStream*>(&streamToAdd)->getAttenuationRatio();
|
gain *= reinterpret_cast<const InjectedAudioStream*>(&streamToAdd)->getAttenuationRatio();
|
||||||
|
// apply master gain
|
||||||
|
gain *= masterInjectorGain;
|
||||||
|
|
||||||
// avatar: apply fixed off-axis attenuation to make them quieter as they turn away
|
// avatar: apply fixed off-axis attenuation to make them quieter as they turn away
|
||||||
} else if (!isEcho && (streamToAdd.getType() == PositionalAudioStream::Microphone)) {
|
} else if (!isEcho && (streamToAdd.getType() == PositionalAudioStream::Microphone)) {
|
||||||
|
@ -754,8 +767,8 @@ float computeGain(float masterListenerGain, const AvatarAudioStream& listeningNo
|
||||||
|
|
||||||
gain *= offAxisCoefficient;
|
gain *= offAxisCoefficient;
|
||||||
|
|
||||||
// apply master gain, only to avatars
|
// apply master gain
|
||||||
gain *= masterListenerGain;
|
gain *= masterAvatarGain;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& audioZones = AudioMixer::getAudioZones();
|
auto& audioZones = AudioMixer::getAudioZones();
|
||||||
|
@ -797,8 +810,9 @@ float computeGain(float masterListenerGain, const AvatarAudioStream& listeningNo
|
||||||
return gain;
|
return gain;
|
||||||
}
|
}
|
||||||
|
|
||||||
float computeAzimuth(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd,
|
float computeAzimuth(const AvatarAudioStream& listeningNodeStream,
|
||||||
const glm::vec3& relativePosition) {
|
const PositionalAudioStream& streamToAdd,
|
||||||
|
const glm::vec3& relativePosition) {
|
||||||
glm::quat inverseOrientation = glm::inverse(listeningNodeStream.getOrientation());
|
glm::quat inverseOrientation = glm::inverse(listeningNodeStream.getOrientation());
|
||||||
|
|
||||||
glm::vec3 rotatedSourcePosition = inverseOrientation * relativePosition;
|
glm::vec3 rotatedSourcePosition = inverseOrientation * relativePosition;
|
||||||
|
|
|
@ -57,10 +57,13 @@ private:
|
||||||
bool prepareMix(const SharedNodePointer& listener);
|
bool prepareMix(const SharedNodePointer& listener);
|
||||||
void addStream(AudioMixerClientData::MixableStream& mixableStream,
|
void addStream(AudioMixerClientData::MixableStream& mixableStream,
|
||||||
AvatarAudioStream& listeningNodeStream,
|
AvatarAudioStream& listeningNodeStream,
|
||||||
float masterListenerGain, bool isSoloing);
|
float masterAvatarGain,
|
||||||
|
float masterInjectorGain,
|
||||||
|
bool isSoloing);
|
||||||
void updateHRTFParameters(AudioMixerClientData::MixableStream& mixableStream,
|
void updateHRTFParameters(AudioMixerClientData::MixableStream& mixableStream,
|
||||||
AvatarAudioStream& listeningNodeStream,
|
AvatarAudioStream& listeningNodeStream,
|
||||||
float masterListenerGain);
|
float masterAvatarGain,
|
||||||
|
float masterInjectorGain);
|
||||||
void resetHRTFState(AudioMixerClientData::MixableStream& mixableStream);
|
void resetHRTFState(AudioMixerClientData::MixableStream& mixableStream);
|
||||||
|
|
||||||
void addStreams(Node& listener, AudioMixerClientData& listenerData);
|
void addStreams(Node& listener, AudioMixerClientData& listenerData);
|
||||||
|
|
Loading…
Reference in a new issue