Brenta Engine 1.0
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;
35using namespace Brenta::Utils;
36
37std::unordered_map<Types::AudioName, Types::AudioFile> Audio::audiofiles;
38std::unordered_map<Types::StreamName, SDL_AudioStream *> Audio::streams;
39
41{
42 if (SDL_Init(SDL_INIT_AUDIO))
43 {
44 auto error = SDL_GetError();
45 ERROR("SDL Audio failed to initialize: ", error);
46 return;
47 }
48
49 Audio::CreateStream("default");
50 INFO("SDL Audio initialized");
51}
52
54{
55 for (auto &stream : Audio::streams)
56 SDL_DestroyAudioStream(stream.second);
57
58 for (auto &audiofile : Audio::audiofiles)
59 {
60 SDL_free(audiofile.second.audio_buf);
61 }
62
63 SDL_Quit();
64 INFO("SDL Audio destroyed");
65}
66
67void Audio::LoadAudio(Types::AudioName name, std::string path)
68{
69 Types::AudioFile audiofile;
70 audiofile.path = path;
71
72 if (SDL_LoadWAV(path.c_str(), &audiofile.spec, &audiofile.audio_buf,
73 &audiofile.audio_len))
74 {
75 auto error = SDL_GetError();
76 ERROR("SDL Audio failed to load WAV file: ", error);
77 return;
78 }
79
80 Audio::audiofiles.insert({name, audiofile});
81 INFO("Loaded audio at ", path);
82}
83
84void Audio::PlayAudio(Types::AudioName audio_name,
85 Types::StreamName stream_name)
86{
87 auto stream = Audio::GetStream(stream_name);
88 if (stream == nullptr)
89 {
90 ERROR("Could not play audio: Audio stream not found");
91 return;
92 }
93
94 ClearStream(stream_name);
95 auto audiofile = Audio::GetAudioFile(audio_name);
96 if (SDL_PutAudioStreamData(stream, audiofile.audio_buf,
97 audiofile.audio_len))
98 CheckError();
99}
100
101void Audio::CreateStream(Types::StreamName name)
102{
103 SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(
104 SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, NULL, NULL, NULL);
105 if (stream == NULL)
106 {
107 const char *error = SDL_GetError();
108 ERROR("SDL Audio failed to create stream: ", error);
109 return;
110 }
111
112 Audio::streams.insert({name, stream});
113 ResumeStream(name);
114 INFO("SDL Audio stream created");
115}
116
118{
119 if (Audio::audiofiles.find(name) == Audio::audiofiles.end())
120 {
121 ERROR("Audio file not found with name: ", name);
122 return Types::AudioFile();
123 }
124 return Audio::audiofiles.at(name);
125}
126
127SDL_AudioStream *Audio::GetStream(Types::StreamName name)
128{
129 if (Audio::streams.find(name) == Audio::streams.end())
130 {
131 ERROR("Audio stream not found with name: " + name);
132 return nullptr;
133 }
134 return Audio::streams.at(name);
135}
136
137void Audio::SetVolume(Types::StreamName name, int volume)
138{
139 auto stream = Audio::GetStream(name);
140 if (stream == nullptr)
141 {
142 ERROR("Could not set volume: Audio stream not found");
143 return;
144 }
145
146 if (SDL_SetAudioStreamGain(stream, volume))
147 CheckError();
148 INFO("Volume set to ", volume);
149}
150
151void Audio::CheckError()
152{
153 auto error = SDL_GetError();
154 ERROR("SDL Audio error: ", error);
155}
156
157void Audio::ClearStream(Types::StreamName name)
158{
159 auto stream = Audio::GetStream(name);
160 if (stream == nullptr)
161 {
162 ERROR("Could not clear stream: Audio stream not found");
163 return;
164 }
165
166 if (SDL_ClearAudioStream(stream))
167 CheckError();
168 INFO("Stream cleared");
169}
170
171void Audio::PauseStream(Types::StreamName name)
172{
173 auto stream = Audio::GetStream(name);
174 if (stream == nullptr)
175 {
176 ERROR("Could not pause stream: Audio stream not found");
177 return;
178 }
179
180 if (SDL_PauseAudioStreamDevice(stream))
181 CheckError();
182 INFO("Stream paused");
183}
184
185void Audio::ResumeStream(Types::StreamName name)
186{
187 auto stream = Audio::GetStream(name);
188 if (stream == nullptr)
189 {
190 ERROR("Could not resume stream: Audio stream not found");
191 return;
192 }
193
194 if (SDL_ResumeAudioStreamDevice(stream))
195 CheckError();
196 INFO("Stream resumed");
197}
static void Init()
Initialize the audio system.
static std::unordered_map< Types::AudioName, Types::AudioFile > audiofiles
Map of audio files.
static void Destroy()
Destroy the audio system.
static void ClearStream(Types::StreamName name)
Stop a stream.
static void SetVolume(Types::StreamName name, int volume)
Set the volume of a stream.
static void CreateStream(Types::StreamName)
Create an audio stream.
static void PlayAudio(Types::AudioName, Types::StreamName="default")
Play an audio file.
static SDL_AudioStream * GetStream(Types::StreamName name)
Get an audio stream.
static void LoadAudio(Types::AudioName name, std::string path)
Load an audio file.
static Types::AudioFile GetAudioFile(Types::AudioName name)
Get an audio file.
static void PauseStream(Types::StreamName name)
Pause a stream.
static void ResumeStream(Types::StreamName name)
Resume a stream.
static std::unordered_map< Types::StreamName, SDL_AudioStream * > streams
Map of audio streams.
Struct containing information about an audio file.
std::string path
The path to the audio file.
Uint32 audio_len
Length of audio buffer.
SDL_AudioSpec spec
Information about the audio format.
Uint8 * audio_buf
Pointer to audio buffer.