audio_input_controller.h revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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_INPUT_CONTROLLER_H_
6#define MEDIA_AUDIO_AUDIO_INPUT_CONTROLLER_H_
7
8#include <string>
9#include "base/atomicops.h"
10#include "base/callback.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/synchronization/lock.h"
14#include "base/synchronization/waitable_event.h"
15#include "base/threading/thread.h"
16#include "base/timer/timer.h"
17#include "media/audio/audio_io.h"
18#include "media/audio/audio_manager_base.h"
19
20// An AudioInputController controls an AudioInputStream and records data
21// from this input stream. The two main methods are Record() and Close() and
22// they are both executed on the audio thread which is injected by the two
23// alternative factory methods, Create() or CreateLowLatency().
24//
25// All public methods of AudioInputController are non-blocking.
26//
27// Here is a state diagram for the AudioInputController:
28//
29//                    .-->  [ Closed / Error ]  <--.
30//                    |                            |
31//                    |                            |
32//               [ Created ]  ---------->  [ Recording ]
33//                    ^
34//                    |
35//              *[  Empty  ]
36//
37// * Initial state
38//
39// State sequences (assuming low-latency):
40//
41//  [Creating Thread]                     [Audio Thread]
42//
43//      User               AudioInputController               EventHandler
44// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
45// CrateLowLatency() ==>        DoCreate()
46//                   AudioManager::MakeAudioInputStream()
47//                        AudioInputStream::Open()
48//                                  .- - - - - - - - - - - - ->   OnError()
49//                          create the data timer
50//                                  .------------------------->  OnCreated()
51//                               kCreated
52// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
53// Record() ==>                 DoRecord()
54//                      AudioInputStream::Start()
55//                                  .------------------------->  OnRecording()
56//                          start the data timer
57//                              kRecording
58// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
59// Close() ==>                  DoClose()
60//                        delete the data timer
61//                           state_ = kClosed
62//                        AudioInputStream::Stop()
63//                        AudioInputStream::Close()
64//                          SyncWriter::Close()
65// Closure::Run() <-----------------.
66// (closure-task)
67//
68// The audio thread itself is owned by the AudioManager that the
69// AudioInputController holds a reference to.  When performing tasks on the
70// audio thread, the controller must not add or release references to the
71// AudioManager or itself (since it in turn holds a reference to the manager).
72//
73namespace media {
74
75class UserInputMonitor;
76
77class MEDIA_EXPORT AudioInputController
78    : public base::RefCountedThreadSafe<AudioInputController>,
79      public AudioInputStream::AudioInputCallback {
80 public:
81
82  // Error codes to make native loggin more clear. These error codes are added
83  // to generic error strings to provide a higher degree of details.
84  // Changing these values can lead to problems when matching native debug
85  // logs with the actual cause of error.
86  enum ErrorCode {
87    // An unspecified error occured.
88    UNKNOWN_ERROR = 0,
89
90    // Failed to create an audio input stream.
91    STREAM_CREATE_ERROR,  // = 1
92
93    // Failed to open an audio input stream.
94    STREAM_OPEN_ERROR,  // = 2
95
96    // Native input stream reports an error. Exact reason differs between
97    // platforms.
98    STREAM_ERROR,  // = 3
99
100    // This can happen if a capture device has been removed or disabled.
101    NO_DATA_ERROR,  // = 4
102  };
103
104  // An event handler that receives events from the AudioInputController. The
105  // following methods are all called on the audio thread.
106  class MEDIA_EXPORT EventHandler {
107   public:
108    virtual void OnCreated(AudioInputController* controller) = 0;
109    virtual void OnRecording(AudioInputController* controller) = 0;
110    virtual void OnError(AudioInputController* controller,
111                         ErrorCode error_code) = 0;
112    virtual void OnData(AudioInputController* controller, const uint8* data,
113                        uint32 size) = 0;
114
115   protected:
116    virtual ~EventHandler() {}
117  };
118
119  // A synchronous writer interface used by AudioInputController for
120  // synchronous writing.
121  class SyncWriter {
122   public:
123    virtual ~SyncWriter() {}
124
125    // Notify the synchronous writer about the number of bytes in the
126    // soundcard which has been recorded.
127    virtual void UpdateRecordedBytes(uint32 bytes) = 0;
128
129    // Write certain amount of data from |data|. This method returns
130    // number of written bytes.
131    virtual uint32 Write(const void* data,
132                         uint32 size,
133                         double volume,
134                         bool key_pressed) = 0;
135
136    // Close this synchronous writer.
137    virtual void Close() = 0;
138  };
139
140  // AudioInputController::Create() can use the currently registered Factory
141  // to create the AudioInputController. Factory is intended for testing only.
142  // |user_input_monitor| is used for typing detection and can be NULL.
143  class Factory {
144   public:
145    virtual AudioInputController* Create(
146        AudioManager* audio_manager,
147        EventHandler* event_handler,
148        AudioParameters params,
149        UserInputMonitor* user_input_monitor) = 0;
150
151   protected:
152    virtual ~Factory() {}
153  };
154
155  // Factory method for creating an AudioInputController.
156  // The audio device will be created on the audio thread, and when that is
157  // done, the event handler will receive an OnCreated() call from that same
158  // thread. |device_id| is the unique ID of the audio device to be opened.
159  // |user_input_monitor| is used for typing detection and can be NULL.
160  static scoped_refptr<AudioInputController> Create(
161      AudioManager* audio_manager,
162      EventHandler* event_handler,
163      const AudioParameters& params,
164      const std::string& device_id,
165      UserInputMonitor* user_input_monitor);
166
167  // Sets the factory used by the static method Create(). AudioInputController
168  // does not take ownership of |factory|. A value of NULL results in an
169  // AudioInputController being created directly.
170  static void set_factory_for_testing(Factory* factory) { factory_ = factory; }
171  AudioInputStream* stream_for_testing() { return stream_; }
172
173  // Factory method for creating an AudioInputController for low-latency mode.
174  // The audio device will be created on the audio thread, and when that is
175  // done, the event handler will receive an OnCreated() call from that same
176  // thread. |user_input_monitor| is used for typing detection and can be NULL.
177  static scoped_refptr<AudioInputController> CreateLowLatency(
178      AudioManager* audio_manager,
179      EventHandler* event_handler,
180      const AudioParameters& params,
181      const std::string& device_id,
182      // External synchronous writer for audio controller.
183      SyncWriter* sync_writer,
184      UserInputMonitor* user_input_monitor);
185
186  // Factory method for creating an AudioInputController for low-latency mode,
187  // taking ownership of |stream|.  The stream will be opened on the audio
188  // thread, and when that is done, the event handler will receive an
189  // OnCreated() call from that same thread. |user_input_monitor| is used for
190  // typing detection and can be NULL.
191  static scoped_refptr<AudioInputController> CreateForStream(
192      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
193      EventHandler* event_handler,
194      AudioInputStream* stream,
195      // External synchronous writer for audio controller.
196      SyncWriter* sync_writer,
197      UserInputMonitor* user_input_monitor);
198
199  // Starts recording using the created audio input stream.
200  // This method is called on the creator thread.
201  virtual void Record();
202
203  // Closes the audio input stream. The state is changed and the resources
204  // are freed on the audio thread. |closed_task| is then executed on the thread
205  // that called Close().
206  // Callbacks (EventHandler and SyncWriter) must exist until |closed_task|
207  // is called.
208  // It is safe to call this method more than once. Calls after the first one
209  // will have no effect.
210  // This method trampolines to the audio thread.
211  virtual void Close(const base::Closure& closed_task);
212
213  // Sets the capture volume of the input stream. The value 0.0 corresponds
214  // to muted and 1.0 to maximum volume.
215  virtual void SetVolume(double volume);
216
217  // Sets the Automatic Gain Control (AGC) state of the input stream.
218  // Changing the AGC state is not supported while recording is active.
219  virtual void SetAutomaticGainControl(bool enabled);
220
221  // AudioInputCallback implementation. Threading details depends on the
222  // device-specific implementation.
223  virtual void OnData(AudioInputStream* stream, const uint8* src, uint32 size,
224                      uint32 hardware_delay_bytes, double volume) OVERRIDE;
225  virtual void OnError(AudioInputStream* stream) OVERRIDE;
226
227  bool LowLatencyMode() const { return sync_writer_ != NULL; }
228
229 protected:
230  friend class base::RefCountedThreadSafe<AudioInputController>;
231
232  // Internal state of the source.
233  enum State {
234    CREATED,
235    RECORDING,
236    CLOSED
237  };
238
239  AudioInputController(EventHandler* handler,
240                       SyncWriter* sync_writer,
241                       UserInputMonitor* user_input_monitor);
242  virtual ~AudioInputController();
243
244  // Methods called on the audio thread (owned by the AudioManager).
245  void DoCreate(AudioManager* audio_manager, const AudioParameters& params,
246                const std::string& device_id);
247  void DoCreateForStream(AudioInputStream* stream_to_control,
248                         bool enable_nodata_timer);
249  void DoRecord();
250  void DoClose();
251  void DoReportError();
252  void DoSetVolume(double volume);
253  void DoSetAutomaticGainControl(bool enabled);
254
255  // Method which ensures that OnError() is triggered when data recording
256  // times out. Called on the audio thread.
257  void DoCheckForNoData();
258
259  // Helper method that stops, closes, and NULL:s |*stream_|.
260  // Signals event when done if the event is not NULL.
261  void DoStopCloseAndClearStream(base::WaitableEvent* done);
262
263  void SetDataIsActive(bool enabled);
264  bool GetDataIsActive();
265
266  // Gives access to the task runner of the creating thread.
267  scoped_refptr<base::SingleThreadTaskRunner> creator_task_runner_;
268
269  // The task runner of audio-manager thread that this object runs on.
270  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
271
272  // Contains the AudioInputController::EventHandler which receives state
273  // notifications from this class.
274  EventHandler* handler_;
275
276  // Pointer to the audio input stream object.
277  AudioInputStream* stream_;
278
279  // |no_data_timer_| is used to call OnError() when we stop receiving
280  // OnData() calls. This can occur when an audio input device is unplugged
281  // whilst recording on Windows.
282  // See http://crbug.com/79936 for details.
283  // This member is only touched by the audio thread.
284  scoped_ptr<base::Timer> no_data_timer_;
285
286  // This flag is used to signal that we are receiving OnData() calls, i.e,
287  // that data is active. It can be touched by the audio thread and by the
288  // low-level audio thread which calls OnData(). E.g. on Windows, the
289  // low-level audio thread is called wasapi_capture_thread.
290  base::subtle::Atomic32 data_is_active_;
291
292  // |state_| is written on the audio thread and is read on the hardware audio
293  // thread. These operations need to be locked. But lock is not required for
294  // reading on the audio input controller thread.
295  State state_;
296
297  base::Lock lock_;
298
299  // SyncWriter is used only in low-latency mode for synchronous writing.
300  SyncWriter* sync_writer_;
301
302  static Factory* factory_;
303
304  double max_volume_;
305
306  UserInputMonitor* user_input_monitor_;
307
308  size_t prev_key_down_count_;
309
310  DISALLOW_COPY_AND_ASSIGN(AudioInputController);
311};
312
313}  // namespace media
314
315#endif  // MEDIA_AUDIO_AUDIO_INPUT_CONTROLLER_H_
316