Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(446)

Unified Diff: media/audio/fake_audio_input_stream.cc

Issue 922663002: Moved the fake input stream's processing onto the audio worker thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/audio/fake_audio_input_stream.cc
diff --git a/media/audio/fake_audio_input_stream.cc b/media/audio/fake_audio_input_stream.cc
index 4632b258eda2abaf261bb7dba214ab6aba15d8bb..679052d31c17f515eb22629732bab65251be82e8 100644
--- a/media/audio/fake_audio_input_stream.cc
+++ b/media/audio/fake_audio_input_stream.cc
@@ -5,16 +5,20 @@
#include "media/audio/fake_audio_input_stream.h"
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/file.h"
+#include "base/files/file_path.h"
#include "base/lazy_instance.h"
+#include "base/location.h"
+#include "base/single_thread_task_runner.h"
+#include "base/time/time.h"
#include "media/audio/audio_manager_base.h"
+#include "media/audio/sounds/wav_audio_handler.h"
#include "media/base/audio_bus.h"
+#include "media/base/audio_converter.h"
#include "media/base/media_switches.h"
-using base::TimeTicks;
-using base::TimeDelta;
-
namespace media {
namespace {
@@ -102,95 +106,37 @@ static base::LazyInstance<BeepContext> g_beep_context =
} // namespace
-AudioInputStream* FakeAudioInputStream::MakeFakeStream(
- AudioManagerBase* manager,
- const AudioParameters& params) {
- return new FakeAudioInputStream(manager, params);
-}
-
-FakeAudioInputStream::FakeAudioInputStream(AudioManagerBase* manager,
- const AudioParameters& params)
- : audio_manager_(manager),
- callback_(NULL),
- buffer_size_((params.channels() * params.bits_per_sample() *
- params.frames_per_buffer()) /
- 8),
- params_(params),
- task_runner_(manager->GetTaskRunner()),
- callback_interval_(base::TimeDelta::FromMilliseconds(
- (params.frames_per_buffer() * 1000) / params.sample_rate())),
- beep_duration_in_buffers_(kBeepDurationMilliseconds *
- params.sample_rate() /
- params.frames_per_buffer() /
- 1000),
- beep_generated_in_buffers_(0),
- beep_period_in_frames_(params.sample_rate() / kBeepFrequency),
- audio_bus_(AudioBus::Create(params)),
- wav_file_read_pos_(0),
- weak_factory_(this) {
- DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
-}
-
-FakeAudioInputStream::~FakeAudioInputStream() {}
-
-bool FakeAudioInputStream::Open() {
- DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
- buffer_.reset(new uint8[buffer_size_]);
- memset(buffer_.get(), 0, buffer_size_);
- audio_bus_->Zero();
-
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kUseFileForFakeAudioCapture)) {
- OpenInFileMode(base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
- switches::kUseFileForFakeAudioCapture));
- }
-
- return true;
-}
-
-void FakeAudioInputStream::Start(AudioInputCallback* callback) {
- DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
- DCHECK(!callback_);
- callback_ = callback;
- last_callback_time_ = TimeTicks::Now();
-
- task_runner_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&FakeAudioInputStream::DoCallback, weak_factory_.GetWeakPtr()),
- callback_interval_);
-}
-
-void FakeAudioInputStream::DoCallback() {
- DCHECK(callback_);
-
- const TimeTicks now = TimeTicks::Now();
- base::TimeDelta next_callback_time =
- last_callback_time_ + callback_interval_ * 2 - now;
-
- // If we are falling behind, try to catch up as much as we can in the next
- // callback.
- if (next_callback_time < base::TimeDelta())
- next_callback_time = base::TimeDelta();
+class FakeAudioInputStream::FileSource : public AudioConverter::InputCallback,
phoglund_chromium 2015/02/18 16:38:15 It felt wrong to toss back all the state into the
DaleCurtis 2015/02/18 19:04:49 Good idea. Take a look at media/audio/simple_sourc
phoglund_chromium 2015/02/19 15:44:10 Sure, done.
+ public FakeAudioInputStream::Source {
+ public:
+ FileSource(const AudioParameters& params);
+ ~FileSource() override {}
- if (PlayingFromFile()) {
- PlayFile();
- } else {
- PlayBeep();
- }
+ void Open(const base::FilePath& path_to_wav_file);
+ void PlayInto(AudioBus* audio_bus, int* buffer_size) override;
- last_callback_time_ = now;
+ private:
+ AudioParameters params_;
+ scoped_ptr<uint8[]> wav_file_data_;
+ scoped_ptr<media::WavAudioHandler> wav_audio_handler_;
+ scoped_ptr<media::AudioConverter> file_audio_converter_;
+ int wav_file_read_pos_;
+ int buffer_size_;
+
+ // Provides audio data from wav_audio_handler_ into the file audio converter.
+ double ProvideInput(AudioBus* audio_bus,
+ base::TimeDelta buffer_delay) override;
+};
- task_runner_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&FakeAudioInputStream::DoCallback, weak_factory_.GetWeakPtr()),
- next_callback_time);
+FakeAudioInputStream::FileSource::FileSource(const AudioParameters& params)
+ : params_(params),
+ wav_file_read_pos_(0),
+ buffer_size_(params.channels() * params.bits_per_sample() *
+ params.frames_per_buffer() / 8) {
}
-void FakeAudioInputStream::OpenInFileMode(const base::FilePath& wav_filename) {
- CHECK(!wav_filename.empty())
- << "You must pass the file to use as argument to --"
- << switches::kUseFileForFakeAudioCapture << ".";
-
+void FakeAudioInputStream::FileSource::Open(
+ const base::FilePath& wav_filename) {
// Read the file, and put its data in a scoped_ptr so it gets deleted later.
size_t file_length = 0;
wav_file_data_ = ReadWavFile(wav_filename, &file_length);
@@ -212,22 +158,68 @@ void FakeAudioInputStream::OpenInFileMode(const base::FilePath& wav_filename) {
file_audio_converter_->AddInput(this);
}
-bool FakeAudioInputStream::PlayingFromFile() {
- return wav_audio_handler_.get() != nullptr;
-}
+void FakeAudioInputStream::FileSource::PlayInto(AudioBus* audio_bus,
+ int* buffer_size) {
+ DCHECK(wav_audio_handler_.get() != nullptr);
-void FakeAudioInputStream::PlayFile() {
// Stop playing if we've played out the whole file.
if (wav_audio_handler_->AtEnd(wav_file_read_pos_))
return;
- file_audio_converter_->Convert(audio_bus_.get());
- callback_->OnData(this, audio_bus_.get(), buffer_size_, 1.0);
+ // This pulls data from ProvideInput.
+ file_audio_converter_->Convert(audio_bus);
+ *buffer_size = buffer_size_;
}
-void FakeAudioInputStream::PlayBeep() {
+double FakeAudioInputStream::FileSource::ProvideInput(
+ AudioBus* audio_bus_into_converter,
+ base::TimeDelta buffer_delay) {
+ // Unfilled frames will be zeroed by CopyTo.
+ size_t bytes_written;
+ wav_audio_handler_->CopyTo(audio_bus_into_converter, wav_file_read_pos_,
+ &bytes_written);
+ wav_file_read_pos_ += bytes_written;
+ return 1.0;
+};
+
+class FakeAudioInputStream::BeepingSource
+ : public FakeAudioInputStream::Source {
+ public:
+ BeepingSource(const AudioParameters& params);
+ ~BeepingSource() override {}
+
+ void PlayInto(AudioBus* audio_bus, int* buffer_size) override;
+ private:
+ scoped_ptr<uint8[]> buffer_;
+ int buffer_size_;
+ AudioParameters params_;
+ base::TimeTicks last_callback_time_;
+ base::TimeDelta interval_from_last_beep_;
+ int beep_duration_in_buffers_;
+ int beep_generated_in_buffers_;
+ int beep_period_in_frames_;
+};
+
+FakeAudioInputStream::BeepingSource::BeepingSource(
+ const AudioParameters& params)
+ : buffer_size_(params.channels() * params.bits_per_sample() *
+ params.frames_per_buffer() / 8),
+ params_(params),
+ beep_duration_in_buffers_(kBeepDurationMilliseconds *
+ params.sample_rate() /
+ params.frames_per_buffer() /
+ 1000),
+ beep_generated_in_buffers_(0),
+ beep_period_in_frames_(params.sample_rate() / kBeepFrequency) {
+ buffer_.reset(new uint8[buffer_size_]);
+ memset(buffer_.get(), 0, buffer_size_);
+}
+
+void FakeAudioInputStream::BeepingSource::PlayInto(AudioBus* audio_bus,
+ int* buffer_size) {
// Accumulate the time from the last beep.
- interval_from_last_beep_ += TimeTicks::Now() - last_callback_time_;
+ interval_from_last_beep_ += base::TimeTicks::Now() - last_callback_time_;
+ last_callback_time_ = base::TimeTicks::Now();
memset(buffer_.get(), 0, buffer_size_);
bool should_beep = false;
@@ -235,7 +227,7 @@ void FakeAudioInputStream::PlayBeep() {
BeepContext* beep_context = g_beep_context.Pointer();
if (beep_context->automatic_beep()) {
base::TimeDelta delta = interval_from_last_beep_ -
- TimeDelta::FromMilliseconds(kAutomaticBeepIntervalInMs);
+ base::TimeDelta::FromMilliseconds(kAutomaticBeepIntervalInMs);
if (delta > base::TimeDelta()) {
should_beep = true;
interval_from_last_beep_ = delta;
@@ -270,19 +262,73 @@ void FakeAudioInputStream::PlayBeep() {
beep_generated_in_buffers_ = 0;
}
- audio_bus_->FromInterleaved(
- buffer_.get(), audio_bus_->frames(), params_.bits_per_sample() / 8);
- callback_->OnData(this, audio_bus_.get(), buffer_size_, 1.0);
+ *buffer_size = buffer_size_;
phoglund_chromium 2015/02/18 16:38:15 Not sure about this: I do feel the sources know be
DaleCurtis 2015/02/18 19:04:49 I don't think you need this, it seems like an inco
phoglund_chromium 2015/02/19 15:44:11 Just passing 0 seems to work so I'll go with that.
+ audio_bus->FromInterleaved(
+ buffer_.get(), audio_bus->frames(), params_.bits_per_sample() / 8);
+}
+
+AudioInputStream* FakeAudioInputStream::MakeFakeStream(
+ AudioManagerBase* manager,
+ const AudioParameters& params) {
+ return new FakeAudioInputStream(manager, params);
+}
+
+FakeAudioInputStream::FakeAudioInputStream(AudioManagerBase* manager,
+ const AudioParameters& params)
+ : audio_manager_(manager),
+ callback_(NULL),
+ fake_audio_worker_(manager->GetWorkerTaskRunner(), params),
+ params_(params),
+ audio_bus_(AudioBus::Create(params)) {
+ DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
+}
+
+FakeAudioInputStream::~FakeAudioInputStream() {
+ DCHECK(!callback_);
+}
+
+bool FakeAudioInputStream::Open() {
+ DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
+ audio_bus_->Zero();
+
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kUseFileForFakeAudioCapture)) {
+ base::FilePath path_to_wav_file =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
+ switches::kUseFileForFakeAudioCapture);
+ CHECK(!path_to_wav_file.empty())
+ << "You must pass the file to use as argument to --"
+ << switches::kUseFileForFakeAudioCapture << ".";
+
+ FileSource* file_source = new FileSource(params_);
+ audio_source_.reset(file_source);
+ audio_manager_->GetWorkerTaskRunner()->PostTask(
phoglund_chromium 2015/02/18 16:38:15 This is the file loading I talked about earlier. A
DaleCurtis 2015/02/18 19:04:49 I think loading the file source on the first callb
phoglund_chromium 2015/02/19 15:44:11 Done.
+ FROM_HERE,
+ base::Bind(&FileSource::Open,
+ base::Unretained(file_source),
+ path_to_wav_file));
+ } else {
+ audio_source_.reset(new BeepingSource(params_));
+ }
+ return true;
+}
+
+void FakeAudioInputStream::Start(AudioInputCallback* callback) {
+ DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
+ callback_ = callback;
+ fake_audio_worker_.Start(base::Bind(
+ &FakeAudioInputStream::ReadAudioFromSource, base::Unretained(this)));
}
void FakeAudioInputStream::Stop() {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
- weak_factory_.InvalidateWeakPtrs();
+ fake_audio_worker_.Stop();
callback_ = NULL;
}
void FakeAudioInputStream::Close() {
DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
+ DCHECK(!callback_);
audio_manager_->ReleaseInputStream(this);
}
@@ -313,20 +359,17 @@ bool FakeAudioInputStream::GetAutomaticGainControl() {
return false;
}
-// static
+void FakeAudioInputStream::ReadAudioFromSource() {
+ DCHECK(audio_manager_->GetWorkerTaskRunner()->BelongsToCurrentThread());
+ DCHECK(callback_);
+ int buffer_size;
+ audio_source_->PlayInto(audio_bus_.get(), &buffer_size);
+ callback_->OnData(this, audio_bus_.get(), buffer_size, 1.0);
DaleCurtis 2015/02/18 19:04:49 Why are you returning the buffer_size like this? I
phoglund_chromium 2015/02/19 15:44:11 Done.
+}
+
void FakeAudioInputStream::BeepOnce() {
BeepContext* beep_context = g_beep_context.Pointer();
beep_context->SetBeepOnce(true);
}
-double FakeAudioInputStream::ProvideInput(AudioBus* audio_bus_into_converter,
- base::TimeDelta buffer_delay) {
- // Unfilled frames will be zeroed by CopyTo.
- size_t bytes_written;
- wav_audio_handler_->CopyTo(audio_bus_into_converter, wav_file_read_pos_,
- &bytes_written);
- wav_file_read_pos_ += bytes_written;
- return 1.0;
-};
-
} // namespace media

Powered by Google App Engine
This is Rietveld 408576698