Home | History | Annotate | Download | only in audio
      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 
     10 namespace media {
     11 
     12 VirtualAudioOutputStream::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 
     25 VirtualAudioOutputStream::~VirtualAudioOutputStream() {
     26   DCHECK(!callback_);
     27 }
     28 
     29 bool VirtualAudioOutputStream::Open() {
     30   DCHECK(thread_checker_.CalledOnValidThread());
     31   return true;
     32 }
     33 
     34 void VirtualAudioOutputStream::Start(AudioSourceCallback* callback)  {
     35   DCHECK(thread_checker_.CalledOnValidThread());
     36   DCHECK(!callback_);
     37   callback_ = callback;
     38   target_input_stream_->AddOutputStream(this, params_);
     39 }
     40 
     41 void VirtualAudioOutputStream::Stop() {
     42   DCHECK(thread_checker_.CalledOnValidThread());
     43   if (callback_) {
     44     target_input_stream_->RemoveOutputStream(this, params_);
     45     callback_ = NULL;
     46   }
     47 }
     48 
     49 void 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 
     64 void VirtualAudioOutputStream::SetVolume(double volume) {
     65   DCHECK(thread_checker_.CalledOnValidThread());
     66   volume_ = volume;
     67 }
     68 
     69 void VirtualAudioOutputStream::GetVolume(double* volume) {
     70   DCHECK(thread_checker_.CalledOnValidThread());
     71   *volume = volume_;
     72 }
     73 
     74 double 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