You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
UE-17938 Fixing some issues that cause mac to sound different than PC client
- Switching to a EQ filter type that is more similar to XAudio2's filter - Piping the per-voice high-frequency attenuation parameter to a new per-voice low-pass filter - making the effect processing serial rather than parallel - Clamping max volumes to 1.0 (linear) before setting volumes on API calls. Not doing this causes sounds to distort as max volume being used was 4.0 and we have volume scale factors greater than 1.0 [CL 2631483 by Aaron McLeran in Main branch]
This commit is contained in:
committed by
Aaron.McLeran@epicgames.com
parent
a94a6f92c7
commit
64e7ff6ccb
@@ -50,6 +50,11 @@ bool FCoreAudioDevice::InitializeHardware()
|
||||
|
||||
InverseTransform = FMatrix::Identity;
|
||||
|
||||
for (int32 Index = 0; Index < CORE_AUDIO_MAX_CHANNELS + 1; ++Index)
|
||||
{
|
||||
AudioChannels[Index] = nullptr;
|
||||
}
|
||||
|
||||
for( SInt32 Index = 0; Index < CORE_AUDIO_MAX_CHANNELS; ++Index )
|
||||
{
|
||||
Mixer3DInputStatus[ Index ] = false;
|
||||
@@ -224,6 +229,9 @@ bool FCoreAudioDevice::InitializeHardware()
|
||||
Status = AUGraphConnectNodeInput( AudioUnitGraph, Mixer3DNode, 0, OutputNode, 0 );
|
||||
}
|
||||
|
||||
// Set the sample rate
|
||||
SampleRate = Mixer3DFormat.mSampleRate;
|
||||
|
||||
if( Status != noErr )
|
||||
{
|
||||
UE_LOG(LogInit, Log, TEXT( "Failed to start audio graph!" ) );
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include "CoreAudioEffects.h"
|
||||
#include "Engine.h"
|
||||
|
||||
extern FCoreAudioSoundSource *GAudioChannels[CORE_AUDIO_MAX_CHANNELS + 1];
|
||||
|
||||
static CFBundleRef LoadRadioEffectComponent()
|
||||
{
|
||||
bool bLoaded = false;
|
||||
@@ -89,7 +87,7 @@ TConsoleVariableData<float>* FCoreAudioEffectsManager::Radio_ChebyshevMultiplier
|
||||
FCoreAudioEffectsManager::FCoreAudioEffectsManager( FAudioDevice* InDevice )
|
||||
: FAudioEffectsManager( InDevice )
|
||||
{
|
||||
#if RADIO_ENABLED
|
||||
#if CORE_AUDIO_RADIO_ENABLED
|
||||
RadioBundle = LoadRadioEffectComponent();
|
||||
bRadioAvailable = (RadioBundle != NULL);
|
||||
#endif
|
||||
@@ -97,7 +95,7 @@ FCoreAudioEffectsManager::FCoreAudioEffectsManager( FAudioDevice* InDevice )
|
||||
|
||||
FCoreAudioEffectsManager::~FCoreAudioEffectsManager()
|
||||
{
|
||||
#if RADIO_ENABLED
|
||||
#if CORE_AUDIO_RADIO_ENABLED
|
||||
if(RadioBundle)
|
||||
{
|
||||
CFRelease(RadioBundle);
|
||||
@@ -111,6 +109,7 @@ FCoreAudioEffectsManager::~FCoreAudioEffectsManager()
|
||||
*/
|
||||
void FCoreAudioEffectsManager::SetReverbEffectParameters( const FAudioReverbEffect& ReverbEffectParameters )
|
||||
{
|
||||
#if CORE_AUDIO_REVERB_ENABLED
|
||||
float DryWetMix = FMath::Sin(ReverbEffectParameters.Volume*M_PI_2) * 100.0f; // 0.0-100.0, 100.0
|
||||
float SmallLargeMix = ReverbEffectParameters.GainHF * 100.0f; // 0.0-100.0, 50.0
|
||||
float PreDelay = ReverbEffectParameters.ReflectionsDelay; // 0.001->0.03, 0.025
|
||||
@@ -134,7 +133,7 @@ void FCoreAudioEffectsManager::SetReverbEffectParameters( const FAudioReverbEffe
|
||||
|
||||
for( uint32 Index = 1; Index < CORE_AUDIO_MAX_CHANNELS + 1; Index++ )
|
||||
{
|
||||
FCoreAudioSoundSource *Source = GAudioChannels[Index];
|
||||
FCoreAudioSoundSource *Source = ((FCoreAudioDevice*)AudioDevice)->AudioChannels[Index];
|
||||
if( Source && Source->ReverbUnit )
|
||||
{
|
||||
AudioUnitSetParameter(Source->ReverbUnit, kReverbParam_DryWetMix, kAudioUnitScope_Global, 0, DryWetMix, 0);
|
||||
@@ -157,39 +156,51 @@ void FCoreAudioEffectsManager::SetReverbEffectParameters( const FAudioReverbEffe
|
||||
AudioUnitSetParameter(Source->ReverbUnit, kReverbParam_LargeBrightness, kAudioUnitScope_Global, 0, LargeBrightness, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the platform specific code to set the parameters that define EQ
|
||||
*/
|
||||
void FCoreAudioEffectsManager::SetEQEffectParameters( const FAudioEQEffect& EQEffectParameters )
|
||||
void FCoreAudioEffectsManager::SetEQEffectParameters( const FAudioEQEffect& Params )
|
||||
{
|
||||
float LowGain = VolumeToDeciBels(EQEffectParameters.LFGain);
|
||||
float CenterGain = VolumeToDeciBels(EQEffectParameters.MFGain);
|
||||
float HighGain = VolumeToDeciBels(EQEffectParameters.HFGain);
|
||||
float LowGain = VolumeToDeciBels(Params.LFGain);
|
||||
float CenterGain = VolumeToDeciBels(Params.MFGain);
|
||||
float HighGain = VolumeToDeciBels(Params.HFGain);
|
||||
|
||||
for( uint32 Index = 1; Index < CORE_AUDIO_MAX_CHANNELS + 1; Index++ )
|
||||
{
|
||||
FCoreAudioSoundSource *Source = GAudioChannels[Index];
|
||||
if( Source && Source->EQUnit )
|
||||
FCoreAudioSoundSource *Source = ((FCoreAudioDevice*)AudioDevice)->AudioChannels[Index];
|
||||
if (Source)
|
||||
{
|
||||
AudioUnitSetParameter( Source->EQUnit, kMultibandFilter_LowFrequency, kAudioUnitScope_Global, 0, EQEffectParameters.LFFrequency, 0 );
|
||||
AudioUnitSetParameter( Source->EQUnit, kMultibandFilter_LowGain, kAudioUnitScope_Global, 0, LowGain, 0 );
|
||||
if (Source->EQUnit)
|
||||
{
|
||||
AudioUnitSetParameter(Source->EQUnit, kAUNBandEQParam_Frequency + 0, kAudioUnitScope_Global, 0, Params.LFFrequency, 0);
|
||||
AudioUnitSetParameter(Source->EQUnit, kAUNBandEQParam_Gain + 0, kAudioUnitScope_Global, 0, LowGain, 0);
|
||||
AudioUnitSetParameter(Source->EQUnit, kAUNBandEQParam_Bandwidth + 0, kAudioUnitScope_Global, 0, 1.0f, 0); // from FXEQ_DEFAULT_BANDWIDTH
|
||||
|
||||
AudioUnitSetParameter( Source->EQUnit, kMultibandFilter_CenterFreq1, kAudioUnitScope_Global, 0, (EQEffectParameters.MFCutoffFrequency - EQEffectParameters.LFFrequency) / 2.0f, 0 );
|
||||
AudioUnitSetParameter( Source->EQUnit, kMultibandFilter_CenterGain1, kAudioUnitScope_Global, 0, CenterGain, 0 );
|
||||
AudioUnitSetParameter( Source->EQUnit, kMultibandFilter_Bandwidth1, kAudioUnitScope_Global, 0, EQEffectParameters.MFBandwidth, 0 );
|
||||
|
||||
AudioUnitSetParameter( Source->EQUnit, kMultibandFilter_CenterFreq2, kAudioUnitScope_Global, 0, EQEffectParameters.MFCutoffFrequency, 0 );
|
||||
AudioUnitSetParameter( Source->EQUnit, kMultibandFilter_CenterGain2, kAudioUnitScope_Global, 0, CenterGain, 0 );
|
||||
AudioUnitSetParameter( Source->EQUnit, kMultibandFilter_Bandwidth2, kAudioUnitScope_Global, 0, EQEffectParameters.MFBandwidth, 0 );
|
||||
AudioUnitSetParameter(Source->EQUnit, kAUNBandEQParam_Frequency + 1, kAudioUnitScope_Global, 0, Params.MFCutoffFrequency, 0);
|
||||
AudioUnitSetParameter(Source->EQUnit, kAUNBandEQParam_Gain + 1, kAudioUnitScope_Global, 0, CenterGain, 0);
|
||||
AudioUnitSetParameter(Source->EQUnit, kAUNBandEQParam_Bandwidth + 1, kAudioUnitScope_Global, 0, Params.MFBandwidth, 0);
|
||||
|
||||
AudioUnitSetParameter( Source->EQUnit, kMultibandFilter_CenterFreq3, kAudioUnitScope_Global, 0, (EQEffectParameters.HFFrequency - EQEffectParameters.MFCutoffFrequency) / 2.0f, 0 );
|
||||
AudioUnitSetParameter( Source->EQUnit, kMultibandFilter_CenterGain3, kAudioUnitScope_Global, 0, CenterGain, 0 );
|
||||
AudioUnitSetParameter( Source->EQUnit, kMultibandFilter_Bandwidth3, kAudioUnitScope_Global, 0, EQEffectParameters.MFBandwidth, 0 );
|
||||
AudioUnitSetParameter(Source->EQUnit, kAUNBandEQParam_Frequency + 2, kAudioUnitScope_Global, 0, Params.HFFrequency, 0);
|
||||
AudioUnitSetParameter(Source->EQUnit, kAUNBandEQParam_Gain + 2, kAudioUnitScope_Global, 0, HighGain, 0);
|
||||
AudioUnitSetParameter(Source->EQUnit, kAUNBandEQParam_Bandwidth + 2, kAudioUnitScope_Global, 0, 1.0f, 0); // from FXEQ_DEFAULT_BANDWIDTH
|
||||
|
||||
AudioUnitSetParameter( Source->EQUnit, kMultibandFilter_HighFrequency, kAudioUnitScope_Global, 0, EQEffectParameters.HFFrequency, 0 );
|
||||
AudioUnitSetParameter( Source->EQUnit, kMultibandFilter_HighGain, kAudioUnitScope_Global, 0, HighGain, 0 );
|
||||
AudioUnitSetParameter(Source->EQUnit, kAUNBandEQParam_Frequency + 3, kAudioUnitScope_Global, 0, 10000.0f, 0); // from FXEQ_DEFAULT_CENTER_3
|
||||
AudioUnitSetParameter(Source->EQUnit, kAUNBandEQParam_Gain + 3, kAudioUnitScope_Global, 0, 1.0, 0); // from FXEQ_DEFAULT_GAIN
|
||||
AudioUnitSetParameter(Source->EQUnit, kAUNBandEQParam_Bandwidth + 3, kAudioUnitScope_Global, 0, 1.0f, 0); // from FXEQ_DEFAULT_BANDWIDTH
|
||||
}
|
||||
|
||||
if (Source->LowPassUnit && Source->HighFrequencyGain < 1.0f - KINDA_SMALL_NUMBER)
|
||||
{
|
||||
float RadianFrequency = 2.0f * FMath::Sin( PI * 6000.0f * Source->HighFrequencyGain / 48000.0f );
|
||||
float CuttoffFrequency = RadianFrequency * ((FCoreAudioDevice*)AudioDevice)->SampleRate;
|
||||
float OneOverQ = ((FCoreAudioDevice*)AudioDevice)->GetLowPassFilterResonance();
|
||||
|
||||
AudioUnitSetParameter(Source->LowPassUnit, kLowPassParam_CutoffFrequency, kAudioUnitScope_Global, 0, CuttoffFrequency, 0);
|
||||
AudioUnitSetParameter(Source->LowPassUnit, kLowPassParam_Resonance, kAudioUnitScope_Global, 0, OneOverQ, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,7 +227,7 @@ void FCoreAudioEffectsManager::SetRadioEffectParameters( const FAudioRadioEffect
|
||||
|
||||
for( uint32 Index = 1; Index < CORE_AUDIO_MAX_CHANNELS + 1; Index++ )
|
||||
{
|
||||
FCoreAudioSoundSource *Source = GAudioChannels[Index];
|
||||
FCoreAudioSoundSource *Source = ((FCoreAudioDevice*)AudioDevice)->AudioChannels[Index];
|
||||
if( Source && Source->RadioUnit )
|
||||
{
|
||||
AudioUnitSetParameter( Source->RadioUnit, RadioParam_ChebyshevPowerMultiplier, kAudioUnitScope_Global, 0, ChebyshevPowerMultiplier, 0 );
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -172,7 +172,6 @@ public:
|
||||
|
||||
typedef FAsyncTask<class FAsyncRealtimeAudioTaskWorker<FCoreAudioSoundBuffer>> FAsyncRealtimeAudioTask;
|
||||
|
||||
|
||||
/**
|
||||
* CoreAudio implementation of FSoundSource, the interface used to play, stop and update sources
|
||||
*/
|
||||
@@ -294,12 +293,12 @@ protected:
|
||||
AUNode SourceNode;
|
||||
AudioUnit SourceUnit;
|
||||
|
||||
AUNode StreamSplitterNode;
|
||||
AudioUnit StreamSplitterUnit;
|
||||
|
||||
AUNode EQNode;
|
||||
AudioUnit EQUnit;
|
||||
|
||||
AUNode LowPassNode;
|
||||
AudioUnit LowPassUnit;
|
||||
|
||||
AUNode RadioNode;
|
||||
AudioUnit RadioUnit;
|
||||
bool bRadioMuted;
|
||||
@@ -310,9 +309,6 @@ protected:
|
||||
|
||||
bool bDryMuted;
|
||||
|
||||
AUNode StreamMergerNode;
|
||||
AudioUnit StreamMergerUnit;
|
||||
|
||||
int32 AudioChannel;
|
||||
int32 BufferInUse;
|
||||
int32 NumActiveBuffers;
|
||||
@@ -323,6 +319,12 @@ private:
|
||||
|
||||
void FreeResources();
|
||||
|
||||
void InitSourceUnit(AudioStreamBasicDescription* Format, AUNode& HeadNode);
|
||||
void InitLowPassEffect(AudioStreamBasicDescription* Format, AUNode& HeadNode);
|
||||
void InitRadioSourceEffect(AudioStreamBasicDescription* Format, AUNode& HeadNode);
|
||||
void InitEqSourceEffect(AudioStreamBasicDescription* Format, AUNode& HeadNode);
|
||||
void InitReverbSourceEffect(AudioStreamBasicDescription* Format, AUNode& HeadNode);
|
||||
|
||||
friend class FCoreAudioDevice;
|
||||
friend class FCoreAudioEffectsManager;
|
||||
};
|
||||
@@ -391,6 +393,19 @@ class FCoreAudioDevice : public FAudioDevice
|
||||
return ( ( InputNum << 16 ) | ( OutputNum & 0x0000FFFF ) );
|
||||
}
|
||||
|
||||
int32 FindFreeAudioChannel()
|
||||
{
|
||||
for (int32 Index = 1; Index < CORE_AUDIO_MAX_CHANNELS + 1; Index++)
|
||||
{
|
||||
if (AudioChannels[Index] == nullptr)
|
||||
{
|
||||
return Index;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/** Inverse listener transformation, used for spatialization */
|
||||
@@ -409,11 +424,14 @@ private:
|
||||
AudioStreamBasicDescription MatrixMixerInputFormat;
|
||||
AudioStreamBasicDescription MatrixMixerOutputFormat;
|
||||
|
||||
bool Mixer3DInputStatus[CORE_AUDIO_MAX_MULTICHANNEL_AUDIOCHANNELS];
|
||||
bool MatrixMixerInputStatus[CORE_AUDIO_MAX_CHANNELS];
|
||||
bool Mixer3DInputStatus[CORE_AUDIO_MAX_CHANNELS];
|
||||
bool MatrixMixerInputStatus[CORE_AUDIO_MAX_MULTICHANNEL_AUDIOCHANNELS];
|
||||
|
||||
class FCoreAudioSoundSource* AudioChannels[CORE_AUDIO_MAX_CHANNELS + 1];
|
||||
|
||||
friend class FCoreAudioSoundBuffer;
|
||||
friend class FCoreAudioSoundSource;
|
||||
friend class FCoreAudioEffectsManager;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
#ifndef _INC_COREAUDIOEFFECTS
|
||||
#define _INC_COREAUDIOEFFECTS
|
||||
|
||||
#define REVERB_ENABLED 1
|
||||
#define EQ_ENABLED 1
|
||||
#define RADIO_ENABLED 1
|
||||
#define CORE_AUDIO_LOWPASS_ENABLED 1
|
||||
#define CORE_AUDIO_REVERB_ENABLED 1
|
||||
#define CORE_AUDIO_EQ_ENABLED 1
|
||||
#define CORE_AUDIO_RADIO_ENABLED 1
|
||||
|
||||
/**
|
||||
* CoreAudio effects manager
|
||||
|
||||
Reference in New Issue
Block a user