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