13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file. 43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "media/audio/clockless_audio_sink.h" 63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/threading/simple_thread.h" 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/time/time.h" 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "media/base/audio_renderer_sink.h" 103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace media { 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Internal to ClocklessAudioSink. Class is used to call Render() on a seperate 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// thread, running as fast as it can read the data. 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class ClocklessAudioSinkThread : public base::DelegateSimpleThread::Delegate { 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public: 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) explicit ClocklessAudioSinkThread(const AudioParameters& params, 183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AudioRendererSink::RenderCallback* callback) 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : callback_(callback), 203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) audio_bus_(AudioBus::Create(params)), 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) stop_event_(new base::WaitableEvent(false, false)) {} 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void Start() { 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) stop_event_->Reset(); 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) thread_.reset(new base::DelegateSimpleThread(this, "ClocklessAudioSink")); 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) thread_->Start(); 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Generate a signal to stop calling Render(). 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::TimeDelta Stop() { 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) stop_event_->Signal(); 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) thread_->Join(); 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return playback_time_; 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private: 373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Call Render() repeatedly, keeping track of the rendering time. 383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual void Run() OVERRIDE { 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::TimeTicks start; 403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) while (!stop_event_->IsSignaled()) { 413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int frames_received = callback_->Render(audio_bus_.get(), 0); 423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (frames_received <= 0) { 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // No data received, so let other threads run to provide data. 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::PlatformThread::YieldCurrentThread(); 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (start.is_null()) { 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // First time we processed some audio, so record the starting time. 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) start = base::TimeTicks::HighResNow(); 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Keep track of the last time data was rendered. 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) playback_time_ = base::TimeTicks::HighResNow() - start; 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AudioRendererSink::RenderCallback* callback_; 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<AudioBus> audio_bus_; 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<base::WaitableEvent> stop_event_; 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<base::DelegateSimpleThread> thread_; 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::TimeDelta playback_time_; 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ClocklessAudioSink::ClocklessAudioSink() 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : initialized_(false), 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) playing_(false) {} 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ClocklessAudioSink::~ClocklessAudioSink() {} 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ClocklessAudioSink::Initialize(const AudioParameters& params, 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RenderCallback* callback) { 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!initialized_); 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) thread_.reset(new ClocklessAudioSinkThread(params, callback)); 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) initialized_ = true; 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ClocklessAudioSink::Start() { 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(initialized_); 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!playing_); 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ClocklessAudioSink::Stop() { 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (initialized_) 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Pause(); 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ClocklessAudioSink::Play() { 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(initialized_); 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (playing_) 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) playing_ = true; 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) thread_->Start(); 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ClocklessAudioSink::Pause() { 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(initialized_); 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!playing_) 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) playing_ = false; 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) playback_time_ = thread_->Stop(); 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ClocklessAudioSink::SetVolume(double volume) { 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Audio is always muted. 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return volume == 0.0; 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace media 111