Audio: Add dummy device (in case OpenAL fails to load) and unifiate unit tests

This commit is contained in:
Jérôme Leclercq
2022-03-18 19:03:57 +01:00
parent efa2c0a253
commit 82641c6653
30 changed files with 809 additions and 107 deletions

View File

@@ -23,9 +23,9 @@ namespace Nz
public:
using Dependencies = TypeList<Core>;
struct Config {};
struct Config;
Audio(Config /*config*/);
Audio(Config config);
Audio(const Audio&) = delete;
Audio(Audio&&) = delete;
~Audio();
@@ -45,10 +45,17 @@ namespace Nz
Audio& operator=(const Audio&) = delete;
Audio& operator=(Audio&&) = delete;
struct Config
{
bool allowDummyDevice = true;
bool noAudio = false;
};
private:
std::shared_ptr<AudioDevice> m_defaultDevice;
SoundBufferLoader m_soundBufferLoader;
SoundStreamLoader m_soundStreamLoader;
bool m_hasDummyDevice;
static Audio* s_instance;
};

View File

@@ -25,8 +25,8 @@ namespace Nz
virtual ~AudioBuffer();
inline const std::shared_ptr<AudioDevice>& GetAudioDevice() const;
virtual UInt32 GetSampleCount() const = 0;
virtual UInt32 GetSize() const = 0;
virtual UInt64 GetSampleCount() const = 0;
virtual UInt64 GetSize() const = 0;
virtual UInt32 GetSampleRate() const = 0;
virtual bool IsCompatibleWith(const AudioDevice& device) const = 0;

View File

@@ -0,0 +1,47 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_AUDIO_DUMMYAUDIOBUFFER_HPP
#define NAZARA_AUDIO_DUMMYAUDIOBUFFER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Audio/AudioBuffer.hpp>
#include <Nazara/Audio/Config.hpp>
#include <Nazara/Audio/Enums.hpp>
namespace Nz
{
class NAZARA_AUDIO_API DummyAudioBuffer final : public AudioBuffer
{
public:
using AudioBuffer::AudioBuffer;
DummyAudioBuffer(const DummyAudioBuffer&) = delete;
DummyAudioBuffer(DummyAudioBuffer&&) = delete;
~DummyAudioBuffer() = default;
AudioFormat GetAudioFormat() const;
UInt32 GetDuration() const;
UInt64 GetSampleCount() const override;
UInt64 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;
DummyAudioBuffer& operator=(const DummyAudioBuffer&) = delete;
DummyAudioBuffer& operator=(DummyAudioBuffer&&) = delete;
private:
AudioFormat m_format;
UInt64 m_sampleCount;
UInt32 m_sampleRate;
};
}
#include <Nazara/Audio/DummyAudioBuffer.inl>
#endif // NAZARA_AUDIO_DUMMYAUDIOBUFFER_HPP

View File

@@ -0,0 +1,12 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Audio/DummyAudioBuffer.hpp>
#include <Nazara/Audio/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Audio/DebugOff.hpp>

View File

@@ -0,0 +1,63 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_AUDIO_DUMMYAUDIODEVICE_HPP
#define NAZARA_AUDIO_DUMMYAUDIODEVICE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Audio/AudioDevice.hpp>
#include <Nazara/Audio/Config.hpp>
#include <Nazara/Audio/Enums.hpp>
#include <array>
#include <string>
namespace Nz
{
class NAZARA_AUDIO_API DummyAudioDevice : public AudioDevice
{
public:
DummyAudioDevice();
DummyAudioDevice(const DummyAudioDevice&) = delete;
DummyAudioDevice(DummyAudioDevice&&) = default;
~DummyAudioDevice() = default;
std::shared_ptr<AudioBuffer> CreateBuffer() override;
std::shared_ptr<AudioSource> CreateSource() override;
float GetDopplerFactor() const override;
float GetGlobalVolume() const override;
Vector3f GetListenerDirection(Vector3f* up = nullptr) const override;
Vector3f GetListenerPosition() 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;
void SetDopplerFactor(float dopplerFactor) override;
void SetGlobalVolume(float volume) override;
void SetListenerDirection(const Vector3f& direction, const Vector3f& up = Vector3f::Up()) override;
void SetListenerPosition(const Vector3f& position) override;
void SetListenerVelocity(const Vector3f& velocity) override;
void SetSpeedOfSound(float speed) override;
DummyAudioDevice& operator=(const DummyAudioDevice&) = delete;
DummyAudioDevice& operator=(DummyAudioDevice&&) = default;
private:
Quaternionf m_listenerRotation;
Vector3f m_listenerVelocity;
Vector3f m_listenerPosition;
float m_dopplerFactor;
float m_globalVolume;
float m_speedOfSound;
};
}
#include <Nazara/Audio/DummyAudioDevice.inl>
#endif // NAZARA_AUDIO_DUMMYAUDIODEVICE_HPP

View File

@@ -0,0 +1,12 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Audio/DummyAudioDevice.hpp>
#include <Nazara/Audio/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Audio/DebugOff.hpp>

View File

@@ -0,0 +1,86 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_AUDIO_DUMMYAUDIOSOURCE_HPP
#define NAZARA_AUDIO_DUMMYAUDIOSOURCE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Audio/AudioSource.hpp>
#include <Nazara/Audio/Config.hpp>
#include <Nazara/Core/Clock.hpp>
namespace Nz
{
class DummyAudioBuffer;
class NAZARA_AUDIO_API DummyAudioSource final : public AudioSource
{
public:
inline DummyAudioSource(std::shared_ptr<AudioDevice> device);
DummyAudioSource(const DummyAudioSource&) = delete;
DummyAudioSource(DummyAudioSource&&) = delete;
~DummyAudioSource() = default;
void EnableLooping(bool loop) override;
void EnableSpatialization(bool spatialization) override;
float GetAttenuation() const override;
float GetMinDistance() const override;
float GetPitch() const override;
Vector3f GetPosition() const override;
UInt32 GetSampleOffset() const override;
Vector3f GetVelocity() const override;
SoundStatus GetStatus() const override;
float GetVolume() const override;
bool IsLooping() const override;
bool IsSpatializationEnabled() const override;
void QueueBuffer(std::shared_ptr<AudioBuffer> audioBuffer) override;
void Pause() override;
void Play() override;
void SetAttenuation(float attenuation) override;
void SetBuffer(std::shared_ptr<AudioBuffer> audioBuffer) override;
void SetMinDistance(float minDistance) override;
void SetPitch(float pitch) override;
void SetPosition(const Vector3f& position) override;
void SetSampleOffset(UInt32 offset) override;
void SetVelocity(const Vector3f& velocity) override;
void SetVolume(float volume) override;
void Stop() override;
std::shared_ptr<AudioBuffer> TryUnqueueProcessedBuffer() override;
void UnqueueAllBuffers() override;
DummyAudioSource& operator=(const DummyAudioSource&) = delete;
DummyAudioSource& operator=(DummyAudioSource&&) = delete;
private:
void RequeueBuffers();
UInt64 UpdateTime() const;
mutable std::vector<std::shared_ptr<DummyAudioBuffer>> m_queuedBuffers;
mutable std::vector<std::shared_ptr<DummyAudioBuffer>> m_processedBuffers;
mutable Clock m_playClock;
mutable SoundStatus m_status;
Vector3f m_position;
Vector3f m_velocity;
bool m_isLooping;
bool m_isSpatialized;
float m_attenuation;
float m_minDistance;
float m_pitch;
float m_volume;
};
}
#include <Nazara/Audio/DummyAudioSource.inl>
#endif // NAZARA_AUDIO_DUMMYAUDIOSOURCE_HPP

View File

@@ -0,0 +1,26 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Audio/DummyAudioSource.hpp>
#include <Nazara/Audio/Debug.hpp>
namespace Nz
{
inline DummyAudioSource::DummyAudioSource(std::shared_ptr<AudioDevice> device) :
AudioSource(std::move(device)),
m_playClock(0, true),
m_status(SoundStatus::Stopped),
m_position(Vector3f::Zero()),
m_velocity(Vector3f::Zero()),
m_isLooping(false),
m_isSpatialized(true),
m_attenuation(1.f),
m_minDistance(1.f),
m_pitch(1.f),
m_volume(1.f)
{
}
}
#include <Nazara/Audio/DebugOff.hpp>

View File

@@ -73,7 +73,8 @@ namespace Nz
bool m_looping;
bool FillAndQueueBuffer(std::shared_ptr<AudioBuffer> buffer);
void MusicThread(std::condition_variable& cv, std::mutex& m, std::exception_ptr& err);
void MusicThread(std::condition_variable& cv, std::mutex& m, std::exception_ptr& err, bool startPaused);
void StartThread(bool startPaused);
void StopThread();
};
}

View File

@@ -28,8 +28,8 @@ namespace Nz
~OpenALBuffer();
inline ALuint GetBufferId() const;
UInt32 GetSampleCount() const override;
UInt32 GetSize() const override;
UInt64 GetSampleCount() const override;
UInt64 GetSize() const override;
UInt32 GetSampleRate() const override;
bool IsCompatibleWith(const AudioDevice& device) const override;

View File

@@ -28,6 +28,8 @@ namespace Nz
OpenALLibrary(OpenALLibrary&&) = delete;
inline ~OpenALLibrary();
inline bool IsLoaded() const;
bool Load();
std::vector<std::string> QueryInputDevices();
@@ -49,6 +51,7 @@ namespace Nz
std::vector<std::string> ParseDevices(const char* deviceString);
DynLib m_library;
bool m_hasCaptureSupport;
};
}

View File

@@ -11,6 +11,11 @@ namespace Nz
{
Unload();
}
inline bool OpenALLibrary::IsLoaded() const
{
return m_library.IsLoaded();
}
}
#include <Nazara/Audio/DebugOff.hpp>

View File

@@ -26,7 +26,7 @@ namespace Nz
bool IsPaused() const;
void Pause();
UInt64 Restart();
UInt64 Restart(UInt64 startingValue = 0, bool paused = false);
void Unpause();
Clock& operator=(const Clock& clock) = default;

View File

@@ -43,7 +43,7 @@ namespace Nz
struct Config
{
Nz::RenderAPI preferredAPI = RenderAPI::Unknown;
RenderAPI preferredAPI = RenderAPI::Unknown;
};
private: