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:
@@ -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(){}
|
||||
|
||||
@@ -34,11 +34,8 @@
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
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<std::string, COggData>;
|
||||
DataMap m_OggDataCache{};
|
||||
|
||||
CSoundManager(CSoundManager* /*other*/){};
|
||||
};
|
||||
|
||||
|
||||
@@ -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 <AL/al.h>
|
||||
#include <algorithm>
|
||||
#include <fmt/format.h>
|
||||
#include <stdexcept>
|
||||
#include <cstddef>
|
||||
#include <span>
|
||||
#include <vector>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <AL/al.h>
|
||||
#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.
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -23,13 +23,13 @@
|
||||
|
||||
#include "soundmanager/ISoundManager.h"
|
||||
#include "soundmanager/SoundManager.h"
|
||||
#include "soundmanager/data/OggData.h"
|
||||
#include "soundmanager/data/SoundData.h"
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <cstddef>
|
||||
#include <mutex>
|
||||
|
||||
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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 <algorithm>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 <AL/al.h>
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#if CONFIG2_AUDIO
|
||||
|
||||
#include "soundmanager/SoundManager.h"
|
||||
#include "soundmanager/data/OggData.h"
|
||||
#include "soundmanager/data/SoundData.h"
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <cstddef>
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
@@ -24,11 +24,12 @@
|
||||
#include "soundmanager/ISoundManager.h"
|
||||
#include "soundmanager/SoundManager.h"
|
||||
#include "soundmanager/data/OggData.h"
|
||||
#include "soundmanager/data/SoundData.h"
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <cstddef>
|
||||
|
||||
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<COggData*>(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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 <AL/al.h>
|
||||
#include <cmath>
|
||||
@@ -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<CSoundManager*>(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*/)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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 <cstddef>
|
||||
#include <string>
|
||||
@@ -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<COggData*> m_SoundGroups;
|
||||
std::vector<CSoundData*> m_SoundGroups;
|
||||
#endif
|
||||
u32 m_Seed;
|
||||
// We need the filenames so we can reload when necessary.
|
||||
|
||||
Reference in New Issue
Block a user