audio_output_controller.h revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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
53namespace 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
60class 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