MXVK Vulkan Framework 0.24.0
C++20 Vulkan rendering framework for practical 2D and 3D application development with SDL3.
Loading...
Searching...
No Matches
mxvk::VK_Mixer Class Reference

SDL3_mixer-based audio manager. More...

#include <mxvk/include/mxvk/mxvk_sound.hpp>

Public Member Functions

void cleanup ()
 Free all loaded audio chunks and music tracks.
void init ()
 Open the audio device (called automatically by constructor).
bool isMusicPlaying (int id) const
 Query whether a loaded music track is currently playing.
bool isPlaying (int channel) const
 Query whether a sound track is currently playing.
int loadMusic (const std::string &filename)
 Load an audio file as streaming background music.
int loadWav (const std::string &filename)
 Load a WAV file as a sound effect chunk.
VK_Mixeroperator= (const VK_Mixer &)=delete
VK_Mixeroperator= (VK_Mixer &&)=delete
int playMusic (int id, int value=0)
 Start playing a previously loaded music track.
int playWav (int id, int value=0, int channel=-1)
 Play a previously loaded WAV chunk.
void stopMusic ()
 Stop background music playback immediately.
 VK_Mixer ()
 Initialise SDL3_mixer and open the audio device.
 VK_Mixer (const VK_Mixer &)=delete
 VK_Mixer (VK_Mixer &&)=delete
 ~VK_Mixer () noexcept
 Halt all playback and free all loaded audio resources.

Detailed Description

SDL3_mixer-based audio manager.

Provides facilities for loading WAV sound chunks and streamed music tracks, playing them, and querying playback state. Only available when the library is built with MIXER enabled.

Definition at line 27 of file mxvk_sound.hpp.

Constructor & Destructor Documentation

◆ VK_Mixer() [1/3]

mxvk::VK_Mixer::VK_Mixer ( )

Initialise SDL3_mixer and open the audio device.

Definition at line 21 of file mxvk_sound.cpp.

21 {
22 init();
23 }
void init()
Open the audio device (called automatically by constructor).

◆ ~VK_Mixer()

mxvk::VK_Mixer::~VK_Mixer ( )
noexcept

Halt all playback and free all loaded audio resources.

Definition at line 25 of file mxvk_sound.cpp.

25 {
26 cleanup();
27 }
void cleanup()
Free all loaded audio chunks and music tracks.

◆ VK_Mixer() [2/3]

mxvk::VK_Mixer::VK_Mixer ( const VK_Mixer & )
delete

◆ VK_Mixer() [3/3]

mxvk::VK_Mixer::VK_Mixer ( VK_Mixer && )
delete

Member Function Documentation

◆ cleanup()

void mxvk::VK_Mixer::cleanup ( )

Free all loaded audio chunks and music tracks.

Definition at line 196 of file mxvk_sound.cpp.

196 {
197 if (!initialized) {
198 return;
199 }
200
201 stopMusic();
202 music_tracks.clear();
203 wav_tracks.clear();
204 music_files.clear();
205 wav_files.clear();
206 mixer.reset();
207 MIX_Quit();
208 initialized = false;
209 }
void stopMusic()
Stop background music playback immediately.

◆ init()

void mxvk::VK_Mixer::init ( )

Open the audio device (called automatically by constructor).

Definition at line 29 of file mxvk_sound.cpp.

29 {
30 if (initialized) {
31 return;
32 }
33
34 if (!MIX_Init()) {
35 throw mxvk::Exception("Could not initialize SDL3_mixer: " + std::string(SDL_GetError()));
36 }
37
38 SDL_AudioSpec spec{};
39 spec.freq = 44100;
40 spec.format = SDL_AUDIO_S16;
41 spec.channels = 2;
42
43 MIX_Mixer *raw_mixer = MIX_CreateMixerDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec);
44 if (raw_mixer == nullptr) {
45 MIX_Quit();
46 throw mxvk::Exception("Could not create mixer device: " + std::string(SDL_GetError()));
47 }
48
49 mixer.reset(raw_mixer);
50 initialized = true;
51 }

◆ isMusicPlaying()

bool mxvk::VK_Mixer::isMusicPlaying ( int id) const
nodiscard

Query whether a loaded music track is currently playing.

Parameters
idMusic index returned by loadMusic().
Returns
true if the music track is active.

Definition at line 171 of file mxvk_sound.cpp.

171 {
172 if (!initialized || id < 0 || id >= static_cast<int>(music_tracks.size())) {
173 return false;
174 }
175
176 MIX_Track *track = music_tracks[toIndex(id)].get();
177 if (track == nullptr) {
178 return false;
179 }
180 return MIX_TrackPlaying(track);
181 }

◆ isPlaying()

bool mxvk::VK_Mixer::isPlaying ( int channel) const
nodiscard

Query whether a sound track is currently playing.

Parameters
channelTrack index.
Returns
true if the channel is active.

Definition at line 159 of file mxvk_sound.cpp.

159 {
160 if (!initialized || channel < 0 || channel >= static_cast<int>(wav_tracks.size())) {
161 return false;
162 }
163
164 MIX_Track *track = wav_tracks[toIndex(channel)].get();
165 if (track == nullptr) {
166 return false;
167 }
168 return MIX_TrackPlaying(track);
169 }

◆ loadMusic()

int mxvk::VK_Mixer::loadMusic ( const std::string & filename)

Load an audio file as streaming background music.

Parameters
filenamePath to the music file (OGG, MP3, WAV, etc.).
Returns
Index used to reference this track in playMusic().

Definition at line 53 of file mxvk_sound.cpp.

53 {
54 if (filename.empty()) {
55 throw mxvk::Exception("Music filename cannot be empty");
56 }
57 if (!initialized || mixer == nullptr) {
58 throw mxvk::Exception("Audio mixer is not initialized");
59 }
60
61 MIX_Audio *raw_audio = MIX_LoadAudio(mixer.get(), filename.c_str(), false);
62 if (raw_audio == nullptr) {
63 throw mxvk::Exception("Error loading music file '" + filename + "': " + std::string(SDL_GetError()));
64 }
65
66 MIX_Track *raw_track = MIX_CreateTrack(mixer.get());
67 if (raw_track == nullptr) {
68 MIX_DestroyAudio(raw_audio);
69 throw mxvk::Exception("Error creating music track: " + std::string(SDL_GetError()));
70 }
71 if (!MIX_SetTrackAudio(raw_track, raw_audio)) {
72 MIX_DestroyTrack(raw_track);
73 MIX_DestroyAudio(raw_audio);
74 throw mxvk::Exception("Error assigning music track audio: " + std::string(SDL_GetError()));
75 }
76
77 music_files.emplace_back(raw_audio, MIX_DestroyAudio);
78 music_tracks.emplace_back(raw_track, MIX_DestroyTrack);
79 return static_cast<int>(music_files.size() - 1);
80 }

◆ loadWav()

int mxvk::VK_Mixer::loadWav ( const std::string & filename)

Load a WAV file as a sound effect chunk.

Parameters
filenamePath to the WAV file.
Returns
Index used to reference this chunk in playWav().

Definition at line 82 of file mxvk_sound.cpp.

82 {
83 if (filename.empty()) {
84 throw mxvk::Exception("WAV filename cannot be empty");
85 }
86 if (!initialized || mixer == nullptr) {
87 throw mxvk::Exception("Audio mixer is not initialized");
88 }
89
90 MIX_Audio *raw_audio = MIX_LoadAudio(mixer.get(), filename.c_str(), true);
91 if (raw_audio == nullptr) {
92 throw mxvk::Exception("Error loading WAV file '" + filename + "': " + std::string(SDL_GetError()));
93 }
94
95 MIX_Track *raw_track = MIX_CreateTrack(mixer.get());
96 if (raw_track == nullptr) {
97 MIX_DestroyAudio(raw_audio);
98 throw mxvk::Exception("Error creating WAV track: " + std::string(SDL_GetError()));
99 }
100 if (!MIX_SetTrackAudio(raw_track, raw_audio)) {
101 MIX_DestroyTrack(raw_track);
102 MIX_DestroyAudio(raw_audio);
103 throw mxvk::Exception("Error assigning WAV track audio: " + std::string(SDL_GetError()));
104 }
105
106 wav_files.emplace_back(raw_audio, MIX_DestroyAudio);
107 wav_tracks.emplace_back(raw_track, MIX_DestroyTrack);
108 return static_cast<int>(wav_files.size() - 1);
109 }

◆ operator=() [1/2]

VK_Mixer & mxvk::VK_Mixer::operator= ( const VK_Mixer & )
delete

◆ operator=() [2/2]

VK_Mixer & mxvk::VK_Mixer::operator= ( VK_Mixer && )
delete

◆ playMusic()

int mxvk::VK_Mixer::playMusic ( int id,
int value = 0 )

Start playing a previously loaded music track.

Parameters
idMusic index returned by loadMusic().
valueNumber of additional loops (0 = play once, -1 = infinite).
Returns
0 on success, negative on failure.

Definition at line 111 of file mxvk_sound.cpp.

111 {
112 if (!initialized) {
113 return -1;
114 }
115 if (id < 0 || id >= static_cast<int>(music_tracks.size())) {
116 return -1;
117 }
118
119 MIX_Track *track = music_tracks[toIndex(id)].get();
120 if (track == nullptr) {
121 return -1;
122 }
123 if (!MIX_SetTrackLoops(track, value)) {
124 return -1;
125 }
126 return MIX_PlayTrack(track, 0) ? 0 : -1;
127 }

◆ playWav()

int mxvk::VK_Mixer::playWav ( int id,
int value = 0,
int channel = -1 )

Play a previously loaded WAV chunk.

Parameters
idChunk index returned by loadWav().
valueNumber of additional loops (0 = play once).
channelTrack index to use (-1 = use track for id).
Returns
The channel used for playback, or -1 on failure.

Definition at line 129 of file mxvk_sound.cpp.

129 {
130 if (!initialized) {
131 return -1;
132 }
133 if (id < 0 || id >= static_cast<int>(wav_files.size())) {
134 return -1;
135 }
136
137 int target = id;
138 if (channel >= 0) {
139 if (channel >= static_cast<int>(wav_tracks.size())) {
140 return -1;
141 }
142 target = channel;
143 }
144
145 MIX_Track *track = wav_tracks[toIndex(target)].get();
146 MIX_Audio *audio = wav_files[toIndex(id)].get();
147 if (track == nullptr || audio == nullptr) {
148 return -1;
149 }
150 if (!MIX_SetTrackAudio(track, audio)) {
151 return -1;
152 }
153 if (!MIX_SetTrackLoops(track, value)) {
154 return -1;
155 }
156 return MIX_PlayTrack(track, 0) ? target : -1;
157 }

◆ stopMusic()

void mxvk::VK_Mixer::stopMusic ( )

Stop background music playback immediately.

Definition at line 183 of file mxvk_sound.cpp.

183 {
184 if (!initialized || mixer == nullptr) {
185 return;
186 }
187
188 for (const auto &track : music_tracks) {
189 if (track != nullptr) {
190 MIX_StopTrack(track.get(), 0);
191 }
192 }
193 MIX_StopAllTracks(mixer.get(), 0);
194 }

The documentation for this class was generated from the following files: