From 19910be27e2110db4cea1729fdb4ae0fca2867a3 Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Fri, 14 Jul 2023 00:23:43 +0200 Subject: [PATCH] Refactoring and comments for MixerInput --- src/engine/audio/audio_mixer.cc | 7 +++++- src/engine/audio/mixer_input.cc | 38 ++++++++++++++--------------- src/engine/audio/mixer_input.h | 43 +++++++++++++++++++++++---------- src/engine/sound_player.cc | 37 ++++++++++++++++------------ src/engine/sound_player.h | 1 - 5 files changed, 76 insertions(+), 50 deletions(-) diff --git a/src/engine/audio/audio_mixer.cc b/src/engine/audio/audio_mixer.cc index c14340a..f9a7ff3 100644 --- a/src/engine/audio/audio_mixer.cc +++ b/src/engine/audio/audio_mixer.cc @@ -176,7 +176,12 @@ void AudioMixer::DoStream(std::shared_ptr input, bool loop) { } void AudioMixer::EndCallback(std::shared_ptr input) { - input->active = false; + input->streaming = false; + + if (input->pending_audio_bus) { + input->audio_bus = input->pending_audio_bus; + input->pending_audio_bus.reset(); + } if (input->end_cb) input->end_cb(); diff --git a/src/engine/audio/mixer_input.cc b/src/engine/audio/mixer_input.cc index a993d20..98c940c 100644 --- a/src/engine/audio/mixer_input.cc +++ b/src/engine/audio/mixer_input.cc @@ -21,45 +21,41 @@ std::shared_ptr MixerInput::Create() { return std::shared_ptr(new MixerInput()); } -void MixerInput::Play(AudioMixer* mixer, - std::shared_ptr bus, - float amp, - bool restart) { +void MixerInput::SetAudioBus(std::shared_ptr bus) { + if (streaming) + pending_audio_bus = bus; + else + audio_bus = bus; +} + +void MixerInput::Play(AudioMixer* mixer, bool restart) { if (!mixer->IsAudioEnabled()) return; - if (bus != audio_bus || src_index >= bus->samples_per_channel()) - restart = true; - - if (active) { + // If already streaming check if stream position needs to be reset. + if (streaming) { if (restart) flags.fetch_or(kStopped, std::memory_order_relaxed); if (flags.load(std::memory_order_relaxed) & kStopped) - restart_cb = [&, mixer, bus, amp, restart]() -> void { - Play(mixer, bus, amp, restart); - }; + restart_cb = [&, mixer, restart]() -> void { Play(mixer, restart); }; return; } - if (restart) { + if (restart || audio_bus->EndOfStream()) { src_index = 0; accumulator = 0; - bus->ResetStream(); + audio_bus->ResetStream(); } - active = true; + streaming = true; flags.fetch_and(~kStopped, std::memory_order_relaxed); - audio_bus = bus; - if (amp >= 0) - amplitude = amp; - mixer->AddInput(shared_from_this()); } void MixerInput::Stop() { - if (active) { + if (streaming) { restart_cb = nullptr; flags.fetch_or(kStopped, std::memory_order_relaxed); } @@ -83,6 +79,10 @@ void MixerInput::SetResampleStep(size_t value) { step.store(value + 100, std::memory_order_relaxed); } +void MixerInput::SetAmplitude(float value) { + amplitude.store(value, std::memory_order_relaxed); +} + void MixerInput::SetMaxAmplitude(float value) { max_amplitude.store(value, std::memory_order_relaxed); } diff --git a/src/engine/audio/mixer_input.h b/src/engine/audio/mixer_input.h index dee474b..8920fde 100644 --- a/src/engine/audio/mixer_input.h +++ b/src/engine/audio/mixer_input.h @@ -20,37 +20,54 @@ struct MixerInput : public std::enable_shared_from_this { static std::shared_ptr Create(); - void Play(AudioMixer* mixer, - std::shared_ptr bus, - float amp, - bool restart); + // Set AudioBus for playback. If this MixerInput is already streaming, keeps + // it as pending and sets once playback ends. + void SetAudioBus(std::shared_ptr bus); + + // Starts playback. Remembers last stream position. Resets the stream position + // if restart is true. + void Play(AudioMixer* mixer, bool restart); + + // Stops playback. Does not reset stream position. void Stop(); void SetLoop(bool loop); + + // Simulate stereo effect slightly delays one channel. void SetSimulateStereo(bool simulate); + + // Vary basic resampling for sound variations. void SetResampleStep(size_t value); + + // Set the current volume, max volume and volume increment steps. + void SetAmplitude(float value); void SetMaxAmplitude(float value); void SetAmplitudeInc(float value); + + // Set a callback to be called once playback ends. void SetEndCallback(base::Closure cb); + // Active AudioBus. + std::shared_ptr audio_bus; + // AudioBus to be set as active once playback ends. + std::shared_ptr pending_audio_bus; + // Stream position. + size_t src_index = 0; + size_t accumulator = 0; + // Accessed by main thread only. - bool active = false; + bool streaming = false; base::Closure end_cb; base::Closure restart_cb; - // Initialized by main thread, used by audio thread. - std::shared_ptr audio_bus; - size_t src_index = 0; - size_t accumulator = 0; - float amplitude = 1.0f; - - // Write accessed by main thread, read-only accessed by audio thread. + // Accessed by main thread and audio thread. std::atomic flags{0}; std::atomic step{100}; + std::atomic amplitude{1.0f}; std::atomic amplitude_inc{0}; std::atomic max_amplitude{1.0f}; - // Accessed by audio thread and decoder thread. + // Accessed by audio thread and decoding worker thread. std::atomic streaming_in_progress{false}; private: diff --git a/src/engine/sound_player.cc b/src/engine/sound_player.cc index 0c8a084..51b536b 100644 --- a/src/engine/sound_player.cc +++ b/src/engine/sound_player.cc @@ -18,45 +18,50 @@ SoundPlayer::~SoundPlayer() { } void SoundPlayer::SetSound(const std::string& asset_name) { - sound_ = Engine::Get().GetAudioBus(asset_name); + input_->SetAudioBus(Engine::Get().GetAudioBus(asset_name)); } void SoundPlayer::SetSound(std::shared_ptr sound) { - sound_ = sound; + input_->SetAudioBus(sound); } void SoundPlayer::Play(bool loop, float fade_in_duration) { - if (!sound_) + if (!input_->audio_bus) return; int step = variate_ ? Engine::Get().GetRandomGenerator().Roll(3) - 2 : 0; input_->SetResampleStep(step * 12); input_->SetLoop(loop); - if (fade_in_duration > 0) - input_->SetAmplitudeInc(1.0f / (sound_->sample_rate() * fade_in_duration)); - else + if (fade_in_duration > 0) { + input_->SetAmplitude(0); + input_->SetAmplitudeInc( + 1.0f / (input_->audio_bus->sample_rate() * fade_in_duration)); + } else { + input_->SetAmplitude(max_amplitude_); input_->SetAmplitudeInc(0); - input_->Play(Engine::Get().GetAudioMixer(), sound_, - fade_in_duration > 0 ? 0 : max_amplitude_, true); + } + input_->Play(Engine::Get().GetAudioMixer(), true); } void SoundPlayer::Resume(float fade_in_duration) { - if (!sound_) + if (!input_->audio_bus) return; - if (fade_in_duration > 0) - input_->SetAmplitudeInc(1.0f / (sound_->sample_rate() * fade_in_duration)); - input_->Play(Engine::Get().GetAudioMixer(), sound_, - fade_in_duration > 0 ? 0 : -1, false); + if (fade_in_duration > 0) { + input_->SetAmplitude(0); + input_->SetAmplitudeInc( + 1.0f / (input_->audio_bus->sample_rate() * fade_in_duration)); + } + input_->Play(Engine::Get().GetAudioMixer(), false); } void SoundPlayer::Stop(float fade_out_duration) { - if (!sound_) + if (!input_->audio_bus) return; if (fade_out_duration > 0) - input_->SetAmplitudeInc(-1.0f / - (sound_->sample_rate() * fade_out_duration)); + input_->SetAmplitudeInc( + -1.0f / (input_->audio_bus->sample_rate() * fade_out_duration)); else input_->Stop(); } diff --git a/src/engine/sound_player.h b/src/engine/sound_player.h index 6af7cb5..9b692b2 100644 --- a/src/engine/sound_player.h +++ b/src/engine/sound_player.h @@ -39,7 +39,6 @@ class SoundPlayer { private: std::shared_ptr input_; - std::shared_ptr sound_; float max_amplitude_ = 1.0f;