Audio: Handle AudioBuffer compatibility
OpenAL buffers are shared between contextes
This commit is contained in:
parent
01061380ee
commit
667a4a0c08
|
|
@ -29,6 +29,8 @@ namespace Nz
|
|||
virtual UInt32 GetSize() const = 0;
|
||||
virtual UInt32 GetSampleRate() const = 0;
|
||||
|
||||
virtual bool IsCompatibleWith(const AudioDevice& device) const = 0;
|
||||
|
||||
virtual bool Reset(AudioFormat format, UInt64 sampleCount, UInt32 sampleRate, const void* samples) = 0;
|
||||
|
||||
AudioBuffer& operator=(const AudioBuffer&) = default;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ namespace Nz
|
|||
virtual Quaternionf GetListenerRotation() const = 0;
|
||||
virtual Vector3f GetListenerVelocity() const = 0;
|
||||
virtual float GetSpeedOfSound() const = 0;
|
||||
virtual const void* GetSubSystemIdentifier() const = 0;
|
||||
|
||||
virtual bool IsFormatSupported(AudioFormat format) const = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ namespace Nz
|
|||
UInt32 GetSize() const override;
|
||||
UInt32 GetSampleRate() const override;
|
||||
|
||||
bool IsCompatibleWith(const AudioDevice& device) const override;
|
||||
|
||||
bool Reset(AudioFormat format, UInt64 sampleCount, UInt32 sampleRate, const void* samples) override;
|
||||
|
||||
OpenALBuffer& operator=(const OpenALBuffer&) = delete;
|
||||
|
|
|
|||
|
|
@ -39,9 +39,10 @@ namespace Nz
|
|||
float GetGlobalVolume() const override;
|
||||
Vector3f GetListenerDirection(Vector3f* up = nullptr) const override;
|
||||
Vector3f GetListenerPosition() const override;
|
||||
Quaternionf GetListenerRotation(Vector3f* up = nullptr) const override;
|
||||
Quaternionf GetListenerRotation() const override;
|
||||
Vector3f GetListenerVelocity() const override;
|
||||
float GetSpeedOfSound() const override;
|
||||
const void* GetSubSystemIdentifier() const override;
|
||||
|
||||
bool IsFormatSupported(AudioFormat format) const override;
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ namespace Nz
|
|||
SoundBuffer(SoundBuffer&&) = delete;
|
||||
~SoundBuffer() = default;
|
||||
|
||||
const std::shared_ptr<AudioBuffer>& GetBuffer(AudioDevice* device);
|
||||
const std::shared_ptr<AudioBuffer>& GetAudioBuffer(AudioDevice* device);
|
||||
|
||||
inline UInt32 GetDuration() const;
|
||||
inline AudioFormat GetFormat() const;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue