Skip to content

Commit

Permalink
Merge pull request #16 from SeedyROM/feature/audio-assets
Browse files Browse the repository at this point in the history
[FEATURE]: Use `AssetManager` to load/play audio.
  • Loading branch information
SeedyROM authored Dec 1, 2024
2 parents 760cad4 + 16eb238 commit 54eeadd
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 101 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
build_type: [Release, RelWithDebInfo]
os: [ubuntu-latest] # , windows-latest]
build_type: [Release] # RelWithDebInfo]
include:
- os: windows-latest
cpp_compiler: cl
separator: '\\'
# - os: windows-latest
# cpp_compiler: cl
# separator: '\\'
- os: ubuntu-latest
cpp_compiler: g++
separator: "/"
Expand Down
19 changes: 19 additions & 0 deletions src/engine/assets/asset_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ AssetHandle<T> AssetManager::load(const std::string &path) {
m_totalAssets--;
throw std::runtime_error(createInfo.errorMsg);
}
// Load AudioFile
} else if constexpr (std::is_same_v<T, AudioFile>) {
AudioFile::CreateInfo createInfo;
if (auto audioFile = AudioFile::createFromFile(path, createInfo)) {
auto asset = std::make_shared<AudioFile>(std::move(*audioFile));
m_assets.try_emplace(path, asset, 1);
m_loadedAssets++;
return AssetHandle<T>(asset);
} else {
m_totalAssets--;
throw std::runtime_error(createInfo.errorMsg);
}
} else {
// Asset type-specific loading logic here
throw std::runtime_error("Unsupported asset type");
Expand Down Expand Up @@ -143,4 +155,11 @@ AssetManager::loadAsync<Texture>(const std::string &);
template bool AssetManager::exists<Texture>(const std::string &) const;
template void AssetManager::remove<Texture>(const std::string &);

template AssetHandle<AudioFile>
AssetManager::load<AudioFile>(const std::string &);
template std::future<AssetHandle<AudioFile>>
AssetManager::loadAsync<AudioFile>(const std::string &);
template bool AssetManager::exists<AudioFile>(const std::string &) const;
template void AssetManager::remove<AudioFile>(const std::string &);

} // namespace ste
1 change: 1 addition & 0 deletions src/engine/assets/asset_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <vector>

#include "engine/async/thread_pool.h"
#include "engine/audio/audio_file.h"
#include "engine/rendering/shader.h"
#include "engine/rendering/texture.h"

Expand Down
60 changes: 32 additions & 28 deletions src/engine/audio/audio_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,11 @@ void AudioChannel::mix(float *buffer, size_t frames) {
m_position = static_cast<size_t>(readPosition);
}

void AudioChannel::play(std::shared_ptr<AudioFile> file, float vol) {
m_currentFile = std::move(file);
void AudioChannel::play(AudioFile *file, float vol) {
if (!file)
return;

m_currentFile = file;
m_position = 0;
m_volume = vol;
m_targetVolume = vol;
Expand All @@ -90,8 +93,10 @@ void AudioChannel::play(std::shared_ptr<AudioFile> file, float vol) {

void AudioChannel::stop() {
m_active = false;
m_currentFile.reset();
m_currentFile = nullptr;
m_position = 0;
m_currentSpeed = 1.0f;
m_targetSpeed = 1.0f;
}

void AudioChannel::setVolume(float vol) {
Expand Down Expand Up @@ -217,37 +222,34 @@ AudioEngine::~AudioEngine() {
stopAll();
}

void AudioEngine::playSound(const std::string &path, float m_volume) {
try {
auto file = std::make_shared<AudioFile>(path);
int channel = findFreeChannel();
if (channel != -1) {
m_commandQueue.pushPlay(file, m_volume, channel);
}
} catch (const AudioFileException &e) {
std::cerr << "Failed to load sound file: " << e.what() << std::endl;
// Handle or propagate error
// Could log error or throw depending on your error handling strategy
void AudioEngine::playSound(AssetHandle<AudioFile> sound, float volume) {
if (!sound.isValid()) {
std::cerr << "Attempted to play invalid sound asset" << std::endl;
return;
}

int channel = findFreeChannel();
if (channel != -1) {
m_commandQueue.pushPlay(sound.operator->(), volume, channel);
}
}

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

// Stop any currently playing music
stopChannel(0);
// Set looping state on the audio file
music->setLooping(loop);

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

// Handle or propagate error
}
// Queue the new music
m_commandQueue.pushPlay(music.operator->(), 1.0f,
0); // Channel 0 reserved for music
}

void AudioEngine::stopChannel(int channelId) {
if (channelId >= 0 && channelId < static_cast<int>(MAX_CHANNELS)) {
m_commandQueue.pushStop(channelId);
Expand Down Expand Up @@ -379,10 +381,12 @@ void AudioEngine::audioCallback(float *buffer, size_t frames) {
}
}

int AudioEngine::findFreeChannel() const {
int AudioEngine::findFreeChannel() {
// Skip channel 0 (reserved for music)
for (size_t i = 1; i < MAX_CHANNELS; ++i) {
if (!m_channels[i].isActive()) {
// Optionally force a stop to ensure clean state
m_channels[i].stop();
return static_cast<int>(i);
}
}
Expand Down
11 changes: 6 additions & 5 deletions src/engine/audio/audio_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "audio_file.h"
#include "audio_queue.h"
#include "engine/assets/asset_manager.h"

namespace ste {

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

// State control
Expand All @@ -36,7 +37,7 @@ class AudioChannel {

private:
// Audio data
std::shared_ptr<AudioFile> m_currentFile;
AudioFile *m_currentFile = nullptr;
size_t m_position = 0;

// Volume control
Expand Down Expand Up @@ -76,8 +77,8 @@ class AudioEngine {
AudioEngine &operator=(AudioEngine &&) = delete;

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

void processCommands();
void mixAudio(float *buffer, size_t frames);
[[nodiscard]] int findFreeChannel() const;
[[nodiscard]] int findFreeChannel();
};

}; // namespace ste
Loading

0 comments on commit 54eeadd

Please sign in to comment.