|
Vulkan Schnee 0.0.1 (22840dc8)
High-performance rendering engine
|
Audio uses miniaudio for decoding and playback and Steam Audio for binaural HRTF spatialization. The HRTF listener follows the headset each frame, and spatial sources are played at world positions through the audio engine.
| Component | File | Purpose |
|---|---|---|
| Audio | Engine/include/Engine/Audio/AudioAsset.h | Stores decoded PCM and clip metadata |
| AudioClipHandle | Engine/include/Engine/Asset/AssetHandles.h | Stable typed handle stored by gameplay code |
| AudioClipStore | Engine/include/Engine/Asset/AssetRegistry.h | Creates handles and requests backing audio payloads |
| AudioAssetRef | Engine/include/Engine/Audio/AudioAssetRef.h | Legacy ref used to inspect the backing payload and loading state |
| AudioLoader | Engine/include/Engine/Audio/AudioLoader.h | Decodes WAV, FLAC, and MP3 through miniaudio |
| AudioAssetPipeline | Engine/include/Engine/Ecs/AudioAssetPipeline.h | Async decode pipeline |
| AudioEngine | Engine/include/Engine/Audio/AudioEngine.h | Owns ma_engine, registers loaded clips, starts and stops playback |
Gameplay code should get audio handles from the scene's AssetRegistry.
AudioClipStore::load() is a get-or-create operation. It immediately returns the stable handle for the path and requests asynchronous decoding when it creates a new handle. Calling it repeatedly with the same path returns the same handle and does not restart an active or completed load.
AssetManager::getAsset<Engine::Assets::Audio>() is the legacy payload-facing API. Use it only when code specifically needs an AudioAssetRef; do not store that ref as the asset's gameplay identity.
AudioAssetPipeline runs once per frame from EngineKern::processResourceLoadingPipelines().
The pipeline has two stages.
| Stage | Work |
|---|---|
| submitDecodeJobs() | Move queued paths to worker futures and call AudioLoader::load() |
| retrieveDecodedAudio() | Poll ready futures, create Audio assets, resolve records, notify AudioEngine |
Decoded audio is stored directly on Engine::Assets::Audio.
Audio does not use hidden ECS entities for PCM storage. Audio::setAudioData() moves decoded PCM into the asset object and marks it loaded.
Asset loading and playback are separate.
AudioEngine::play() resolves the handle through AudioClipStore. It returns INVALID_AUDIO_HANDLE when the handle is invalid or its payload has not finished loading. The path overload remains available for legacy callers.
Spatial playback uses AudioEngine::playSpatialized() with a world position. AudioEngine::updateSpatializedSource() moves a playing source to a new position, for example when the emitting actor moves.
Store the typed handle on the actor and pass it directly to AudioEngine.
| Area | Current State |
|---|---|
| Asset access | Gameplay stores AudioClipHandle; payload readiness uses legacy AudioAssetRef |
| Playback access | Accepts AudioClipHandle; a path overload remains for legacy callers |
| Spatial audio | Implemented. AudioEngine::playSpatialized() plays at a world position through the Steam Audio HRTF backend; updateSpatializedSource() moves a playing source. The listener follows the headset each frame |
| Streaming music | Not implemented; clips decode fully into memory |
| ECS audio source/listener components | No dedicated source/listener ECS component; gameplay drives spatial sources from actors via AudioEngine::playSpatialized() |
| Cleanup | AssetManager::unloadAllData() clears audio asset records with the other asset managers |
Spatial playback uses AudioClipHandle and the Steam Audio HRTF backend. Future work can wrap this in a dedicated audio source component.
miniaudio uses values from Engine/include/Engine/Audio/AudioConfig.h.
| Setting | Value |
|---|---|
| Sample rate | Engine::Core::Audio::SAMPLE_RATE |
| Frame size | Engine::Core::Audio::FRAME_SIZE |
| Output channels | Engine::Core::Audio::OUTPUT_CHANNELS |