fake_audio_consumer.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "media/audio/fake_audio_consumer.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/logging.h" 10#include "base/message_loop.h" 11#include "base/message_loop_proxy.h" 12#include "media/base/audio_bus.h" 13 14namespace media { 15 16FakeAudioConsumer::FakeAudioConsumer( 17 const scoped_refptr<base::MessageLoopProxy>& message_loop, 18 const AudioParameters& params) 19 : message_loop_(message_loop), 20 audio_bus_(AudioBus::Create(params)), 21 buffer_duration_(base::TimeDelta::FromMicroseconds( 22 params.frames_per_buffer() * base::Time::kMicrosecondsPerSecond / 23 static_cast<float>(params.sample_rate()))) { 24 audio_bus_->Zero(); 25} 26 27FakeAudioConsumer::~FakeAudioConsumer() { 28 DCHECK(read_cb_.is_null()); 29} 30 31void FakeAudioConsumer::Start(const ReadCB& read_cb) { 32 DCHECK(message_loop_->BelongsToCurrentThread()); 33 DCHECK(read_cb_.is_null()); 34 DCHECK(!read_cb.is_null()); 35 read_cb_ = read_cb; 36 next_read_time_ = base::Time::Now(); 37 read_task_cb_.Reset(base::Bind( 38 &FakeAudioConsumer::DoRead, base::Unretained(this))); 39 message_loop_->PostTask(FROM_HERE, read_task_cb_.callback()); 40} 41 42void FakeAudioConsumer::Stop() { 43 DCHECK(message_loop_->BelongsToCurrentThread()); 44 read_cb_.Reset(); 45 read_task_cb_.Cancel(); 46} 47 48void FakeAudioConsumer::DoRead() { 49 DCHECK(message_loop_->BelongsToCurrentThread()); 50 DCHECK(!read_cb_.is_null()); 51 52 read_cb_.Run(audio_bus_.get()); 53 54 // Need to account for time spent here due to the cost of |read_cb_| as well 55 // as the imprecision of PostDelayedTask(). 56 base::Time now = base::Time::Now(); 57 base::TimeDelta delay = next_read_time_ + buffer_duration_ - now; 58 59 // If we're behind, find the next nearest ontime interval. 60 if (delay < base::TimeDelta()) 61 delay += buffer_duration_ * (-delay / buffer_duration_ + 1); 62 next_read_time_ = now + delay; 63 64 message_loop_->PostDelayedTask(FROM_HERE, read_task_cb_.callback(), delay); 65} 66 67} // namespace media 68