Skip to content

Commit 54eeadd

Browse files
authored
Merge pull request #16 from SeedyROM/feature/audio-assets
[FEATURE]: Use `AssetManager` to load/play audio.
2 parents 760cad4 + 16eb238 commit 54eeadd

File tree

10 files changed

+194
-101
lines changed

10 files changed

+194
-101
lines changed

.github/workflows/cmake-multi-platform.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ jobs:
1111
strategy:
1212
fail-fast: false
1313
matrix:
14-
os: [ubuntu-latest, windows-latest]
15-
build_type: [Release, RelWithDebInfo]
14+
os: [ubuntu-latest] # , windows-latest]
15+
build_type: [Release] # RelWithDebInfo]
1616
include:
17-
- os: windows-latest
18-
cpp_compiler: cl
19-
separator: '\\'
17+
# - os: windows-latest
18+
# cpp_compiler: cl
19+
# separator: '\\'
2020
- os: ubuntu-latest
2121
cpp_compiler: g++
2222
separator: "/"

src/engine/assets/asset_manager.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@ AssetHandle<T> AssetManager::load(const std::string &path) {
7777
m_totalAssets--;
7878
throw std::runtime_error(createInfo.errorMsg);
7979
}
80+
// Load AudioFile
81+
} else if constexpr (std::is_same_v<T, AudioFile>) {
82+
AudioFile::CreateInfo createInfo;
83+
if (auto audioFile = AudioFile::createFromFile(path, createInfo)) {
84+
auto asset = std::make_shared<AudioFile>(std::move(*audioFile));
85+
m_assets.try_emplace(path, asset, 1);
86+
m_loadedAssets++;
87+
return AssetHandle<T>(asset);
88+
} else {
89+
m_totalAssets--;
90+
throw std::runtime_error(createInfo.errorMsg);
91+
}
8092
} else {
8193
// Asset type-specific loading logic here
8294
throw std::runtime_error("Unsupported asset type");
@@ -143,4 +155,11 @@ AssetManager::loadAsync<Texture>(const std::string &);
143155
template bool AssetManager::exists<Texture>(const std::string &) const;
144156
template void AssetManager::remove<Texture>(const std::string &);
145157

158+
template AssetHandle<AudioFile>
159+
AssetManager::load<AudioFile>(const std::string &);
160+
template std::future<AssetHandle<AudioFile>>
161+
AssetManager::loadAsync<AudioFile>(const std::string &);
162+
template bool AssetManager::exists<AudioFile>(const std::string &) const;
163+
template void AssetManager::remove<AudioFile>(const std::string &);
164+
146165
} // namespace ste

src/engine/assets/asset_manager.h

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <vector>
1212

1313
#include "engine/async/thread_pool.h"
14+
#include "engine/audio/audio_file.h"
1415
#include "engine/rendering/shader.h"
1516
#include "engine/rendering/texture.h"
1617

src/engine/audio/audio_engine.cpp

+32-28
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,11 @@ void AudioChannel::mix(float *buffer, size_t frames) {
7979
m_position = static_cast<size_t>(readPosition);
8080
}
8181

82-
void AudioChannel::play(std::shared_ptr<AudioFile> file, float vol) {
83-
m_currentFile = std::move(file);
82+
void AudioChannel::play(AudioFile *file, float vol) {
83+
if (!file)
84+
return;
85+
86+
m_currentFile = file;
8487
m_position = 0;
8588
m_volume = vol;
8689
m_targetVolume = vol;
@@ -90,8 +93,10 @@ void AudioChannel::play(std::shared_ptr<AudioFile> file, float vol) {
9093

9194
void AudioChannel::stop() {
9295
m_active = false;
93-
m_currentFile.reset();
96+
m_currentFile = nullptr;
9497
m_position = 0;
98+
m_currentSpeed = 1.0f;
99+
m_targetSpeed = 1.0f;
95100
}
96101

97102
void AudioChannel::setVolume(float vol) {
@@ -217,37 +222,34 @@ AudioEngine::~AudioEngine() {
217222
stopAll();
218223
}
219224

220-
void AudioEngine::playSound(const std::string &path, float m_volume) {
221-
try {
222-
auto file = std::make_shared<AudioFile>(path);
223-
int channel = findFreeChannel();
224-
if (channel != -1) {
225-
m_commandQueue.pushPlay(file, m_volume, channel);
226-
}
227-
} catch (const AudioFileException &e) {
228-
std::cerr << "Failed to load sound file: " << e.what() << std::endl;
229-
// Handle or propagate error
230-
// Could log error or throw depending on your error handling strategy
225+
void AudioEngine::playSound(AssetHandle<AudioFile> sound, float volume) {
226+
if (!sound.isValid()) {
227+
std::cerr << "Attempted to play invalid sound asset" << std::endl;
228+
return;
229+
}
230+
231+
int channel = findFreeChannel();
232+
if (channel != -1) {
233+
m_commandQueue.pushPlay(sound.operator->(), volume, channel);
231234
}
232235
}
233236

234-
void AudioEngine::playMusic(const std::string &path, bool loop) {
235-
try {
236-
auto file = std::make_shared<AudioFile>(path);
237-
file->setLooping(loop);
237+
void AudioEngine::playMusic(AssetHandle<AudioFile> music, bool loop) {
238+
if (!music.isValid()) {
239+
std::cerr << "Attempted to play invalid music asset" << std::endl;
240+
return;
241+
}
238242

239-
// Stop any currently playing music
240-
stopChannel(0);
243+
// Set looping state on the audio file
244+
music->setLooping(loop);
241245

242-
// Queue the new music
243-
m_commandQueue.pushPlay(file, 1.0f, 0); // Channel 0 reserved for music
244-
} catch (const AudioFileException &e) {
245-
std::cerr << "Failed to load sound file: " << e.what() << std::endl;
246+
// Stop any currently playing music
247+
stopChannel(0);
246248

247-
// Handle or propagate error
248-
}
249+
// Queue the new music
250+
m_commandQueue.pushPlay(music.operator->(), 1.0f,
251+
0); // Channel 0 reserved for music
249252
}
250-
251253
void AudioEngine::stopChannel(int channelId) {
252254
if (channelId >= 0 && channelId < static_cast<int>(MAX_CHANNELS)) {
253255
m_commandQueue.pushStop(channelId);
@@ -379,10 +381,12 @@ void AudioEngine::audioCallback(float *buffer, size_t frames) {
379381
}
380382
}
381383

382-
int AudioEngine::findFreeChannel() const {
384+
int AudioEngine::findFreeChannel() {
383385
// Skip channel 0 (reserved for music)
384386
for (size_t i = 1; i < MAX_CHANNELS; ++i) {
385387
if (!m_channels[i].isActive()) {
388+
// Optionally force a stop to ensure clean state
389+
m_channels[i].stop();
386390
return static_cast<int>(i);
387391
}
388392
}

src/engine/audio/audio_engine.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "audio_file.h"
99
#include "audio_queue.h"
10+
#include "engine/assets/asset_manager.h"
1011

1112
namespace ste {
1213

@@ -18,7 +19,7 @@ class AudioChannel {
1819
// Core audio functions
1920
void update(float deltaTime);
2021
void mix(float *buffer, size_t frames);
21-
void play(std::shared_ptr<AudioFile> file, float vol = 1.0f);
22+
void play(AudioFile *file, float vol = 1.0f);
2223
void stop();
2324

2425
// State control
@@ -36,7 +37,7 @@ class AudioChannel {
3637

3738
private:
3839
// Audio data
39-
std::shared_ptr<AudioFile> m_currentFile;
40+
AudioFile *m_currentFile = nullptr;
4041
size_t m_position = 0;
4142

4243
// Volume control
@@ -76,8 +77,8 @@ class AudioEngine {
7677
AudioEngine &operator=(AudioEngine &&) = delete;
7778

7879
// Main interface
79-
void playSound(const std::string &path, float volume = 1.0f);
80-
void playMusic(const std::string &path, bool loop = true);
80+
void playSound(AssetHandle<AudioFile> sound, float volume = 1.0f);
81+
void playMusic(AssetHandle<AudioFile> music, bool loop = true);
8182
void stopChannel(int channelId);
8283
void stopAll();
8384
void setChannelVolume(int channelId, float volume);
@@ -113,7 +114,7 @@ class AudioEngine {
113114

114115
void processCommands();
115116
void mixAudio(float *buffer, size_t frames);
116-
[[nodiscard]] int findFreeChannel() const;
117+
[[nodiscard]] int findFreeChannel();
117118
};
118119

119120
}; // namespace ste

0 commit comments

Comments
 (0)