Brenta Engine 1.1
Loading...
Searching...
No Matches
engine_audio.cpp
1/*
2 * MIT License
3 *
4 * Copyright (c) 2024 Giovanni Santini
5
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 */
26
27#include "engine_audio.hpp"
28
29#include "SDL3/SDL_init.h"
30#include "engine_logger.hpp"
31
32#include <string>
33
34using namespace brenta;
35
36std::unordered_map<types::audio_name_t, types::audio_file_t> audio::audio_files;
37std::unordered_map<types::stream_name_t, SDL_AudioStream *> audio::streams;
38
40{
41 if (SDL_Init(SDL_INIT_AUDIO))
42 {
43 auto error = SDL_GetError();
44 ERROR("SDL Audio failed to initialize: {}", error);
45 return;
46 }
47
48 audio::create_stream("default");
49 INFO("SDL Audio initialized");
50}
51
53{
54 for (auto &stream : audio::streams)
55 SDL_DestroyAudioStream(stream.second);
56
57 for (auto &audiofile : audio::audio_files)
58 {
59 SDL_free(audiofile.second.audio_buf);
60 }
61
62 SDL_Quit();
63 INFO("SDL Audio destroyed");
64}
65
66void audio::load_audio(types::audio_name_t name, std::string path)
67{
68 types::audio_file_t audiofile;
69 audiofile.path = path;
70
71 if (SDL_LoadWAV(path.c_str(), &audiofile.spec, &audiofile.audio_buf,
72 &audiofile.audio_len))
73 {
74 auto error = SDL_GetError();
75 ERROR("SDL Audio failed to load WAV file: {}", error);
76 return;
77 }
78
79 audio::audio_files.insert({name, audiofile});
80 INFO("Loaded audio at {}", path);
81}
82
83void audio::play_audio(types::audio_name_t audio_name,
84 types::stream_name_t stream_name)
85{
86 auto stream = audio::get_stream(stream_name);
87 if (stream == nullptr)
88 {
89 ERROR("Could not play audio: Audio stream not found");
90 return;
91 }
92
93 clear_stream(stream_name);
94 auto audiofile = audio::get_audio_file(audio_name);
95 if (SDL_PutAudioStreamData(stream, audiofile.audio_buf,
96 audiofile.audio_len))
97 check_error_audio();
98}
99
100void audio::create_stream(types::stream_name_t name)
101{
102 SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(
103 SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, NULL, NULL, NULL);
104 if (stream == NULL)
105 {
106 const char *error = SDL_GetError();
107 ERROR("SDL Audio failed to create stream: {}", error);
108 return;
109 }
110
111 audio::streams.insert({name, stream});
112 resume_stream(name);
113 INFO("SDL Audio stream created");
114}
115
117{
118 if (audio::audio_files.find(name) == audio::audio_files.end())
119 {
120 ERROR("Audio file not found with name: {}", name);
121 return types::audio_file_t();
122 }
123 return audio::audio_files.at(name);
124}
125
126SDL_AudioStream *audio::get_stream(types::stream_name_t name)
127{
128 if (audio::streams.find(name) == audio::streams.end())
129 {
130 ERROR("Audio stream not found with name: {}", name);
131 return nullptr;
132 }
133 return audio::streams.at(name);
134}
135
136void audio::set_volume(types::stream_name_t name, int volume)
137{
138 auto stream = audio::get_stream(name);
139 if (stream == nullptr)
140 {
141 ERROR("Could not set volume: Audio stream not found");
142 return;
143 }
144
145 if (SDL_SetAudioStreamGain(stream, volume))
146 check_error_audio();
147 INFO("Volume set to {}", volume);
148}
149
150void audio::check_error_audio()
151{
152 auto error = SDL_GetError();
153 ERROR("SDL Audio error: {}", error);
154}
155
156void audio::clear_stream(types::stream_name_t name)
157{
158 auto stream = audio::get_stream(name);
159 if (stream == nullptr)
160 {
161 ERROR("Could not clear stream: Audio stream not found");
162 return;
163 }
164
165 if (SDL_ClearAudioStream(stream))
166 check_error_audio();
167 INFO("Stream cleared");
168}
169
170void audio::pause_stream(types::stream_name_t name)
171{
172 auto stream = audio::get_stream(name);
173 if (stream == nullptr)
174 {
175 ERROR("Could not pause stream: Audio stream not found");
176 return;
177 }
178
179 if (SDL_PauseAudioStreamDevice(stream))
180 check_error_audio();
181 INFO("Stream paused");
182}
183
184void audio::resume_stream(types::stream_name_t name)
185{
186 auto stream = audio::get_stream(name);
187 if (stream == nullptr)
188 {
189 ERROR("Could not resume stream: Audio stream not found");
190 return;
191 }
192
193 if (SDL_ResumeAudioStreamDevice(stream))
194 check_error_audio();
195 INFO("Stream resumed");
196}
static void destroy()
Destroy the audio system.
static std::unordered_map< types::stream_name_t, SDL_AudioStream * > streams
Map of audio streams.
static void load_audio(types::audio_name_t name, std::string path)
Load an audio file.
static void resume_stream(types::stream_name_t name)
Resume a stream.
static std::unordered_map< types::audio_name_t, types::audio_file_t > audio_files
Map of audio files.
static void play_audio(types::audio_name_t, types::stream_name_t="default")
Play an audio file.
static types::audio_file_t get_audio_file(types::audio_name_t name)
Get an audio file.
static void clear_stream(types::stream_name_t name)
Stop a stream.
static void create_stream(types::stream_name_t)
Create an audio stream.
static void set_volume(types::stream_name_t name, int volume)
Set the volume of a stream.
static void pause_stream(types::stream_name_t name)
Pause a stream.
static void init()
Initialize the audio system.
static SDL_AudioStream * get_stream(types::stream_name_t name)
Get an audio stream.
Struct containing information about an audio file.
SDL_AudioSpec spec
Information about the audio format.
Uint8 * audio_buf
Pointer to audio buffer.
std::string path
The path to the audio file.
Uint32 audio_len
Length of audio buffer.