virtual_audio_output_stream.cc revision 868fa2fe829687343ffae624259930155e16dbd8
1// Copyright (c) 2012 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/virtual_audio_output_stream.h" 6 7#include "base/message_loop/message_loop_proxy.h" 8#include "media/audio/virtual_audio_input_stream.h" 9 10namespace media { 11 12VirtualAudioOutputStream::VirtualAudioOutputStream( 13 const AudioParameters& params, base::MessageLoopProxy* message_loop, 14 VirtualAudioInputStream* target, const AfterCloseCallback& after_close_cb) 15 : params_(params), message_loop_(message_loop), 16 target_input_stream_(target), after_close_cb_(after_close_cb), 17 callback_(NULL), volume_(1.0f) { 18 DCHECK(params_.IsValid()); 19 DCHECK(message_loop_); 20 DCHECK(target); 21} 22 23VirtualAudioOutputStream::~VirtualAudioOutputStream() { 24 DCHECK(!callback_); 25} 26 27bool VirtualAudioOutputStream::Open() { 28 DCHECK(message_loop_->BelongsToCurrentThread()); 29 return true; 30} 31 32void VirtualAudioOutputStream::Start(AudioSourceCallback* callback) { 33 DCHECK(message_loop_->BelongsToCurrentThread()); 34 DCHECK(!callback_); 35 callback_ = callback; 36 target_input_stream_->AddOutputStream(this, params_); 37} 38 39void VirtualAudioOutputStream::Stop() { 40 DCHECK(message_loop_->BelongsToCurrentThread()); 41 if (callback_) { 42 callback_ = NULL; 43 target_input_stream_->RemoveOutputStream(this, params_); 44 } 45} 46 47void VirtualAudioOutputStream::Close() { 48 DCHECK(message_loop_->BelongsToCurrentThread()); 49 50 Stop(); 51 52 // If a non-null AfterCloseCallback was provided to the constructor, invoke it 53 // here. The callback is moved to a stack-local first since |this| could be 54 // destroyed during Run(). 55 if (!after_close_cb_.is_null()) { 56 const AfterCloseCallback cb = after_close_cb_; 57 after_close_cb_.Reset(); 58 cb.Run(this); 59 } 60} 61 62void VirtualAudioOutputStream::SetVolume(double volume) { 63 DCHECK(message_loop_->BelongsToCurrentThread()); 64 volume_ = volume; 65} 66 67void VirtualAudioOutputStream::GetVolume(double* volume) { 68 DCHECK(message_loop_->BelongsToCurrentThread()); 69 *volume = volume_; 70} 71 72double VirtualAudioOutputStream::ProvideInput(AudioBus* audio_bus, 73 base::TimeDelta buffer_delay) { 74 DCHECK(message_loop_->BelongsToCurrentThread()); 75 DCHECK(callback_); 76 77 const int frames = callback_->OnMoreData(audio_bus, AudioBuffersState()); 78 if (frames < audio_bus->frames()) 79 audio_bus->ZeroFramesPartial(frames, audio_bus->frames() - frames); 80 81 return frames > 0 ? volume_ : 0; 82} 83 84} // namespace media 85