audio_low_latency_input_mac.h revision 868fa2fe829687343ffae624259930155e16dbd8
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// Implementation of AudioInputStream for Mac OS X using the special AUHAL
6// input Audio Unit present in OS 10.4 and later.
7// The AUHAL input Audio Unit is for low-latency audio I/O.
8//
9// Overview of operation:
10//
11// - An object of AUAudioInputStream is created by the AudioManager
12//   factory: audio_man->MakeAudioInputStream().
13// - Next some thread will call Open(), at that point the underlying
14//   AUHAL output Audio Unit is created and configured.
15// - Then some thread will call Start(sink).
16//   Then the Audio Unit is started which creates its own thread which
17//   periodically will provide the sink with more data as buffers are being
18//   produced/recorded.
19// - At some point some thread will call Stop(), which we handle by directly
20//   stopping the AUHAL output Audio Unit.
21// - The same thread that called stop will call Close() where we cleanup
22//   and notify the audio manager, which likely will destroy this object.
23//
24// Implementation notes:
25//
26// - It is recommended to first acquire the native sample rate of the default
27//   input device and then use the same rate when creating this object.
28//   Use AUAudioInputStream::HardwareSampleRate() to retrieve the sample rate.
29// - Calling Close() also leads to self destruction.
30// - The latency consists of two parts:
31//   1) Hardware latency, which includes Audio Unit latency, audio device
32//      latency;
33//   2) The delay between the actual recording instant and the time when the
34//      data packet is provided as a callback.
35//
36#ifndef MEDIA_AUDIO_MAC_AUDIO_LOW_LATENCY_INPUT_MAC_H_
37#define MEDIA_AUDIO_MAC_AUDIO_LOW_LATENCY_INPUT_MAC_H_
38
39#include <AudioUnit/AudioUnit.h>
40#include <CoreAudio/CoreAudio.h>
41
42#include "base/atomicops.h"
43#include "base/memory/scoped_ptr.h"
44#include "base/synchronization/lock.h"
45#include "media/audio/agc_audio_stream.h"
46#include "media/audio/audio_io.h"
47#include "media/audio/audio_parameters.h"
48#include "media/base/seekable_buffer.h"
49
50namespace media {
51
52class AudioManagerMac;
53class DataBuffer;
54
55class AUAudioInputStream : public AgcAudioStream<AudioInputStream> {
56 public:
57  // The ctor takes all the usual parameters, plus |manager| which is the
58  // the audio manager who is creating this object.
59  AUAudioInputStream(AudioManagerMac* manager,
60                     const AudioParameters& params,
61                     AudioDeviceID audio_device_id);
62  // The dtor is typically called by the AudioManager only and it is usually
63  // triggered by calling AudioInputStream::Close().
64  virtual ~AUAudioInputStream();
65
66  // Implementation of AudioInputStream.
67  virtual bool Open() OVERRIDE;
68  virtual void Start(AudioInputCallback* callback) OVERRIDE;
69  virtual void Stop() OVERRIDE;
70  virtual void Close() OVERRIDE;
71  virtual double GetMaxVolume() OVERRIDE;
72  virtual void SetVolume(double volume) OVERRIDE;
73  virtual double GetVolume() OVERRIDE;
74
75  // Returns the current hardware sample rate for the default input device.
76  MEDIA_EXPORT static int HardwareSampleRate();
77
78  bool started() const { return started_; }
79  AudioUnit audio_unit() { return audio_unit_; }
80  AudioBufferList* audio_buffer_list() { return &audio_buffer_list_; }
81
82 private:
83  // AudioOutputUnit callback.
84  static OSStatus InputProc(void* user_data,
85                            AudioUnitRenderActionFlags* flags,
86                            const AudioTimeStamp* time_stamp,
87                            UInt32 bus_number,
88                            UInt32 number_of_frames,
89                            AudioBufferList* io_data);
90
91  // Pushes recorded data to consumer of the input audio stream.
92  OSStatus Provide(UInt32 number_of_frames, AudioBufferList* io_data,
93                   const AudioTimeStamp* time_stamp);
94
95  // Gets the fixed capture hardware latency and store it during initialization.
96  // Returns 0 if not available.
97  double GetHardwareLatency();
98
99  // Gets the current capture delay value.
100  double GetCaptureLatency(const AudioTimeStamp* input_time_stamp);
101
102  // Gets the number of channels for a stream of audio data.
103  int GetNumberOfChannelsFromStream();
104
105  // Issues the OnError() callback to the |sink_|.
106  void HandleError(OSStatus err);
107
108  // Helper function to check if the volume control is avialable on specific
109  // channel.
110  bool IsVolumeSettableOnChannel(int channel);
111
112  // Our creator, the audio manager needs to be notified when we close.
113  AudioManagerMac* manager_;
114
115  // Contains the desired number of audio frames in each callback.
116  size_t number_of_frames_;
117
118  // Pointer to the object that will receive the recorded audio samples.
119  AudioInputCallback* sink_;
120
121  // Structure that holds the desired output format of the stream.
122  // Note that, this format can differ from the device(=input) format.
123  AudioStreamBasicDescription format_;
124
125  // The special Audio Unit called AUHAL, which allows us to pass audio data
126  // directly from a microphone, through the HAL, and to our application.
127  // The AUHAL also enables selection of non default devices.
128  AudioUnit audio_unit_;
129
130  // The UID refers to the current input audio device.
131  AudioDeviceID input_device_id_;
132
133  // Provides a mechanism for encapsulating one or more buffers of audio data.
134  AudioBufferList audio_buffer_list_;
135
136  // Temporary storage for recorded data. The InputProc() renders into this
137  // array as soon as a frame of the desired buffer size has been recorded.
138  scoped_ptr<uint8[]> audio_data_buffer_;
139
140  // True after successfull Start(), false after successful Stop().
141  bool started_;
142
143  // Fixed capture hardware latency in frames.
144  double hardware_latency_frames_;
145
146  // Delay due to the FIFO in bytes.
147  int fifo_delay_bytes_;
148
149  // The number of channels in each frame of audio data, which is used
150  // when querying the volume of each channel.
151  int number_of_channels_in_frame_;
152
153  // Accumulates recorded data packets until the requested size has been stored.
154  scoped_ptr<media::SeekableBuffer> fifo_;
155
156   // Intermediate storage of data from the FIFO before sending it to the
157   // client using the OnData() callback.
158  scoped_refptr<media::DataBuffer> data_;
159
160  // The client requests that the recorded data shall be delivered using
161  // OnData() callbacks where each callback contains this amount of bytes.
162  int requested_size_bytes_;
163
164  DISALLOW_COPY_AND_ASSIGN(AUAudioInputStream);
165};
166
167}  // namespace media
168
169#endif  // MEDIA_AUDIO_MAC_AUDIO_LOW_LATENCY_INPUT_MAC_H_
170