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 GetSize() const = 0;
|
||||||
virtual UInt32 GetSampleRate() 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;
|
virtual bool Reset(AudioFormat format, UInt64 sampleCount, UInt32 sampleRate, const void* samples) = 0;
|
||||||
|
|
||||||
AudioBuffer& operator=(const AudioBuffer&) = default;
|
AudioBuffer& operator=(const AudioBuffer&) = default;
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ namespace Nz
|
||||||
virtual Quaternionf GetListenerRotation() const = 0;
|
virtual Quaternionf GetListenerRotation() const = 0;
|
||||||
virtual Vector3f GetListenerVelocity() const = 0;
|
virtual Vector3f GetListenerVelocity() const = 0;
|
||||||
virtual float GetSpeedOfSound() const = 0;
|
virtual float GetSpeedOfSound() const = 0;
|
||||||
|
virtual const void* GetSubSystemIdentifier() const = 0;
|
||||||
|
|
||||||
virtual bool IsFormatSupported(AudioFormat format) const = 0;
|
virtual bool IsFormatSupported(AudioFormat format) const = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ namespace Nz
|
||||||
UInt32 GetSize() const override;
|
UInt32 GetSize() const override;
|
||||||
UInt32 GetSampleRate() 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;
|
bool Reset(AudioFormat format, UInt64 sampleCount, UInt32 sampleRate, const void* samples) override;
|
||||||
|
|
||||||
OpenALBuffer& operator=(const OpenALBuffer&) = delete;
|
OpenALBuffer& operator=(const OpenALBuffer&) = delete;
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,10 @@ namespace Nz
|
||||||
float GetGlobalVolume() const override;
|
float GetGlobalVolume() const override;
|
||||||
Vector3f GetListenerDirection(Vector3f* up = nullptr) const override;
|
Vector3f GetListenerDirection(Vector3f* up = nullptr) const override;
|
||||||
Vector3f GetListenerPosition() const override;
|
Vector3f GetListenerPosition() const override;
|
||||||
Quaternionf GetListenerRotation(Vector3f* up = nullptr) const override;
|
Quaternionf GetListenerRotation() const override;
|
||||||
Vector3f GetListenerVelocity() const override;
|
Vector3f GetListenerVelocity() const override;
|
||||||
float GetSpeedOfSound() const override;
|
float GetSpeedOfSound() const override;
|
||||||
|
const void* GetSubSystemIdentifier() const override;
|
||||||
|
|
||||||
bool IsFormatSupported(AudioFormat format) const override;
|
bool IsFormatSupported(AudioFormat format) const override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ namespace Nz
|
||||||
SoundBuffer(SoundBuffer&&) = delete;
|
SoundBuffer(SoundBuffer&&) = delete;
|
||||||
~SoundBuffer() = default;
|
~SoundBuffer() = default;
|
||||||
|
|
||||||
const std::shared_ptr<AudioBuffer>& GetBuffer(AudioDevice* device);
|
const std::shared_ptr<AudioBuffer>& GetAudioBuffer(AudioDevice* device);
|
||||||
|
|
||||||
inline UInt32 GetDuration() const;
|
inline UInt32 GetDuration() const;
|
||||||
inline AudioFormat GetFormat() const;
|
inline AudioFormat GetFormat() const;
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,12 @@ namespace Nz
|
||||||
return SafeCast<UInt32>(sampleRate);
|
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)
|
bool OpenALBuffer::Reset(AudioFormat format, UInt64 sampleCount, UInt32 sampleRate, const void* samples)
|
||||||
{
|
{
|
||||||
OpenALDevice& device = GetDevice();
|
OpenALDevice& device = GetDevice();
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,11 @@ namespace Nz
|
||||||
return m_library.alGetFloat(AL_SPEED_OF_SOUND);
|
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
|
* \brief Checks whether the format is supported by the engine
|
||||||
* \return true if it is the case
|
* \return true if it is the case
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ namespace Nz
|
||||||
void OpenALSource::QueueBuffer(std::shared_ptr<AudioBuffer> audioBuffer)
|
void OpenALSource::QueueBuffer(std::shared_ptr<AudioBuffer> audioBuffer)
|
||||||
{
|
{
|
||||||
NazaraAssert(audioBuffer, "invalid buffer");
|
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));
|
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)
|
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));
|
std::shared_ptr<OpenALBuffer> newBuffer = std::static_pointer_cast<OpenALBuffer>(std::move(audioBuffer));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ namespace Nz
|
||||||
Stop();
|
Stop();
|
||||||
|
|
||||||
m_buffer = std::move(buffer);
|
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));
|
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);
|
auto it = m_audioBufferByDevice.find(device);
|
||||||
if (it == m_audioBufferByDevice.end())
|
if (it == m_audioBufferByDevice.end())
|
||||||
{
|
{
|
||||||
auto audioBuffer = device->CreateBuffer();
|
// Try to find an existing compatible buffer
|
||||||
if (!audioBuffer->Reset(m_format, m_sampleCount, m_sampleRate, m_samples.get()))
|
std::shared_ptr<AudioBuffer> audioBuffer;
|
||||||
throw std::runtime_error("failed to initialize audio buffer");
|
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;
|
it = m_audioBufferByDevice.emplace(device, AudioDeviceEntry{}).first;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue