Skip to content

Commit

Permalink
fix: Stability fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
na2axl committed Jan 2, 2025
1 parent 4ef5b3b commit c6dfe19
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 62 deletions.
22 changes: 22 additions & 0 deletions include/SparkyStudios/Audio/Amplitude/Core/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,28 @@ namespace SparkyStudios::Audio::Amplitude
eSpatialization_HRTF
};

/**
* @brief Enumerates the list of available scopes for sound objects.
*
* @ingroup core
*/
enum eScope : AmUInt8
{
/**
* @brief The sound object is within the game world. Instances of collections played in this scope
* will be treated as one object across all entities.
*/
eScope_World,

/**
* @brief The sound object is within a specific entity. Instances of collections played in this scope
* will be treated as separate objects, and no data will be shared across entities.
*
* @note Sound objects using this scope are required to be attached to an [`Entity`](./Entity.md).
*/
eScope_Entity
};

/**
* @brief Enumerates the list of available panning modes.
*
Expand Down
14 changes: 14 additions & 0 deletions include/SparkyStudios/Audio/Amplitude/Sound/SoundObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,20 @@ namespace SparkyStudios::Audio::Amplitude
* @return The bus this sound object will play on.
*/
[[nodiscard]] virtual Bus GetBus() const = 0;

/**
* @brief Returns the spatialization mode of the sound object.
*
* @return The spatialization mode of the sound object.
*/
[[nodiscard]] virtual eSpatialization GetSpatialization() const = 0;

/**
* @brief Returns the scope of the sound object.
*
* @return The scope of the sound object.
*/
[[nodiscard]] virtual eScope GetScope() const = 0;
};
} // namespace SparkyStudios::Audio::Amplitude

Expand Down
34 changes: 11 additions & 23 deletions src/Core/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1209,14 +1209,14 @@ namespace SparkyStudios::Audio::Amplitude
const AmReal32 soundGain,
const AmReal32 soundPitch,
const BusInternalState* bus,
const Spatialization spatialization,
const eSpatialization spatialization,
const AmReal32 userGain)
{
*gain = soundGain * bus->GetGain() * userGain;
*pitch = soundPitch;
*pan = AM_V2(0, 0); // TODO: This may be removed in the future, since panning is handled automatically in pipeline nodes..

if (spatialization != Spatialization_None && listener != nullptr && channel != nullptr)
if (spatialization != eSpatialization_None && listener != nullptr && channel != nullptr)
*pitch *= channel->GetDopplerFactor(listener->GetId());
}

Expand Down Expand Up @@ -2210,27 +2210,21 @@ namespace SparkyStudios::Audio::Amplitude

if (const SwitchContainer* switchContainer = channel->GetSwitchContainer(); switchContainer != nullptr)
{
const SwitchContainerDefinition* definition = dynamic_cast<const SwitchContainerImpl*>(switchContainer)->GetDefinition();

CalculateGainPanPitch(
&gain, &pan, &pitch, listener, nullptr, switchContainer->GetGain().GetValue(), switchContainer->GetPitch().GetValue(),
switchContainer->GetBus().GetState(), definition->spatialization(), channel->GetUserGain());
switchContainer->GetBus().GetState(), switchContainer->GetSpatialization(), channel->GetUserGain());
}
else if (const Collection* collection = channel->GetCollection(); collection != nullptr)
{
const CollectionDefinition* definition = dynamic_cast<const CollectionImpl*>(collection)->GetDefinition();

CalculateGainPanPitch(
&gain, &pan, &pitch, listener, nullptr, collection->GetGain().GetValue(), collection->GetPitch().GetValue(),
collection->GetBus().GetState(), definition->spatialization(), channel->GetUserGain());
collection->GetBus().GetState(), collection->GetSpatialization(), channel->GetUserGain());
}
else if (const Sound* sound = channel->GetSound(); sound != nullptr)
{
const SoundDefinition* definition = dynamic_cast<const SoundImpl*>(sound)->GetDefinition();

CalculateGainPanPitch(
&gain, &pan, &pitch, listener, nullptr, sound->GetGain().GetValue(), sound->GetPitch().GetValue(),
sound->GetBus().GetState(), definition->spatialization(), channel->GetUserGain());
sound->GetBus().GetState(), sound->GetSpatialization(), channel->GetUserGain());
}
else
{
Expand Down Expand Up @@ -2525,9 +2519,7 @@ namespace SparkyStudios::Audio::Amplitude
return Channel(nullptr);
}

const SwitchContainerDefinition* definition = dynamic_cast<SwitchContainerImpl*>(handle)->GetDefinition();

if (definition->scope() == Scope_Entity && !entity.Valid())
if (handle->GetScope() == eScope_Entity && !entity.Valid())
{
amLogError("Cannot play a switch container in Entity scope. No entity defined.");
return Channel(nullptr);
Expand All @@ -2548,7 +2540,7 @@ namespace SparkyStudios::Audio::Amplitude
AmReal32 pitch;
CalculateGainPanPitch(
&gain, &pan, &pitch, listener, nullptr, handle->GetGain().GetValue(), handle->GetPitch().GetValue(),
handle->GetBus().GetState(), definition->spatialization(), userGain);
handle->GetBus().GetState(), handle->GetSpatialization(), userGain);
const AmReal32 priority = gain * handle->GetPriority().GetValue();
const auto insertionPoint = FindInsertionPoint(&_state->playing_channel_list, priority);

Expand Down Expand Up @@ -2602,9 +2594,7 @@ namespace SparkyStudios::Audio::Amplitude
return Channel(nullptr);
}

const CollectionDefinition* definition = dynamic_cast<CollectionImpl*>(handle)->GetDefinition();

if (definition->scope() == Scope_Entity && !entity.Valid())
if (handle->GetScope() == eScope_Entity && !entity.Valid())
{
amLogError("Cannot play a collection in Entity scope. No entity defined.");
return Channel(nullptr);
Expand All @@ -2625,7 +2615,7 @@ namespace SparkyStudios::Audio::Amplitude
AmReal32 pitch;
CalculateGainPanPitch(
&gain, &pan, &pitch, listener, nullptr, handle->GetGain().GetValue(), handle->GetPitch().GetValue(),
handle->GetBus().GetState(), definition->spatialization(), userGain);
handle->GetBus().GetState(), handle->GetSpatialization(), userGain);
const AmReal32 priority = gain * handle->GetPriority().GetValue();
const auto insertionPoint = FindInsertionPoint(&_state->playing_channel_list, priority);

Expand Down Expand Up @@ -2678,9 +2668,7 @@ namespace SparkyStudios::Audio::Amplitude
return Channel(nullptr);
}

const SoundDefinition* definition = dynamic_cast<SoundImpl*>(handle)->GetDefinition();

if (definition->scope() == Scope_Entity && !entity.Valid())
if (handle->GetScope() == Scope_Entity && !entity.Valid())

Check warning on line 2671 in src/Core/Engine.cpp

View workflow job for this annotation

GitHub Actions / Amplitude Audio SDK / [release] macOS arm64 Latest Clang

comparison of different enumeration types ('eScope' and 'SparkyStudios::Audio::Amplitude::Scope') is deprecated [-Wdeprecated-enum-compare]

Check warning on line 2671 in src/Core/Engine.cpp

View workflow job for this annotation

GitHub Actions / Amplitude Audio SDK / [release] macOS arm64 Latest Clang

comparison of different enumeration types ('eScope' and 'SparkyStudios::Audio::Amplitude::Scope') is deprecated [-Wdeprecated-enum-compare]

Check warning on line 2671 in src/Core/Engine.cpp

View workflow job for this annotation

GitHub Actions / Amplitude Audio SDK / [release] macOS x64 Latest Clang

comparison of different enumeration types ('eScope' and 'SparkyStudios::Audio::Amplitude::Scope') is deprecated [-Wdeprecated-enum-compare]

Check warning on line 2671 in src/Core/Engine.cpp

View workflow job for this annotation

GitHub Actions / Amplitude Audio SDK / [release] macOS x64 Latest Clang

comparison of different enumeration types ('eScope' and 'SparkyStudios::Audio::Amplitude::Scope') is deprecated [-Wdeprecated-enum-compare]

Check warning on line 2671 in src/Core/Engine.cpp

View workflow job for this annotation

GitHub Actions / Amplitude Audio SDK / [debug] macOS arm64 Latest Clang

comparison of different enumeration types ('eScope' and 'SparkyStudios::Audio::Amplitude::Scope') is deprecated [-Wdeprecated-enum-compare]

Check warning on line 2671 in src/Core/Engine.cpp

View workflow job for this annotation

GitHub Actions / Amplitude Audio SDK / [debug] macOS arm64 Latest Clang

comparison of different enumeration types ('eScope' and 'SparkyStudios::Audio::Amplitude::Scope') is deprecated [-Wdeprecated-enum-compare]

Check warning on line 2671 in src/Core/Engine.cpp

View workflow job for this annotation

GitHub Actions / Amplitude Audio SDK / [release] Ubuntu Latest GCC

comparison between ‘enum SparkyStudios::Audio::Amplitude::eScope’ and ‘enum SparkyStudios::Audio::Amplitude::Scope’ [-Wenum-compare]

Check warning on line 2671 in src/Core/Engine.cpp

View workflow job for this annotation

GitHub Actions / Amplitude Audio SDK / [debug] Ubuntu Latest GCC

comparison between ‘enum SparkyStudios::Audio::Amplitude::eScope’ and ‘enum SparkyStudios::Audio::Amplitude::Scope’ [-Wenum-compare]

Check warning on line 2671 in src/Core/Engine.cpp

View workflow job for this annotation

GitHub Actions / Amplitude Audio SDK / [debug] macOS x64 Latest Clang

comparison of different enumeration types ('eScope' and 'SparkyStudios::Audio::Amplitude::Scope') is deprecated [-Wdeprecated-enum-compare]

Check warning on line 2671 in src/Core/Engine.cpp

View workflow job for this annotation

GitHub Actions / Amplitude Audio SDK / [debug] macOS x64 Latest Clang

comparison of different enumeration types ('eScope' and 'SparkyStudios::Audio::Amplitude::Scope') is deprecated [-Wdeprecated-enum-compare]
{
amLogError("Cannot play a sound in Entity scope. No entity defined.");
return Channel(nullptr);
Expand All @@ -2701,7 +2689,7 @@ namespace SparkyStudios::Audio::Amplitude
AmReal32 pitch;
CalculateGainPanPitch(
&gain, &pan, &pitch, listener, nullptr, handle->GetGain().GetValue(), handle->GetPitch().GetValue(),
handle->GetBus().GetState(), definition->spatialization(), userGain);
handle->GetBus().GetState(), handle->GetSpatialization(), userGain);
const AmReal32 priority = gain * handle->GetPriority().GetValue();
const auto insertionPoint = FindInsertionPoint(&_state->playing_channel_list, priority);

Expand Down
46 changes: 33 additions & 13 deletions src/Sound/Collection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,15 @@ namespace SparkyStudios::Audio::Amplitude

_entityScopeSchedulers.clear();

m_bus = nullptr;
m_effect = nullptr;
m_attenuation = nullptr;

m_id = kAmInvalidObjectId;
m_name.clear();

m_spatialization = eSpatialization_None;
m_scope = eScope_World;
}

Sound* CollectionImpl::SelectFromWorld(const std::vector<AmSoundID>& toSkip) const
Expand Down Expand Up @@ -114,22 +121,30 @@ namespace SparkyStudios::Audio::Amplitude

bool CollectionImpl::LoadDefinition(const CollectionDefinition* definition, EngineInternalState* state)
{
if (!definition->bus())
if (definition->id() == kAmInvalidObjectId)
{
amLogError("Invalid ID for collection.");
return false;
}

const uint64_t busID = definition->bus();
if (busID == kAmInvalidObjectId)
{
amLogError("Collection %s does not specify a bus.", definition->name()->c_str());
return false;
}

m_bus = FindBusInternalState(state, definition->bus());
m_bus = FindBusInternalState(state, busID);
if (!m_bus)
{
amLogError("Collection %s specifies an unknown bus ID: " AM_ID_CHAR_FMT ".", definition->name()->c_str(), definition->bus());
return false;
}

if (definition->effect() != kAmInvalidObjectId)
const uint64_t effectID = definition->effect();
if (effectID != kAmInvalidObjectId)
{
if (const auto findIt = state->effect_map.find(definition->effect()); findIt != state->effect_map.end())
if (const auto findIt = state->effect_map.find(effectID); findIt != state->effect_map.end())
{
m_effect = findIt->second.get();
}
Expand All @@ -140,9 +155,10 @@ namespace SparkyStudios::Audio::Amplitude
}
}

if (definition->attenuation() != kAmInvalidObjectId)
const uint64_t attenuationID = definition->attenuation();
if (attenuationID != kAmInvalidObjectId)
{
if (const auto findIt = state->attenuation_map.find(definition->attenuation()); findIt != state->attenuation_map.end())
if (const auto findIt = state->attenuation_map.find(attenuationID); findIt != state->attenuation_map.end())
{
m_attenuation = findIt->second.get();
}
Expand All @@ -163,14 +179,18 @@ namespace SparkyStudios::Audio::Amplitude
RtpcValue::Init(m_pitch, definition->pitch(), 1);
RtpcValue::Init(m_priority, definition->priority(), 1);

const flatbuffers::uoffset_t sampleCount = definition->sounds() ? definition->sounds()->size() : 0;
m_spatialization = static_cast<eSpatialization>(definition->spatialization());
m_scope = static_cast<eScope>(definition->scope());

const auto* sounds = definition->sounds();
const flatbuffers::uoffset_t sampleCount = sounds != nullptr ? sounds->size() : 0;

_sounds.resize(sampleCount);
_soundSettings.clear();

for (flatbuffers::uoffset_t i = 0; i < sampleCount; ++i)
{
const auto* entry = definition->sounds()->GetAs<DefaultCollectionEntry>(i);
const auto* entry = sounds->GetAs<DefaultCollectionEntry>(i);
AmSoundID id = entry->sound();

if (id == kAmInvalidObjectId)
Expand All @@ -187,12 +207,12 @@ namespace SparkyStudios::Audio::Amplitude
else
{
SoundInstanceSettings settings;
settings.m_id = definition->id();
settings.m_id = m_id;
settings.m_kind = SoundKind::Contained;
settings.m_busID = definition->bus();
settings.m_effectID = definition->effect();
settings.m_attenuationID = definition->attenuation();
settings.m_spatialization = definition->spatialization();
settings.m_busID = busID;
settings.m_effectID = effectID;
settings.m_attenuationID = attenuationID;
settings.m_spatialization = m_spatialization;
settings.m_priority = RtpcValue(m_priority);
RtpcValue::Init(settings.m_gain, entry->gain(), 1);
settings.m_nearFieldGain = findIt->second->GetNearFieldGain();
Expand Down
16 changes: 16 additions & 0 deletions src/Sound/Collection.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,22 @@ namespace SparkyStudios::Audio::Amplitude
return SoundObjectImpl::GetBus();
}

/**
* @copydoc SoundObject::GetSpatialization
*/
[[nodiscard]] AM_INLINE eSpatialization GetSpatialization() const override
{
return SoundObjectImpl::GetSpatialization();
}

/**
* @copydoc SoundObject::GetScope
*/
[[nodiscard]] AM_INLINE eScope GetScope() const override
{
return SoundObjectImpl::GetScope();
}

/**
* @copydoc Collection::SelectFromWorld
*/
Expand Down
39 changes: 26 additions & 13 deletions src/Sound/Sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ namespace SparkyStudios::Audio::Amplitude
m_bus = nullptr;
m_effect = nullptr;
m_attenuation = nullptr;

m_id = kAmInvalidObjectId;
m_name.clear();

m_spatialization = eSpatialization_None;
m_scope = eScope_World;
}

SoundInstance* SoundImpl::CreateInstance()
Expand Down Expand Up @@ -227,26 +233,28 @@ namespace SparkyStudios::Audio::Amplitude
{
if (definition->id() == kAmInvalidObjectId)
{
amLogError("Sound definition is invalid: no ID defined.");
amLogError("Invalid ID for sound.");
return false;
}

if (definition->bus() == kAmInvalidObjectId)
const uint64_t busID = definition->bus();
if (busID == kAmInvalidObjectId)
{
amLogError("Sound definition is invalid: no bus ID defined.");
return false;
}

m_bus = FindBusInternalState(state, definition->bus());
m_bus = FindBusInternalState(state, busID);
if (!m_bus)
{
amLogError("Sound %s specifies an unknown bus ID: " AM_ID_CHAR_FMT ".", definition->name()->c_str(), definition->bus());
return false;
}

if (definition->effect() != kAmInvalidObjectId)
const uint64_t effectID = definition->effect();
if (effectID != kAmInvalidObjectId)
{
if (const auto findIt = state->effect_map.find(definition->effect()); findIt != state->effect_map.end())
if (const auto findIt = state->effect_map.find(effectID); findIt != state->effect_map.end())
{
m_effect = findIt->second.get();
}
Expand All @@ -257,9 +265,10 @@ namespace SparkyStudios::Audio::Amplitude
}
}

if (definition->attenuation() != kAmInvalidObjectId)
const uint64_t attenuationID = definition->attenuation();
if (attenuationID != kAmInvalidObjectId)
{
if (const auto findIt = state->attenuation_map.find(definition->attenuation()); findIt != state->attenuation_map.end())
if (const auto findIt = state->attenuation_map.find(attenuationID); findIt != state->attenuation_map.end())
{
m_attenuation = findIt->second.get();
}
Expand All @@ -272,12 +281,16 @@ namespace SparkyStudios::Audio::Amplitude

m_id = definition->id();
m_name = definition->name()->str();
m_spatialization = static_cast<eSpatialization>(definition->spatialization());
m_scope = static_cast<eScope>(definition->scope());

auto* fs = amEngine->GetFileSystem();

const SoundLoopConfig* loopConfig = definition->loop();

_stream = definition->stream();
_loop = definition->loop() != nullptr && definition->loop()->enabled();
_loopCount = definition->loop() ? definition->loop()->loop_count() : 0;
_loop = loopConfig != nullptr && loopConfig->enabled();
_loopCount = loopConfig ? loopConfig->loop_count() : 0;
m_filename = fs->ResolvePath(fs->Join({ AM_OS_STRING("data"), AM_STRING_TO_OS_STRING(definition->path()->str()) }));

RtpcValue::Init(m_gain, definition->gain(), 1);
Expand All @@ -287,10 +300,10 @@ namespace SparkyStudios::Audio::Amplitude

_settings.m_id = m_id;
_settings.m_kind = SoundKind::Standalone;
_settings.m_busID = definition->bus();
_settings.m_effectID = definition->effect();
_settings.m_attenuationID = definition->attenuation();
_settings.m_spatialization = definition->spatialization();
_settings.m_busID = busID;
_settings.m_effectID = effectID;
_settings.m_attenuationID = attenuationID;
_settings.m_spatialization = m_spatialization;
_settings.m_priority = RtpcValue(m_priority);
_settings.m_gain = RtpcValue(m_gain);
_settings.m_nearFieldGain = RtpcValue(_nearFieldGain);
Expand Down
Loading

0 comments on commit c6dfe19

Please sign in to comment.