audio_output_controller.h revision 868fa2fe829687343ffae624259930155e16dbd8
1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file. 4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifndef MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ 6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#define MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ 7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/atomic_ref_count.h" 9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/callback.h" 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/memory/ref_counted.h" 11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/timer.h" 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/audio/audio_io.h" 14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/audio/audio_manager.h" 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/audio/audio_source_diverter.h" 16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/audio/simple_sources.h" 17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/base/media_export.h" 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// An AudioOutputController controls an AudioOutputStream and provides data 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// to this output stream. It has an important function that it executes 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// audio operations like play, pause, stop, etc. on a separate thread, 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// namely the audio manager thread. 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// All the public methods of AudioOutputController are non-blocking. 25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// The actual operations are performed on the audio manager thread. 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Here is a state transition diagram for the AudioOutputController: 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// *[ Empty ] --> [ Created ] --> [ Playing ] -------. 30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// | | | ^ | 31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// | | | | | 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// | | | | v 33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// | | | `----- [ Paused ] 34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// | | | | 35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// | v v | 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// `-----------> [ Closed ] <-----------' 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// * Initial state 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// At any time after reaching the Created state but before Closed, the 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// AudioOutputController may be notified of a device change via 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// OnDeviceChange(). As the OnDeviceChange() is processed, state transitions 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// will occur, ultimately ending up in an equivalent pre-call state. E.g., if 44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// the state was Paused, the new state will be Created, since these states are 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// all functionally equivalent and require a Play() call to continue to the next 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// state. 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// The AudioOutputStream can request data from the AudioOutputController via the 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// AudioSourceCallback interface. AudioOutputController uses the SyncReader 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// passed to it via construction to synchronously fulfill this read request. 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace media { 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class AudioSilenceDetector; 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class MEDIA_EXPORT AudioOutputController 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : public base::RefCountedThreadSafe<AudioOutputController>, 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public AudioOutputStream::AudioSourceCallback, 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public AudioSourceDiverter, 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) NON_EXPORTED_BASE(public AudioManager::AudioDeviceListener) { 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public: 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // An event handler that receives events from the AudioOutputController. The 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // following methods are called on the audio manager thread. 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) class MEDIA_EXPORT EventHandler { 66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public: 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void OnCreated() = 0; 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void OnPlaying() = 0; 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void OnAudible(bool is_audible) = 0; 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void OnPaused() = 0; 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void OnError() = 0; 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void OnDeviceChange(int new_buffer_size, int new_sample_rate) = 0; 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) protected: 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual ~EventHandler() {} 76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) }; 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // A synchronous reader interface used by AudioOutputController for 79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // synchronous reading. 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // TODO(crogers): find a better name for this class and the Read() method 81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // now that it can handle synchronized I/O. 82 class SyncReader { 83 public: 84 virtual ~SyncReader() {} 85 86 // Notify the synchronous reader the number of bytes in the 87 // AudioOutputController not yet played. This is used by SyncReader to 88 // prepare more data and perform synchronization. 89 virtual void UpdatePendingBytes(uint32 bytes) = 0; 90 91 // Attempt to completely fill |dest|, return the actual number of frames 92 // that could be read. |source| may optionally be provided for input data. 93 // If |block| is specified, the Read() will block until data is available 94 // or a timeout is reached. 95 virtual int Read(bool block, const AudioBus* source, AudioBus* dest) = 0; 96 97 // Close this synchronous reader. 98 virtual void Close() = 0; 99 }; 100 101 // Factory method for creating an AudioOutputController. 102 // This also creates and opens an AudioOutputStream on the audio manager 103 // thread, and if this is successful, the |event_handler| will receive an 104 // OnCreated() call from the same audio manager thread. |audio_manager| must 105 // outlive AudioOutputController. 106 static scoped_refptr<AudioOutputController> Create( 107 AudioManager* audio_manager, EventHandler* event_handler, 108 const AudioParameters& params, const std::string& input_device_id, 109 SyncReader* sync_reader); 110 111 // Methods to control playback of the stream. 112 113 // Starts the playback of this audio output stream. 114 void Play(); 115 116 // Pause this audio output stream. 117 void Pause(); 118 119 // Closes the audio output stream. The state is changed and the resources 120 // are freed on the audio manager thread. closed_task is executed after that. 121 // Callbacks (EventHandler and SyncReader) must exist until closed_task is 122 // called. 123 // 124 // It is safe to call this method more than once. Calls after the first one 125 // will have no effect. 126 void Close(const base::Closure& closed_task); 127 128 // Sets the volume of the audio output stream. 129 void SetVolume(double volume); 130 131 // AudioSourceCallback implementation. 132 virtual int OnMoreData(AudioBus* dest, 133 AudioBuffersState buffers_state) OVERRIDE; 134 virtual int OnMoreIOData(AudioBus* source, 135 AudioBus* dest, 136 AudioBuffersState buffers_state) OVERRIDE; 137 virtual void OnError(AudioOutputStream* stream) OVERRIDE; 138 139 // AudioDeviceListener implementation. When called AudioOutputController will 140 // shutdown the existing |stream_|, transition to the kRecreating state, 141 // create a new stream, and then transition back to an equivalent state prior 142 // to being called. 143 virtual void OnDeviceChange() OVERRIDE; 144 145 // AudioSourceDiverter implementation. 146 virtual const AudioParameters& GetAudioParameters() OVERRIDE; 147 virtual void StartDiverting(AudioOutputStream* to_stream) OVERRIDE; 148 virtual void StopDiverting() OVERRIDE; 149 150 protected: 151 // Internal state of the source. 152 enum State { 153 kEmpty, 154 kCreated, 155 kPlaying, 156 kPaused, 157 kClosed, 158 kError, 159 }; 160 161 friend class base::RefCountedThreadSafe<AudioOutputController>; 162 virtual ~AudioOutputController(); 163 164 private: 165 // We are polling sync reader if data became available. 166 static const int kPollNumAttempts; 167 static const int kPollPauseInMilliseconds; 168 169 AudioOutputController(AudioManager* audio_manager, EventHandler* handler, 170 const AudioParameters& params, 171 const std::string& input_device_id, 172 SyncReader* sync_reader); 173 174 // The following methods are executed on the audio manager thread. 175 void DoCreate(bool is_for_device_change); 176 void DoPlay(); 177 void DoPause(); 178 void DoClose(); 179 void DoSetVolume(double volume); 180 void DoReportError(); 181 void DoStartDiverting(AudioOutputStream* to_stream); 182 void DoStopDiverting(); 183 184 // Called at regular intervals during playback to check for a change in 185 // silence and call EventHandler::OnAudible() when state changes occur. 186 void MaybeInvokeAudibleCallback(); 187 188 // Helper method that stops the physical stream. 189 void StopStream(); 190 191 // Helper method that stops, closes, and NULLs |*stream_|. 192 void DoStopCloseAndClearStream(); 193 194 // Sanity-check that entry/exit to OnMoreIOData() by the hardware audio thread 195 // happens only between AudioOutputStream::Start() and Stop(). 196 void AllowEntryToOnMoreIOData(); 197 void DisallowEntryToOnMoreIOData(); 198 199 AudioManager* const audio_manager_; 200 const AudioParameters params_; 201 EventHandler* const handler_; 202 203 // Used by the unified IO to open the correct input device. 204 std::string input_device_id_; 205 206 AudioOutputStream* stream_; 207 208 // When non-NULL, audio is being diverted to this stream. 209 AudioOutputStream* diverting_to_stream_; 210 211 // The current volume of the audio stream. 212 double volume_; 213 214 // |state_| is written on the audio manager thread and is read on the 215 // hardware audio thread. These operations need to be locked. But lock 216 // is not required for reading on the audio manager thread. 217 State state_; 218 219 // Binary semaphore, used to ensure that only one thread enters the 220 // OnMoreIOData() method, and only when it is valid to do so. This is for 221 // sanity-checking the behavior of platform implementations of 222 // AudioOutputStream. In other words, multiple contention is not expected, 223 // nor in the design here. 224 base::AtomicRefCount num_allowed_io_; 225 226 // SyncReader is used only in low latency mode for synchronous reading. 227 SyncReader* const sync_reader_; 228 229 // The message loop of audio manager thread that this object runs on. 230 const scoped_refptr<base::MessageLoopProxy> message_loop_; 231 232 // When starting stream we wait for data to become available. 233 // Number of times left. 234 int number_polling_attempts_left_; 235 236 // Scans audio samples from OnMoreIOData() as input and causes 237 // EventHandler::OnAudbile() to be called whenever a transition to a period of 238 // silence or non-silence is detected. 239 scoped_ptr<AudioSilenceDetector> silence_detector_; 240 241 DISALLOW_COPY_AND_ASSIGN(AudioOutputController); 242}; 243 244} // namespace media 245 246#endif // MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ 247