Audio: Handle AudioBuffer compatibility
OpenAL buffers are shared between contextes
This commit is contained in:
@@ -52,6 +52,12 @@ namespace Nz
|
||||
return SafeCast<UInt32>(sampleRate);
|
||||
}
|
||||
|
||||
bool OpenALBuffer::IsCompatibleWith(const AudioDevice& device) const
|
||||
{
|
||||
// OpenAL buffers are shared among contexts and thus devices
|
||||
return device.GetSubSystemIdentifier() == &m_library;
|
||||
}
|
||||
|
||||
bool OpenALBuffer::Reset(AudioFormat format, UInt64 sampleCount, UInt32 sampleRate, const void* samples)
|
||||
{
|
||||
OpenALDevice& device = GetDevice();
|
||||
|
||||
@@ -206,6 +206,11 @@ namespace Nz
|
||||
return m_library.alGetFloat(AL_SPEED_OF_SOUND);
|
||||
}
|
||||
|
||||
const void* OpenALDevice::GetSubSystemIdentifier() const
|
||||
{
|
||||
return &m_library;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether the format is supported by the engine
|
||||
* \return true if it is the case
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace Nz
|
||||
void OpenALSource::QueueBuffer(std::shared_ptr<AudioBuffer> audioBuffer)
|
||||
{
|
||||
NazaraAssert(audioBuffer, "invalid buffer");
|
||||
NazaraAssert(audioBuffer->GetAudioDevice() == GetAudioDevice(), "incompatible buffer");
|
||||
NazaraAssert(audioBuffer->IsCompatibleWith(*GetAudioDevice()), "incompatible buffer");
|
||||
|
||||
std::shared_ptr<OpenALBuffer> newBuffer = std::static_pointer_cast<OpenALBuffer>(std::move(audioBuffer));
|
||||
|
||||
@@ -185,7 +185,7 @@ namespace Nz
|
||||
|
||||
void OpenALSource::SetBuffer(std::shared_ptr<AudioBuffer> audioBuffer)
|
||||
{
|
||||
NazaraAssert(audioBuffer->GetAudioDevice() == GetAudioDevice(), "incompatible buffer");
|
||||
NazaraAssert(audioBuffer->IsCompatibleWith(*GetAudioDevice()), "incompatible buffer");
|
||||
|
||||
std::shared_ptr<OpenALBuffer> newBuffer = std::static_pointer_cast<OpenALBuffer>(std::move(audioBuffer));
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ namespace Nz
|
||||
Stop();
|
||||
|
||||
m_buffer = std::move(buffer);
|
||||
m_source->SetBuffer(m_buffer->GetBuffer(m_source->GetAudioDevice().get()));
|
||||
m_source->SetBuffer(m_buffer->GetAudioBuffer(m_source->GetAudioDevice().get()));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -58,14 +58,32 @@ namespace Nz
|
||||
std::memcpy(&m_samples[0], samples, sampleCount * sizeof(Int16));
|
||||
}
|
||||
|
||||
const std::shared_ptr<AudioBuffer>& SoundBuffer::GetBuffer(AudioDevice* device)
|
||||
const std::shared_ptr<AudioBuffer>& SoundBuffer::GetAudioBuffer(AudioDevice* device)
|
||||
{
|
||||
NazaraAssert(device, "invalid device");
|
||||
|
||||
auto it = m_audioBufferByDevice.find(device);
|
||||
if (it == m_audioBufferByDevice.end())
|
||||
{
|
||||
auto audioBuffer = device->CreateBuffer();
|
||||
if (!audioBuffer->Reset(m_format, m_sampleCount, m_sampleRate, m_samples.get()))
|
||||
throw std::runtime_error("failed to initialize audio buffer");
|
||||
// Try to find an existing compatible buffer
|
||||
std::shared_ptr<AudioBuffer> audioBuffer;
|
||||
for (it = m_audioBufferByDevice.begin(); it != m_audioBufferByDevice.end(); ++it)
|
||||
{
|
||||
const auto& entry = it->second;
|
||||
if (entry.audioBuffer->IsCompatibleWith(*device))
|
||||
{
|
||||
audioBuffer = entry.audioBuffer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!audioBuffer)
|
||||
{
|
||||
// Create a new buffer
|
||||
audioBuffer = device->CreateBuffer();
|
||||
if (!audioBuffer->Reset(m_format, m_sampleCount, m_sampleRate, m_samples.get()))
|
||||
throw std::runtime_error("failed to initialize audio buffer");
|
||||
}
|
||||
|
||||
it = m_audioBufferByDevice.emplace(device, AudioDeviceEntry{}).first;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user