MXVK Vulkan Framework 0.35.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_Mixer & operator= (const VK_Mixer &)=delete
VK_Mixer & operator= (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 19 of file mxvk_sound.cpp.

19{ init(); }
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 21 of file mxvk_sound.cpp.

21{ cleanup(); }
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 190 of file mxvk_sound.cpp.

190 {
191 if (!initialized) {
192 return;
193 }
194
195 stopMusic();
196 music_tracks.clear();
197 wav_tracks.clear();
198 music_files.clear();
199 wav_files.clear();
200 mixer.reset();
201 MIX_Quit();
202 initialized = false;
203 }
void stopMusic()
Stop background music playback immediately.

◆ init()

void mxvk::VK_Mixer::init ( )

Open the audio device (called automatically by constructor).

Definition at line 23 of file mxvk_sound.cpp.

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

◆ 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 165 of file mxvk_sound.cpp.

165 {
166 if (!initialized || id < 0 || id >= static_cast<int>(music_tracks.size())) {
167 return false;
168 }
169
170 MIX_Track *track = music_tracks[toIndex(id)].get();
171 if (track == nullptr) {
172 return false;
173 }
174 return MIX_TrackPlaying(track);
175 }

◆ 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 153 of file mxvk_sound.cpp.

153 {
154 if (!initialized || channel < 0 || channel >= static_cast<int>(wav_tracks.size())) {
155 return false;
156 }
157
158 MIX_Track *track = wav_tracks[toIndex(channel)].get();
159 if (track == nullptr) {
160 return false;
161 }
162 return MIX_TrackPlaying(track);
163 }

◆ 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 47 of file mxvk_sound.cpp.

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

◆ 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 76 of file mxvk_sound.cpp.

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

◆ 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 105 of file mxvk_sound.cpp.

105 {
106 if (!initialized) {
107 return -1;
108 }
109 if (id < 0 || id >= static_cast<int>(music_tracks.size())) {
110 return -1;
111 }
112
113 MIX_Track *track = music_tracks[toIndex(id)].get();
114 if (track == nullptr) {
115 return -1;
116 }
117 if (!MIX_SetTrackLoops(track, value)) {
118 return -1;
119 }
120 return MIX_PlayTrack(track, 0) ? 0 : -1;
121 }

◆ 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 123 of file mxvk_sound.cpp.

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

◆ stopMusic()

void mxvk::VK_Mixer::stopMusic ( )

Stop background music playback immediately.

Definition at line 177 of file mxvk_sound.cpp.

177 {
178 if (!initialized || mixer == nullptr) {
179 return;
180 }
181
182 for (const auto &track : music_tracks) {
183 if (track != nullptr) {
184 MIX_StopTrack(track.get(), 0);
185 }
186 }
187 MIX_StopAllTracks(mixer.get(), 0);
188 }

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