mirror of https://github.com/auygun/kaliber.git
Refactoring and comments for MixerInput
This commit is contained in:
parent
34a73082a6
commit
19910be27e
|
@ -176,7 +176,12 @@ void AudioMixer::DoStream(std::shared_ptr<MixerInput> input, bool loop) {
|
|||
}
|
||||
|
||||
void AudioMixer::EndCallback(std::shared_ptr<MixerInput> 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();
|
||||
|
|
|
@ -21,45 +21,41 @@ std::shared_ptr<MixerInput> MixerInput::Create() {
|
|||
return std::shared_ptr<MixerInput>(new MixerInput());
|
||||
}
|
||||
|
||||
void MixerInput::Play(AudioMixer* mixer,
|
||||
std::shared_ptr<AudioBus> bus,
|
||||
float amp,
|
||||
bool restart) {
|
||||
void MixerInput::SetAudioBus(std::shared_ptr<AudioBus> 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);
|
||||
}
|
||||
|
|
|
@ -20,37 +20,54 @@ struct MixerInput : public std::enable_shared_from_this<MixerInput> {
|
|||
|
||||
static std::shared_ptr<MixerInput> Create();
|
||||
|
||||
void Play(AudioMixer* mixer,
|
||||
std::shared_ptr<AudioBus> 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<AudioBus> 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<AudioBus> audio_bus;
|
||||
// AudioBus to be set as active once playback ends.
|
||||
std::shared_ptr<AudioBus> 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<AudioBus> 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<unsigned> flags{0};
|
||||
std::atomic<size_t> step{100};
|
||||
std::atomic<float> amplitude{1.0f};
|
||||
std::atomic<float> amplitude_inc{0};
|
||||
std::atomic<float> max_amplitude{1.0f};
|
||||
|
||||
// Accessed by audio thread and decoder thread.
|
||||
// Accessed by audio thread and decoding worker thread.
|
||||
std::atomic<bool> streaming_in_progress{false};
|
||||
|
||||
private:
|
||||
|
|
|
@ -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<AudioBus> 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();
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ class SoundPlayer {
|
|||
|
||||
private:
|
||||
std::shared_ptr<MixerInput> input_;
|
||||
std::shared_ptr<AudioBus> sound_;
|
||||
|
||||
float max_amplitude_ = 1.0f;
|
||||
|
||||
|
|
Loading…
Reference in New Issue