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