From 44aa8b2a33fc160c81abf857798bd94c94b88d21 Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Thu, 30 Sep 2021 02:00:18 +0200 Subject: [PATCH] Audio code refactoring. --- build/android/app/CMakeLists.txt | 1 - build/linux/Makefile | 1 - src/base/mem.h | 5 + src/engine/BUILD.gn | 2 - src/engine/audio/audio_alsa.cc | 1 - src/engine/audio/audio_alsa.h | 2 - src/engine/audio/audio_base.cc | 220 ++++++++++++++++++++++------- src/engine/audio/audio_base.h | 55 +++++++- src/engine/audio/audio_oboe.cc | 1 - src/engine/audio/audio_oboe.h | 2 - src/engine/audio/audio_resource.cc | 92 ------------ src/engine/audio/audio_resource.h | 41 ------ src/engine/audio/audio_sample.h | 41 ------ src/engine/engine.cc | 5 - src/engine/engine.h | 5 +- src/engine/sound_player.cc | 41 +++--- src/engine/sound_player.h | 3 +- 17 files changed, 250 insertions(+), 268 deletions(-) delete mode 100644 src/engine/audio/audio_resource.cc delete mode 100644 src/engine/audio/audio_resource.h delete mode 100644 src/engine/audio/audio_sample.h diff --git a/build/android/app/CMakeLists.txt b/build/android/app/CMakeLists.txt index 4b4763c..8ca756b 100644 --- a/build/android/app/CMakeLists.txt +++ b/build/android/app/CMakeLists.txt @@ -66,7 +66,6 @@ add_library(kaliber SHARED ../../../src/engine/animator.cc ../../../src/engine/audio/audio_base.cc ../../../src/engine/audio/audio_oboe.cc - ../../../src/engine/audio/audio_resource.cc ../../../src/engine/drawable.cc ../../../src/engine/engine.cc ../../../src/engine/font.cc diff --git a/build/linux/Makefile b/build/linux/Makefile index 0311be3..9b02295 100644 --- a/build/linux/Makefile +++ b/build/linux/Makefile @@ -91,7 +91,6 @@ GLTEST_SRC := \ $(SRC_ROOT)/engine/animator.cc \ $(SRC_ROOT)/engine/audio/audio_alsa.cc \ $(SRC_ROOT)/engine/audio/audio_base.cc \ - $(SRC_ROOT)/engine/audio/audio_resource.cc \ $(SRC_ROOT)/engine/drawable.cc \ $(SRC_ROOT)/engine/engine.cc \ $(SRC_ROOT)/engine/font.cc \ diff --git a/src/base/mem.h b/src/base/mem.h index ad1bb58..3bfd1c2 100644 --- a/src/base/mem.h +++ b/src/base/mem.h @@ -46,6 +46,11 @@ inline void AlignedFree(void* mem) { free(mem); } +template +inline bool IsAligned(void* ptr) { + return (reinterpret_cast(ptr) & (kAlignment - 1)) == 0U; +} + } // namespace base #endif // MEM_H diff --git a/src/engine/BUILD.gn b/src/engine/BUILD.gn index 8f67541..a7dca6c 100644 --- a/src/engine/BUILD.gn +++ b/src/engine/BUILD.gn @@ -8,8 +8,6 @@ source_set("engine") { "audio/audio_base.cc", "audio/audio_base.h", "audio/audio_forward.h", - "audio/audio_resource.cc", - "audio/audio_resource.h", "audio/audio_sample.h", "audio/audio.h", "drawable.cc", diff --git a/src/engine/audio/audio_alsa.cc b/src/engine/audio/audio_alsa.cc index ba3e1d1..095e6b8 100644 --- a/src/engine/audio/audio_alsa.cc +++ b/src/engine/audio/audio_alsa.cc @@ -5,7 +5,6 @@ #include #include "../../base/log.h" -#include "audio_resource.h" using namespace base; diff --git a/src/engine/audio/audio_alsa.h b/src/engine/audio/audio_alsa.h index adf8c39..dd37409 100644 --- a/src/engine/audio/audio_alsa.h +++ b/src/engine/audio/audio_alsa.h @@ -10,8 +10,6 @@ typedef struct _snd_pcm snd_pcm_t; namespace eng { -class AudioResource; - class AudioAlsa : public AudioBase { public: AudioAlsa(); diff --git a/src/engine/audio/audio_base.cc b/src/engine/audio/audio_base.cc index 39f54b7..57c258e 100644 --- a/src/engine/audio/audio_base.cc +++ b/src/engine/audio/audio_base.cc @@ -16,50 +16,161 @@ AudioBase::AudioBase() AudioBase::~AudioBase() = default; -void AudioBase::Play(std::shared_ptr sample) { - if (audio_enabled_) { - std::lock_guard scoped_lock(lock_); - samples_[0].push_back(sample); - } else if ((sample->flags.load(std::memory_order_relaxed) & - AudioSample::kStopped) == 0) { - sample->active = false; +size_t AudioBase::CreateResource() { + size_t resource_id = ++last_resource_id_; + resources_[resource_id] = std::make_shared(); + return resource_id; +} + +void AudioBase::DestroyResource(size_t resource_id) { + auto it = resources_.find(resource_id); + if (it == resources_.end()) + return; + + it->second->flags.fetch_or(kStopped, std::memory_order_relaxed); + resources_.erase(it); +} + +void AudioBase::Play(size_t resource_id, + std::shared_ptr sound, + float amplitude, + bool reset_pos) { + if (!audio_enabled_) + return; + + auto it = resources_.find(resource_id); + if (it == resources_.end()) + return; + + if (it->second->active) { + if (reset_pos) + it->second->flags.fetch_or(kStopped, std::memory_order_relaxed); + + if (it->second->flags.load(std::memory_order_relaxed) & kStopped) { + Closure ocb = std::move(it->second->end_cb); + SetEndCallback( + resource_id, + [&, resource_id, sound, amplitude, reset_pos, ocb]() -> void { + Play(resource_id, sound, amplitude, reset_pos); + SetEndCallback(resource_id, std::move(ocb)); + }); + } + + return; } + + if (reset_pos) { + it->second->src_index = 0; + it->second->accumulator = 0; + sound->ResetStream(); + } + + it->second->active = true; + it->second->flags.fetch_and(~kStopped, std::memory_order_relaxed); + it->second->sound = sound; + if (amplitude >= 0) + it->second->amplitude = amplitude; + + std::lock_guard scoped_lock(lock_); + play_list_[0].push_back(it->second); +} + +void AudioBase::Stop(size_t resource_id) { + auto it = resources_.find(resource_id); + if (it == resources_.end()) + return; + + if (it->second->active) + it->second->flags.fetch_or(kStopped, std::memory_order_relaxed); +} + +void AudioBase::SetLoop(size_t resource_id, bool loop) { + auto it = resources_.find(resource_id); + if (it == resources_.end()) + return; + + if (loop) + it->second->flags.fetch_or(kLoop, std::memory_order_relaxed); + else + it->second->flags.fetch_and(~kLoop, std::memory_order_relaxed); +} + +void AudioBase::SetSimulateStereo(size_t resource_id, bool simulate) { + auto it = resources_.find(resource_id); + if (it == resources_.end()) + return; + + if (simulate) + it->second->flags.fetch_or(kSimulateStereo, std::memory_order_relaxed); + else + it->second->flags.fetch_and(~kSimulateStereo, std::memory_order_relaxed); +} + +void AudioBase::SetResampleStep(size_t resource_id, size_t step) { + auto it = resources_.find(resource_id); + if (it == resources_.end()) + return; + + it->second->step.store(step + 100, std::memory_order_relaxed); +} + +void AudioBase::SetMaxAmplitude(size_t resource_id, float max_amplitude) { + auto it = resources_.find(resource_id); + if (it == resources_.end()) + return; + + it->second->max_amplitude.store(max_amplitude, std::memory_order_relaxed); +} + +void AudioBase::SetAmplitudeInc(size_t resource_id, float amplitude_inc) { + auto it = resources_.find(resource_id); + if (it == resources_.end()) + return; + + it->second->amplitude_inc.store(amplitude_inc, std::memory_order_relaxed); +} + +void AudioBase::SetEndCallback(size_t resource_id, base::Closure cb) { + auto it = resources_.find(resource_id); + if (it == resources_.end()) + return; + + it->second->end_cb = std::move(cb); } void AudioBase::RenderAudio(float* output_buffer, size_t num_frames) { { std::unique_lock scoped_lock(lock_, std::try_to_lock); if (scoped_lock) - samples_[1].splice(samples_[1].end(), samples_[0]); + play_list_[1].splice(play_list_[1].end(), play_list_[0]); } memset(output_buffer, 0, sizeof(float) * num_frames * kChannelCount); - for (auto it = samples_[1].begin(); it != samples_[1].end();) { - AudioSample* sample = it->get(); + for (auto it = play_list_[1].begin(); it != play_list_[1].end();) { + auto sound = it->get()->sound.get(); + unsigned flags = it->get()->flags.load(std::memory_order_relaxed); + bool marked_for_removal = false; - auto sound = sample->sound.get(); - unsigned flags = sample->flags.load(std::memory_order_relaxed); - - if (flags & AudioSample::kStopped) { - sample->marked_for_removal = true; - } else if (!sample->marked_for_removal) { + if (flags & kStopped) { + marked_for_removal = true; + } else { const float* src[2] = {sound->GetBuffer(0), sound->GetBuffer(1)}; if (!src[1]) src[1] = src[0]; // mono. size_t num_samples = sound->GetNumSamples(); - size_t src_index = sample->src_index; - size_t step = sample->step.load(std::memory_order_relaxed); - size_t accumulator = sample->accumulator; - float amplitude = sample->amplitude; + size_t src_index = it->get()->src_index; + size_t step = it->get()->step.load(std::memory_order_relaxed); + size_t accumulator = it->get()->accumulator; + float amplitude = it->get()->amplitude; float amplitude_inc = - sample->amplitude_inc.load(std::memory_order_relaxed); + it->get()->amplitude_inc.load(std::memory_order_relaxed); float max_amplitude = - sample->max_amplitude.load(std::memory_order_relaxed); + it->get()->max_amplitude.load(std::memory_order_relaxed); size_t channel_offset = - (flags & AudioSample::kSimulateStereo) && !sound->is_streaming_sound() + (flags & kSimulateStereo) && !sound->is_streaming_sound() ? sound->sample_rate() / 10 : 0; @@ -74,7 +185,7 @@ void AudioBase::RenderAudio(float* output_buffer, size_t num_frames) { size_t ind = channel_offset + src_index; if (ind < num_samples) output_buffer[i++] += src[1][ind] * amplitude; - else if (flags & AudioSample::kLoop) + else if (flags & kLoop) output_buffer[i++] += src[1][ind % num_samples] * amplitude; else i++; @@ -82,39 +193,40 @@ void AudioBase::RenderAudio(float* output_buffer, size_t num_frames) { // Apply amplitude modification. amplitude += amplitude_inc; if (amplitude <= 0) { - sample->marked_for_removal = true; + marked_for_removal = true; break; } else if (amplitude > max_amplitude) { amplitude = max_amplitude; } - // Basic resampling for variations. + // Advance source index. Apply basic resampling for variations. accumulator += step; src_index += accumulator / 100; accumulator %= 100; } - // Advance source index. + // Remove, loop or stream if the source data is consumed if (src_index >= num_samples) { if (!sound->is_streaming_sound()) { src_index %= num_samples; - if (!(flags & AudioSample::kLoop)) { - sample->marked_for_removal = true; + if (!(flags & kLoop)) { + marked_for_removal = true; break; } - } else if (!sample->streaming_in_progress.load( + } else if (!it->get()->streaming_in_progress.load( std::memory_order_acquire)) { if (num_samples) src_index %= num_samples; + // Looping streaming sounds never return eof. if (sound->eof()) { - sample->marked_for_removal = true; + marked_for_removal = true; break; } - sample->streaming_in_progress.store(true, - std::memory_order_relaxed); + it->get()->streaming_in_progress.store(true, + std::memory_order_relaxed); // Swap buffers and start streaming in background. sound->SwapBuffers(); @@ -124,9 +236,8 @@ void AudioBase::RenderAudio(float* output_buffer, size_t num_frames) { src[1] = src[0]; // mono. num_samples = sound->GetNumSamples(); - Worker::Get().PostTask(HERE, - std::bind(&AudioBase::DoStream, this, *it, - flags & AudioSample::kLoop)); + Worker::Get().PostTask(HERE, std::bind(&AudioBase::DoStream, this, + *it, flags & kLoop)); } else if (num_samples) { DLOG << "Buffer underrun!"; src_index %= num_samples; @@ -134,37 +245,44 @@ void AudioBase::RenderAudio(float* output_buffer, size_t num_frames) { } } - sample->src_index = src_index; - sample->accumulator = accumulator; - sample->amplitude = amplitude; + it->get()->src_index = src_index; + it->get()->accumulator = accumulator; + it->get()->amplitude = amplitude; } - if (sample->marked_for_removal && - (!sound->is_streaming_sound() || - !sample->streaming_in_progress.load(std::memory_order_relaxed))) { - sample->marked_for_removal = false; + if (marked_for_removal) { + end_list_.push_back(*it); + it = play_list_[1].erase(it); + } else { + ++it; + } + } + + for (auto it = end_list_.begin(); it != end_list_.end();) { + if ((!it->get()->sound->is_streaming_sound() || + !it->get()->streaming_in_progress.load(std::memory_order_relaxed))) { main_thread_task_runner_->PostTask( HERE, std::bind(&AudioBase::EndCallback, this, *it)); - it = samples_[1].erase(it); + it = end_list_.erase(it); } else { ++it; } } } -void AudioBase::DoStream(std::shared_ptr sample, bool loop) { - sample->sound->Stream(loop); +void AudioBase::DoStream(std::shared_ptr resource, bool loop) { + resource->sound->Stream(loop); // Memory barrier to ensure all memory writes become visible to the audio // thread. - sample->streaming_in_progress.store(false, std::memory_order_release); + resource->streaming_in_progress.store(false, std::memory_order_release); } -void AudioBase::EndCallback(std::shared_ptr sample) { - sample->active = false; +void AudioBase::EndCallback(std::shared_ptr resource) { + resource->active = false; - if (sample->end_cb) - sample->end_cb(); + if (resource->end_cb) + resource->end_cb(); } } // namespace eng diff --git a/src/engine/audio/audio_base.h b/src/engine/audio/audio_base.h index 0fc036d..1b6c6e0 100644 --- a/src/engine/audio/audio_base.h +++ b/src/engine/audio/audio_base.h @@ -4,9 +4,9 @@ #include #include #include +#include #include "../../base/closure.h" -#include "audio_sample.h" namespace base { class TaskRunner; @@ -16,9 +16,26 @@ namespace eng { class Sound; +// Class representing the end-point for rendered audio. A platform specific +// implementation is expected to periodically call RenderAudio() in a background +// thread. class AudioBase { public: - void Play(std::shared_ptr sample); + size_t CreateResource(); + void DestroyResource(size_t resource_id); + + void Play(size_t resource_id, + std::shared_ptr sound, + float amplitude, + bool reset_pos); + void Stop(size_t resource_id); + + void SetLoop(size_t resource_id, bool loop); + void SetSimulateStereo(size_t resource_id, bool simulate); + void SetResampleStep(size_t resource_id, size_t step); + void SetMaxAmplitude(size_t resource_id, float max_amplitude); + void SetAmplitudeInc(size_t resource_id, float amplitude_inc); + void SetEndCallback(size_t resource_id, base::Closure cb); void SetEnableAudio(bool enable) { audio_enabled_ = enable; } @@ -31,16 +48,44 @@ class AudioBase { void RenderAudio(float* output_buffer, size_t num_frames); private: - std::list> samples_[2]; + enum SampleFlags { kLoop = 1, kStopped = 2, kSimulateStereo = 4 }; + + struct Resource { + // Accessed by main thread only. + bool active = false; + base::Closure end_cb; + + // Initialized by main thread, used by audio thread. + std::shared_ptr sound; + size_t src_index = 0; + size_t accumulator = 0; + float amplitude = 1.0f; + + // Write accessed by main thread, read-only accessed by audio thread. + std::atomic flags{0}; + std::atomic step{100}; + std::atomic amplitude_inc{0}; + std::atomic max_amplitude{1.0f}; + + // Accessed by audio thread and decoder thread. + std::atomic streaming_in_progress{false}; + }; + + std::unordered_map> resources_; + size_t last_resource_id_ = 0; + + std::list> play_list_[2]; std::mutex lock_; + std::list> end_list_; + base::TaskRunner* main_thread_task_runner_; bool audio_enabled_ = true; - void DoStream(std::shared_ptr sample, bool loop); + void DoStream(std::shared_ptr sample, bool loop); - void EndCallback(std::shared_ptr sample); + void EndCallback(std::shared_ptr sample); AudioBase(const AudioBase&) = delete; AudioBase& operator=(const AudioBase&) = delete; diff --git a/src/engine/audio/audio_oboe.cc b/src/engine/audio/audio_oboe.cc index 2ad52d1..9e62f3d 100644 --- a/src/engine/audio/audio_oboe.cc +++ b/src/engine/audio/audio_oboe.cc @@ -2,7 +2,6 @@ #include "../../base/log.h" #include "../../third_party/oboe/include/oboe/Oboe.h" -#include "audio_resource.h" using namespace base; diff --git a/src/engine/audio/audio_oboe.h b/src/engine/audio/audio_oboe.h index 7bdecfa..7b76255 100644 --- a/src/engine/audio/audio_oboe.h +++ b/src/engine/audio/audio_oboe.h @@ -9,8 +9,6 @@ namespace eng { -class AudioResource; - class AudioOboe : public AudioBase { public: AudioOboe(); diff --git a/src/engine/audio/audio_resource.cc b/src/engine/audio/audio_resource.cc deleted file mode 100644 index 71f8175..0000000 --- a/src/engine/audio/audio_resource.cc +++ /dev/null @@ -1,92 +0,0 @@ -#include "audio_resource.h" - -#include "../../base/log.h" -#include "../sound.h" -#include "audio.h" -#include "audio_sample.h" - -using namespace base; - -namespace eng { - -AudioResource::AudioResource(Audio* audio) - : sample_(std::make_shared()), audio_(audio) {} - -AudioResource::~AudioResource() { - sample_->flags.fetch_or(AudioSample::kStopped, std::memory_order_relaxed); -} - -void AudioResource::Play(std::shared_ptr sound, - float amplitude, - bool reset_pos) { - AudioSample* sample = sample_.get(); - - if (sample->active) { - if (reset_pos) - sample_->flags.fetch_or(AudioSample::kStopped, std::memory_order_relaxed); - - if (reset_pos || - sample->flags.load(std::memory_order_relaxed) & AudioSample::kStopped) { - Closure ocb = sample_->end_cb; - SetEndCallback([&, sound, amplitude, reset_pos, ocb]() -> void { - Play(sound, amplitude, reset_pos); - SetEndCallback(ocb); - }); - } - - return; - } - - if (reset_pos) { - sample->src_index = 0; - sample->accumulator = 0; - sound->ResetStream(); - } - - sample->active = true; - sample_->flags.fetch_and(~AudioSample::kStopped, std::memory_order_relaxed); - sample->sound = sound; - if (amplitude >= 0) - sample->amplitude = amplitude; - - audio_->Play(sample_); -} - -void AudioResource::Stop() { - if (sample_->active) - sample_->flags.fetch_or(AudioSample::kStopped, std::memory_order_relaxed); -} - -void AudioResource::SetLoop(bool loop) { - if (loop) - sample_->flags.fetch_or(AudioSample::kLoop, std::memory_order_relaxed); - else - sample_->flags.fetch_and(~AudioSample::kLoop, std::memory_order_relaxed); -} - -void AudioResource::SetSimulateStereo(bool simulate) { - if (simulate) - sample_->flags.fetch_or(AudioSample::kSimulateStereo, - std::memory_order_relaxed); - else - sample_->flags.fetch_and(~AudioSample::kSimulateStereo, - std::memory_order_relaxed); -} - -void AudioResource::SetResampleStep(size_t step) { - sample_->step.store(step + 100, std::memory_order_relaxed); -} - -void AudioResource::SetMaxAmplitude(float max_amplitude) { - sample_->max_amplitude.store(max_amplitude, std::memory_order_relaxed); -} - -void AudioResource::SetAmplitudeInc(float amplitude_inc) { - sample_->amplitude_inc.store(amplitude_inc, std::memory_order_relaxed); -} - -void AudioResource::SetEndCallback(base::Closure cb) { - sample_->end_cb = cb; -} - -} // namespace eng diff --git a/src/engine/audio/audio_resource.h b/src/engine/audio/audio_resource.h deleted file mode 100644 index b791227..0000000 --- a/src/engine/audio/audio_resource.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef AUDIO_RESOURCE_H -#define AUDIO_RESOURCE_H - -#include - -#include "../../base/closure.h" -#include "audio_forward.h" - -namespace eng { - -struct AudioSample; -class Sound; - -class AudioResource { - public: - AudioResource(Audio* audio); - ~AudioResource(); - - void Play(std::shared_ptr sound, float amplitude, bool reset_pos); - - void Stop(); - - void SetLoop(bool loop); - void SetSimulateStereo(bool simulate); - void SetResampleStep(size_t step); - void SetMaxAmplitude(float max_amplitude); - void SetAmplitudeInc(float amplitude_inc); - void SetEndCallback(base::Closure cb); - - private: - std::shared_ptr sample_; - - Audio* audio_ = nullptr; - - AudioResource(const AudioResource&) = delete; - AudioResource& operator=(const AudioResource&) = delete; -}; - -} // namespace eng - -#endif // AUDIO_RESOURCE_H diff --git a/src/engine/audio/audio_sample.h b/src/engine/audio/audio_sample.h deleted file mode 100644 index 97035d6..0000000 --- a/src/engine/audio/audio_sample.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef AUDIO_SAMPLE_H -#define AUDIO_SAMPLE_H - -#include -#include - -#include "../../base/closure.h" - -namespace eng { - -class Sound; - -struct AudioSample { - enum SampleFlags { kLoop = 1, kStopped = 2, kSimulateStereo = 4 }; - - // Accessed by main thread only. - bool active = false; - base::Closure end_cb; - - // Accessed by audio thread only. - bool marked_for_removal = false; - - // Initialized by main thread, used by audio thread. - std::shared_ptr sound; - size_t src_index = 0; - size_t accumulator = 0; - float amplitude = 1.0f; - - // Write accessed by main thread, read-only accessed by audio thread. - std::atomic flags{0}; - std::atomic step{100}; - std::atomic amplitude_inc{0}; - std::atomic max_amplitude{1.0f}; - - // Accessed by audio thread and decoder thread. - std::atomic streaming_in_progress{false}; -}; - -} // namespace eng - -#endif // AUDIO_SAMPLE_H diff --git a/src/engine/engine.cc b/src/engine/engine.cc index a4d6e1f..f71adee 100644 --- a/src/engine/engine.cc +++ b/src/engine/engine.cc @@ -4,7 +4,6 @@ #include "../third_party/texture_compressor/texture_compressor.h" #include "animator.h" #include "audio/audio.h" -#include "audio/audio_resource.h" #include "drawable.h" #include "font.h" #include "game.h" @@ -274,10 +273,6 @@ std::shared_ptr Engine::GetTexture(const std::string& asset_name) { return texture; } -std::unique_ptr Engine::CreateAudioResource() { - return std::make_unique(audio_); -} - void Engine::AddInputEvent(std::unique_ptr event) { if (replaying_) return; diff --git a/src/engine/engine.h b/src/engine/engine.h index 0b4fa69..70e5a57 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -19,7 +19,6 @@ class TextureCompressor; namespace eng { class Animator; -class AudioResource; class Font; class Game; class Drawable; @@ -83,8 +82,6 @@ class Engine { std::shared_ptr GetTexture(const std::string& asset_name); - std::unique_ptr CreateAudioResource(); - void AddInputEvent(std::unique_ptr event); std::unique_ptr GetNextInputEvent(); @@ -108,6 +105,8 @@ class Engine { void SetEnableVibration(bool enable) { vibration_enabled_ = enable; } + Audio* GetAudio() { return audio_; } + // Access to the render resources. Geometry* GetQuad() { return quad_.get(); } Shader* GetPassThroughShader() { return pass_through_shader_.get(); } diff --git a/src/engine/sound_player.cc b/src/engine/sound_player.cc index 164b738..9cede1c 100644 --- a/src/engine/sound_player.cc +++ b/src/engine/sound_player.cc @@ -2,7 +2,7 @@ #include "../base/interpolation.h" #include "../base/log.h" -#include "audio/audio_resource.h" +#include "audio/audio.h" #include "engine.h" #include "sound.h" @@ -10,9 +10,12 @@ using namespace base; namespace eng { -SoundPlayer::SoundPlayer() : resource_(Engine::Get().CreateAudioResource()) {} +SoundPlayer::SoundPlayer() + : resource_id_(Engine::Get().GetAudio()->CreateResource()) {} -SoundPlayer::~SoundPlayer() = default; +SoundPlayer::~SoundPlayer() { + Engine::Get().GetAudio()->DestroyResource(resource_id_); +} void SoundPlayer::SetSound(std::shared_ptr sound) { CHECK(!sound->is_streaming_sound()) << "Streaming sound cannot be shared."; @@ -29,14 +32,15 @@ void SoundPlayer::Play(bool loop, float fade_in_duration) { return; int step = variate_ ? Engine::Get().GetRandomGenerator().Roll(3) - 2 : 0; - resource_->SetResampleStep(step * 12); - resource_->SetLoop(loop); + Engine::Get().GetAudio()->SetResampleStep(resource_id_, step * 12); + Engine::Get().GetAudio()->SetLoop(resource_id_, loop); if (fade_in_duration > 0) - resource_->SetAmplitudeInc(1.0f / - (sound_->sample_rate() * fade_in_duration)); + Engine::Get().GetAudio()->SetAmplitudeInc( + resource_id_, 1.0f / (sound_->sample_rate() * fade_in_duration)); else - resource_->SetAmplitudeInc(0); - resource_->Play(sound_, fade_in_duration > 0 ? 0 : max_amplitude_, true); + Engine::Get().GetAudio()->SetAmplitudeInc(resource_id_, 0); + Engine::Get().GetAudio()->Play( + resource_id_, sound_, fade_in_duration > 0 ? 0 : max_amplitude_, true); } void SoundPlayer::Resume(float fade_in_duration) { @@ -44,9 +48,10 @@ void SoundPlayer::Resume(float fade_in_duration) { return; if (fade_in_duration > 0) - resource_->SetAmplitudeInc(1.0f / - (sound_->sample_rate() * fade_in_duration)); - resource_->Play(sound_, fade_in_duration > 0 ? 0 : -1, false); + Engine::Get().GetAudio()->SetAmplitudeInc( + resource_id_, 1.0f / (sound_->sample_rate() * fade_in_duration)); + Engine::Get().GetAudio()->Play(resource_id_, sound_, + fade_in_duration > 0 ? 0 : -1, false); } void SoundPlayer::Stop(float fade_out_duration) { @@ -54,10 +59,10 @@ void SoundPlayer::Stop(float fade_out_duration) { return; if (fade_out_duration > 0) - resource_->SetAmplitudeInc(-1.0f / - (sound_->sample_rate() * fade_out_duration)); + Engine::Get().GetAudio()->SetAmplitudeInc( + resource_id_, -1.0f / (sound_->sample_rate() * fade_out_duration)); else - resource_->Stop(); + Engine::Get().GetAudio()->Stop(resource_id_); } void SoundPlayer::SetVariate(bool variate) { @@ -65,16 +70,16 @@ void SoundPlayer::SetVariate(bool variate) { } void SoundPlayer::SetSimulateStereo(bool simulate) { - resource_->SetSimulateStereo(simulate); + Engine::Get().GetAudio()->SetSimulateStereo(resource_id_, simulate); } void SoundPlayer::SetMaxAplitude(float max_amplitude) { max_amplitude_ = max_amplitude; - resource_->SetMaxAmplitude(max_amplitude); + Engine::Get().GetAudio()->SetMaxAmplitude(resource_id_, max_amplitude); } void SoundPlayer::SetEndCallback(base::Closure cb) { - resource_->SetEndCallback(cb); + Engine::Get().GetAudio()->SetEndCallback(resource_id_, cb); } } // namespace eng diff --git a/src/engine/sound_player.h b/src/engine/sound_player.h index 5cf737f..6313689 100644 --- a/src/engine/sound_player.h +++ b/src/engine/sound_player.h @@ -7,7 +7,6 @@ namespace eng { -class AudioResource; class Sound; class SoundPlayer { @@ -37,7 +36,7 @@ class SoundPlayer { void SetEndCallback(base::Closure cb); private: - std::unique_ptr resource_; + size_t resource_id_ = 0; std::shared_ptr sound_; float max_amplitude_ = 1.0f;