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/audio_output_proxy.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "media/audio/audio_manager.h"
     10 #include "media/audio/audio_output_dispatcher.h"
     11 
     12 namespace media {
     13 
     14 AudioOutputProxy::AudioOutputProxy(AudioOutputDispatcher* dispatcher)
     15     : dispatcher_(dispatcher),
     16       state_(kCreated),
     17       volume_(1.0) {
     18 }
     19 
     20 AudioOutputProxy::~AudioOutputProxy() {
     21   DCHECK(CalledOnValidThread());
     22   DCHECK(state_ == kCreated || state_ == kClosed) << "State is: " << state_;
     23 }
     24 
     25 bool AudioOutputProxy::Open() {
     26   DCHECK(CalledOnValidThread());
     27   DCHECK_EQ(state_, kCreated);
     28 
     29   if (!dispatcher_->OpenStream()) {
     30     state_ = kOpenError;
     31     return false;
     32   }
     33 
     34   state_ = kOpened;
     35   return true;
     36 }
     37 
     38 void AudioOutputProxy::Start(AudioSourceCallback* callback) {
     39   DCHECK(CalledOnValidThread());
     40 
     41   // We need to support both states since the callback may not handle OnError()
     42   // immediately (or at all).  It's also possible for subsequent StartStream()
     43   // calls to succeed after failing, so we allow it to be called again.
     44   DCHECK(state_ == kOpened || state_ == kStartError);
     45 
     46   if (!dispatcher_->StartStream(callback, this)) {
     47     state_ = kStartError;
     48     callback->OnError(this);
     49     return;
     50   }
     51   state_ = kPlaying;
     52 }
     53 
     54 void AudioOutputProxy::Stop() {
     55   DCHECK(CalledOnValidThread());
     56   if (state_ != kPlaying)
     57     return;
     58 
     59   dispatcher_->StopStream(this);
     60   state_ = kOpened;
     61 }
     62 
     63 void AudioOutputProxy::SetVolume(double volume) {
     64   DCHECK(CalledOnValidThread());
     65   volume_ = volume;
     66   dispatcher_->StreamVolumeSet(this, volume);
     67 }
     68 
     69 void AudioOutputProxy::GetVolume(double* volume) {
     70   DCHECK(CalledOnValidThread());
     71   *volume = volume_;
     72 }
     73 
     74 void AudioOutputProxy::Close() {
     75   DCHECK(CalledOnValidThread());
     76   DCHECK(state_ == kCreated || state_ == kOpenError || state_ == kOpened ||
     77          state_ == kStartError);
     78 
     79   // kStartError means OpenStream() succeeded and the stream must be closed
     80   // before destruction.
     81   if (state_ != kCreated && state_ != kOpenError)
     82     dispatcher_->CloseStream(this);
     83 
     84   state_ = kClosed;
     85 
     86   // Delete the object now like is done in the Close() implementation of
     87   // physical stream objects.  If we delete the object via DeleteSoon, we
     88   // unnecessarily complicate the Shutdown procedure of the
     89   // dispatcher+audio manager.
     90   delete this;
     91 }
     92 
     93 }  // namespace media
     94