vkmEngine 1.0.0
A C++ game engine · vkmengine.com
Loading...
Searching...
No Matches
audio_device.h
1#pragma once
2
3#include <algorithm>
4#include <cmath>
5#include <cstdint>
6#include <memory>
7
8#include <glm/glm.hpp>
9
10namespace Vkm::Engine {
11
12struct AudioClipAsset;
13
17using VoiceId = uint32_t;
18
25inline constexpr size_t MAX_ACTIVE_VOICES = 128;
26
39 float volume = 1.0f;
40 float pitch = 1.0f;
41 bool loop = false;
42 bool spatial = true;
43 glm::vec3 position = {0.0f, 0.0f, 0.0f};
44 float minDistance = 1.0f;
45 float maxDistance = 50.0f;
46
54 float heardMinDistance() const { return std::isfinite(minDistance) ? std::max(0.0f, minDistance) : 0.0f; }
55
61 float heardMaxDistance() const { return std::isfinite(maxDistance) ? std::max(0.0f, maxDistance) : 0.0f; }
62
68 bool hasFar() const { return heardMaxDistance() > heardMinDistance(); }
69};
70
80class AudioDevice {
81 public:
82 AudioDevice();
83 ~AudioDevice();
84
85 AudioDevice(const AudioDevice& other) = delete;
86 AudioDevice& operator=(const AudioDevice& other) = delete;
87
88 AudioDevice(AudioDevice && other) = delete;
89 AudioDevice& operator=(AudioDevice && other) = delete;
90
91 public:
99 bool open();
100
110 bool openOffline(uint32_t sampleRate, uint32_t channels);
111
115 void close();
116
127 uint64_t render(float* frames, uint64_t frameCount);
128
137 VoiceId play(const AudioClipAsset& clip, const VoiceParams& params);
138
145 void updateVoice(VoiceId voice, const VoiceParams& params);
146
156 bool isVoiceActive(VoiceId voice) const;
157
166 void pauseVoice(VoiceId voice);
167
175 void resumeVoice(VoiceId voice);
176
183 bool isVoicePaused(VoiceId voice) const;
184
195 float voiceCursor(VoiceId voice) const;
196
207 void seekVoice(VoiceId voice, float seconds);
208
217 void stopVoice(VoiceId voice);
218
226
234
242
249
255 size_t voiceCount() const;
256
265 void setListener(const glm::vec3& position, const glm::vec3& forward, const glm::vec3& up);
266
274 void setListenerActive(bool active);
275
281 void setMasterVolume(float volume);
282
283 public:
284 bool isOpen() const noexcept { return m_backend != nullptr; }
285
291 float masterVolume() const noexcept { return m_masterVolume; }
292
293 private:
294 // ma_engine, the voice table and each voice's sound; held by pointer so
295 // miniaudio's header stays out of this one.
296 struct Backend;
297
298 private:
305 void reopenLostDevice();
306
307 private:
308 std::unique_ptr<Backend> m_backend;
309 float m_masterVolume = 1.0f;
310
312 bool m_voiceBudgetSpent = false;
313};
314
315} // namespace Vkm::Engine
uint64_t render(float *frames, uint64_t frameCount)
Pull mixed frames from an offline mixer into frames.
void updateVoice(VoiceId voice, const VoiceParams &params)
Push a voice's parameters to the mixer; an unknown or finished voice is ignored.
size_t voiceCount() const
Number of voices the mixer currently holds.
void setListener(const glm::vec3 &position, const glm::vec3 &forward, const glm::vec3 &up)
Place the ear.
void setListenerActive(bool active)
Whether anything is listening.
void setMasterVolume(float volume)
Master gain applied to the whole mix.
void seekVoice(VoiceId voice, float seconds)
Move voice's cursor to seconds into its clip.
void reapFinishedVoices()
Release every voice that has played to its end, or been ramped out by stopVoice().
void resumeAllVoices()
Let every voice pauseAllVoices() is still holding play on.
void pauseVoice(VoiceId voice)
Hold voice at its cursor, silently, without ending it.
void pauseAllVoices()
Hold every voice that is sounding right now.
bool openOffline(uint32_t sampleRate, uint32_t channels)
Open the mixer with no device, to be pumped by render().
float masterVolume() const noexcept
The master gain the mix is running at, after setMasterVolume's sanitising.
Definition audio_device.h:291
void stopAllVoices()
Cut and release every voice at once, leaving the device open.
VoiceId play(const AudioClipAsset &clip, const VoiceParams &params)
Start playing clip and return the voice driving it.
bool isVoiceActive(VoiceId voice) const
Whether voice is still there with audio left to play.
bool open()
Open the default playback device and start its mixer thread.
void close()
Stop every voice and shut the mixer down; idempotent.
bool isVoicePaused(VoiceId voice) const
Whether voice is being held by a pause rather than playing.
float voiceCursor(VoiceId voice) const
How far into its clip voice has played, in seconds.
void resumeVoice(VoiceId voice)
Let voice play on from where it was held, ramped back in.
void stopVoice(VoiceId voice)
Ramp voice to silence and let it go.
A sound: fully decoded interleaved PCM, plus the rate and layout it was written at.
Definition audio_clip_asset.h:58
Everything the mixer needs to know about one voice, pushed every frame.
Definition audio_device.h:32
float heardMinDistance() const
The near distance as the mixer takes it.
Definition audio_device.h:54
bool hasFar() const
Whether the voice fades with distance and so has a range past which it is silent.
Definition audio_device.h:68
float heardMaxDistance() const
The far distance as the mixer takes it.
Definition audio_device.h:61
float volume
Linear gain for this voice, multiplied into the master.
Definition audio_device.h:39