112 lines
3.2 KiB
C++
112 lines
3.2 KiB
C++
#ifndef DESTRUM_AUDIOSYSTEM_H
|
|
#define DESTRUM_AUDIOSYSTEM_H
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <unordered_map>
|
|
#include <unordered_set>
|
|
#include <vector>
|
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include <destrum/Singleton.h>
|
|
|
|
struct AudioData;
|
|
struct ALCdevice;
|
|
struct ALCcontext;
|
|
class Camera;
|
|
|
|
class AudioClip {
|
|
public:
|
|
AudioClip(std::string path, std::uint32_t buffer, int channels, int sampleRate, float duration);
|
|
~AudioClip();
|
|
|
|
AudioClip(const AudioClip&) = delete;
|
|
AudioClip& operator=(const AudioClip&) = delete;
|
|
|
|
[[nodiscard]] const std::string& GetPath() const { return m_Path; }
|
|
[[nodiscard]] std::uint32_t GetBuffer() const { return m_Buffer; }
|
|
[[nodiscard]] int GetChannels() const { return m_Channels; }
|
|
[[nodiscard]] int GetSampleRate() const { return m_SampleRate; }
|
|
[[nodiscard]] float GetDuration() const { return m_Duration; }
|
|
|
|
private:
|
|
std::string m_Path;
|
|
std::uint32_t m_Buffer{0};
|
|
int m_Channels{0};
|
|
int m_SampleRate{0};
|
|
float m_Duration{0.0f};
|
|
};
|
|
|
|
[[nodiscard]] glm::vec3 SmoothAudioVelocity(const glm::vec3& current, const glm::vec3& previous,
|
|
const glm::vec3& smoothed, float dt);
|
|
|
|
struct OneShotParams {
|
|
float volume{1.0f};
|
|
float pitch{1.0f};
|
|
bool spatial{true};
|
|
float minDistance{1.0f};
|
|
float maxDistance{50.0f};
|
|
};
|
|
|
|
class AudioSystem final : public Singleton<AudioSystem> {
|
|
public:
|
|
friend class Singleton<AudioSystem>;
|
|
|
|
~AudioSystem() override;
|
|
|
|
bool Init();
|
|
void Shutdown();
|
|
[[nodiscard]] bool IsAvailable() const { return m_Context != nullptr; }
|
|
|
|
std::shared_ptr<const AudioClip> LoadClip(std::string_view vpath);
|
|
std::shared_ptr<const AudioClip> CreateClip(std::string path, const AudioData& data);
|
|
void ReleaseUnusedClips();
|
|
|
|
std::uint32_t CreateSource();
|
|
void DestroySource(std::uint32_t source);
|
|
|
|
void PlayOneShot(std::string_view vpath, const glm::vec3& position, const OneShotParams& params = {});
|
|
|
|
void SetListener(const glm::vec3& position, const glm::vec3& forward, const glm::vec3& up);
|
|
|
|
void Update(float dt, bool paused, const Camera* fallbackListener);
|
|
|
|
void SetMasterVolume(float volume);
|
|
[[nodiscard]] float GetMasterVolume() const { return m_MasterVolume; }
|
|
[[nodiscard]] bool IsPaused() const { return m_Paused; }
|
|
|
|
private:
|
|
AudioSystem() = default;
|
|
|
|
void SetPaused(bool paused);
|
|
|
|
struct OneShot {
|
|
std::uint32_t source{0};
|
|
std::shared_ptr<const AudioClip> clip;
|
|
};
|
|
|
|
ALCdevice* m_Device{nullptr};
|
|
ALCcontext* m_Context{nullptr};
|
|
|
|
std::unordered_map<std::string, std::shared_ptr<const AudioClip>> m_Clips;
|
|
std::unordered_set<std::uint32_t> m_Sources;
|
|
std::vector<std::uint32_t> m_PausedSources;
|
|
std::vector<OneShot> m_OneShots;
|
|
|
|
glm::vec3 m_ListenerPosition{0.0f};
|
|
glm::vec3 m_ListenerForward{0.0f, 0.0f, -1.0f};
|
|
glm::vec3 m_ListenerUp{0.0f, 1.0f, 0.0f};
|
|
glm::vec3 m_LastListenerPosition{0.0f};
|
|
glm::vec3 m_ListenerVelocity{0.0f};
|
|
bool m_HasLastListenerPosition{false};
|
|
bool m_ListenerSetThisFrame{false};
|
|
|
|
float m_MasterVolume{1.0f};
|
|
bool m_Paused{false};
|
|
};
|
|
|
|
#endif // DESTRUM_AUDIOSYSTEM_H
|