text// AudioManager is a lazy singleton: it initializes on the first Audio() ever createdmain.cpp
│
├── Audio sfx { "assets/jump.wav" } ← first Audio() lazily creates AudioManager
│ ├── AudioManager::getInstance() ← inits the shared miniaudio ma_engine (once)
│ └── ResourceManager::loadResource<ResourceAudio>()
│ └── pool of `poolSize` ma_sound voices, each fully decoded from the file
│
└── (program exit)
└── ~AudioManager() ← ma_engine_uninit(), runs at static destruction
C++#include <darkmoon/audio.hpp>
int main() {
DarkMoonEngine dm{};
Window win = Window(800, 600, "Audio Example");
Audio music("assets/theme.ogg", 1); // poolSize 1: no overlap needed for music
music.setLooping(true);
music.setVolume(0.6f);
music.play();
while(!win.ShouldClose()){
win.BeginDrawing(BLACK);
win.EndDrawing();
}
}
textplay()
│
├── pickVoice() ← scans the pool for a voice NOT currently playing
│ ├── found free voice → use it
│ └── none free → reuse the next voice round-robin (cuts it off)
│
└── stop + seek to 0 + apply volume/looping + start
C++#include <darkmoon/audio.hpp>
int main(){
DarkMoonEngine dm{};
Window win = Window(800, 600, "Voice Pool Example");
// poolSize 8: up to 8 overlapping hits before voices start getting cut off
Audio hit("assets/hit.wav", 8);
while(!win.ShouldClose()){
// Hold the key: every frame it's held triggers a new overlapping voiceif(win.IsKeyDown(KEY_X))
hit.play();
win.BeginDrawing(BLACK);
win.EndDrawing();
}
}
C++#include <darkmoon/audio.hpp>
int main(){
DarkMoonEngine dm{};
Window win = Window(800, 600, "Music Example");
Audio music("assets/theme.ogg", 1);
music.setLooping(true);
music.setVolume(0.5f);
music.play();
while(!win.ShouldClose()){
if(win.IsKeyPressed(KEY_UP))
music.setVolume(0.8f);
if(win.IsKeyPressed(KEY_DOWN))
music.setVolume(0.3f);
// NOTE: stops the track entirely, does NOT pause/resume (see "Playback lifecycle")if(win.IsKeyPressed(KEY_P))
music.pause();
win.BeginDrawing(BLACK);
win.EndDrawing();
}
}