Home | History | Annotate | Download | only in base
      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/base/audio_renderer_mixer_input.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/logging.h"
      9 #include "media/base/audio_renderer_mixer.h"
     10 
     11 namespace media {
     12 
     13 AudioRendererMixerInput::AudioRendererMixerInput(
     14     const GetMixerCB& get_mixer_cb, const RemoveMixerCB& remove_mixer_cb)
     15     : playing_(false),
     16       initialized_(false),
     17       volume_(1.0f),
     18       get_mixer_cb_(get_mixer_cb),
     19       remove_mixer_cb_(remove_mixer_cb),
     20       mixer_(NULL),
     21       callback_(NULL),
     22       error_cb_(base::Bind(
     23           &AudioRendererMixerInput::OnRenderError, base::Unretained(this))) {
     24 }
     25 
     26 AudioRendererMixerInput::~AudioRendererMixerInput() {
     27   // Mixer is no longer safe to use after |remove_mixer_cb_| has been called.
     28   if (initialized_)
     29     remove_mixer_cb_.Run(params_);
     30 }
     31 
     32 void AudioRendererMixerInput::Initialize(
     33     const AudioParameters& params,
     34     AudioRendererSink::RenderCallback* callback) {
     35   DCHECK(!initialized_);
     36   params_ = params;
     37   mixer_ = get_mixer_cb_.Run(params_);
     38   callback_ = callback;
     39   initialized_ = true;
     40 }
     41 
     42 void AudioRendererMixerInput::Start() {
     43   DCHECK(initialized_);
     44   DCHECK(!playing_);
     45 }
     46 
     47 void AudioRendererMixerInput::Stop() {
     48   // Stop() may be called at any time, if Pause() hasn't been called we need to
     49   // remove our mixer input before shutdown.
     50   if (!playing_)
     51     return;
     52 
     53   mixer_->RemoveMixerInput(this);
     54   playing_ = false;
     55 }
     56 
     57 void AudioRendererMixerInput::Play() {
     58   DCHECK(initialized_);
     59 
     60   if (playing_)
     61     return;
     62 
     63   mixer_->AddMixerInput(this, error_cb_);
     64   playing_ = true;
     65 }
     66 
     67 void AudioRendererMixerInput::Pause() {
     68   DCHECK(initialized_);
     69 
     70   if (!playing_)
     71     return;
     72 
     73   mixer_->RemoveMixerInput(this);
     74   playing_ = false;
     75 }
     76 
     77 bool AudioRendererMixerInput::SetVolume(double volume) {
     78   volume_ = volume;
     79   return true;
     80 }
     81 
     82 double AudioRendererMixerInput::ProvideInput(AudioBus* audio_bus,
     83                                              base::TimeDelta buffer_delay) {
     84   int frames_filled = callback_->Render(
     85       audio_bus, static_cast<int>(buffer_delay.InMillisecondsF() + 0.5));
     86 
     87   // AudioConverter expects unfilled frames to be zeroed.
     88   if (frames_filled < audio_bus->frames()) {
     89     audio_bus->ZeroFramesPartial(
     90         frames_filled, audio_bus->frames() - frames_filled);
     91   }
     92 
     93   return frames_filled > 0 ? volume_ : 0;
     94 }
     95 
     96 void AudioRendererMixerInput::OnRenderError() {
     97   callback_->OnRenderError();
     98 }
     99 
    100 }  // namespace media
    101