Files
UnrealEngineUWP/Engine/Source/Runtime/SignalProcessing/Private/AudioBufferDistanceAttenuation.cpp
aaron mcleran 29e6d3593a Fixing and adding more logging to voice chat attenuation.
Refactored the way data is retrieved in voice chat manager.

#rb none

#ROBOMERGE-AUTHOR: aaron.mcleran
#ROBOMERGE-SOURCE: CL 18425719 via CL 18425754 via CL 18425767 via CL 18425779 via CL 18435113 via CL 18437391
#ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v897-18405271)

[CL 18437669 by aaron mcleran in ue5-release-engine-test branch]
2021-12-10 20:59:47 -05:00

85 lines
3.7 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "DSP/AudioBufferDistanceAttenuation.h"
#include "DSP/Dsp.h"
#include "DSP/BufferVectorOperations.h"
namespace Audio
{
static float ComputeNextLinearAttenuation(const FAudioBufferDistanceAttenuationSettings& InSettings, float InCurrentDistance)
{
float NextAttenuationDb = 0.0f;
const float Denom = FMath::Max(InSettings.DistanceRange.Y - InSettings.DistanceRange.X, SMALL_NUMBER);
const float Alpha = FMath::Clamp((InCurrentDistance - InSettings.DistanceRange.X) / Denom, 0.0f, 1.0f);
float CurveValue = 0.0f;
bool bSuccess = InSettings.AttenuationCurve.Eval(Alpha, CurveValue);
// This should succeed since we ensure we always have at least two points in the curve when it's set
check(bSuccess);
// Note the curve is expected to map to the attenuation amount (i.e. at right-most value, it'll be 0.0, which corresponds to max dB attenuation)
// This then needs to be used to interpolate the dB range (0.0 is no attenuation, -60 for example, is a lot of attenuation)
NextAttenuationDb = FMath::Lerp(InSettings.AttenuationDbAtMaxRange, 0.0f, CurveValue);
float TargetAttenuationLinear = 0.0f;
if (NextAttenuationDb > InSettings.AttenuationDbAtMaxRange)
{
TargetAttenuationLinear = Audio::ConvertToLinear(NextAttenuationDb);
}
return TargetAttenuationLinear;
}
void DistanceAttenuationProcessAudio(TArrayView<int16>& InOutBuffer, uint32 InNumChannels, float InDistance, const FAudioBufferDistanceAttenuationSettings& InSettings, float& InOutAttenuation)
{
check(InOutBuffer.Num() > 0);
check(InNumChannels > 0);
check(InDistance >= 0.0f);
int32 FrameCount = InOutBuffer.Num() / InNumChannels;
float TargetAttenuationLinear = ComputeNextLinearAttenuation(InSettings, InDistance);
// TODO: investigate adding int16 flavors of utilities in BufferVectorOperations.h to avoid format conversions
uint32 CurrentSampleIndex = 0;
// If we're passed in a negative value for InOutAttenuation, that means we don't want to interpolate from that value to target value (i.e. it's the first one).
// This prevents a pop when first applying attenuation if a sound is far away.
float Gain = InOutAttenuation < 0.0f ? TargetAttenuationLinear : InOutAttenuation;
const float DeltaValue = (TargetAttenuationLinear - Gain) / FrameCount;
for (int32 FrameIndex = 0; FrameIndex < FrameCount; ++FrameIndex)
{
for (uint32 ChannelIndex = 0; ChannelIndex < InNumChannels; ++ChannelIndex)
{
InOutBuffer[CurrentSampleIndex + ChannelIndex] = InOutBuffer[CurrentSampleIndex + ChannelIndex] * Gain;
}
CurrentSampleIndex += InNumChannels;
Gain += DeltaValue;
}
// Update the current attenuation linear for the next render block
InOutAttenuation = TargetAttenuationLinear;
}
void DistanceAttenuationProcessAudio(TArrayView<float>& InOutBuffer, uint32 InNumChannels, float InDistance, const FAudioBufferDistanceAttenuationSettings& InSettings, float& InOutAttenuation)
{
check(InOutBuffer.Num() > 0);
check(InNumChannels > 0);
check(InDistance >= 0.0f);
int32 FrameCount = InOutBuffer.Num() / InNumChannels;
float TargetAttenuationLinear = ComputeNextLinearAttenuation(InSettings, InDistance);
int32 NumSamples = (int32)(FrameCount * InNumChannels);
// If we're passed in a negative value for InOutAttenuation, that means we don't want to interpolate from that value to target value (i.e. it's the first one).
// This prevents a pop when first applying attenuation if a sound is far away.
float Gain = InOutAttenuation < 0.0f ? TargetAttenuationLinear : InOutAttenuation;
Audio::FadeBufferFast(InOutBuffer.GetData(), NumSamples, Gain, TargetAttenuationLinear);
InOutAttenuation = TargetAttenuationLinear;
}
}