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) {
|
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)
|
if (input->end_cb)
|
||||||
input->end_cb();
|
input->end_cb();
|
||||||
|
|
|
@ -21,45 +21,41 @@ std::shared_ptr<MixerInput> MixerInput::Create() {
|
||||||
return std::shared_ptr<MixerInput>(new MixerInput());
|
return std::shared_ptr<MixerInput>(new MixerInput());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixerInput::Play(AudioMixer* mixer,
|
void MixerInput::SetAudioBus(std::shared_ptr<AudioBus> bus) {
|
||||||
std::shared_ptr<AudioBus> bus,
|
if (streaming)
|
||||||
float amp,
|
pending_audio_bus = bus;
|
||||||
bool restart) {
|
else
|
||||||
|
audio_bus = bus;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixerInput::Play(AudioMixer* mixer, bool restart) {
|
||||||
if (!mixer->IsAudioEnabled())
|
if (!mixer->IsAudioEnabled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (bus != audio_bus || src_index >= bus->samples_per_channel())
|
// If already streaming check if stream position needs to be reset.
|
||||||
restart = true;
|
if (streaming) {
|
||||||
|
|
||||||
if (active) {
|
|
||||||
if (restart)
|
if (restart)
|
||||||
flags.fetch_or(kStopped, std::memory_order_relaxed);
|
flags.fetch_or(kStopped, std::memory_order_relaxed);
|
||||||
|
|
||||||
if (flags.load(std::memory_order_relaxed) & kStopped)
|
if (flags.load(std::memory_order_relaxed) & kStopped)
|
||||||
restart_cb = [&, mixer, bus, amp, restart]() -> void {
|
restart_cb = [&, mixer, restart]() -> void { Play(mixer, restart); };
|
||||||
Play(mixer, bus, amp, restart);
|
|
||||||
};
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (restart) {
|
if (restart || audio_bus->EndOfStream()) {
|
||||||
src_index = 0;
|
src_index = 0;
|
||||||
accumulator = 0;
|
accumulator = 0;
|
||||||
bus->ResetStream();
|
audio_bus->ResetStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
active = true;
|
streaming = true;
|
||||||
flags.fetch_and(~kStopped, std::memory_order_relaxed);
|
flags.fetch_and(~kStopped, std::memory_order_relaxed);
|
||||||
audio_bus = bus;
|
|
||||||
if (amp >= 0)
|
|
||||||
amplitude = amp;
|
|
||||||
|
|
||||||
mixer->AddInput(shared_from_this());
|
mixer->AddInput(shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixerInput::Stop() {
|
void MixerInput::Stop() {
|
||||||
if (active) {
|
if (streaming) {
|
||||||
restart_cb = nullptr;
|
restart_cb = nullptr;
|
||||||
flags.fetch_or(kStopped, std::memory_order_relaxed);
|
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);
|
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) {
|
void MixerInput::SetMaxAmplitude(float value) {
|
||||||
max_amplitude.store(value, std::memory_order_relaxed);
|
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();
|
static std::shared_ptr<MixerInput> Create();
|
||||||
|
|
||||||
void Play(AudioMixer* mixer,
|
// Set AudioBus for playback. If this MixerInput is already streaming, keeps
|
||||||
std::shared_ptr<AudioBus> bus,
|
// it as pending and sets once playback ends.
|
||||||
float amp,
|
void SetAudioBus(std::shared_ptr<AudioBus> bus);
|
||||||
bool restart);
|
|
||||||
|
// 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 Stop();
|
||||||
|
|
||||||
void SetLoop(bool loop);
|
void SetLoop(bool loop);
|
||||||
|
|
||||||
|
// Simulate stereo effect slightly delays one channel.
|
||||||
void SetSimulateStereo(bool simulate);
|
void SetSimulateStereo(bool simulate);
|
||||||
|
|
||||||
|
// Vary basic resampling for sound variations.
|
||||||
void SetResampleStep(size_t value);
|
void SetResampleStep(size_t value);
|
||||||
|
|
||||||
|
// Set the current volume, max volume and volume increment steps.
|
||||||
|
void SetAmplitude(float value);
|
||||||
void SetMaxAmplitude(float value);
|
void SetMaxAmplitude(float value);
|
||||||
void SetAmplitudeInc(float value);
|
void SetAmplitudeInc(float value);
|
||||||
|
|
||||||
|
// Set a callback to be called once playback ends.
|
||||||
void SetEndCallback(base::Closure cb);
|
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.
|
// Accessed by main thread only.
|
||||||
bool active = false;
|
bool streaming = false;
|
||||||
base::Closure end_cb;
|
base::Closure end_cb;
|
||||||
base::Closure restart_cb;
|
base::Closure restart_cb;
|
||||||
|
|
||||||
// Initialized by main thread, used by audio thread.
|
// Accessed by main thread and 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.
|
|
||||||
std::atomic<unsigned> flags{0};
|
std::atomic<unsigned> flags{0};
|
||||||
std::atomic<size_t> step{100};
|
std::atomic<size_t> step{100};
|
||||||
|
std::atomic<float> amplitude{1.0f};
|
||||||
std::atomic<float> amplitude_inc{0};
|
std::atomic<float> amplitude_inc{0};
|
||||||
std::atomic<float> max_amplitude{1.0f};
|
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};
|
std::atomic<bool> streaming_in_progress{false};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -18,45 +18,50 @@ SoundPlayer::~SoundPlayer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundPlayer::SetSound(const std::string& asset_name) {
|
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) {
|
void SoundPlayer::SetSound(std::shared_ptr<AudioBus> sound) {
|
||||||
sound_ = sound;
|
input_->SetAudioBus(sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundPlayer::Play(bool loop, float fade_in_duration) {
|
void SoundPlayer::Play(bool loop, float fade_in_duration) {
|
||||||
if (!sound_)
|
if (!input_->audio_bus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int step = variate_ ? Engine::Get().GetRandomGenerator().Roll(3) - 2 : 0;
|
int step = variate_ ? Engine::Get().GetRandomGenerator().Roll(3) - 2 : 0;
|
||||||
input_->SetResampleStep(step * 12);
|
input_->SetResampleStep(step * 12);
|
||||||
input_->SetLoop(loop);
|
input_->SetLoop(loop);
|
||||||
if (fade_in_duration > 0)
|
if (fade_in_duration > 0) {
|
||||||
input_->SetAmplitudeInc(1.0f / (sound_->sample_rate() * fade_in_duration));
|
input_->SetAmplitude(0);
|
||||||
else
|
input_->SetAmplitudeInc(
|
||||||
|
1.0f / (input_->audio_bus->sample_rate() * fade_in_duration));
|
||||||
|
} else {
|
||||||
|
input_->SetAmplitude(max_amplitude_);
|
||||||
input_->SetAmplitudeInc(0);
|
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) {
|
void SoundPlayer::Resume(float fade_in_duration) {
|
||||||
if (!sound_)
|
if (!input_->audio_bus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fade_in_duration > 0)
|
if (fade_in_duration > 0) {
|
||||||
input_->SetAmplitudeInc(1.0f / (sound_->sample_rate() * fade_in_duration));
|
input_->SetAmplitude(0);
|
||||||
input_->Play(Engine::Get().GetAudioMixer(), sound_,
|
input_->SetAmplitudeInc(
|
||||||
fade_in_duration > 0 ? 0 : -1, false);
|
1.0f / (input_->audio_bus->sample_rate() * fade_in_duration));
|
||||||
|
}
|
||||||
|
input_->Play(Engine::Get().GetAudioMixer(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundPlayer::Stop(float fade_out_duration) {
|
void SoundPlayer::Stop(float fade_out_duration) {
|
||||||
if (!sound_)
|
if (!input_->audio_bus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fade_out_duration > 0)
|
if (fade_out_duration > 0)
|
||||||
input_->SetAmplitudeInc(-1.0f /
|
input_->SetAmplitudeInc(
|
||||||
(sound_->sample_rate() * fade_out_duration));
|
-1.0f / (input_->audio_bus->sample_rate() * fade_out_duration));
|
||||||
else
|
else
|
||||||
input_->Stop();
|
input_->Stop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ class SoundPlayer {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<MixerInput> input_;
|
std::shared_ptr<MixerInput> input_;
|
||||||
std::shared_ptr<AudioBus> sound_;
|
|
||||||
|
|
||||||
float max_amplitude_ = 1.0f;
|
float max_amplitude_ = 1.0f;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue