mirror of https://github.com/auygun/kaliber.git
Make member variables in MixerInput private
This commit is contained in:
parent
19910be27e
commit
e65d37e846
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include "base/log.h"
|
#include "base/log.h"
|
||||||
#include "base/task_runner.h"
|
#include "base/task_runner.h"
|
||||||
#include "base/thread_pool.h"
|
|
||||||
#include "engine/audio/audio_bus.h"
|
#include "engine/audio/audio_bus.h"
|
||||||
#include "engine/audio/mixer_input.h"
|
#include "engine/audio/mixer_input.h"
|
||||||
|
|
||||||
|
@ -33,11 +32,11 @@ AudioMixer::~AudioMixer() {
|
||||||
audio_sink_.reset();
|
audio_sink_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioMixer::AddInput(std::shared_ptr<MixerInput> input) {
|
void AudioMixer::AddInput(std::shared_ptr<MixerInput> mixer_input) {
|
||||||
DCHECK(audio_enabled_);
|
DCHECK(audio_enabled_);
|
||||||
|
|
||||||
std::lock_guard<std::mutex> scoped_lock(lock_);
|
std::lock_guard<std::mutex> scoped_lock(lock_);
|
||||||
inputs_[0].push_back(input);
|
inputs_[0].push_back(mixer_input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioMixer::Suspend() {
|
void AudioMixer::Suspend() {
|
||||||
|
@ -62,8 +61,8 @@ void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) {
|
||||||
memset(output_buffer, 0, sizeof(float) * num_frames * kChannelCount);
|
memset(output_buffer, 0, sizeof(float) * num_frames * kChannelCount);
|
||||||
|
|
||||||
for (auto it = inputs_[1].begin(); it != inputs_[1].end();) {
|
for (auto it = inputs_[1].begin(); it != inputs_[1].end();) {
|
||||||
auto audio_bus = (*it)->audio_bus.get();
|
auto* audio_bus = (*it)->GetAudioBus().get();
|
||||||
unsigned flags = (*it)->flags.load(std::memory_order_relaxed);
|
unsigned flags = (*it)->GetFlags();
|
||||||
bool marked_for_removal = false;
|
bool marked_for_removal = false;
|
||||||
|
|
||||||
if (flags & MixerInput::kStopped) {
|
if (flags & MixerInput::kStopped) {
|
||||||
|
@ -75,14 +74,12 @@ void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) {
|
||||||
src[1] = src[0]; // mono.
|
src[1] = src[0]; // mono.
|
||||||
|
|
||||||
size_t num_samples = audio_bus->samples_per_channel();
|
size_t num_samples = audio_bus->samples_per_channel();
|
||||||
size_t src_index = (*it)->src_index;
|
size_t src_index = (*it)->GetSrcIndex();
|
||||||
size_t step = (*it)->step.load(std::memory_order_relaxed);
|
size_t step = (*it)->GetStep();
|
||||||
size_t accumulator = (*it)->accumulator;
|
size_t accumulator = (*it)->GetAccumulator();
|
||||||
float amplitude = (*it)->amplitude;
|
float amplitude = (*it)->GetAmplitude();
|
||||||
float amplitude_inc =
|
float amplitude_inc = (*it)->GetAmplitudeInc();
|
||||||
(*it)->amplitude_inc.load(std::memory_order_relaxed);
|
float max_amplitude = (*it)->GetMaxAmplitude();
|
||||||
float max_amplitude =
|
|
||||||
(*it)->max_amplitude.load(std::memory_order_relaxed);
|
|
||||||
size_t channel_offset = (flags & MixerInput::kSimulateStereo)
|
size_t channel_offset = (flags & MixerInput::kSimulateStereo)
|
||||||
? audio_bus->sample_rate() / 10
|
? audio_bus->sample_rate() / 10
|
||||||
: 0;
|
: 0;
|
||||||
|
@ -118,37 +115,29 @@ void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) {
|
||||||
accumulator %= 100;
|
accumulator %= 100;
|
||||||
} else {
|
} else {
|
||||||
if (audio_bus->EndOfStream()) {
|
if (audio_bus->EndOfStream()) {
|
||||||
src_index %= num_samples;
|
if (!(flags & MixerInput::kLoop))
|
||||||
marked_for_removal = !(flags & MixerInput::kLoop);
|
marked_for_removal = true;
|
||||||
|
else
|
||||||
|
src_index %= num_samples;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*it)->streaming_in_progress.load(std::memory_order_acquire)) {
|
if ((*it)->OnMoreData(!!(flags & MixerInput::kLoop))) {
|
||||||
src_index %= num_samples;
|
src_index %= num_samples;
|
||||||
(*it)->streaming_in_progress.store(true, std::memory_order_relaxed);
|
|
||||||
|
|
||||||
// Swap buffers and start streaming in background.
|
|
||||||
audio_bus->SwapBuffers();
|
|
||||||
src[0] = audio_bus->GetChannelData(0);
|
src[0] = audio_bus->GetChannelData(0);
|
||||||
src[1] = audio_bus->GetChannelData(1);
|
src[1] = audio_bus->GetChannelData(1);
|
||||||
if (!src[1])
|
if (!src[1])
|
||||||
src[1] = src[0]; // mono.
|
src[1] = src[0]; // mono.
|
||||||
num_samples = audio_bus->samples_per_channel();
|
num_samples = audio_bus->samples_per_channel();
|
||||||
|
|
||||||
ThreadPool::Get().PostTask(
|
|
||||||
HERE,
|
|
||||||
std::bind(&AudioMixer::DoStream, this, *it,
|
|
||||||
flags & MixerInput::kLoop),
|
|
||||||
true);
|
|
||||||
} else {
|
} else {
|
||||||
DLOG(0) << "Mixer buffer underrun!";
|
DLOG(0) << "Mixer buffer underrun!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(*it)->src_index = src_index;
|
// Remember last sample position and volume.
|
||||||
(*it)->accumulator = accumulator;
|
(*it)->SetPosition(src_index, accumulator);
|
||||||
(*it)->amplitude = amplitude;
|
(*it)->SetAmplitude(amplitude);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (marked_for_removal) {
|
if (marked_for_removal) {
|
||||||
|
@ -160,9 +149,9 @@ void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it = removed_inputs_.begin(); it != removed_inputs_.end();) {
|
for (auto it = removed_inputs_.begin(); it != removed_inputs_.end();) {
|
||||||
if (!(*it)->streaming_in_progress.load(std::memory_order_relaxed)) {
|
if (!(*it)->IsStreamingInProgress()) {
|
||||||
main_thread_task_runner_->PostTask(
|
main_thread_task_runner_->PostTask(
|
||||||
HERE, std::bind(&AudioMixer::EndCallback, this, *it));
|
HERE, std::bind(&MixerInput::OnRemovedFromMixer, *it));
|
||||||
it = removed_inputs_.erase(it);
|
it = removed_inputs_.erase(it);
|
||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
|
@ -170,25 +159,4 @@ void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioMixer::DoStream(std::shared_ptr<MixerInput> input, bool loop) {
|
|
||||||
input->audio_bus->Stream(loop);
|
|
||||||
input->streaming_in_progress.store(false, std::memory_order_release);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioMixer::EndCallback(std::shared_ptr<MixerInput> input) {
|
|
||||||
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();
|
|
||||||
if (input->restart_cb) {
|
|
||||||
input->restart_cb();
|
|
||||||
input->restart_cb = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace eng
|
} // namespace eng
|
||||||
|
|
|
@ -14,8 +14,7 @@ class TaskRunner;
|
||||||
|
|
||||||
namespace eng {
|
namespace eng {
|
||||||
|
|
||||||
class AudioBus;
|
class MixerInput;
|
||||||
struct MixerInput;
|
|
||||||
|
|
||||||
// Mix and render audio with low overhead. The mixer has zero or more inputs
|
// Mix and render audio with low overhead. The mixer has zero or more inputs
|
||||||
// which can be added at any time. The mixer will pull from each input source
|
// which can be added at any time. The mixer will pull from each input source
|
||||||
|
@ -29,7 +28,7 @@ class AudioMixer : public AudioSink::Delegate {
|
||||||
AudioMixer();
|
AudioMixer();
|
||||||
~AudioMixer();
|
~AudioMixer();
|
||||||
|
|
||||||
void AddInput(std::shared_ptr<MixerInput> input);
|
void AddInput(std::shared_ptr<MixerInput> mixer_input);
|
||||||
|
|
||||||
void SetEnableAudio(bool enable) { audio_enabled_ = enable; }
|
void SetEnableAudio(bool enable) { audio_enabled_ = enable; }
|
||||||
bool IsAudioEnabled() const { return audio_enabled_; }
|
bool IsAudioEnabled() const { return audio_enabled_; }
|
||||||
|
@ -57,10 +56,6 @@ class AudioMixer : public AudioSink::Delegate {
|
||||||
int GetChannelCount() final { return kChannelCount; }
|
int GetChannelCount() final { return kChannelCount; }
|
||||||
void RenderAudio(float* output_buffer, size_t num_frames) final;
|
void RenderAudio(float* output_buffer, size_t num_frames) final;
|
||||||
|
|
||||||
void DoStream(std::shared_ptr<MixerInput> sample, bool loop);
|
|
||||||
|
|
||||||
void EndCallback(std::shared_ptr<MixerInput> sample);
|
|
||||||
|
|
||||||
AudioMixer(const AudioMixer&) = delete;
|
AudioMixer(const AudioMixer&) = delete;
|
||||||
AudioMixer& operator=(const AudioMixer&) = delete;
|
AudioMixer& operator=(const AudioMixer&) = delete;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "engine/audio/mixer_input.h"
|
#include "engine/audio/mixer_input.h"
|
||||||
|
|
||||||
#include "base/log.h"
|
#include "base/log.h"
|
||||||
|
#include "base/thread_pool.h"
|
||||||
#include "engine/audio/audio_bus.h"
|
#include "engine/audio/audio_bus.h"
|
||||||
#include "engine/audio/audio_mixer.h"
|
#include "engine/audio/audio_mixer.h"
|
||||||
|
|
||||||
|
@ -21,78 +22,124 @@ std::shared_ptr<MixerInput> MixerInput::Create() {
|
||||||
return std::shared_ptr<MixerInput>(new MixerInput());
|
return std::shared_ptr<MixerInput>(new MixerInput());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixerInput::SetAudioBus(std::shared_ptr<AudioBus> bus) {
|
void MixerInput::SetAudioBus(std::shared_ptr<AudioBus> audio_bus) {
|
||||||
if (streaming)
|
if (playing_)
|
||||||
pending_audio_bus = bus;
|
pending_audio_bus_ = audio_bus;
|
||||||
else
|
else
|
||||||
audio_bus = bus;
|
audio_bus_ = audio_bus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixerInput::Play(AudioMixer* mixer, bool restart) {
|
void MixerInput::Play(AudioMixer* mixer, bool restart) {
|
||||||
if (!mixer->IsAudioEnabled())
|
if (!mixer->IsAudioEnabled()) {
|
||||||
|
if (!playing_ && end_cb_)
|
||||||
|
end_cb_();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If already streaming check if stream position needs to be reset.
|
// If already playing check if stream position needs to be reset.
|
||||||
if (streaming) {
|
if (playing_) {
|
||||||
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, restart]() -> void { Play(mixer, restart); };
|
restart_cb_ = [&, mixer, restart]() -> void { Play(mixer, restart); };
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (restart || audio_bus->EndOfStream()) {
|
if (restart || audio_bus_->EndOfStream()) {
|
||||||
src_index = 0;
|
src_index_ = 0;
|
||||||
accumulator = 0;
|
accumulator_ = 0;
|
||||||
audio_bus->ResetStream();
|
audio_bus_->ResetStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
streaming = true;
|
playing_ = true;
|
||||||
flags.fetch_and(~kStopped, std::memory_order_relaxed);
|
flags_.fetch_and(~kStopped, std::memory_order_relaxed);
|
||||||
mixer->AddInput(shared_from_this());
|
mixer->AddInput(shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixerInput::Stop() {
|
void MixerInput::Stop() {
|
||||||
if (streaming) {
|
if (playing_) {
|
||||||
restart_cb = nullptr;
|
restart_cb_ = nullptr;
|
||||||
flags.fetch_or(kStopped, std::memory_order_relaxed);
|
flags_.fetch_or(kStopped, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixerInput::SetLoop(bool loop) {
|
void MixerInput::SetLoop(bool loop) {
|
||||||
if (loop)
|
if (loop)
|
||||||
flags.fetch_or(kLoop, std::memory_order_relaxed);
|
flags_.fetch_or(kLoop, std::memory_order_relaxed);
|
||||||
else
|
else
|
||||||
flags.fetch_and(~kLoop, std::memory_order_relaxed);
|
flags_.fetch_and(~kLoop, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixerInput::SetSimulateStereo(bool simulate) {
|
void MixerInput::SetSimulateStereo(bool simulate) {
|
||||||
if (simulate)
|
if (simulate)
|
||||||
flags.fetch_or(kSimulateStereo, std::memory_order_relaxed);
|
flags_.fetch_or(kSimulateStereo, std::memory_order_relaxed);
|
||||||
else
|
else
|
||||||
flags.fetch_and(~kSimulateStereo, std::memory_order_relaxed);
|
flags_.fetch_and(~kSimulateStereo, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixerInput::SetResampleStep(size_t value) {
|
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) {
|
void MixerInput::SetAmplitude(float value) {
|
||||||
amplitude.store(value, std::memory_order_relaxed);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixerInput::SetAmplitudeInc(float value) {
|
void MixerInput::SetAmplitudeInc(float value) {
|
||||||
amplitude_inc.store(value, std::memory_order_relaxed);
|
amplitude_inc_.store(value, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixerInput::SetEndCallback(base::Closure cb) {
|
void MixerInput::SetEndCallback(base::Closure cb) {
|
||||||
end_cb = std::move(cb);
|
end_cb_ = std::move(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MixerInput::IsStreamingInProgress() const {
|
||||||
|
return streaming_in_progress_.load(std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixerInput::SetPosition(size_t index, int accumulator) {
|
||||||
|
src_index_ = index;
|
||||||
|
accumulator_ = accumulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MixerInput::OnMoreData(bool loop) {
|
||||||
|
if (streaming_in_progress_.load(std::memory_order_acquire))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
streaming_in_progress_.store(true, std::memory_order_relaxed);
|
||||||
|
audio_bus_->SwapBuffers();
|
||||||
|
ThreadPool::Get().PostTask(
|
||||||
|
HERE,
|
||||||
|
[&, loop]() {
|
||||||
|
audio_bus_->Stream(loop);
|
||||||
|
streaming_in_progress_.store(false, std::memory_order_release);
|
||||||
|
},
|
||||||
|
true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MixerInput::OnRemovedFromMixer() {
|
||||||
|
DCHECK(!streaming_in_progress_.load(std::memory_order_relaxed));
|
||||||
|
DCHECK(playing_);
|
||||||
|
playing_ = false;
|
||||||
|
|
||||||
|
if (pending_audio_bus_) {
|
||||||
|
audio_bus_ = pending_audio_bus_;
|
||||||
|
pending_audio_bus_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end_cb_)
|
||||||
|
end_cb_();
|
||||||
|
if (restart_cb_) {
|
||||||
|
restart_cb_();
|
||||||
|
restart_cb_ = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace eng
|
} // namespace eng
|
||||||
|
|
|
@ -13,16 +13,19 @@ class AudioMixer;
|
||||||
|
|
||||||
// An audio input stream that gets mixed and rendered to the audio sink. Handles
|
// An audio input stream that gets mixed and rendered to the audio sink. Handles
|
||||||
// playback and volume control.
|
// playback and volume control.
|
||||||
struct MixerInput : public std::enable_shared_from_this<MixerInput> {
|
class MixerInput : public std::enable_shared_from_this<MixerInput> {
|
||||||
|
public:
|
||||||
enum Flags { kLoop = 1, kStopped = 2, kSimulateStereo = 4 };
|
enum Flags { kLoop = 1, kStopped = 2, kSimulateStereo = 4 };
|
||||||
|
|
||||||
~MixerInput();
|
~MixerInput();
|
||||||
|
|
||||||
static std::shared_ptr<MixerInput> Create();
|
static std::shared_ptr<MixerInput> Create();
|
||||||
|
|
||||||
// Set AudioBus for playback. If this MixerInput is already streaming, keeps
|
bool IsValid() const { return !!audio_bus_; }
|
||||||
// it as pending and sets once playback ends.
|
|
||||||
void SetAudioBus(std::shared_ptr<AudioBus> bus);
|
// Set AudioBus for playback. If this MixerInput is already playing, keeps it
|
||||||
|
// as pending and sets once playback ends.
|
||||||
|
void SetAudioBus(std::shared_ptr<AudioBus> audio_bus);
|
||||||
|
|
||||||
// Starts playback. Remembers last stream position. Resets the stream position
|
// Starts playback. Remembers last stream position. Resets the stream position
|
||||||
// if restart is true.
|
// if restart is true.
|
||||||
|
@ -31,6 +34,7 @@ struct MixerInput : public std::enable_shared_from_this<MixerInput> {
|
||||||
// Stops playback. Does not reset stream position.
|
// Stops playback. Does not reset stream position.
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
|
// Set whether the playback should loop or not.
|
||||||
void SetLoop(bool loop);
|
void SetLoop(bool loop);
|
||||||
|
|
||||||
// Simulate stereo effect slightly delays one channel.
|
// Simulate stereo effect slightly delays one channel.
|
||||||
|
@ -47,30 +51,57 @@ struct MixerInput : public std::enable_shared_from_this<MixerInput> {
|
||||||
// Set a callback to be called once playback ends.
|
// Set a callback to be called once playback ends.
|
||||||
void SetEndCallback(base::Closure cb);
|
void SetEndCallback(base::Closure cb);
|
||||||
|
|
||||||
// Active AudioBus.
|
// Getters
|
||||||
std::shared_ptr<AudioBus> audio_bus;
|
std::shared_ptr<AudioBus> GetAudioBus() const { return audio_bus_; }
|
||||||
// AudioBus to be set as active once playback ends.
|
unsigned GetFlags() const { return flags_.load(std::memory_order_relaxed); }
|
||||||
std::shared_ptr<AudioBus> pending_audio_bus;
|
size_t GetStep() const { return step_.load(std::memory_order_relaxed); }
|
||||||
// Stream position.
|
float GetAmplitude() const {
|
||||||
size_t src_index = 0;
|
return amplitude_.load(std::memory_order_relaxed);
|
||||||
size_t accumulator = 0;
|
}
|
||||||
|
float GetAmplitudeInc() const {
|
||||||
|
return amplitude_inc_.load(std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
float GetMaxAmplitude() const {
|
||||||
|
return max_amplitude_.load(std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
size_t GetSrcIndex() const { return src_index_; }
|
||||||
|
size_t GetAccumulator() const { return accumulator_; }
|
||||||
|
|
||||||
// Accessed by main thread only.
|
bool IsStreamingInProgress() const;
|
||||||
bool streaming = false;
|
|
||||||
base::Closure end_cb;
|
|
||||||
base::Closure restart_cb;
|
|
||||||
|
|
||||||
// Accessed by main thread and audio thread.
|
// Called by the mixer to save the last sample position.
|
||||||
std::atomic<unsigned> flags{0};
|
void SetPosition(size_t index, int accumulator);
|
||||||
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 decoding worker thread.
|
// Called by the mixer when more data is needed.
|
||||||
std::atomic<bool> streaming_in_progress{false};
|
bool OnMoreData(bool loop);
|
||||||
|
|
||||||
|
// Called by the mixer when playback ends.
|
||||||
|
void OnRemovedFromMixer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// 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 playing_ = false;
|
||||||
|
base::Closure end_cb_;
|
||||||
|
base::Closure restart_cb_;
|
||||||
|
|
||||||
|
// 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 decoding worker thread.
|
||||||
|
std::atomic<bool> streaming_in_progress_{false};
|
||||||
|
|
||||||
MixerInput();
|
MixerInput();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ void SoundPlayer::SetSound(std::shared_ptr<AudioBus> sound) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundPlayer::Play(bool loop, float fade_in_duration) {
|
void SoundPlayer::Play(bool loop, float fade_in_duration) {
|
||||||
if (!input_->audio_bus)
|
if (!input_->IsValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int step = variate_ ? Engine::Get().GetRandomGenerator().Roll(3) - 2 : 0;
|
int step = variate_ ? Engine::Get().GetRandomGenerator().Roll(3) - 2 : 0;
|
||||||
|
@ -35,7 +35,7 @@ void SoundPlayer::Play(bool loop, float fade_in_duration) {
|
||||||
if (fade_in_duration > 0) {
|
if (fade_in_duration > 0) {
|
||||||
input_->SetAmplitude(0);
|
input_->SetAmplitude(0);
|
||||||
input_->SetAmplitudeInc(
|
input_->SetAmplitudeInc(
|
||||||
1.0f / (input_->audio_bus->sample_rate() * fade_in_duration));
|
1.0f / (input_->GetAudioBus()->sample_rate() * fade_in_duration));
|
||||||
} else {
|
} else {
|
||||||
input_->SetAmplitude(max_amplitude_);
|
input_->SetAmplitude(max_amplitude_);
|
||||||
input_->SetAmplitudeInc(0);
|
input_->SetAmplitudeInc(0);
|
||||||
|
@ -44,24 +44,24 @@ void SoundPlayer::Play(bool loop, float fade_in_duration) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundPlayer::Resume(float fade_in_duration) {
|
void SoundPlayer::Resume(float fade_in_duration) {
|
||||||
if (!input_->audio_bus)
|
if (!input_->IsValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fade_in_duration > 0) {
|
if (fade_in_duration > 0) {
|
||||||
input_->SetAmplitude(0);
|
input_->SetAmplitude(0);
|
||||||
input_->SetAmplitudeInc(
|
input_->SetAmplitudeInc(
|
||||||
1.0f / (input_->audio_bus->sample_rate() * fade_in_duration));
|
1.0f / (input_->GetAudioBus()->sample_rate() * fade_in_duration));
|
||||||
}
|
}
|
||||||
input_->Play(Engine::Get().GetAudioMixer(), false);
|
input_->Play(Engine::Get().GetAudioMixer(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundPlayer::Stop(float fade_out_duration) {
|
void SoundPlayer::Stop(float fade_out_duration) {
|
||||||
if (!input_->audio_bus)
|
if (!input_->IsValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fade_out_duration > 0)
|
if (fade_out_duration > 0)
|
||||||
input_->SetAmplitudeInc(
|
input_->SetAmplitudeInc(
|
||||||
-1.0f / (input_->audio_bus->sample_rate() * fade_out_duration));
|
-1.0f / (input_->GetAudioBus()->sample_rate() * fade_out_duration));
|
||||||
else
|
else
|
||||||
input_->Stop();
|
input_->Stop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
namespace eng {
|
namespace eng {
|
||||||
|
|
||||||
class AudioBus;
|
class AudioBus;
|
||||||
struct MixerInput;
|
class MixerInput;
|
||||||
|
|
||||||
class SoundPlayer {
|
class SoundPlayer {
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue