1
0
forked from mirrors/0ad

SoundManager: reintroduce manual memory management

This reverts commit 94c907342a.

It introduced multiple errors and is to big to find the actual errors.

Fixes: #8342
Fixes: #8426
This commit is contained in:
phosit
2025-10-10 20:49:37 +02:00
parent 70893b6a32
commit e2ed4afe00
17 changed files with 388 additions and 132 deletions
+19 -27
View File
@@ -18,6 +18,7 @@
#include "precompiled.h" #include "precompiled.h"
#include "SoundManager.h" #include "SoundManager.h"
#include "items/CBufferItem.h" #include "items/CBufferItem.h"
#include "items/CSoundItem.h" #include "items/CSoundItem.h"
#include "items/CStreamItem.h" #include "items/CStreamItem.h"
@@ -35,7 +36,7 @@
#include "ps/XMB/XMBStorage.h" #include "ps/XMB/XMBStorage.h"
#include "ps/XML/Xeromyces.h" #include "ps/XML/Xeromyces.h"
#include "soundmanager/ISoundManager.h" #include "soundmanager/ISoundManager.h"
#include "soundmanager/data/OggData.h" #include "soundmanager/data/SoundData.h"
#include "soundmanager/items/ISoundItem.h" #include "soundmanager/items/ISoundItem.h"
#include "soundmanager/scripting/SoundGroup.h" #include "soundmanager/scripting/SoundGroup.h"
@@ -513,17 +514,21 @@ void CSoundManager::SetUIGain(float gain)
ISoundItem* CSoundManager::LoadItem(const VfsPath& itemPath) ISoundItem* CSoundManager::LoadItem(const VfsPath& itemPath)
{ {
if (!m_Enabled || itemPath.empty()) AL_CHECK;
return nullptr;
COggData* itemData{this->GetSoundDataFromFile(itemPath)}; if (m_Enabled)
if (!itemData) {
return nullptr; 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; AL_CHECK;
ISoundItem* answer = NULL; 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) ISoundItem* currentItem = NULL;
return nullptr;
return ItemForData(sndData); if (m_Enabled)
currentItem = ItemForData(sndData);
return currentItem;
} }
@@ -861,21 +868,6 @@ CStr8 CSoundManager::GetSoundCardNames() const
return m_SoundCardNames; 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 #else // CONFIG2_AUDIO
void ISoundManager::CreateSoundManager(){} void ISoundManager::CreateSoundManager(){}
+3 -9
View File
@@ -34,11 +34,8 @@
#include <AL/al.h> #include <AL/al.h>
#include <AL/alc.h> #include <AL/alc.h>
#include <map> #include <map>
#include <memory>
#include <mutex> #include <mutex>
#include <optional>
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
class CSoundData; class CSoundData;
@@ -103,8 +100,8 @@ public:
void StartWorker(); void StartWorker();
ISoundItem* LoadItem(const VfsPath& itemPath); ISoundItem* LoadItem(const VfsPath& itemPath);
ISoundItem* ItemForData(COggData* itemData); ISoundItem* ItemForData(CSoundData* itemData);
ISoundItem* ItemForEntity(entity_id_t source, COggData* sndData); ISoundItem* ItemForEntity(entity_id_t source, CSoundData* sndData);
Status ReloadChangedFiles(const VfsPath& path); Status ReloadChangedFiles(const VfsPath& path);
@@ -126,6 +123,7 @@ public:
ALuint GetALSource(ISoundItem* anItem); ALuint GetALSource(ISoundItem* anItem);
void ReleaseALSource(ALuint theSource); void ReleaseALSource(ALuint theSource);
ISoundItem* ItemFromData(CSoundData* itemData);
ISoundItem* ItemFromWAV(VfsPath& fname); ISoundItem* ItemFromWAV(VfsPath& fname);
ISoundItem* ItemFromOgg(VfsPath& fname); ISoundItem* ItemFromOgg(VfsPath& fname);
@@ -164,16 +162,12 @@ public:
void SetActionGain(float gain); void SetActionGain(float gain);
void SetUIGain(float gain); void SetUIGain(float gain);
COggData* GetSoundDataFromFile(const VfsPath& itemPath);
protected: protected:
void InitListener(); void InitListener();
Status AlcInit(); Status AlcInit();
void SetMusicItem(ISoundItem* anItem); void SetMusicItem(ISoundItem* anItem);
private: private:
using DataMap = std::unordered_map<std::string, COggData>;
DataMap m_OggDataCache{};
CSoundManager(CSoundManager* /*other*/){}; CSoundManager(CSoundManager* /*other*/){};
}; };
+36 -28
View File
@@ -23,14 +23,13 @@
#include "lib/status.h" #include "lib/status.h"
#include "lib/types.h" #include "lib/types.h"
#include "ps/CLogger.h"
#include "ps/Filesystem.h" #include "ps/Filesystem.h"
#include "soundmanager/SoundManager.h" #include "soundmanager/SoundManager.h"
#include "soundmanager/data/ogg.h" #include "soundmanager/data/ogg.h"
#include <AL/al.h>
#include <algorithm> #include <algorithm>
#include <fmt/format.h> #include <cstddef>
#include <stdexcept>
#include <span> #include <span>
#include <vector> #include <vector>
@@ -42,33 +41,9 @@
*/ */
constexpr int OGG_DEFAULT_BUFFER_SIZE = 98304; 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) : 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() COggData::~COggData()
@@ -92,6 +67,38 @@ bool COggData::IsStereo()
return m_Format == AL_FORMAT_STEREO16; 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() ALsizei COggData::GetBufferCount()
{ {
return m_BuffersCount; return m_BuffersCount;
@@ -142,4 +149,5 @@ ALuint* COggData::GetBufferPtr()
{ {
return m_Buffer.data(); return m_Buffer.data();
} }
#endif // CONFIG2_AUDIO #endif // CONFIG2_AUDIO
+10 -18
View File
@@ -23,43 +23,32 @@
#if CONFIG2_AUDIO #if CONFIG2_AUDIO
#include "ogg.h" #include "ogg.h"
#include "SoundData.h"
#include "lib/file/vfs/vfs_path.h" #include "lib/file/vfs/vfs_path.h"
#include "lib/path.h"
#include <AL/al.h> #include <AL/al.h>
#include <array> #include <array>
#include <string>
#include <stdexcept>
/* /*
* 50 buffers of 98304 bytes each gives us 4.9 seconds of audio, which is a good amount to have buffered at once. * 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; constexpr int OGG_DEFAULT_BUFFER_COUNT = 50;
struct OggDataError : std::runtime_error class COggData final : public CSoundData
{
using std::runtime_error::runtime_error;
};
class COggData
{ {
public: public:
COggData(const VfsPath& itemPath); COggData();
~COggData(); ~COggData();
bool InitOggFile(const VfsPath& itemPath);
bool IsFileFinished(); bool IsFileFinished();
bool IsOneShot(); bool IsOneShot() override;
bool IsStereo(); bool IsStereo() override;
int FetchDataIntoBuffer(int count, ALuint* buffers); int FetchDataIntoBuffer(int count, ALuint* buffers);
void ResetFile(); void ResetFile();
int GetBufferCount();
ALuint GetBuffer();
ALuint* GetBufferPtr();
Path m_FileName;
private: private:
ALuint m_Format; ALuint m_Format;
ALsizei m_Frequency; ALsizei m_Frequency;
@@ -71,6 +60,9 @@ protected:
int m_BuffersCount; int m_BuffersCount;
void SetFormatAndFreq(ALenum form, ALsizei freq); void SetFormatAndFreq(ALenum form, ALsizei freq);
int GetBufferCount() override;
unsigned int GetBuffer() override;
unsigned int* GetBufferPtr() override;
}; };
#endif // CONFIG2_AUDIO #endif // CONFIG2_AUDIO
+152
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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 <AL/al.h>
#include <cstddef>
#include <utility>
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
+71
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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 <map>
#include <string>
class CSoundData;
typedef std::map<std::wstring, CSoundData*> 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
+15 -6
View File
@@ -23,13 +23,13 @@
#include "soundmanager/ISoundManager.h" #include "soundmanager/ISoundManager.h"
#include "soundmanager/SoundManager.h" #include "soundmanager/SoundManager.h"
#include "soundmanager/data/OggData.h" #include "soundmanager/data/SoundData.h"
#include <AL/al.h> #include <AL/al.h>
#include <cstddef> #include <cstddef>
#include <mutex> #include <mutex>
CBufferItem::CBufferItem(COggData* sndData) CBufferItem::CBufferItem(CSoundData* sndData)
{ {
ResetVars(); ResetVars();
if (InitOpenAL()) if (InitOpenAL())
@@ -106,15 +106,24 @@ bool CBufferItem::IdleTask()
return true; return true;
} }
void CBufferItem::Attach(COggData* itemData) void CBufferItem::Attach(CSoundData* itemData)
{ {
if (!m_ALSource || !itemData) if ( m_ALSource == 0 )
return; return;
AL_CHECK; AL_CHECK;
m_SoundData = itemData; if (m_SoundData != NULL)
alSourceQueueBuffers(m_ALSource, m_SoundData->GetBufferCount(), m_SoundData->GetBufferPtr()); {
CSoundData::ReleaseSoundData(m_SoundData);
m_SoundData = 0;
}
AL_CHECK; 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) void CBufferItem::SetLooping(bool loops)
+2 -2
View File
@@ -29,13 +29,13 @@ class CSoundData;
class CBufferItem : public CSoundBase class CBufferItem : public CSoundBase
{ {
public: public:
CBufferItem(COggData* sndData); CBufferItem(CSoundData* sndData);
virtual ~CBufferItem(); virtual ~CBufferItem();
virtual void SetLooping(bool loops); virtual void SetLooping(bool loops);
virtual bool IdleTask(); virtual bool IdleTask();
virtual void Attach(COggData* itemData); virtual void Attach(CSoundData* itemData);
protected: protected:
void ReleaseOpenALBuffer(); void ReleaseOpenALBuffer();
+11 -3
View File
@@ -26,7 +26,7 @@
#include "maths/Vector3D.h" #include "maths/Vector3D.h"
#include "soundmanager/ISoundManager.h" #include "soundmanager/ISoundManager.h"
#include "soundmanager/SoundManager.h" #include "soundmanager/SoundManager.h"
#include "soundmanager/data/OggData.h" #include "soundmanager/data/SoundData.h"
#include <algorithm> #include <algorithm>
@@ -52,15 +52,23 @@ void CSoundBase::ReleaseOpenAL()
AL_CHECK; AL_CHECK;
m_ALSource = 0; 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() void CSoundBase::ResetVars()
{ {
m_ALSource = 0; m_ALSource = 0;
m_SoundData = 0;
m_LastPlay = false; m_LastPlay = false;
m_Looping = false; m_Looping = false;
m_StartFadeTime = 0; m_StartFadeTime = 0;
@@ -357,7 +365,7 @@ void CSoundBase::Stop()
const Path CSoundBase::GetName() const Path CSoundBase::GetName()
{ {
if (m_SoundData) if (m_SoundData)
return m_SoundData->m_FileName; return m_SoundData->GetFileName();
return Path(); return Path();
} }
+3 -3
View File
@@ -22,7 +22,7 @@
#if CONFIG2_AUDIO #if CONFIG2_AUDIO
#include "soundmanager/data/OggData.h" #include "lib/file/vfs/vfs_path.h"
#include "soundmanager/items/ISoundItem.h" #include "soundmanager/items/ISoundItem.h"
#include <AL/al.h> #include <AL/al.h>
@@ -36,7 +36,7 @@ class CSoundBase : public ISoundItem
protected: protected:
ALuint m_ALSource; ALuint m_ALSource;
COggData* m_SoundData; CSoundData* m_SoundData;
bool m_LastPlay; bool m_LastPlay;
bool m_Looping; bool m_Looping;
@@ -91,7 +91,7 @@ public:
virtual void SetLooping(bool loops); virtual void SetLooping(bool loops);
virtual bool IdleTask(); virtual bool IdleTask();
virtual void Attach(COggData* itemData); virtual void Attach(CSoundData* itemData);
protected: protected:
+17 -11
View File
@@ -22,7 +22,7 @@
#if CONFIG2_AUDIO #if CONFIG2_AUDIO
#include "soundmanager/SoundManager.h" #include "soundmanager/SoundManager.h"
#include "soundmanager/data/OggData.h" #include "soundmanager/data/SoundData.h"
#include <AL/al.h> #include <AL/al.h>
#include <cstddef> #include <cstddef>
@@ -33,7 +33,7 @@ CSoundItem::CSoundItem()
ResetVars(); ResetVars();
} }
CSoundItem::CSoundItem(COggData* sndData) CSoundItem::CSoundItem(CSoundData* sndData)
{ {
ResetVars(); ResetVars();
if (InitOpenAL()) if (InitOpenAL())
@@ -65,18 +65,24 @@ bool CSoundItem::IdleTask()
return true; return true;
} }
void CSoundItem::Attach(COggData* itemData) void CSoundItem::Attach(CSoundData* itemData)
{ {
if (!itemData) if (m_SoundData != NULL)
return; {
CSoundData::ReleaseSoundData(m_SoundData);
m_SoundData = 0;
}
AL_CHECK; if (itemData != NULL)
alSourcei(m_ALSource, AL_BUFFER, 0); {
AL_CHECK; AL_CHECK;
m_SoundData = itemData; alSourcei(m_ALSource, AL_BUFFER, 0);
alSourcei(m_ALSource, AL_BUFFER, m_SoundData->GetBuffer()); AL_CHECK;
m_SoundData = itemData->IncrementCount();
alSourcei(m_ALSource, AL_BUFFER, m_SoundData->GetBuffer());
AL_CHECK; AL_CHECK;
}
} }
#endif // CONFIG2_AUDIO #endif // CONFIG2_AUDIO
+3 -3
View File
@@ -24,16 +24,16 @@
#include "CSoundBase.h" #include "CSoundBase.h"
class COggData; class CSoundData;
class CSoundItem : public CSoundBase class CSoundItem : public CSoundBase
{ {
public: public:
CSoundItem(); CSoundItem();
CSoundItem(COggData* sndData); CSoundItem(CSoundData* sndData);
virtual ~CSoundItem(); virtual ~CSoundItem();
void Attach(COggData* itemData); void Attach(CSoundData* itemData);
bool IdleTask(); bool IdleTask();
}; };
+15 -8
View File
@@ -24,11 +24,12 @@
#include "soundmanager/ISoundManager.h" #include "soundmanager/ISoundManager.h"
#include "soundmanager/SoundManager.h" #include "soundmanager/SoundManager.h"
#include "soundmanager/data/OggData.h" #include "soundmanager/data/OggData.h"
#include "soundmanager/data/SoundData.h"
#include <AL/al.h> #include <AL/al.h>
#include <cstddef> #include <cstddef>
CStreamItem::CStreamItem(COggData* sndData) CStreamItem::CStreamItem(CSoundData* sndData)
{ {
ResetVars(); ResetVars();
if (InitOpenAL()) if (InitOpenAL())
@@ -84,7 +85,7 @@ bool CStreamItem::IdleTask()
if (m_SoundData == nullptr) if (m_SoundData == nullptr)
return true; return true;
COggData* theData{static_cast<COggData*>(m_SoundData)}; COggData* theData = (COggData*)m_SoundData;
if (!theData->IsFileFinished()) if (!theData->IsFileFinished())
{ {
@@ -117,14 +118,20 @@ bool CStreamItem::IdleTask()
return true; return true;
} }
void CStreamItem::Attach(COggData* itemData) void CStreamItem::Attach(CSoundData* itemData)
{ {
if (!itemData) if (m_SoundData != NULL)
return; {
CSoundData::ReleaseSoundData(m_SoundData);
m_SoundData = 0;
}
m_SoundData = itemData; if (itemData != NULL)
alSourceQueueBuffers(m_ALSource, m_SoundData->GetBufferCount(), m_SoundData->GetBufferPtr()); {
AL_CHECK; m_SoundData = itemData->IncrementCount();
alSourceQueueBuffers(m_ALSource, m_SoundData->GetBufferCount(), (const ALuint *)m_SoundData->GetBufferPtr());
AL_CHECK;
}
} }
void CStreamItem::SetLooping(bool loops) void CStreamItem::SetLooping(bool loops)
+2 -3
View File
@@ -22,7 +22,6 @@
#if CONFIG2_AUDIO #if CONFIG2_AUDIO
#include "soundmanager/data/OggData.h"
#include "CSoundBase.h" #include "CSoundBase.h"
class CSoundData; class CSoundData;
@@ -30,12 +29,12 @@ class CSoundData;
class CStreamItem : public CSoundBase class CStreamItem : public CSoundBase
{ {
public: public:
CStreamItem(COggData* sndData); CStreamItem(CSoundData* sndData);
virtual ~CStreamItem(); virtual ~CStreamItem();
virtual void SetLooping(bool loops); virtual void SetLooping(bool loops);
virtual bool IdleTask(); virtual bool IdleTask();
virtual void Attach(COggData* itemData); virtual void Attach(CSoundData* itemData);
protected: protected:
void ReleaseOpenALStream(); void ReleaseOpenALStream();
+2 -2
View File
@@ -24,7 +24,7 @@
#include "maths/Vector3D.h" #include "maths/Vector3D.h"
#include "ps/CStr.h" #include "ps/CStr.h"
#include "soundmanager/data/OggData.h" #include "soundmanager/data/SoundData.h"
class ISoundItem class ISoundItem
{ {
@@ -44,7 +44,7 @@ public:
virtual void Play() = 0; virtual void Play() = 0;
virtual void Stop() = 0; virtual void Stop() = 0;
virtual void Attach(COggData* itemData) = 0; virtual void Attach(CSoundData* itemData) = 0;
virtual void EnsurePlay() = 0; virtual void EnsurePlay() = 0;
+22 -7
View File
@@ -50,7 +50,7 @@ extern CGame *g_Game;
#include "ps/XMB/XMBData.h" #include "ps/XMB/XMBData.h"
#include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptInterface.h"
#include "soundmanager/ISoundManager.h" #include "soundmanager/ISoundManager.h"
#include "soundmanager/data/OggData.h" #include "soundmanager/data/SoundData.h"
#include <AL/al.h> #include <AL/al.h>
#include <cmath> #include <cmath>
@@ -137,6 +137,12 @@ CSoundGroup::CSoundGroup(const VfsPath& pathnameXML)
LoadSoundGroup(pathnameXML); LoadSoundGroup(pathnameXML);
} }
CSoundGroup::~CSoundGroup()
{
// clean up all the handles from this group.
ReleaseGroup();
}
float CSoundGroup::RadiansOffCenter([[maybe_unused]] const CVector3D& position, float CSoundGroup::RadiansOffCenter([[maybe_unused]] const CVector3D& position,
[[maybe_unused]] bool& onScreen, [[maybe_unused]] float& itemRollOff) [[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) if (m_SoundGroups.size() <= index)
return; return;
COggData* sndData = m_SoundGroups.at(index); CSoundData* sndData = m_SoundGroups[index];
if (!sndData) if (!sndData)
return; return;
@@ -225,7 +231,7 @@ void CSoundGroup::UploadPropertiesAndPlay([[maybe_unused]] size_t index,
itemRollOff = 0; itemRollOff = 0;
if (sndData->IsStereo()) 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->SetLocation(CVector3D(itemDist * sin(offset), 0, -itemDist * cos(offset)));
hSound->SetRollOff(itemRollOff, m_MinDist, m_MaxDist); hSound->SetRollOff(itemRollOff, m_MinDist, m_MaxDist);
@@ -267,20 +273,19 @@ void CSoundGroup::Reload()
{ {
m_CurrentSoundIndex = 0; m_CurrentSoundIndex = 0;
#if CONFIG2_AUDIO #if CONFIG2_AUDIO
m_SoundGroups.clear(); ReleaseGroup();
if (!g_SoundManager) if (!g_SoundManager)
return; return;
CSoundManager* soundManager{static_cast<CSoundManager*>(g_SoundManager)};
for (const std::wstring& filename : m_Filenames) for (const std::wstring& filename : m_Filenames)
{ {
VfsPath absolutePath = m_Filepath / filename; VfsPath absolutePath = m_Filepath / filename;
COggData* itemData{soundManager->GetSoundDataFromFile(absolutePath)}; CSoundData* itemData = CSoundData::SoundDataFromFile(absolutePath);
if (!itemData) if (!itemData)
HandleError(L"error loading sound", absolutePath, ERR::FAIL); HandleError(L"error loading sound", absolutePath, ERR::FAIL);
else else
m_SoundGroups.push_back(itemData); m_SoundGroups.push_back(itemData->IncrementCount());
} }
if (TestFlag(eRandOrder)) if (TestFlag(eRandOrder))
@@ -288,6 +293,16 @@ void CSoundGroup::Reload()
#endif #endif
} }
void CSoundGroup::ReleaseGroup()
{
#if CONFIG2_AUDIO
for (CSoundData* soundGroup : m_SoundGroups)
CSoundData::ReleaseSoundData(soundGroup);
m_SoundGroups.clear();
#endif
}
void CSoundGroup::Update(float /*TimeSinceLastFrame*/) void CSoundGroup::Update(float /*TimeSinceLastFrame*/)
{ {
} }
+5 -2
View File
@@ -23,7 +23,6 @@
#include "lib/file/vfs/vfs_path.h" #include "lib/file/vfs/vfs_path.h"
#include "lib/types.h" #include "lib/types.h"
#include "simulation2/system/Entity.h" #include "simulation2/system/Entity.h"
#include "soundmanager/data/OggData.h"
#include <cstddef> #include <cstddef>
#include <string> #include <string>
@@ -51,6 +50,7 @@ class CSoundGroup
public: public:
CSoundGroup(const VfsPath& pathnameXML); CSoundGroup(const VfsPath& pathnameXML);
CSoundGroup(); CSoundGroup();
~CSoundGroup();
// Play next sound in group // Play next sound in group
// @param position world position of the entity generating the sound // @param position world position of the entity generating the sound
@@ -64,6 +64,9 @@ public:
void Reload(); void Reload();
// Release all remaining loaded handles
void ReleaseGroup();
// Update SoundGroup, remove dead sounds from intensity count // Update SoundGroup, remove dead sounds from intensity count
void Update(float TimeSinceLastFrame); void Update(float TimeSinceLastFrame);
@@ -81,7 +84,7 @@ private:
void SetDefaultValues(); void SetDefaultValues();
#if CONFIG2_AUDIO #if CONFIG2_AUDIO
// We store the handles so we can load now and play later // We store the handles so we can load now and play later
std::vector<COggData*> m_SoundGroups; std::vector<CSoundData*> m_SoundGroups;
#endif #endif
u32 m_Seed; u32 m_Seed;
// We need the filenames so we can reload when necessary. // We need the filenames so we can reload when necessary.