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 #ifndef MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ 6 #define MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ 7 8 #include "base/atomic_ref_count.h" 9 #include "base/callback.h" 10 #include "base/cancelable_callback.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/timer/timer.h" 13 #include "media/audio/audio_io.h" 14 #include "media/audio/audio_manager.h" 15 #include "media/audio/audio_power_monitor.h" 16 #include "media/audio/audio_source_diverter.h" 17 #include "media/audio/simple_sources.h" 18 #include "media/base/media_export.h" 19 20 // An AudioOutputController controls an AudioOutputStream and provides data 21 // to this output stream. It has an important function that it executes 22 // audio operations like play, pause, stop, etc. on a separate thread, 23 // namely the audio manager thread. 24 // 25 // All the public methods of AudioOutputController are non-blocking. 26 // The actual operations are performed on the audio manager thread. 27 // 28 // Here is a state transition diagram for the AudioOutputController: 29 // 30 // *[ Empty ] --> [ Created ] --> [ Playing ] -------. 31 // | | | ^ | 32 // | | | | | 33 // | | | | v 34 // | | | `----- [ Paused ] 35 // | | | | 36 // | v v | 37 // `-----------> [ Closed ] <-----------' 38 // 39 // * Initial state 40 // 41 // At any time after reaching the Created state but before Closed, the 42 // AudioOutputController may be notified of a device change via 43 // OnDeviceChange(). As the OnDeviceChange() is processed, state transitions 44 // will occur, ultimately ending up in an equivalent pre-call state. E.g., if 45 // the state was Paused, the new state will be Created, since these states are 46 // all functionally equivalent and require a Play() call to continue to the next 47 // state. 48 // 49 // The AudioOutputStream can request data from the AudioOutputController via the 50 // AudioSourceCallback interface. AudioOutputController uses the SyncReader 51 // passed to it via construction to synchronously fulfill this read request. 52 // 53 54 namespace media { 55 56 // Only do power monitoring for non-mobile platforms that need it for the UI. 57 #if !defined(OS_ANDROID) && !defined(OS_IOS) 58 #define AUDIO_POWER_MONITORING 59 #endif 60 61 class MEDIA_EXPORT AudioOutputController 62 : public base::RefCountedThreadSafe<AudioOutputController>, 63 public AudioOutputStream::AudioSourceCallback, 64 public AudioSourceDiverter, 65 NON_EXPORTED_BASE(public AudioManager::AudioDeviceListener) { 66 public: 67 // An event handler that receives events from the AudioOutputController. The 68 // following methods are called on the audio manager thread. 69 class MEDIA_EXPORT EventHandler { 70 public: 71 virtual void OnCreated() = 0; 72 virtual void OnPlaying() = 0; 73 virtual void OnPowerMeasured(float power_dbfs, bool clipped) = 0; 74 virtual void OnPaused() = 0; 75 virtual void OnError() = 0; 76 virtual void OnDeviceChange(int new_buffer_size, int new_sample_rate) = 0; 77 78 protected: 79 virtual ~EventHandler() {} 80 }; 81 82 // A synchronous reader interface used by AudioOutputController for 83 // synchronous reading. 84 // TODO(crogers): find a better name for this class and the Read() method 85 // now that it can handle synchronized I/O. 86 class SyncReader { 87 public: 88 virtual ~SyncReader() {} 89 90 // Notify the synchronous reader the number of bytes in the 91 // AudioOutputController not yet played. This is used by SyncReader to 92 // prepare more data and perform synchronization. 93 virtual void UpdatePendingBytes(uint32 bytes) = 0; 94 95 // Attempts to completely fill |dest|, zeroing |dest| if the request can not 96 // be fulfilled (due to timeout). |source| may optionally be provided for 97 // input data. 98 virtual void Read(const AudioBus* source, AudioBus* dest) = 0; 99 100 // Close this synchronous reader. 101 virtual void Close() = 0; 102 }; 103 104 // Factory method for creating an AudioOutputController. 105 // This also creates and opens an AudioOutputStream on the audio manager 106 // thread, and if this is successful, the |event_handler| will receive an 107 // OnCreated() call from the same audio manager thread. |audio_manager| must 108 // outlive AudioOutputController. 109 // The |output_device_id| can be either empty (default device) or specify a 110 // specific hardware device for audio output. The |input_device_id| is 111 // used only for unified audio when opening up input and output at the same 112 // time (controlled by |params.input_channel_count()|). 113 static scoped_refptr<AudioOutputController> Create( 114 AudioManager* audio_manager, EventHandler* event_handler, 115 const AudioParameters& params, const std::string& output_device_id, 116 const std::string& input_device_id, SyncReader* sync_reader); 117 118 // Methods to control playback of the stream. 119 120 // Starts the playback of this audio output stream. 121 void Play(); 122 123 // Pause this audio output stream. 124 void Pause(); 125 126 // Closes the audio output stream. The state is changed and the resources 127 // are freed on the audio manager thread. closed_task is executed after that. 128 // Callbacks (EventHandler and SyncReader) must exist until closed_task is 129 // called. 130 // 131 // It is safe to call this method more than once. Calls after the first one 132 // will have no effect. 133 void Close(const base::Closure& closed_task); 134 135 // Sets the volume of the audio output stream. 136 void SetVolume(double volume); 137 138 // Calls |callback| (on the caller's thread) with the current output 139 // device ID. 140 void GetOutputDeviceId( 141 base::Callback<void(const std::string&)> callback) const; 142 143 // Changes which output device to use. If desired, you can provide a 144 // callback that will be notified (on the thread you called from) 145 // when the function has completed execution. 146 // 147 // Changing the output device causes the controller to go through 148 // the same state transition back to the current state as a call to 149 // OnDeviceChange (unless it is currently diverting, see 150 // Start/StopDiverting below, in which case the state transition 151 // will happen when StopDiverting is called). 152 void SwitchOutputDevice(const std::string& output_device_id, 153 const base::Closure& callback); 154 155 // AudioSourceCallback implementation. 156 virtual int OnMoreData(AudioBus* dest, 157 AudioBuffersState buffers_state) OVERRIDE; 158 virtual int OnMoreIOData(AudioBus* source, 159 AudioBus* dest, 160 AudioBuffersState buffers_state) OVERRIDE; 161 virtual void OnError(AudioOutputStream* stream) OVERRIDE; 162 163 // AudioDeviceListener implementation. When called AudioOutputController will 164 // shutdown the existing |stream_|, transition to the kRecreating state, 165 // create a new stream, and then transition back to an equivalent state prior 166 // to being called. 167 virtual void OnDeviceChange() OVERRIDE; 168 169 // AudioSourceDiverter implementation. 170 virtual const AudioParameters& GetAudioParameters() OVERRIDE; 171 virtual void StartDiverting(AudioOutputStream* to_stream) OVERRIDE; 172 virtual void StopDiverting() OVERRIDE; 173 174 protected: 175 // Internal state of the source. 176 enum State { 177 kEmpty, 178 kCreated, 179 kPlaying, 180 kPaused, 181 kClosed, 182 kError, 183 }; 184 185 friend class base::RefCountedThreadSafe<AudioOutputController>; 186 virtual ~AudioOutputController(); 187 188 private: 189 // We are polling sync reader if data became available. 190 static const int kPollNumAttempts; 191 static const int kPollPauseInMilliseconds; 192 193 AudioOutputController(AudioManager* audio_manager, EventHandler* handler, 194 const AudioParameters& params, 195 const std::string& output_device_id, 196 const std::string& input_device_id, 197 SyncReader* sync_reader); 198 199 // The following methods are executed on the audio manager thread. 200 void DoCreate(bool is_for_device_change); 201 void DoPlay(); 202 void DoPause(); 203 void DoClose(); 204 void DoSetVolume(double volume); 205 std::string DoGetOutputDeviceId() const; 206 void DoSwitchOutputDevice(const std::string& output_device_id); 207 void DoReportError(); 208 void DoStartDiverting(AudioOutputStream* to_stream); 209 void DoStopDiverting(); 210 211 // Calls EventHandler::OnPowerMeasured() with the current power level and then 212 // schedules itself to be called again later. 213 void ReportPowerMeasurementPeriodically(); 214 215 // Helper method that stops the physical stream. 216 void StopStream(); 217 218 // Helper method that stops, closes, and NULLs |*stream_|. 219 void DoStopCloseAndClearStream(); 220 221 // Sanity-check that entry/exit to OnMoreIOData() by the hardware audio thread 222 // happens only between AudioOutputStream::Start() and Stop(). 223 void AllowEntryToOnMoreIOData(); 224 void DisallowEntryToOnMoreIOData(); 225 226 // Checks if a stream was started successfully but never calls OnMoreIOData(). 227 void WedgeCheck(); 228 229 AudioManager* const audio_manager_; 230 const AudioParameters params_; 231 EventHandler* const handler_; 232 233 // Specifies the device id of the output device to open or empty for the 234 // default output device. 235 std::string output_device_id_; 236 237 // Used by the unified IO to open the correct input device. 238 const std::string input_device_id_; 239 240 AudioOutputStream* stream_; 241 242 // When non-NULL, audio is being diverted to this stream. 243 AudioOutputStream* diverting_to_stream_; 244 245 // The current volume of the audio stream. 246 double volume_; 247 248 // |state_| is written on the audio manager thread and is read on the 249 // hardware audio thread. These operations need to be locked. But lock 250 // is not required for reading on the audio manager thread. 251 State state_; 252 253 // Binary semaphore, used to ensure that only one thread enters the 254 // OnMoreIOData() method, and only when it is valid to do so. This is for 255 // sanity-checking the behavior of platform implementations of 256 // AudioOutputStream. In other words, multiple contention is not expected, 257 // nor in the design here. 258 base::AtomicRefCount num_allowed_io_; 259 260 // SyncReader is used only in low latency mode for synchronous reading. 261 SyncReader* const sync_reader_; 262 263 // The message loop of audio manager thread that this object runs on. 264 const scoped_refptr<base::MessageLoopProxy> message_loop_; 265 266 #if defined(AUDIO_POWER_MONITORING) 267 // Scans audio samples from OnMoreIOData() as input to compute power levels. 268 AudioPowerMonitor power_monitor_; 269 270 // Periodic callback to report power levels during playback. 271 base::CancelableClosure power_poll_callback_; 272 #endif 273 274 // Flags when we've asked for a stream to start but it never did. 275 base::AtomicRefCount on_more_io_data_called_; 276 scoped_ptr<base::OneShotTimer<AudioOutputController> > wedge_timer_; 277 278 DISALLOW_COPY_AND_ASSIGN(AudioOutputController); 279 }; 280 281 } // namespace media 282 283 #endif // MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ 284