summaryrefslogtreecommitdiffstats
path: root/media/audio/fake_audio_consumer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'media/audio/fake_audio_consumer.cc')
-rw-r--r--media/audio/fake_audio_consumer.cc67
1 files changed, 67 insertions, 0 deletions
diff --git a/media/audio/fake_audio_consumer.cc b/media/audio/fake_audio_consumer.cc
new file mode 100644
index 0000000..95db9cd
--- /dev/null
+++ b/media/audio/fake_audio_consumer.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/audio/fake_audio_consumer.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/message_loop_proxy.h"
+#include "media/base/audio_bus.h"
+
+namespace media {
+
+FakeAudioConsumer::FakeAudioConsumer(
+ const scoped_refptr<base::MessageLoopProxy>& message_loop,
+ const AudioParameters& params)
+ : message_loop_(message_loop),
+ audio_bus_(AudioBus::Create(params)),
+ buffer_duration_(base::TimeDelta::FromMicroseconds(
+ params.frames_per_buffer() * base::Time::kMicrosecondsPerSecond /
+ static_cast<float>(params.sample_rate()))) {
+ audio_bus_->Zero();
+}
+
+FakeAudioConsumer::~FakeAudioConsumer() {
+ DCHECK(read_cb_.is_null());
+}
+
+void FakeAudioConsumer::Start(const ReadCB& read_cb) {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+ DCHECK(read_cb_.is_null());
+ DCHECK(!read_cb.is_null());
+ read_cb_ = read_cb;
+ next_read_time_ = base::Time::Now();
+ read_task_cb_.Reset(base::Bind(
+ &FakeAudioConsumer::DoRead, base::Unretained(this)));
+ message_loop_->PostTask(FROM_HERE, read_task_cb_.callback());
+}
+
+void FakeAudioConsumer::Stop() {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+ read_cb_.Reset();
+ read_task_cb_.Cancel();
+}
+
+void FakeAudioConsumer::DoRead() {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+ DCHECK(!read_cb_.is_null());
+
+ read_cb_.Run(audio_bus_.get());
+
+ // Need to account for time spent here due to the cost of |read_cb_| as well
+ // as the imprecision of PostDelayedTask().
+ base::Time now = base::Time::Now();
+ base::TimeDelta delay = next_read_time_ + buffer_duration_ - now;
+
+ // If we're behind, find the next nearest ontime interval.
+ if (delay < base::TimeDelta())
+ delay += buffer_duration_ * (-delay / buffer_duration_ + 1);
+ next_read_time_ = now + delay;
+
+ message_loop_->PostDelayedTask(FROM_HERE, read_task_cb_.callback(), delay);
+}
+
+} // namespace media