15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_renderer_mixer_input.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_renderer_mixer.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioRendererMixerInput::AudioRendererMixerInput( 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GetMixerCB& get_mixer_cb, const RemoveMixerCB& remove_mixer_cb) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : playing_(false), 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized_(false), 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) volume_(1.0f), 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get_mixer_cb_(get_mixer_cb), 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remove_mixer_cb_(remove_mixer_cb), 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_(NULL), 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_(NULL), 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_cb_(base::Bind( 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &AudioRendererMixerInput::OnRenderError, base::Unretained(this))) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioRendererMixerInput::~AudioRendererMixerInput() { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mixer is no longer safe to use after |remove_mixer_cb_| has been called. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (initialized_) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remove_mixer_cb_.Run(params_); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererMixerInput::Initialize( 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AudioParameters& params, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioRendererSink::RenderCallback* callback) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!initialized_); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_ = params; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_ = get_mixer_cb_.Run(params_); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_ = callback; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized_ = true; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererMixerInput::Start() { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(initialized_); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!playing_); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererMixerInput::Stop() { 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Stop() may be called at any time, if Pause() hasn't been called we need to 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // remove our mixer input before shutdown. 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!playing_) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_->RemoveMixerInput(this); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) playing_ = false; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererMixerInput::Play() { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(initialized_); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (playing_) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mixer_->AddMixerInput(this, error_cb_); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) playing_ = true; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioRendererMixerInput::Pause() { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(initialized_); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!playing_) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_->RemoveMixerInput(this); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) playing_ = false; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AudioRendererMixerInput::SetVolume(double volume) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) volume_ = volume; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)double AudioRendererMixerInput::ProvideInput(AudioBus* audio_bus, 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta buffer_delay) { 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int frames_filled = callback_->Render( 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) audio_bus, static_cast<int>(buffer_delay.InMillisecondsF() + 0.5)); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // AudioConverter expects unfilled frames to be zeroed. 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (frames_filled < audio_bus->frames()) { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_bus->ZeroFramesPartial( 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frames_filled, audio_bus->frames() - frames_filled); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return frames_filled > 0 ? volume_ : 0; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AudioRendererMixerInput::OnRenderError() { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_->OnRenderError(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 101