Game Audio Module
A C++ audio system using miniaudio with Python bindings
Loading...
Searching...
No Matches
audio_manager.h
Go to the documentation of this file.
1#pragma once
2
3#include <atomic>
4#include <mutex>
5#include <thread>
6#include <unordered_set>
7#include <unordered_map>
8#include <chrono>
9#include <string>
10#include <memory>
11#include <vector>
12#include <stdexcept>
13#include <random>
14#include <functional>
15#include "logging.h"
16#include "vec3.h"
17
18#ifdef PlaySound
19#undef PlaySound
20#endif
21
30namespace audio {
31
35class AudioException : public std::runtime_error {
36public:
37 explicit AudioException(const std::string& message)
38 : std::runtime_error(message) {}
39};
40
45public:
46 explicit InvalidHandleException(const std::string& message)
47 : AudioException(message) {}
48};
49
54public:
55 explicit FileLoadException(const std::string& message)
56 : AudioException(message) {}
57};
58
63public:
64 explicit NotInitializedException(const std::string& message)
65 : AudioException(message) {}
66};
67
68} // namespace audio
69
70// Forward declarations
71namespace audio {
72 class AudioSystem;
73 class AudioTrack;
74 class AudioGroup;
75 class Sound;
76}
77
78// Place std type usage in global namespace
79using ::std::atomic;
80using ::std::mutex;
81using ::std::thread;
82using ::std::unordered_set;
83using ::std::unordered_map;
84using ::std::string;
85using ::std::unique_ptr;
86using ::std::shared_ptr;
87using namespace ::std::chrono_literals;
88
89namespace audio {
90
101 uint32_t value{0};
102
103 static constexpr TrackHandle Invalid() { return TrackHandle{0}; }
104 constexpr bool IsValid() const { return value != 0; }
105 constexpr uint32_t Value() const { return value; }
106 explicit constexpr operator bool() const { return IsValid(); }
107 friend constexpr bool operator==(const TrackHandle&, const TrackHandle&) = default;
108};
109
114 uint32_t value{0};
115
116 static constexpr GroupHandle Invalid() { return GroupHandle{0}; }
117 constexpr bool IsValid() const { return value != 0; }
118 constexpr uint32_t Value() const { return value; }
119 explicit constexpr operator bool() const { return IsValid(); }
120 friend constexpr bool operator==(const GroupHandle&, const GroupHandle&) = default;
121};
122
127 uint32_t value{0};
128
129 static constexpr SoundHandle Invalid() { return SoundHandle{0}; }
130 constexpr bool IsValid() const { return value != 0; }
131 constexpr uint32_t Value() const { return value; }
132 explicit constexpr operator bool() const { return IsValid(); }
133 friend constexpr bool operator==(const SoundHandle&, const SoundHandle&) = default;
134};
135
136} // namespace audio
137
138namespace std {
139template <>
140struct hash<audio::TrackHandle> {
141 size_t operator()(const audio::TrackHandle& handle) const noexcept {
142 return std::hash<uint32_t>{}(handle.Value());
143 }
144};
145
146template <>
147struct hash<audio::GroupHandle> {
148 size_t operator()(const audio::GroupHandle& handle) const noexcept {
149 return std::hash<uint32_t>{}(handle.Value());
150 }
151};
152
153template <>
154struct hash<audio::SoundHandle> {
155 size_t operator()(const audio::SoundHandle& handle) const noexcept {
156 return std::hash<uint32_t>{}(handle.Value());
157 }
158};
159} // namespace std
160
161namespace audio {
162
180public:
186 static AudioManager& GetInstance();
187
190
200 bool Initialize();
201
208 void Shutdown();
210
213
219 void SetMasterVolume(float volume);
220
226 float GetMasterVolume() const;
227
233 static void SetLogLevel(LogLevel level);
234
238 static LogLevel GetLogLevel();
240
243
253
261 void DestroyTrack(TrackHandle track);
262
272 void PlayTrack(TrackHandle track);
273
282 void StopTrack(TrackHandle track);
283
285
288
302 void AddLayer(TrackHandle track, const string& layerName, const string& filepath, GroupHandle group = GroupHandle::Invalid());
303
310 void RemoveLayer(TrackHandle track, const string& layerName);
311
319 void SetLayerVolume(TrackHandle track, const string& layerName, float volume);
320
329 void FadeLayer(TrackHandle track, const string& layerName, float targetVolume, std::chrono::milliseconds duration);
331
334
345
351 void DestroyGroup(GroupHandle group);
352
362 void SetGroupVolume(GroupHandle group, float volume);
363
370 float GetGroupVolume(GroupHandle group) const;
371
379 void FadeGroup(GroupHandle group, float targetVolume, std::chrono::milliseconds duration);
381
384
392 SoundHandle LoadSound(const string& filepath);
393
402 SoundHandle LoadSound(const string& filepath, GroupHandle group);
403
409 void DestroySound(SoundHandle sound);
410
426 void PlaySound(SoundHandle sound);
427
442 void PlaySound(SoundHandle sound, const Vec3& position);
443
450 void StopSound(SoundHandle sound);
451
459 void SetSoundVolume(SoundHandle sound, float volume);
460
467 void SetSoundPitch(SoundHandle sound, float pitch);
468
476 void SetSoundLooping(SoundHandle sound, bool should_loop);
477
484 bool IsSoundPlaying(SoundHandle sound) const;
485
497 void PlayRandomSoundFromFolder(const string& folderPath, GroupHandle group = GroupHandle::Invalid());
499
502
534 void SetListenerPosition(const Vec3& position, uint32_t listenerIndex = 0);
535
542 Vec3 GetListenerPosition(uint32_t listenerIndex = 0) const;
543
553 void SetListenerDirection(const Vec3& direction, uint32_t listenerIndex = 0);
554
561 Vec3 GetListenerDirection(uint32_t listenerIndex = 0) const;
562
572 void SetListenerUp(const Vec3& up, uint32_t listenerIndex = 0);
573
580 Vec3 GetListenerUp(uint32_t listenerIndex = 0) const;
581
609 void SetSoundPosition(SoundHandle sound, const Vec3& position);
610
618 Vec3 GetSoundPosition(SoundHandle sound) const;
619
630 void SetSoundMinDistance(SoundHandle sound, float minDistance);
631
639 float GetSoundMinDistance(SoundHandle sound) const;
640
650 void SetSoundMaxDistance(SoundHandle sound, float maxDistance);
651
659 float GetSoundMaxDistance(SoundHandle sound) const;
660
671 void SetSoundRolloff(SoundHandle sound, float rolloff);
672
680 float GetSoundRolloff(SoundHandle sound) const;
681
689 void SetSoundSpatializationEnabled(SoundHandle sound, bool enabled);
690
700
706 bool IsInitialized() const { return running_.load(); }
707
708private:
712 AudioManager();
713
718
719 // Disable copy and assignment
720 AudioManager(const AudioManager&) = delete;
722
728 void EnsureInitialized() const;
729
732
738
744
751
754 unique_ptr<AudioSystem> audio_system_;
755 unordered_map<TrackHandle, unique_ptr<AudioTrack>> tracks_;
756 unordered_map<GroupHandle, unique_ptr<AudioGroup>> groups_;
757 unordered_map<SoundHandle, unique_ptr<Sound>> sounds_;
758 unordered_map<string, std::vector<SoundHandle>> folder_sounds_;
760
763 atomic<bool> running_{false};
765 mutable mutex resource_mutex_;
766 std::mt19937 rng_{std::random_device{}()};
768
771 atomic<uint32_t> next_track_handle_{1};
772 atomic<uint32_t> next_group_handle_{1};
773 atomic<uint32_t> next_sound_handle_{1};
775};
776
777} // namespace audio
Exception thrown when an audio operation fails.
Definition audio_manager.h:35
AudioException(const std::string &message)
Definition audio_manager.h:37
Central manager for all audio functionality.
Definition audio_manager.h:179
void StopTrack(TrackHandle track)
Stop playing an audio track.
Definition audio_manager.cpp:222
void StopSound(SoundHandle sound)
Stop a currently playing sound.
Definition audio_manager.cpp:448
AudioManager(const AudioManager &)=delete
static LogLevel GetLogLevel()
Get the current audio log level.
Definition audio_manager.cpp:178
atomic< bool > running_
Flag indicating if audio system is running.
Definition audio_manager.h:763
std::mt19937 rng_
RNG for random playback.
Definition audio_manager.h:766
void EnsureInitialized() const
Ensures the audio system is initialized before use.
Definition audio_manager.cpp:55
void DestroyTrack(TrackHandle track)
Destroy an audio track.
Definition audio_manager.cpp:203
void DestroyGroup(GroupHandle group)
Destroy an audio group.
Definition audio_manager.cpp:318
void SetSoundMinDistance(SoundHandle sound, float minDistance)
Set the minimum distance for distance attenuation.
Definition audio_manager.cpp:697
atomic< uint32_t > next_group_handle_
Counter for generating unique group handles.
Definition audio_manager.h:772
~AudioManager()
Destructor.
Definition audio_manager.cpp:44
void SetSoundPitch(SoundHandle sound, float pitch)
Set the pitch of a sound for its next playback.
Definition audio_manager.cpp:470
bool IsInitialized() const
Check if the audio system is initialized and running.
Definition audio_manager.h:706
AudioManager & operator=(const AudioManager &)=delete
void SetListenerDirection(const Vec3 &direction, uint32_t listenerIndex=0)
Set the listener direction (forward vector)
Definition audio_manager.cpp:647
AudioManager()
Constructor - private due to singleton pattern.
Definition audio_manager.cpp:40
static void SetLogLevel(LogLevel level)
Set the global audio log level (runtime).
Definition audio_manager.cpp:174
float GetMasterVolume() const
Get the current master volume level.
Definition audio_manager.cpp:182
Vec3 GetListenerPosition(uint32_t listenerIndex=0) const
Get the listener position.
Definition audio_manager.cpp:640
void RemoveLayer(TrackHandle track, const string &layerName)
Remove a layer from a track.
Definition audio_manager.cpp:261
bool IsSoundSpatializationEnabled(SoundHandle sound) const
Check if spatialization is enabled for a sound.
Definition audio_manager.cpp:767
GroupHandle NextGroupHandle()
Generate a new group handle.
Definition audio_manager.h:743
void Shutdown()
Shut down the audio system.
Definition audio_manager.cpp:122
thread update_thread_
Thread for audio updates.
Definition audio_manager.h:764
void SetGroupVolume(GroupHandle group, float volume)
Set the volume for an entire audio group.
Definition audio_manager.cpp:327
bool Initialize()
Initialize the audio system.
Definition audio_manager.cpp:61
Vec3 GetSoundPosition(SoundHandle sound) const
Get the 3D position of a sound.
Definition audio_manager.cpp:687
void SetSoundVolume(SoundHandle sound, float volume)
Set the volume of a sound.
Definition audio_manager.cpp:458
void FadeGroup(GroupHandle group, float targetVolume, std::chrono::milliseconds duration)
Fade a group's volume to a target value over time.
Definition audio_manager.cpp:349
float GetGroupVolume(GroupHandle group) const
Get the current volume for an audio group.
Definition audio_manager.cpp:339
void SetSoundMaxDistance(SoundHandle sound, float maxDistance)
Set the maximum distance for distance attenuation.
Definition audio_manager.cpp:717
SoundHandle NextSoundHandle()
Generate a new sound handle.
Definition audio_manager.h:749
float GetSoundRolloff(SoundHandle sound) const
Get the rolloff factor of a sound.
Definition audio_manager.cpp:747
void DestroySound(SoundHandle sound)
Destroy a previously loaded sound.
Definition audio_manager.cpp:410
unordered_map< string, std::vector< SoundHandle > > folder_sounds_
Cached sounds per folder.
Definition audio_manager.h:758
mutex resource_mutex_
Mutex for thread-safe resource access (mutable for const methods)
Definition audio_manager.h:765
void SetListenerPosition(const Vec3 &position, uint32_t listenerIndex=0)
Set the listener position in 3D space.
Definition audio_manager.cpp:632
void SetSoundRolloff(SoundHandle sound, float rolloff)
Set the rolloff factor for distance attenuation.
Definition audio_manager.cpp:737
atomic< uint32_t > next_sound_handle_
Counter for generating unique sound handles.
Definition audio_manager.h:773
unique_ptr< AudioSystem > audio_system_
Core audio system.
Definition audio_manager.h:754
void SetSoundPosition(SoundHandle sound, const Vec3 &position)
Set the 3D position of a sound.
Definition audio_manager.cpp:677
unordered_map< SoundHandle, unique_ptr< Sound > > sounds_
Sound storage.
Definition audio_manager.h:757
unordered_map< TrackHandle, unique_ptr< AudioTrack > > tracks_
Track storage.
Definition audio_manager.h:755
void PlayRandomSoundFromFolder(const string &folderPath, GroupHandle group=GroupHandle::Invalid())
Play a random sound from a folder.
Definition audio_manager.cpp:499
void SetSoundLooping(SoundHandle sound, bool should_loop)
Set whether a sound should loop.
Definition audio_manager.cpp:479
Vec3 GetListenerUp(uint32_t listenerIndex=0) const
Get the listener up vector.
Definition audio_manager.cpp:670
void PlaySound(SoundHandle sound)
Play a sound.
Definition audio_manager.cpp:428
float GetSoundMinDistance(SoundHandle sound) const
Get the minimum distance of a sound.
Definition audio_manager.cpp:707
void AddLayer(TrackHandle track, const string &layerName, const string &filepath, GroupHandle group=GroupHandle::Invalid())
Add an audio layer to a track.
Definition audio_manager.cpp:233
TrackHandle NextTrackHandle()
Generate a new track handle.
Definition audio_manager.h:737
unordered_map< GroupHandle, unique_ptr< AudioGroup > > groups_
Group storage.
Definition audio_manager.h:756
bool IsSoundPlaying(SoundHandle sound) const
Check if a sound is currently playing.
Definition audio_manager.cpp:489
SoundHandle LoadSound(const string &filepath)
Load a sound from a file.
Definition audio_manager.cpp:363
void SetListenerUp(const Vec3 &up, uint32_t listenerIndex=0)
Set the listener up vector.
Definition audio_manager.cpp:662
void FadeLayer(TrackHandle track, const string &layerName, float targetVolume, std::chrono::milliseconds duration)
Fade a layer's volume to a target value over time.
Definition audio_manager.cpp:285
void SetLayerVolume(TrackHandle track, const string &layerName, float volume)
Set the volume of a specific layer.
Definition audio_manager.cpp:272
Vec3 GetListenerDirection(uint32_t listenerIndex=0) const
Get the listener direction.
Definition audio_manager.cpp:655
atomic< uint32_t > next_track_handle_
Counter for generating unique track handles.
Definition audio_manager.h:771
void SetMasterVolume(float volume)
Set the master volume for all audio.
Definition audio_manager.cpp:164
void SetSoundSpatializationEnabled(SoundHandle sound, bool enabled)
Enable or disable spatialization for a sound.
Definition audio_manager.cpp:757
TrackHandle CreateTrack()
Create a new audio track.
Definition audio_manager.cpp:190
GroupHandle CreateGroup()
Create a new audio group.
Definition audio_manager.cpp:299
static AudioManager & GetInstance()
Get the singleton instance of the AudioManager.
Definition audio_manager.cpp:50
void PlayTrack(TrackHandle track)
Start playing an audio track.
Definition audio_manager.cpp:212
float GetSoundMaxDistance(SoundHandle sound) const
Get the maximum distance of a sound.
Definition audio_manager.cpp:727
Exception thrown when a file cannot be loaded.
Definition audio_manager.h:53
FileLoadException(const std::string &message)
Definition audio_manager.h:55
Exception thrown when an invalid handle is used.
Definition audio_manager.h:44
InvalidHandleException(const std::string &message)
Definition audio_manager.h:46
Exception thrown when the audio system is not initialized.
Definition audio_manager.h:62
NotInitializedException(const std::string &message)
Definition audio_manager.h:64
Definition audio_group.cpp:7
LogLevel
Log severity levels for audio diagnostics.
Definition logging.h:18
STL namespace.
Strongly typed handle for audio groups.
Definition audio_manager.h:113
uint32_t value
Definition audio_manager.h:114
friend constexpr bool operator==(const GroupHandle &, const GroupHandle &)=default
constexpr bool IsValid() const
Definition audio_manager.h:117
static constexpr GroupHandle Invalid()
Definition audio_manager.h:116
constexpr uint32_t Value() const
Definition audio_manager.h:118
Strongly typed handle for individual sounds.
Definition audio_manager.h:126
constexpr bool IsValid() const
Definition audio_manager.h:130
friend constexpr bool operator==(const SoundHandle &, const SoundHandle &)=default
uint32_t value
Definition audio_manager.h:127
constexpr uint32_t Value() const
Definition audio_manager.h:131
static constexpr SoundHandle Invalid()
Definition audio_manager.h:129
Opaque handle types for audio objects.
Definition audio_manager.h:100
uint32_t value
Definition audio_manager.h:101
constexpr uint32_t Value() const
Definition audio_manager.h:105
friend constexpr bool operator==(const TrackHandle &, const TrackHandle &)=default
constexpr bool IsValid() const
Definition audio_manager.h:104
static constexpr TrackHandle Invalid()
Definition audio_manager.h:103
3D vector for spatial audio positioning
Definition vec3.h:46
size_t operator()(const audio::GroupHandle &handle) const noexcept
Definition audio_manager.h:148
size_t operator()(const audio::SoundHandle &handle) const noexcept
Definition audio_manager.h:155
size_t operator()(const audio::TrackHandle &handle) const noexcept
Definition audio_manager.h:141
3D vector class for spatial audio positioning