From e509588f61500886e0a0dfaff4fac0e0ca1a1bfa Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Mon, 10 Jul 2023 20:32:56 +0200 Subject: [PATCH] Optimization for AudioMixer Remove resource map and use std::shared_ptr --- src/base/thread_pool.cc | 4 - src/engine/audio/audio_mixer.cc | 165 +++++++++++++------------------- src/engine/audio/audio_mixer.h | 25 +++-- src/engine/sound_player.cc | 28 +++--- src/engine/sound_player.h | 2 +- 5 files changed, 95 insertions(+), 129 deletions(-) diff --git a/src/base/thread_pool.cc b/src/base/thread_pool.cc index 03b3f99..1d86297 100644 --- a/src/base/thread_pool.cc +++ b/src/base/thread_pool.cc @@ -41,8 +41,6 @@ void ThreadPool::Shutdown() { } void ThreadPool::PostTask(Location from, Closure task, bool front) { - DCHECK((!threads_.empty())); - task_runner_.PostTask(from, std::move(task), front); semaphore_.release(); } @@ -51,8 +49,6 @@ void ThreadPool::PostTaskAndReply(Location from, Closure task, Closure reply, bool front) { - DCHECK((!threads_.empty())); - task_runner_.PostTaskAndReply(from, std::move(task), std::move(reply), front); semaphore_.release(); } diff --git a/src/engine/audio/audio_mixer.cc b/src/engine/audio/audio_mixer.cc index dab15cd..8b51b57 100644 --- a/src/engine/audio/audio_mixer.cc +++ b/src/engine/audio/audio_mixer.cc @@ -17,6 +17,10 @@ using namespace base; namespace eng { +AudioMixer::Resource::~Resource() { + DLOG(1) << "Destroying audio resource: " << uintptr_t(this); +} + AudioMixer::AudioMixer() : main_thread_task_runner_(TaskRunner::GetThreadLocalTaskRunner()), #if defined(__ANDROID__) @@ -28,131 +32,102 @@ AudioMixer::AudioMixer() CHECK(res) << "Failed to initialize audio sink."; } -AudioMixer::~AudioMixer() = default; - -uint64_t AudioMixer::CreateResource() { - uint64_t resource_id = ++last_resource_id_; - resources_[resource_id] = std::make_shared(); - return resource_id; +AudioMixer::~AudioMixer() { + audio_sink_.reset(); } -void AudioMixer::DestroyResource(uint64_t resource_id) { - auto it = resources_.find(resource_id); - if (it == resources_.end()) - return; - - if (it->second->active) { - it->second->restart_cb = nullptr; - it->second->flags.fetch_or(kStopped, std::memory_order_relaxed); - } - resources_.erase(it); +std::shared_ptr AudioMixer::CreateResource() { + auto resource = std::make_shared(); + DLOG(1) << "Audio resource created: " << uintptr_t(resource.get()); + return resource; } -void AudioMixer::Play(uint64_t resource_id, +void AudioMixer::Play(std::shared_ptr resource, std::shared_ptr audio_bus, float amplitude, bool reset_pos) { if (!audio_enabled_) return; - auto it = resources_.find(resource_id); - if (it == resources_.end()) - return; + auto resource_ptr = std::static_pointer_cast(resource); - if (it->second->active) { + if (resource_ptr->active) { if (reset_pos) - it->second->flags.fetch_or(kStopped, std::memory_order_relaxed); + resource_ptr->flags.fetch_or(kStopped, std::memory_order_relaxed); - if (it->second->flags.load(std::memory_order_relaxed) & kStopped) - it->second->restart_cb = [&, resource_id, audio_bus, amplitude, - reset_pos]() -> void { - Play(resource_id, audio_bus, amplitude, reset_pos); + if (resource_ptr->flags.load(std::memory_order_relaxed) & kStopped) + resource_ptr->restart_cb = [&, resource, audio_bus, amplitude, + reset_pos]() -> void { + Play(resource, audio_bus, amplitude, reset_pos); }; return; } if (reset_pos) { - it->second->src_index = 0; - it->second->accumulator = 0; + resource_ptr->src_index = 0; + resource_ptr->accumulator = 0; audio_bus->ResetStream(); - } else if (it->second->src_index >= audio_bus->samples_per_channel()) { + } else if (resource_ptr->src_index >= audio_bus->samples_per_channel()) { return; } - it->second->active = true; - it->second->flags.fetch_and(~kStopped, std::memory_order_relaxed); - it->second->audio_bus = audio_bus; + resource_ptr->active = true; + resource_ptr->flags.fetch_and(~kStopped, std::memory_order_relaxed); + resource_ptr->audio_bus = audio_bus; if (amplitude >= 0) - it->second->amplitude = amplitude; + resource_ptr->amplitude = amplitude; std::lock_guard scoped_lock(lock_); - play_list_[0].push_back(it->second); + play_list_[0].push_back(resource_ptr); } -void AudioMixer::Stop(uint64_t resource_id) { - auto it = resources_.find(resource_id); - if (it == resources_.end()) - return; - - if (it->second->active) { - it->second->restart_cb = nullptr; - it->second->flags.fetch_or(kStopped, std::memory_order_relaxed); +void AudioMixer::Stop(std::shared_ptr resource) { + auto resource_ptr = std::static_pointer_cast(resource); + if (resource_ptr->active) { + resource_ptr->restart_cb = nullptr; + resource_ptr->flags.fetch_or(kStopped, std::memory_order_relaxed); } } -void AudioMixer::SetLoop(uint64_t resource_id, bool loop) { - auto it = resources_.find(resource_id); - if (it == resources_.end()) - return; - +void AudioMixer::SetLoop(std::shared_ptr resource, bool loop) { + auto resource_ptr = std::static_pointer_cast(resource); if (loop) - it->second->flags.fetch_or(kLoop, std::memory_order_relaxed); + resource_ptr->flags.fetch_or(kLoop, std::memory_order_relaxed); else - it->second->flags.fetch_and(~kLoop, std::memory_order_relaxed); + resource_ptr->flags.fetch_and(~kLoop, std::memory_order_relaxed); } -void AudioMixer::SetSimulateStereo(uint64_t resource_id, bool simulate) { - auto it = resources_.find(resource_id); - if (it == resources_.end()) - return; - +void AudioMixer::SetSimulateStereo(std::shared_ptr resource, + bool simulate) { + auto resource_ptr = std::static_pointer_cast(resource); if (simulate) - it->second->flags.fetch_or(kSimulateStereo, std::memory_order_relaxed); + resource_ptr->flags.fetch_or(kSimulateStereo, std::memory_order_relaxed); else - it->second->flags.fetch_and(~kSimulateStereo, std::memory_order_relaxed); + resource_ptr->flags.fetch_and(~kSimulateStereo, std::memory_order_relaxed); } -void AudioMixer::SetResampleStep(uint64_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 AudioMixer::SetResampleStep(std::shared_ptr resource, size_t step) { + auto resource_ptr = std::static_pointer_cast(resource); + resource_ptr->step.store(step + 100, std::memory_order_relaxed); } -void AudioMixer::SetMaxAmplitude(uint64_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 AudioMixer::SetMaxAmplitude(std::shared_ptr resource, + float max_amplitude) { + auto resource_ptr = std::static_pointer_cast(resource); + resource_ptr->max_amplitude.store(max_amplitude, std::memory_order_relaxed); } -void AudioMixer::SetAmplitudeInc(uint64_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 AudioMixer::SetAmplitudeInc(std::shared_ptr resource, + float amplitude_inc) { + auto resource_ptr = std::static_pointer_cast(resource); + resource_ptr->amplitude_inc.store(amplitude_inc, std::memory_order_relaxed); } -void AudioMixer::SetEndCallback(uint64_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 AudioMixer::SetEndCallback(std::shared_ptr resource, + base::Closure cb) { + auto resource_ptr = std::static_pointer_cast(resource); + resource_ptr->end_cb = std::move(cb); } void AudioMixer::Suspend() { @@ -177,8 +152,8 @@ void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) { memset(output_buffer, 0, sizeof(float) * num_frames * kChannelCount); for (auto it = play_list_[1].begin(); it != play_list_[1].end();) { - auto audio_bus = it->get()->audio_bus.get(); - unsigned flags = it->get()->flags.load(std::memory_order_relaxed); + auto audio_bus = (*it)->audio_bus.get(); + unsigned flags = (*it)->flags.load(std::memory_order_relaxed); bool marked_for_removal = false; if (flags & kStopped) { @@ -190,14 +165,14 @@ void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) { src[1] = src[0]; // mono. size_t num_samples = audio_bus->samples_per_channel(); - 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; + size_t src_index = (*it)->src_index; + size_t step = (*it)->step.load(std::memory_order_relaxed); + size_t accumulator = (*it)->accumulator; + float amplitude = (*it)->amplitude; float amplitude_inc = - it->get()->amplitude_inc.load(std::memory_order_relaxed); + (*it)->amplitude_inc.load(std::memory_order_relaxed); float max_amplitude = - it->get()->max_amplitude.load(std::memory_order_relaxed); + (*it)->max_amplitude.load(std::memory_order_relaxed); size_t channel_offset = (flags & kSimulateStereo) ? audio_bus->sample_rate() / 10 : 0; @@ -237,11 +212,9 @@ void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) { break; } - if (!it->get()->streaming_in_progress.load( - std::memory_order_acquire)) { + if (!(*it)->streaming_in_progress.load(std::memory_order_acquire)) { src_index %= num_samples; - it->get()->streaming_in_progress.store(true, - std::memory_order_relaxed); + (*it)->streaming_in_progress.store(true, std::memory_order_relaxed); // Swap buffers and start streaming in background. audio_bus->SwapBuffers(); @@ -261,9 +234,9 @@ void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) { } } - it->get()->src_index = src_index; - it->get()->accumulator = accumulator; - it->get()->amplitude = amplitude; + (*it)->src_index = src_index; + (*it)->accumulator = accumulator; + (*it)->amplitude = amplitude; } if (marked_for_removal) { @@ -275,7 +248,7 @@ void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) { } for (auto it = end_list_.begin(); it != end_list_.end();) { - if (!it->get()->streaming_in_progress.load(std::memory_order_relaxed)) { + if (!(*it)->streaming_in_progress.load(std::memory_order_relaxed)) { main_thread_task_runner_->PostTask( HERE, std::bind(&AudioMixer::EndCallback, this, *it)); it = end_list_.erase(it); diff --git a/src/engine/audio/audio_mixer.h b/src/engine/audio/audio_mixer.h index 5884b41..6e82c35 100644 --- a/src/engine/audio/audio_mixer.h +++ b/src/engine/audio/audio_mixer.h @@ -5,7 +5,6 @@ #include #include #include -#include #include "base/closure.h" #include "engine/audio/audio_sink.h" @@ -26,21 +25,20 @@ class AudioMixer : public AudioSink::Delegate { AudioMixer(); ~AudioMixer(); - uint64_t CreateResource(); - void DestroyResource(uint64_t resource_id); + std::shared_ptr CreateResource(); - void Play(uint64_t resource_id, + void Play(std::shared_ptr resource, std::shared_ptr audio_bus, float amplitude, bool reset_pos); - void Stop(uint64_t resource_id); + void Stop(std::shared_ptr resource); - void SetLoop(uint64_t resource_id, bool loop); - void SetSimulateStereo(uint64_t resource_id, bool simulate); - void SetResampleStep(uint64_t resource_id, size_t step); - void SetMaxAmplitude(uint64_t resource_id, float max_amplitude); - void SetAmplitudeInc(uint64_t resource_id, float amplitude_inc); - void SetEndCallback(uint64_t resource_id, base::Closure cb); + void SetLoop(std::shared_ptr resource, bool loop); + void SetSimulateStereo(std::shared_ptr resource, bool simulate); + void SetResampleStep(std::shared_ptr resource, size_t step); + void SetMaxAmplitude(std::shared_ptr resource, float max_amplitude); + void SetAmplitudeInc(std::shared_ptr resource, float amplitude_inc); + void SetEndCallback(std::shared_ptr resource, base::Closure cb); void SetEnableAudio(bool enable) { audio_enabled_ = enable; } @@ -74,10 +72,9 @@ class AudioMixer : public AudioSink::Delegate { // Accessed by audio thread and decoder thread. std::atomic streaming_in_progress{false}; - }; - std::unordered_map> resources_; - uint64_t last_resource_id_ = 0; + ~Resource(); + }; std::list> play_list_[2]; std::mutex lock_; diff --git a/src/engine/sound_player.cc b/src/engine/sound_player.cc index 06f37ae..44b2067 100644 --- a/src/engine/sound_player.cc +++ b/src/engine/sound_player.cc @@ -11,10 +11,10 @@ using namespace base; namespace eng { SoundPlayer::SoundPlayer() - : resource_id_(Engine::Get().GetAudioMixer()->CreateResource()) {} + : resource_(Engine::Get().GetAudioMixer()->CreateResource()) {} SoundPlayer::~SoundPlayer() { - Engine::Get().GetAudioMixer()->DestroyResource(resource_id_); + Engine::Get().GetAudioMixer()->Stop(resource_); } void SoundPlayer::SetSound(const std::string& asset_name) { @@ -30,15 +30,15 @@ void SoundPlayer::Play(bool loop, float fade_in_duration) { return; int step = variate_ ? Engine::Get().GetRandomGenerator().Roll(3) - 2 : 0; - Engine::Get().GetAudioMixer()->SetResampleStep(resource_id_, step * 12); - Engine::Get().GetAudioMixer()->SetLoop(resource_id_, loop); + Engine::Get().GetAudioMixer()->SetResampleStep(resource_, step * 12); + Engine::Get().GetAudioMixer()->SetLoop(resource_, loop); if (fade_in_duration > 0) Engine::Get().GetAudioMixer()->SetAmplitudeInc( - resource_id_, 1.0f / (sound_->sample_rate() * fade_in_duration)); + resource_, 1.0f / (sound_->sample_rate() * fade_in_duration)); else - Engine::Get().GetAudioMixer()->SetAmplitudeInc(resource_id_, 0); + Engine::Get().GetAudioMixer()->SetAmplitudeInc(resource_, 0); Engine::Get().GetAudioMixer()->Play( - resource_id_, sound_, fade_in_duration > 0 ? 0 : max_amplitude_, true); + resource_, sound_, fade_in_duration > 0 ? 0 : max_amplitude_, true); } void SoundPlayer::Resume(float fade_in_duration) { @@ -47,8 +47,8 @@ void SoundPlayer::Resume(float fade_in_duration) { if (fade_in_duration > 0) Engine::Get().GetAudioMixer()->SetAmplitudeInc( - resource_id_, 1.0f / (sound_->sample_rate() * fade_in_duration)); - Engine::Get().GetAudioMixer()->Play(resource_id_, sound_, + resource_, 1.0f / (sound_->sample_rate() * fade_in_duration)); + Engine::Get().GetAudioMixer()->Play(resource_, sound_, fade_in_duration > 0 ? 0 : -1, false); } @@ -58,9 +58,9 @@ void SoundPlayer::Stop(float fade_out_duration) { if (fade_out_duration > 0) Engine::Get().GetAudioMixer()->SetAmplitudeInc( - resource_id_, -1.0f / (sound_->sample_rate() * fade_out_duration)); + resource_, -1.0f / (sound_->sample_rate() * fade_out_duration)); else - Engine::Get().GetAudioMixer()->Stop(resource_id_); + Engine::Get().GetAudioMixer()->Stop(resource_); } void SoundPlayer::SetVariate(bool variate) { @@ -68,16 +68,16 @@ void SoundPlayer::SetVariate(bool variate) { } void SoundPlayer::SetSimulateStereo(bool simulate) { - Engine::Get().GetAudioMixer()->SetSimulateStereo(resource_id_, simulate); + Engine::Get().GetAudioMixer()->SetSimulateStereo(resource_, simulate); } void SoundPlayer::SetMaxAplitude(float max_amplitude) { max_amplitude_ = max_amplitude; - Engine::Get().GetAudioMixer()->SetMaxAmplitude(resource_id_, max_amplitude); + Engine::Get().GetAudioMixer()->SetMaxAmplitude(resource_, max_amplitude); } void SoundPlayer::SetEndCallback(base::Closure cb) { - Engine::Get().GetAudioMixer()->SetEndCallback(resource_id_, cb); + Engine::Get().GetAudioMixer()->SetEndCallback(resource_, cb); } } // namespace eng diff --git a/src/engine/sound_player.h b/src/engine/sound_player.h index a7aa246..808fa12 100644 --- a/src/engine/sound_player.h +++ b/src/engine/sound_player.h @@ -37,7 +37,7 @@ class SoundPlayer { void SetEndCallback(base::Closure cb); private: - uint64_t resource_id_ = 0; + std::shared_ptr resource_; std::shared_ptr sound_; float max_amplitude_ = 1.0f;