diff --git a/source/soundmanager/SoundManager.cpp b/source/soundmanager/SoundManager.cpp index 55f83ff20a..622d8fc367 100644 --- a/source/soundmanager/SoundManager.cpp +++ b/source/soundmanager/SoundManager.cpp @@ -18,6 +18,7 @@ #include "precompiled.h" #include "SoundManager.h" + #include "items/CBufferItem.h" #include "items/CSoundItem.h" #include "items/CStreamItem.h" @@ -35,7 +36,7 @@ #include "ps/XMB/XMBStorage.h" #include "ps/XML/Xeromyces.h" #include "soundmanager/ISoundManager.h" -#include "soundmanager/data/OggData.h" +#include "soundmanager/data/SoundData.h" #include "soundmanager/items/ISoundItem.h" #include "soundmanager/scripting/SoundGroup.h" @@ -513,17 +514,21 @@ void CSoundManager::SetUIGain(float gain) ISoundItem* CSoundManager::LoadItem(const VfsPath& itemPath) { - if (!m_Enabled || itemPath.empty()) - return nullptr; + AL_CHECK; - COggData* itemData{this->GetSoundDataFromFile(itemPath)}; - if (!itemData) - return nullptr; + if (m_Enabled) + { + CSoundData* itemData = CSoundData::SoundDataFromFile(itemPath); - return ItemForData(itemData); + AL_CHECK; + if (itemData) + return CSoundManager::ItemForData(itemData); + } + + return NULL; } -ISoundItem* CSoundManager::ItemForData(COggData* itemData) +ISoundItem* CSoundManager::ItemForData(CSoundData* itemData) { AL_CHECK; ISoundItem* answer = NULL; @@ -597,12 +602,14 @@ void CSoundManager::IdleTask() } } -ISoundItem* CSoundManager::ItemForEntity(entity_id_t /*source*/, COggData* sndData) +ISoundItem* CSoundManager::ItemForEntity(entity_id_t /*source*/, CSoundData* sndData) { - if (!m_Enabled) - return nullptr; + ISoundItem* currentItem = NULL; - return ItemForData(sndData); + if (m_Enabled) + currentItem = ItemForData(sndData); + + return currentItem; } @@ -861,21 +868,6 @@ CStr8 CSoundManager::GetSoundCardNames() const return m_SoundCardNames; } -COggData* CSoundManager::GetSoundDataFromFile(const VfsPath& itemPath) -{ - try - { - const std::string key = itemPath.string8(); - auto [it, inserted] = m_OggDataCache.try_emplace(key, itemPath); - return &it->second; - } - catch (OggDataError& e) - { - LOGERROR("Failed to load sound data from '%s': %s", itemPath.string8(), e.what()); - return nullptr; - } -} - #else // CONFIG2_AUDIO void ISoundManager::CreateSoundManager(){} diff --git a/source/soundmanager/SoundManager.h b/source/soundmanager/SoundManager.h index d191819c6f..e652815809 100644 --- a/source/soundmanager/SoundManager.h +++ b/source/soundmanager/SoundManager.h @@ -34,11 +34,8 @@ #include #include #include -#include #include -#include #include -#include #include class CSoundData; @@ -103,8 +100,8 @@ public: void StartWorker(); ISoundItem* LoadItem(const VfsPath& itemPath); - ISoundItem* ItemForData(COggData* itemData); - ISoundItem* ItemForEntity(entity_id_t source, COggData* sndData); + ISoundItem* ItemForData(CSoundData* itemData); + ISoundItem* ItemForEntity(entity_id_t source, CSoundData* sndData); Status ReloadChangedFiles(const VfsPath& path); @@ -126,6 +123,7 @@ public: ALuint GetALSource(ISoundItem* anItem); void ReleaseALSource(ALuint theSource); + ISoundItem* ItemFromData(CSoundData* itemData); ISoundItem* ItemFromWAV(VfsPath& fname); ISoundItem* ItemFromOgg(VfsPath& fname); @@ -164,16 +162,12 @@ public: void SetActionGain(float gain); void SetUIGain(float gain); - COggData* GetSoundDataFromFile(const VfsPath& itemPath); protected: void InitListener(); Status AlcInit(); void SetMusicItem(ISoundItem* anItem); private: - using DataMap = std::unordered_map; - DataMap m_OggDataCache{}; - CSoundManager(CSoundManager* /*other*/){}; }; diff --git a/source/soundmanager/data/OggData.cpp b/source/soundmanager/data/OggData.cpp index 1ec2a0a53d..4d960eaf39 100644 --- a/source/soundmanager/data/OggData.cpp +++ b/source/soundmanager/data/OggData.cpp @@ -23,14 +23,13 @@ #include "lib/status.h" #include "lib/types.h" +#include "ps/CLogger.h" #include "ps/Filesystem.h" #include "soundmanager/SoundManager.h" #include "soundmanager/data/ogg.h" -#include #include -#include -#include +#include #include #include @@ -42,33 +41,9 @@ */ constexpr int OGG_DEFAULT_BUFFER_SIZE = 98304; -COggData::COggData(const VfsPath& itemPath) +COggData::COggData() : m_Format(0), m_Frequency(0), m_OneShot(false), m_BuffersCount(0) { - if (OpenOggNonstream(g_VFS, itemPath, m_Stream) != INFO::OK) - throw new OggDataError("Can't open Ogg file"); - - m_FileFinished = false; - - SetFormatAndFreq(m_Stream->Format(), m_Stream->SamplingRate()); - m_FileName = itemPath; - - AL_CHECK; - alGenBuffers(m_Buffer.size(), m_Buffer.data()); - - ALenum err{alGetError()}; - if (err != AL_NO_ERROR) - throw new OggDataError(fmt::format("Failed to create initial buffer. OpenAL error: {}", alGetString(err))); - - m_BuffersCount = FetchDataIntoBuffer(m_Buffer.size(), m_Buffer.data()); - if (!m_FileFinished) - return; - - m_OneShot = true; - if (m_BuffersCount < OGG_DEFAULT_BUFFER_COUNT) - alDeleteBuffers(OGG_DEFAULT_BUFFER_COUNT - m_BuffersCount, &m_Buffer.at(m_BuffersCount)); - - AL_CHECK; } COggData::~COggData() @@ -92,6 +67,38 @@ bool COggData::IsStereo() return m_Format == AL_FORMAT_STEREO16; } +bool COggData::InitOggFile(const VfsPath& itemPath) +{ + if (OpenOggNonstream(g_VFS, itemPath, m_Stream) != INFO::OK) + return false; + + m_FileFinished = false; + + SetFormatAndFreq(m_Stream->Format(), m_Stream->SamplingRate()); + SetFileName(itemPath); + + AL_CHECK; + alGenBuffers(m_Buffer.size(), m_Buffer.data()); + + ALenum err{alGetError()}; + if (err != AL_NO_ERROR) + { + LOGERROR("Failed to create initial buffer. OpenAL error: %s\n", alGetString(err)); + return false; + } + + m_BuffersCount = FetchDataIntoBuffer(m_Buffer.size(), m_Buffer.data()); + if (m_FileFinished) + { + m_OneShot = true; + if (m_BuffersCount < OGG_DEFAULT_BUFFER_COUNT) + alDeleteBuffers(OGG_DEFAULT_BUFFER_COUNT - m_BuffersCount, &m_Buffer.at(m_BuffersCount)); + } + AL_CHECK; + + return true; +} + ALsizei COggData::GetBufferCount() { return m_BuffersCount; @@ -142,4 +149,5 @@ ALuint* COggData::GetBufferPtr() { return m_Buffer.data(); } + #endif // CONFIG2_AUDIO diff --git a/source/soundmanager/data/OggData.h b/source/soundmanager/data/OggData.h index c2d09f1b13..23e0eef13f 100644 --- a/source/soundmanager/data/OggData.h +++ b/source/soundmanager/data/OggData.h @@ -23,43 +23,32 @@ #if CONFIG2_AUDIO #include "ogg.h" +#include "SoundData.h" #include "lib/file/vfs/vfs_path.h" -#include "lib/path.h" #include #include -#include -#include - /* * 50 buffers of 98304 bytes each gives us 4.9 seconds of audio, which is a good amount to have buffered at once. */ constexpr int OGG_DEFAULT_BUFFER_COUNT = 50; -struct OggDataError : std::runtime_error -{ - using std::runtime_error::runtime_error; -}; - -class COggData +class COggData final : public CSoundData { public: - COggData(const VfsPath& itemPath); + COggData(); ~COggData(); + + bool InitOggFile(const VfsPath& itemPath); bool IsFileFinished(); - bool IsOneShot(); - bool IsStereo(); + bool IsOneShot() override; + bool IsStereo() override; int FetchDataIntoBuffer(int count, ALuint* buffers); void ResetFile(); - int GetBufferCount(); - ALuint GetBuffer(); - ALuint* GetBufferPtr(); - - Path m_FileName; private: ALuint m_Format; ALsizei m_Frequency; @@ -71,6 +60,9 @@ protected: int m_BuffersCount; void SetFormatAndFreq(ALenum form, ALsizei freq); + int GetBufferCount() override; + unsigned int GetBuffer() override; + unsigned int* GetBufferPtr() override; }; #endif // CONFIG2_AUDIO diff --git a/source/soundmanager/data/SoundData.cpp b/source/soundmanager/data/SoundData.cpp new file mode 100644 index 0000000000..3997ef2298 --- /dev/null +++ b/source/soundmanager/data/SoundData.cpp @@ -0,0 +1,152 @@ +/* Copyright (C) 2025 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + +#include "precompiled.h" + +#include "SoundData.h" +#include "soundmanager/SoundManager.h" + +#if CONFIG2_AUDIO + +#include "ps/CLogger.h" +#include "soundmanager/data/OggData.h" +#include "soundmanager/data/SoundData.h" + +#include +#include +#include + +DataMap CSoundData::sSoundData; + +CSoundData::CSoundData() + : m_ALBuffer(0), m_RetentionCount(0) +{ +} + +CSoundData::~CSoundData() +{ + AL_CHECK; + if (m_ALBuffer != 0) + alDeleteBuffers(1, &m_ALBuffer); + m_ALBuffer = 0; + AL_CHECK; +} + +void CSoundData::ReleaseSoundData(CSoundData* theData) +{ + DataMap::iterator itemFind; + + if (theData->DecrementCount()) + { + if ((itemFind = CSoundData::sSoundData.find( theData->GetFileName().string() )) != CSoundData::sSoundData.end()) + { + CSoundData::sSoundData.erase(itemFind); + } + delete theData; + } +} + +CSoundData* CSoundData::SoundDataFromFile(const VfsPath& itemPath) +{ + Path fExt = itemPath.Extension(); + DataMap::iterator itemFind; + CSoundData* answer = NULL; + + if ((itemFind = CSoundData::sSoundData.find(itemPath.string())) != CSoundData::sSoundData.end()) + { + answer = itemFind->second; + } + else + { + if (fExt == ".ogg") + answer = SoundDataFromOgg(itemPath); + + if (answer && answer->IsOneShot()) + { + CSoundData::sSoundData[itemPath.string()] = answer; + } + + } + + return answer; +} + +bool CSoundData::IsOneShot() +{ + return true; +} + + +CSoundData* CSoundData::SoundDataFromOgg(const VfsPath& itemPath) +{ + COggData* oggAnswer = new COggData(); + + if (!oggAnswer->InitOggFile(itemPath)) + { + LOGERROR("could not initialize ogg data at %s", itemPath.string8()); + delete oggAnswer; + return NULL; + } + + return oggAnswer; +} + +int CSoundData::GetBufferCount() +{ + return 1; +} + +const Path& CSoundData::GetFileName() +{ + return m_FileName; +} + +void CSoundData::SetFileName(const Path& aName) +{ + m_FileName = aName; +} + +CSoundData* CSoundData::IncrementCount() +{ + m_RetentionCount++; + return this; +} + +bool CSoundData::DecrementCount() +{ + m_RetentionCount--; + + return (m_RetentionCount <= 0); +} + +unsigned int CSoundData::GetBuffer() +{ + return m_ALBuffer; +} + +unsigned int* CSoundData::GetBufferPtr() +{ + return &m_ALBuffer; +} + +bool CSoundData::IsStereo() +{ + return false; +} + +#endif // CONFIG2_AUDIO + diff --git a/source/soundmanager/data/SoundData.h b/source/soundmanager/data/SoundData.h new file mode 100644 index 0000000000..87d0592a1b --- /dev/null +++ b/source/soundmanager/data/SoundData.h @@ -0,0 +1,71 @@ +/* Copyright (C) 2025 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + +#ifndef INCLUDED_SOUNDDATA_H +#define INCLUDED_SOUNDDATA_H + +#include "lib/config2.h" + +#if CONFIG2_AUDIO + +#include "lib/file/vfs/vfs_path.h" +#include "lib/path.h" + +#include +#include + +class CSoundData; +typedef std::map DataMap; + + +class CSoundData +{ +public: + static CSoundData* SoundDataFromFile(const VfsPath& itemPath); + static CSoundData* SoundDataFromOgg(const VfsPath& itemPath); + + static void ReleaseSoundData(CSoundData* theData); + + CSoundData(); + virtual ~CSoundData(); + + CSoundData* IncrementCount(); + bool DecrementCount(); + virtual bool IsOneShot(); + virtual bool IsStereo(); + + + virtual unsigned int GetBuffer(); + virtual int GetBufferCount(); + virtual const Path& GetFileName(); + virtual void SetFileName(const Path& aName); + + virtual unsigned int* GetBufferPtr(); + +protected: + static DataMap sSoundData; + + unsigned int m_ALBuffer; + int m_RetentionCount; + Path m_FileName; + +}; + +#endif // CONFIG2_AUDIO + +#endif // INCLUDED_SOUNDDATA_H + diff --git a/source/soundmanager/items/CBufferItem.cpp b/source/soundmanager/items/CBufferItem.cpp index a818e1e58f..a3ec9706fa 100644 --- a/source/soundmanager/items/CBufferItem.cpp +++ b/source/soundmanager/items/CBufferItem.cpp @@ -23,13 +23,13 @@ #include "soundmanager/ISoundManager.h" #include "soundmanager/SoundManager.h" -#include "soundmanager/data/OggData.h" +#include "soundmanager/data/SoundData.h" #include #include #include -CBufferItem::CBufferItem(COggData* sndData) +CBufferItem::CBufferItem(CSoundData* sndData) { ResetVars(); if (InitOpenAL()) @@ -106,15 +106,24 @@ bool CBufferItem::IdleTask() return true; } -void CBufferItem::Attach(COggData* itemData) +void CBufferItem::Attach(CSoundData* itemData) { - if (!m_ALSource || !itemData) + if ( m_ALSource == 0 ) return; AL_CHECK; - m_SoundData = itemData; - alSourceQueueBuffers(m_ALSource, m_SoundData->GetBufferCount(), m_SoundData->GetBufferPtr()); + if (m_SoundData != NULL) + { + CSoundData::ReleaseSoundData(m_SoundData); + m_SoundData = 0; + } AL_CHECK; + if (itemData != NULL) + { + m_SoundData = itemData->IncrementCount(); + alSourceQueueBuffers(m_ALSource, m_SoundData->GetBufferCount(),(const ALuint *) m_SoundData->GetBufferPtr()); + AL_CHECK; + } } void CBufferItem::SetLooping(bool loops) diff --git a/source/soundmanager/items/CBufferItem.h b/source/soundmanager/items/CBufferItem.h index ea9bccf867..8fd55b48e6 100644 --- a/source/soundmanager/items/CBufferItem.h +++ b/source/soundmanager/items/CBufferItem.h @@ -29,13 +29,13 @@ class CSoundData; class CBufferItem : public CSoundBase { public: - CBufferItem(COggData* sndData); + CBufferItem(CSoundData* sndData); virtual ~CBufferItem(); virtual void SetLooping(bool loops); virtual bool IdleTask(); - virtual void Attach(COggData* itemData); + virtual void Attach(CSoundData* itemData); protected: void ReleaseOpenALBuffer(); diff --git a/source/soundmanager/items/CSoundBase.cpp b/source/soundmanager/items/CSoundBase.cpp index 236f913caf..3bf47f57d7 100644 --- a/source/soundmanager/items/CSoundBase.cpp +++ b/source/soundmanager/items/CSoundBase.cpp @@ -26,7 +26,7 @@ #include "maths/Vector3D.h" #include "soundmanager/ISoundManager.h" #include "soundmanager/SoundManager.h" -#include "soundmanager/data/OggData.h" +#include "soundmanager/data/SoundData.h" #include @@ -52,15 +52,23 @@ void CSoundBase::ReleaseOpenAL() AL_CHECK; m_ALSource = 0; } + if (m_SoundData != 0) + { + AL_CHECK; + CSoundData::ReleaseSoundData(m_SoundData); + AL_CHECK; + m_SoundData = 0; + } } -void CSoundBase::Attach(COggData*) +void CSoundBase::Attach(CSoundData* /*itemData*/) { } void CSoundBase::ResetVars() { m_ALSource = 0; + m_SoundData = 0; m_LastPlay = false; m_Looping = false; m_StartFadeTime = 0; @@ -357,7 +365,7 @@ void CSoundBase::Stop() const Path CSoundBase::GetName() { if (m_SoundData) - return m_SoundData->m_FileName; + return m_SoundData->GetFileName(); return Path(); } diff --git a/source/soundmanager/items/CSoundBase.h b/source/soundmanager/items/CSoundBase.h index dec4227def..04720cbc10 100644 --- a/source/soundmanager/items/CSoundBase.h +++ b/source/soundmanager/items/CSoundBase.h @@ -22,7 +22,7 @@ #if CONFIG2_AUDIO -#include "soundmanager/data/OggData.h" +#include "lib/file/vfs/vfs_path.h" #include "soundmanager/items/ISoundItem.h" #include @@ -36,7 +36,7 @@ class CSoundBase : public ISoundItem protected: ALuint m_ALSource; - COggData* m_SoundData; + CSoundData* m_SoundData; bool m_LastPlay; bool m_Looping; @@ -91,7 +91,7 @@ public: virtual void SetLooping(bool loops); virtual bool IdleTask(); - virtual void Attach(COggData* itemData); + virtual void Attach(CSoundData* itemData); protected: diff --git a/source/soundmanager/items/CSoundItem.cpp b/source/soundmanager/items/CSoundItem.cpp index 7872197d75..d7fedf1ed7 100644 --- a/source/soundmanager/items/CSoundItem.cpp +++ b/source/soundmanager/items/CSoundItem.cpp @@ -22,7 +22,7 @@ #if CONFIG2_AUDIO #include "soundmanager/SoundManager.h" -#include "soundmanager/data/OggData.h" +#include "soundmanager/data/SoundData.h" #include #include @@ -33,7 +33,7 @@ CSoundItem::CSoundItem() ResetVars(); } -CSoundItem::CSoundItem(COggData* sndData) +CSoundItem::CSoundItem(CSoundData* sndData) { ResetVars(); if (InitOpenAL()) @@ -65,18 +65,24 @@ bool CSoundItem::IdleTask() return true; } -void CSoundItem::Attach(COggData* itemData) +void CSoundItem::Attach(CSoundData* itemData) { - if (!itemData) - return; + if (m_SoundData != NULL) + { + CSoundData::ReleaseSoundData(m_SoundData); + m_SoundData = 0; + } - AL_CHECK; - alSourcei(m_ALSource, AL_BUFFER, 0); - AL_CHECK; - m_SoundData = itemData; - alSourcei(m_ALSource, AL_BUFFER, m_SoundData->GetBuffer()); + if (itemData != NULL) + { + AL_CHECK; + alSourcei(m_ALSource, AL_BUFFER, 0); + AL_CHECK; + m_SoundData = itemData->IncrementCount(); + alSourcei(m_ALSource, AL_BUFFER, m_SoundData->GetBuffer()); - AL_CHECK; + AL_CHECK; + } } #endif // CONFIG2_AUDIO diff --git a/source/soundmanager/items/CSoundItem.h b/source/soundmanager/items/CSoundItem.h index 4cbc71bbc5..36657f0a40 100644 --- a/source/soundmanager/items/CSoundItem.h +++ b/source/soundmanager/items/CSoundItem.h @@ -24,16 +24,16 @@ #include "CSoundBase.h" -class COggData; +class CSoundData; class CSoundItem : public CSoundBase { public: CSoundItem(); - CSoundItem(COggData* sndData); + CSoundItem(CSoundData* sndData); virtual ~CSoundItem(); - void Attach(COggData* itemData); + void Attach(CSoundData* itemData); bool IdleTask(); }; diff --git a/source/soundmanager/items/CStreamItem.cpp b/source/soundmanager/items/CStreamItem.cpp index 569a126cf1..309a627705 100644 --- a/source/soundmanager/items/CStreamItem.cpp +++ b/source/soundmanager/items/CStreamItem.cpp @@ -24,11 +24,12 @@ #include "soundmanager/ISoundManager.h" #include "soundmanager/SoundManager.h" #include "soundmanager/data/OggData.h" +#include "soundmanager/data/SoundData.h" #include #include -CStreamItem::CStreamItem(COggData* sndData) +CStreamItem::CStreamItem(CSoundData* sndData) { ResetVars(); if (InitOpenAL()) @@ -84,7 +85,7 @@ bool CStreamItem::IdleTask() if (m_SoundData == nullptr) return true; - COggData* theData{static_cast(m_SoundData)}; + COggData* theData = (COggData*)m_SoundData; if (!theData->IsFileFinished()) { @@ -117,14 +118,20 @@ bool CStreamItem::IdleTask() return true; } -void CStreamItem::Attach(COggData* itemData) +void CStreamItem::Attach(CSoundData* itemData) { - if (!itemData) - return; + if (m_SoundData != NULL) + { + CSoundData::ReleaseSoundData(m_SoundData); + m_SoundData = 0; + } - m_SoundData = itemData; - alSourceQueueBuffers(m_ALSource, m_SoundData->GetBufferCount(), m_SoundData->GetBufferPtr()); - AL_CHECK; + if (itemData != NULL) + { + m_SoundData = itemData->IncrementCount(); + alSourceQueueBuffers(m_ALSource, m_SoundData->GetBufferCount(), (const ALuint *)m_SoundData->GetBufferPtr()); + AL_CHECK; + } } void CStreamItem::SetLooping(bool loops) diff --git a/source/soundmanager/items/CStreamItem.h b/source/soundmanager/items/CStreamItem.h index 62defd4b58..a66cd5f51a 100644 --- a/source/soundmanager/items/CStreamItem.h +++ b/source/soundmanager/items/CStreamItem.h @@ -22,7 +22,6 @@ #if CONFIG2_AUDIO -#include "soundmanager/data/OggData.h" #include "CSoundBase.h" class CSoundData; @@ -30,12 +29,12 @@ class CSoundData; class CStreamItem : public CSoundBase { public: - CStreamItem(COggData* sndData); + CStreamItem(CSoundData* sndData); virtual ~CStreamItem(); virtual void SetLooping(bool loops); virtual bool IdleTask(); - virtual void Attach(COggData* itemData); + virtual void Attach(CSoundData* itemData); protected: void ReleaseOpenALStream(); diff --git a/source/soundmanager/items/ISoundItem.h b/source/soundmanager/items/ISoundItem.h index cad2217cb3..c3f5619715 100644 --- a/source/soundmanager/items/ISoundItem.h +++ b/source/soundmanager/items/ISoundItem.h @@ -24,7 +24,7 @@ #include "maths/Vector3D.h" #include "ps/CStr.h" -#include "soundmanager/data/OggData.h" +#include "soundmanager/data/SoundData.h" class ISoundItem { @@ -44,7 +44,7 @@ public: virtual void Play() = 0; virtual void Stop() = 0; - virtual void Attach(COggData* itemData) = 0; + virtual void Attach(CSoundData* itemData) = 0; virtual void EnsurePlay() = 0; diff --git a/source/soundmanager/scripting/SoundGroup.cpp b/source/soundmanager/scripting/SoundGroup.cpp index 28bbcf5728..809eca59b2 100644 --- a/source/soundmanager/scripting/SoundGroup.cpp +++ b/source/soundmanager/scripting/SoundGroup.cpp @@ -50,7 +50,7 @@ extern CGame *g_Game; #include "ps/XMB/XMBData.h" #include "scriptinterface/ScriptInterface.h" #include "soundmanager/ISoundManager.h" -#include "soundmanager/data/OggData.h" +#include "soundmanager/data/SoundData.h" #include #include @@ -137,6 +137,12 @@ CSoundGroup::CSoundGroup(const VfsPath& pathnameXML) LoadSoundGroup(pathnameXML); } +CSoundGroup::~CSoundGroup() +{ + // clean up all the handles from this group. + ReleaseGroup(); +} + float CSoundGroup::RadiansOffCenter([[maybe_unused]] const CVector3D& position, [[maybe_unused]] bool& onScreen, [[maybe_unused]] float& itemRollOff) { @@ -208,7 +214,7 @@ void CSoundGroup::UploadPropertiesAndPlay([[maybe_unused]] size_t index, if (m_SoundGroups.size() <= index) return; - COggData* sndData = m_SoundGroups.at(index); + CSoundData* sndData = m_SoundGroups[index]; if (!sndData) return; @@ -225,7 +231,7 @@ void CSoundGroup::UploadPropertiesAndPlay([[maybe_unused]] size_t index, itemRollOff = 0; if (sndData->IsStereo()) - LOGWARNING("OpenAL: stereo sounds can't be positioned: %s", sndData->m_FileName.string8()); + LOGWARNING("OpenAL: stereo sounds can't be positioned: %s", sndData->GetFileName().string8()); hSound->SetLocation(CVector3D(itemDist * sin(offset), 0, -itemDist * cos(offset))); hSound->SetRollOff(itemRollOff, m_MinDist, m_MaxDist); @@ -267,20 +273,19 @@ void CSoundGroup::Reload() { m_CurrentSoundIndex = 0; #if CONFIG2_AUDIO - m_SoundGroups.clear(); + ReleaseGroup(); if (!g_SoundManager) return; - CSoundManager* soundManager{static_cast(g_SoundManager)}; for (const std::wstring& filename : m_Filenames) { VfsPath absolutePath = m_Filepath / filename; - COggData* itemData{soundManager->GetSoundDataFromFile(absolutePath)}; + CSoundData* itemData = CSoundData::SoundDataFromFile(absolutePath); if (!itemData) HandleError(L"error loading sound", absolutePath, ERR::FAIL); else - m_SoundGroups.push_back(itemData); + m_SoundGroups.push_back(itemData->IncrementCount()); } if (TestFlag(eRandOrder)) @@ -288,6 +293,16 @@ void CSoundGroup::Reload() #endif } +void CSoundGroup::ReleaseGroup() +{ +#if CONFIG2_AUDIO + for (CSoundData* soundGroup : m_SoundGroups) + CSoundData::ReleaseSoundData(soundGroup); + + m_SoundGroups.clear(); +#endif +} + void CSoundGroup::Update(float /*TimeSinceLastFrame*/) { } diff --git a/source/soundmanager/scripting/SoundGroup.h b/source/soundmanager/scripting/SoundGroup.h index c0f87441ea..ff8be23c26 100644 --- a/source/soundmanager/scripting/SoundGroup.h +++ b/source/soundmanager/scripting/SoundGroup.h @@ -23,7 +23,6 @@ #include "lib/file/vfs/vfs_path.h" #include "lib/types.h" #include "simulation2/system/Entity.h" -#include "soundmanager/data/OggData.h" #include #include @@ -51,6 +50,7 @@ class CSoundGroup public: CSoundGroup(const VfsPath& pathnameXML); CSoundGroup(); + ~CSoundGroup(); // Play next sound in group // @param position world position of the entity generating the sound @@ -64,6 +64,9 @@ public: void Reload(); + // Release all remaining loaded handles + void ReleaseGroup(); + // Update SoundGroup, remove dead sounds from intensity count void Update(float TimeSinceLastFrame); @@ -81,7 +84,7 @@ private: void SetDefaultValues(); #if CONFIG2_AUDIO // We store the handles so we can load now and play later - std::vector m_SoundGroups; + std::vector m_SoundGroups; #endif u32 m_Seed; // We need the filenames so we can reload when necessary.