From 094a3cfe5a878ec35e2dabf7f8c62a8fd144acde Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 20 Apr 2023 14:54:12 +0200 Subject: [PATCH] Refactor 3d audio for good spatial sound quality --- Flax.sln.DotSettings | 1 + Source/Engine/Audio/Audio.cpp | 13 ---- Source/Engine/Audio/AudioBackend.h | 12 +--- Source/Engine/Audio/AudioSource.cpp | 40 ++++++------ Source/Engine/Audio/AudioSource.h | 8 ++- Source/Engine/Audio/None/AudioBackendNone.cpp | 6 +- Source/Engine/Audio/None/AudioBackendNone.h | 3 +- .../Engine/Audio/OpenAL/AudioBackendOAL.cpp | 63 ++++++++++--------- Source/Engine/Audio/OpenAL/AudioBackendOAL.h | 3 +- Source/Engine/Audio/Types.h | 2 - .../Audio/XAudio2/AudioBackendXAudio2.cpp | 35 ++++------- .../Audio/XAudio2/AudioBackendXAudio2.h | 3 +- .../Engine/ContentImporters/ImportAudio.cpp | 29 ++------- Source/Engine/ContentImporters/ImportAudio.h | 24 ++----- 14 files changed, 86 insertions(+), 156 deletions(-) diff --git a/Flax.sln.DotSettings b/Flax.sln.DotSettings index 8478d97b5..a270ffa47 100644 --- a/Flax.sln.DotSettings +++ b/Flax.sln.DotSettings @@ -335,6 +335,7 @@ True True True + True True True True diff --git a/Source/Engine/Audio/Audio.cpp b/Source/Engine/Audio/Audio.cpp index dd8eae629..45cc1e445 100644 --- a/Source/Engine/Audio/Audio.cpp +++ b/Source/Engine/Audio/Audio.cpp @@ -31,19 +31,6 @@ #include "XAudio2/AudioBackendXAudio2.h" #endif -const Char* ToString(AudioFormat value) -{ - switch (value) - { - case AudioFormat::Raw: - return TEXT("Raw"); - case AudioFormat::Vorbis: - return TEXT("Vorbis"); - default: - return TEXT(""); - } -} - float AudioDataInfo::GetLength() const { return (float)NumSamples / (float)Math::Max(1U, SampleRate * NumChannels); diff --git a/Source/Engine/Audio/AudioBackend.h b/Source/Engine/Audio/AudioBackend.h index 8ca9f545c..bce418beb 100644 --- a/Source/Engine/Audio/AudioBackend.h +++ b/Source/Engine/Audio/AudioBackend.h @@ -35,8 +35,7 @@ private: virtual void Source_VolumeChanged(AudioSource* source) = 0; virtual void Source_PitchChanged(AudioSource* source) = 0; virtual void Source_IsLoopingChanged(AudioSource* source) = 0; - virtual void Source_MinDistanceChanged(AudioSource* source) = 0; - virtual void Source_AttenuationChanged(AudioSource* source) = 0; + virtual void Source_SpatialSetupChanged(AudioSource* source) = 0; virtual void Source_ClipLoaded(AudioSource* source) = 0; virtual void Source_Cleanup(AudioSource* source) = 0; virtual void Source_Play(AudioSource* source) = 0; @@ -141,14 +140,9 @@ public: Instance->Source_IsLoopingChanged(source); } - FORCE_INLINE static void MinDistanceChanged(AudioSource* source) + FORCE_INLINE static void SpatialSetupChanged(AudioSource* source) { - Instance->Source_MinDistanceChanged(source); - } - - FORCE_INLINE static void AttenuationChanged(AudioSource* source) - { - Instance->Source_AttenuationChanged(source); + Instance->Source_SpatialSetupChanged(source); } FORCE_INLINE static void ClipLoaded(AudioSource* source) diff --git a/Source/Engine/Audio/AudioSource.cpp b/Source/Engine/Audio/AudioSource.cpp index 42a27bff4..f3c335573 100644 --- a/Source/Engine/Audio/AudioSource.cpp +++ b/Source/Engine/Audio/AudioSource.cpp @@ -16,7 +16,7 @@ AudioSource::AudioSource(const SpawnParams& params) , _velocity(Vector3::Zero) , _volume(1.0f) , _pitch(1.0f) - , _minDistance(1.0f) + , _minDistance(1000.0f) , _attenuation(1.0f) , _loop(false) , _playOnStart(false) @@ -30,13 +30,9 @@ void AudioSource::SetVolume(float value) value = Math::Saturate(value); if (Math::NearEqual(_volume, value)) return; - _volume = value; - if (SourceIDs.HasItems()) - { AudioBackend::Source::VolumeChanged(this); - } } void AudioSource::SetPitch(float value) @@ -44,27 +40,20 @@ void AudioSource::SetPitch(float value) value = Math::Clamp(value, 0.5f, 2.0f); if (Math::NearEqual(_pitch, value)) return; - _pitch = value; - if (SourceIDs.HasItems()) - { AudioBackend::Source::PitchChanged(this); - } } void AudioSource::SetIsLooping(bool value) { if (_loop == value) return; - _loop = value; // When streaming we handle looping manually by the proper buffers submission if (SourceIDs.HasItems() && !UseStreaming()) - { AudioBackend::Source::IsLoopingChanged(this); - } } void AudioSource::SetPlayOnStart(bool value) @@ -77,13 +66,9 @@ void AudioSource::SetMinDistance(float value) value = Math::Max(0.0f, value); if (Math::NearEqual(_minDistance, value)) return; - _minDistance = value; - if (SourceIDs.HasItems()) - { - AudioBackend::Source::MinDistanceChanged(this); - } + AudioBackend::Source::SpatialSetupChanged(this); } void AudioSource::SetAttenuation(float value) @@ -91,13 +76,10 @@ void AudioSource::SetAttenuation(float value) value = Math::Max(0.0f, value); if (Math::NearEqual(_attenuation, value)) return; - _attenuation = value; if (SourceIDs.HasItems()) - { - AudioBackend::Source::AttenuationChanged(this); - } + AudioBackend::Source::SpatialSetupChanged(this); } void AudioSource::Play() @@ -313,6 +295,22 @@ void AudioSource::PlayInternal() _isActuallyPlayingSth = true; } +#if USE_EDITOR + +#include "Engine/Debug/DebugDraw.h" + +void AudioSource::OnDebugDrawSelected() +{ + // Draw influence range + if (_allowSpatialization) + DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(_transform.Translation, _minDistance), Color::CornflowerBlue, 0, true); + + // Base + Actor::OnDebugDrawSelected(); +} + +#endif + void AudioSource::Serialize(SerializeStream& stream, const void* otherObj) { // Base diff --git a/Source/Engine/Audio/AudioSource.h b/Source/Engine/Audio/AudioSource.h index d7719ec02..0ed2c87a0 100644 --- a/Source/Engine/Audio/AudioSource.h +++ b/Source/Engine/Audio/AudioSource.h @@ -138,8 +138,7 @@ public: /// /// Gets the minimum distance at which audio attenuation starts. When the listener is closer to the source than this value, audio is heard at full volume. Once farther away the audio starts attenuating. /// - /// The value. - API_PROPERTY(Attributes="EditorOrder(60), DefaultValue(1.0f), Limit(0, float.MaxValue, 0.1f), EditorDisplay(\"Audio Source\")") + API_PROPERTY(Attributes="EditorOrder(60), DefaultValue(1000.0f), Limit(0, float.MaxValue, 0.1f), EditorDisplay(\"Audio Source\")") FORCE_INLINE float GetMinDistance() const { return _minDistance; @@ -160,7 +159,7 @@ public: } /// - /// Sets the attenuation that controls how quickly does audio volume drop off as the listener moves further from the source. + /// Sets the attenuation that controls how quickly does audio volume drop off as the listener moves further from the source. At 0, no distance attenuation ever occurs. /// API_PROPERTY() void SetAttenuation(float value); @@ -257,6 +256,9 @@ public: const Vector3 size(50); return BoundingBox(_transform.Translation - size, _transform.Translation + size); } +#endif +#if USE_EDITOR + void OnDebugDrawSelected() override; #endif void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; diff --git a/Source/Engine/Audio/None/AudioBackendNone.cpp b/Source/Engine/Audio/None/AudioBackendNone.cpp index 452d5af53..a1a747763 100644 --- a/Source/Engine/Audio/None/AudioBackendNone.cpp +++ b/Source/Engine/Audio/None/AudioBackendNone.cpp @@ -56,11 +56,7 @@ void AudioBackendNone::Source_IsLoopingChanged(AudioSource* source) { } -void AudioBackendNone::Source_MinDistanceChanged(AudioSource* source) -{ -} - -void AudioBackendNone::Source_AttenuationChanged(AudioSource* source) +void AudioBackendNone::Source_SpatialSetupChanged(AudioSource* source) { } diff --git a/Source/Engine/Audio/None/AudioBackendNone.h b/Source/Engine/Audio/None/AudioBackendNone.h index 49a62e6e3..2b6bb9606 100644 --- a/Source/Engine/Audio/None/AudioBackendNone.h +++ b/Source/Engine/Audio/None/AudioBackendNone.h @@ -26,8 +26,7 @@ public: void Source_VolumeChanged(AudioSource* source) override; void Source_PitchChanged(AudioSource* source) override; void Source_IsLoopingChanged(AudioSource* source) override; - void Source_MinDistanceChanged(AudioSource* source) override; - void Source_AttenuationChanged(AudioSource* source) override; + void Source_SpatialSetupChanged(AudioSource* source) override; void Source_ClipLoaded(AudioSource* source) override; void Source_Cleanup(AudioSource* source) override; void Source_Play(AudioSource* source) override; diff --git a/Source/Engine/Audio/OpenAL/AudioBackendOAL.cpp b/Source/Engine/Audio/OpenAL/AudioBackendOAL.cpp index d74ded82e..813f25ab1 100644 --- a/Source/Engine/Audio/OpenAL/AudioBackendOAL.cpp +++ b/Source/Engine/Audio/OpenAL/AudioBackendOAL.cpp @@ -21,7 +21,8 @@ #define ALC_MULTIPLE_LISTENERS 0 -#define FLAX_COORD_SCALE 0.01f +#define FLAX_COORD_SCALE 0.01f // units are meters +#define FLAX_DST_TO_OAL(x) x * FLAX_COORD_SCALE #define FLAX_POS_TO_OAL(vec) ((ALfloat)vec.X * -FLAX_COORD_SCALE), ((ALfloat)vec.Y * FLAX_COORD_SCALE), ((ALfloat)vec.Z * FLAX_COORD_SCALE) #define FLAX_VEL_TO_OAL(vec) ((ALfloat)vec.X * -(FLAX_COORD_SCALE*FLAX_COORD_SCALE)), ((ALfloat)vec.Y * (FLAX_COORD_SCALE*FLAX_COORD_SCALE)), ((ALfloat)vec.Z * (FLAX_COORD_SCALE*FLAX_COORD_SCALE)) #if BUILD_RELEASE @@ -102,7 +103,7 @@ namespace ALC { alcMakeContextCurrent(nullptr); - for (auto& context : Contexts) + for (ALCcontext* context : Contexts) alcDestroyContext(context); Contexts.Clear(); } @@ -113,7 +114,7 @@ namespace ALC { AudioBackend::Listener::TransformChanged(listener); - const auto& velocity = listener->GetVelocity(); + const Vector3 velocity = listener->GetVelocity(); alListener3f(AL_VELOCITY, FLAX_VEL_TO_OAL(velocity)); alListenerf(AL_GAIN, Audio::GetVolume()); } @@ -146,13 +147,14 @@ namespace ALC if (is3D) { alSourcef(sourceID, AL_ROLLOFF_FACTOR, source->GetAttenuation()); - alSourcef(sourceID, AL_REFERENCE_DISTANCE, source->GetMinDistance()); + alSourcef(sourceID, AL_REFERENCE_DISTANCE, FLAX_DST_TO_OAL(source->GetMinDistance())); alSource3f(sourceID, AL_POSITION, FLAX_POS_TO_OAL(source->GetPosition())); alSource3f(sourceID, AL_VELOCITY, FLAX_VEL_TO_OAL(source->GetVelocity())); } else { alSourcef(sourceID, AL_ROLLOFF_FACTOR, 0.0f); + alSourcef(sourceID, AL_REFERENCE_DISTANCE, 0.0f); alSource3f(sourceID, AL_POSITION, 0.0f, 0.0f, 0.0f); alSource3f(sourceID, AL_VELOCITY, 0.0f, 0.0f, 0.0f); } @@ -169,7 +171,7 @@ namespace ALC if (!isChangingDevice) { - for (auto& source : Audio::Sources) + for (AudioSource* source : Audio::Sources) source->Cleanup(); } @@ -204,10 +206,10 @@ namespace ALC // Audio listeners and sources will avoid excessive context switching in such case. alcMakeContextCurrent(Contexts[0]); - for (auto& listener : Audio::Listeners) + for (AudioListener* listener : Audio::Listeners) Listener::Rebuild(listener); - for (auto& source : Audio::Sources) + for (AudioSource* source : Audio::Sources) Source::Rebuild(source); } } @@ -293,7 +295,7 @@ void AudioBackendOAL::Listener_OnAdd(AudioListener* listener) ALC::RebuildContexts(false); #else AudioBackend::Listener::TransformChanged(listener); - const auto& velocity = listener->GetVelocity(); + const Vector3 velocity = listener->GetVelocity(); alListener3f(AL_VELOCITY, FLAX_VEL_TO_OAL(velocity)); alListenerf(AL_GAIN, Audio::GetVolume()); #endif @@ -310,7 +312,7 @@ void AudioBackendOAL::Listener_VelocityChanged(AudioListener* listener) { ALC_GET_LISTENER_CONTEXT(listener) - const auto& velocity = listener->GetVelocity(); + const Vector3 velocity = listener->GetVelocity(); alListener3f(AL_VELOCITY, FLAX_VEL_TO_OAL(velocity)); } @@ -318,11 +320,10 @@ void AudioBackendOAL::Listener_TransformChanged(AudioListener* listener) { ALC_GET_LISTENER_CONTEXT(listener) - const Vector3& position = listener->GetPosition(); - const Quaternion& orientation = listener->GetOrientation(); - const Vector3& flipX = Vector3(-1, 1, 1); - - Vector3 alOrientation[2] = + const Vector3 position = listener->GetPosition(); + const Quaternion orientation = listener->GetOrientation(); + const Vector3 flipX(-1, 1, 1); + const Vector3 alOrientation[2] = { // Forward orientation * Vector3::Forward * flipX, @@ -394,23 +395,22 @@ void AudioBackendOAL::Source_IsLoopingChanged(AudioSource* source) } } -void AudioBackendOAL::Source_MinDistanceChanged(AudioSource* source) +void AudioBackendOAL::Source_SpatialSetupChanged(AudioSource* source) { - if (!source->Is3D()) - return; + const bool is3D = source->Is3D(); ALC_FOR_EACH_CONTEXT() const uint32 sourceID = source->SourceIDs[i]; - alSourcef(sourceID, AL_REFERENCE_DISTANCE, source->GetMinDistance()); - } -} - -void AudioBackendOAL::Source_AttenuationChanged(AudioSource* source) -{ - if (!source->Is3D()) - return; - ALC_FOR_EACH_CONTEXT() - const uint32 sourceID = source->SourceIDs[i]; - alSourcef(sourceID, AL_ROLLOFF_FACTOR, source->GetAttenuation()); + alSourcei(sourceID, AL_SOURCE_RELATIVE, !is3D); + if (is3D) + { + alSourcef(sourceID, AL_ROLLOFF_FACTOR, source->GetAttenuation()); + alSourcef(sourceID, AL_REFERENCE_DISTANCE, FLAX_DST_TO_OAL(source->GetMinDistance())); + } + else + { + alSourcef(sourceID, AL_ROLLOFF_FACTOR, 0.0f); + alSourcef(sourceID, AL_REFERENCE_DISTANCE, 0.0f); + } } } @@ -496,7 +496,7 @@ float AudioBackendOAL::Source_GetCurrentBufferTime(const AudioSource* source) alGetSourcef(source->SourceIDs[0], AL_SEC_OFFSET, &time); #else ASSERT(source->Clip && source->Clip->IsLoaded()); - const auto& clipInfo = source->Clip->AudioHeader.Info; + const AudioDataInfo& clipInfo = source->Clip->AudioHeader.Info; ALint samplesPlayed; alGetSourcei(source->SourceIDs[0], AL_SAMPLE_OFFSET, &samplesPlayed); const uint32 totalSamples = clipInfo.NumSamples / clipInfo.NumChannels; @@ -686,7 +686,7 @@ const Char* AudioBackendOAL::Base_Name() void AudioBackendOAL::Base_OnActiveDeviceChanged() { // Cleanup - for (auto& source : Audio::Sources) + for (AudioSource* source : Audio::Sources) source->Cleanup(); ALC::ClearContexts(); if (ALC::Device != nullptr) @@ -696,7 +696,7 @@ void AudioBackendOAL::Base_OnActiveDeviceChanged() } // Open device - const auto& name = Audio::GetActiveDevice()->InternalName; + const StringAnsi& name = Audio::GetActiveDevice()->InternalName; ALC::Device = alcOpenDevice(name.Get()); if (ALC::Device == nullptr) { @@ -817,6 +817,7 @@ bool AudioBackendOAL::Base_Init() // Init SetDopplerFactor(AudioSettings::Get()->DopplerFactor); + alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); // Default attenuation model ALC::RebuildContexts(true); Audio::SetActiveDeviceIndex(activeDeviceIndex); diff --git a/Source/Engine/Audio/OpenAL/AudioBackendOAL.h b/Source/Engine/Audio/OpenAL/AudioBackendOAL.h index 1688dda1e..2f6fed237 100644 --- a/Source/Engine/Audio/OpenAL/AudioBackendOAL.h +++ b/Source/Engine/Audio/OpenAL/AudioBackendOAL.h @@ -26,8 +26,7 @@ public: void Source_VolumeChanged(AudioSource* source) override; void Source_PitchChanged(AudioSource* source) override; void Source_IsLoopingChanged(AudioSource* source) override; - void Source_MinDistanceChanged(AudioSource* source) override; - void Source_AttenuationChanged(AudioSource* source) override; + void Source_SpatialSetupChanged(AudioSource* source) override; void Source_ClipLoaded(AudioSource* source) override; void Source_Cleanup(AudioSource* source) override; void Source_Play(AudioSource* source) override; diff --git a/Source/Engine/Audio/Types.h b/Source/Engine/Audio/Types.h index 193b10045..98b1f0401 100644 --- a/Source/Engine/Audio/Types.h +++ b/Source/Engine/Audio/Types.h @@ -25,8 +25,6 @@ API_ENUM() enum class AudioFormat Vorbis, }; -const Char* ToString(AudioFormat value); - /// /// Meta-data describing a chunk of audio. /// diff --git a/Source/Engine/Audio/XAudio2/AudioBackendXAudio2.cpp b/Source/Engine/Audio/XAudio2/AudioBackendXAudio2.cpp index 505b0d6c2..2d4fe5841 100644 --- a/Source/Engine/Audio/XAudio2/AudioBackendXAudio2.cpp +++ b/Source/Engine/Audio/XAudio2/AudioBackendXAudio2.cpp @@ -26,7 +26,8 @@ #define MAX_OUTPUT_CHANNELS 8 #define MAX_CHANNELS_MATRIX_SIZE (MAX_INPUT_CHANNELS*MAX_OUTPUT_CHANNELS) -#define FLAX_COORD_SCALE 0.01f +#define FLAX_COORD_SCALE 0.01f // units are meters +#define FLAX_DST_TO_XAUDIO(x) x * FLAX_COORD_SCALE #define FLAX_POS_TO_XAUDIO(vec) X3DAUDIO_VECTOR(vec.X * FLAX_COORD_SCALE, vec.Y * FLAX_COORD_SCALE, vec.Z * FLAX_COORD_SCALE) #define FLAX_VEL_TO_XAUDIO(vec) X3DAUDIO_VECTOR(vec.X * (FLAX_COORD_SCALE*FLAX_COORD_SCALE), vec.Y * (FLAX_COORD_SCALE*FLAX_COORD_SCALE), vec.Z * (FLAX_COORD_SCALE*FLAX_COORD_SCALE)) #define FLAX_VEC_TO_XAUDIO(vec) (*((X3DAUDIO_VECTOR*)&vec)) @@ -105,7 +106,6 @@ namespace XAudio2 } public: - AudioSource* Source; void PeekSamples(); @@ -200,13 +200,11 @@ namespace XAudio2 DWORD ChannelMask; UINT32 SampleRate; UINT32 Channels; - bool UseRedirectToLFE; bool ForceDirty = true; Listener Listeners[AUDIO_MAX_LISTENERS]; Array Sources(32); // TODO: use ChunkedArray for better performance Array Buffers(64); // TODO: use ChunkedArray for better performance or use buffers pool? EngineCallback Callback; - float MatrixCoefficients[MAX_CHANNELS_MATRIX_SIZE]; Listener* GetListener() { @@ -397,9 +395,9 @@ void AudioBackendXAudio2::Source_OnAdd(AudioSource* source) aSource->Callback.Source = source; aSource->IsDirty = true; aSource->Data.ChannelCount = header.Info.NumChannels; + aSource->Data.InnerRadius = FLAX_DST_TO_XAUDIO(source->GetMinDistance()); aSource->Is3D = source->Is3D(); aSource->Pitch = source->GetPitch(); - aSource->Data.InnerRadius = source->GetMinDistance(); aSource->UpdateTransform(source); aSource->UpdateVelocity(source); @@ -498,21 +496,17 @@ void AudioBackendXAudio2::Source_IsLoopingChanged(AudioSource* source) aSource->Voice->Start(); } -void AudioBackendXAudio2::Source_MinDistanceChanged(AudioSource* source) +void AudioBackendXAudio2::Source_SpatialSetupChanged(AudioSource* source) { auto aSource = XAudio2::GetSource(source); if (aSource) { - aSource->Data.InnerRadius = source->GetMinDistance(); + // TODO: implement attenuation settings for 3d audio + aSource->Data.InnerRadius = FLAX_DST_TO_XAUDIO(source->GetMinDistance()); aSource->IsDirty = true; } } -void AudioBackendXAudio2::Source_AttenuationChanged(AudioSource* source) -{ - // TODO: implement it -} - void AudioBackendXAudio2::Source_ClipLoaded(AudioSource* source) { auto aSource = XAudio2::GetSource(source); @@ -769,7 +763,6 @@ bool AudioBackendXAudio2::Base_Init() LOG(Error, "Failed to get XAudio2 mastering voice channel mask. Error: 0x{0:x}", hr); return true; } - XAudio2::UseRedirectToLFE = ((XAudio2::ChannelMask & SPEAKER_LOW_FREQUENCY) != 0); // Initialize spatial audio subsystem DWORD dwChannelMask; @@ -794,19 +787,13 @@ bool AudioBackendXAudio2::Base_Init() void AudioBackendXAudio2::Base_Update() { - // Note: only one listener is supported for now - const auto listener = XAudio2::GetListener(); - if (!listener) - { - // How can we play audio when no one is listening - return; - } - // Update dirty voices + const auto listener = XAudio2::GetListener(); const float dopplerFactor = AudioSettings::Get()->DopplerFactor; + float matrixCoefficients[MAX_CHANNELS_MATRIX_SIZE]; X3DAUDIO_DSP_SETTINGS dsp = { 0 }; dsp.DstChannelCount = XAudio2::Channels; - dsp.pMatrixCoefficients = XAudio2::MatrixCoefficients; + dsp.pMatrixCoefficients = matrixCoefficients; for (int32 i = 0; i < XAudio2::Sources.Count(); i++) { auto& source = XAudio2::Sources[i]; @@ -814,7 +801,7 @@ void AudioBackendXAudio2::Base_Update() continue; dsp.SrcChannelCount = source.Data.ChannelCount; - if (source.Is3D) + if (source.Is3D && listener) { X3DAudioCalculate(XAudio2::X3DInstance, &listener->Data, &source.Data, X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER, &dsp); } @@ -822,7 +809,7 @@ void AudioBackendXAudio2::Base_Update() { // Stereo dsp.DopplerFactor = 1.0f; - Platform::MemoryClear(dsp.pMatrixCoefficients, sizeof(XAudio2::MatrixCoefficients)); + Platform::MemoryClear(dsp.pMatrixCoefficients, sizeof(matrixCoefficients)); dsp.pMatrixCoefficients[0] = 1.0f; if (source.Format.nChannels == 1) { diff --git a/Source/Engine/Audio/XAudio2/AudioBackendXAudio2.h b/Source/Engine/Audio/XAudio2/AudioBackendXAudio2.h index 7668c0e42..23e43be42 100644 --- a/Source/Engine/Audio/XAudio2/AudioBackendXAudio2.h +++ b/Source/Engine/Audio/XAudio2/AudioBackendXAudio2.h @@ -26,8 +26,7 @@ public: void Source_VolumeChanged(AudioSource* source) override; void Source_PitchChanged(AudioSource* source) override; void Source_IsLoopingChanged(AudioSource* source) override; - void Source_MinDistanceChanged(AudioSource* source) override; - void Source_AttenuationChanged(AudioSource* source) override; + void Source_SpatialSetupChanged(AudioSource* source) override; void Source_ClipLoaded(AudioSource* source) override; void Source_Cleanup(AudioSource* source) override; void Source_Play(AudioSource* source) override; diff --git a/Source/Engine/ContentImporters/ImportAudio.cpp b/Source/Engine/ContentImporters/ImportAudio.cpp index 6fa19a15b..73556dc26 100644 --- a/Source/Engine/ContentImporters/ImportAudio.cpp +++ b/Source/Engine/ContentImporters/ImportAudio.cpp @@ -18,25 +18,11 @@ #include "Engine/Tools/AudioTool/OggVorbisDecoder.h" #include "Engine/Tools/AudioTool/OggVorbisEncoder.h" #include "Engine/Serialization/JsonWriters.h" - -ImportAudio::Options::Options() -{ - Format = AudioFormat::Vorbis; - DisableStreaming = false; - Is3D = false; - Quality = 0.4f; - BitDepth = 16; -} +#include "Engine/Scripting/Enums.h" String ImportAudio::Options::ToString() const { - return String::Format(TEXT("Format:{}, DisableStreaming:{}, Is3D:{}, Quality:{}, BitDepth:{}"), - ::ToString(Format), - DisableStreaming, - Is3D, - Quality, - BitDepth - ); + return String::Format(TEXT("Format:{}, DisableStreaming:{}, Is3D:{}, Quality:{}, BitDepth:{}"), ScriptingEnum::ToString(Format), DisableStreaming, Is3D, Quality, BitDepth); } void ImportAudio::Options::Serialize(SerializeStream& stream, const void* otherObj) @@ -59,11 +45,9 @@ void ImportAudio::Options::Deserialize(DeserializeStream& stream, ISerializeModi DESERIALIZE(BitDepth); } -bool ImportAudio::TryGetImportOptions(String path, Options& options) +bool ImportAudio::TryGetImportOptions(const String& path, Options& options) { #if IMPORT_AUDIO_CACHE_OPTIONS - - // Check if target asset file exists if (FileSystem::FileExists(path)) { // Try to load asset file and asset info @@ -88,7 +72,6 @@ bool ImportAudio::TryGetImportOptions(String path, Options& options) } #endif - return false; } @@ -123,9 +106,7 @@ CreateAssetResult ImportAudio::Import(CreateAssetContext& context, AudioDecoder& Array audioData; if (decoder.Convert(stream, info, audioData)) return CreateAssetResult::Error; - - const float length = info.NumSamples / static_cast(Math::Max(1U, info.SampleRate * info.NumChannels)); - LOG(Info, "Audio: {0}kHz, channels: {1}, Bit depth: {2}, Length: {3}s", info.SampleRate / 1000.0f, info.NumChannels, info.BitDepth, length); + LOG(Info, "Audio: {0}kHz, channels: {1}, Bit depth: {2}, Length: {3}s", info.SampleRate / 1000.0f, info.NumChannels, info.BitDepth, info.GetLength()); // Load the whole audio data uint32 bytesPerSample = info.BitDepth / 8; @@ -222,7 +203,7 @@ CreateAssetResult ImportAudio::Import(CreateAssetContext& context, AudioDecoder& { // Split audio data into a several chunks (uniform data spread) const int32 MinChunkSize = 1 * 1024 * 1024; // 1 MB - const int32 chunkSize = Math::Max(MinChunkSize, Math::AlignUp(bufferSize / ASSET_FILE_DATA_CHUNKS, 256)); + const int32 chunkSize = Math::Max(MinChunkSize, (int32)Math::AlignUp(bufferSize / ASSET_FILE_DATA_CHUNKS, 256)); const int32 chunksCount = Math::CeilToInt((float)bufferSize / chunkSize); ASSERT(chunksCount > 0 && chunksCount <= ASSET_FILE_DATA_CHUNKS); diff --git a/Source/Engine/ContentImporters/ImportAudio.h b/Source/Engine/ContentImporters/ImportAudio.h index f0097eef9..28c8a2e67 100644 --- a/Source/Engine/ContentImporters/ImportAudio.h +++ b/Source/Engine/ContentImporters/ImportAudio.h @@ -25,24 +25,14 @@ public: /// struct Options : public ISerializable { - AudioFormat Format; - bool DisableStreaming; - bool Is3D; - int32 BitDepth; - float Quality; + AudioFormat Format = AudioFormat::Vorbis; + bool DisableStreaming = false; + bool Is3D = false; + int32 BitDepth = 16; + float Quality = 0.4f; - /// - /// Initializes a new instance of the struct. - /// - Options(); - - /// - /// Gets string that contains information about options - /// - /// String String ToString() const; - public: // [ISerializable] void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; @@ -55,7 +45,7 @@ public: /// The asset path. /// The options. /// True if success, otherwise false. - static bool TryGetImportOptions(String path, Options& options); + static bool TryGetImportOptions(const String& path, Options& options); /// /// Imports the audio data (with given audio decoder). @@ -80,14 +70,12 @@ public: static CreateAssetResult ImportMp3(CreateAssetContext& context); #if COMPILE_WITH_OGG_VORBIS - /// /// Imports the .ogg audio file. /// /// The importing context. /// Result. static CreateAssetResult ImportOgg(CreateAssetContext& context); - #endif };