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.
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.
9 // Overview of operation:
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
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.
24 // Implementation notes:
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
33 // 2) The delay between the actual recording instant and the time when the
34 // data packet is provided as a callback.
36 #ifndef MEDIA_AUDIO_MAC_AUDIO_LOW_LATENCY_INPUT_MAC_H_
37 #define MEDIA_AUDIO_MAC_AUDIO_LOW_LATENCY_INPUT_MAC_H_
39 #include <AudioUnit/AudioUnit.h>
40 #include <CoreAudio/CoreAudio.h>
42 #include "base/atomicops.h"
43 #include "base/memory/scoped_ptr.h"
44 #include "base/synchronization/lock.h"
45 #include "media/audio/audio_io.h"
46 #include "media/audio/audio_input_stream_impl.h"
47 #include "media/audio/audio_parameters.h"
48 #include "media/base/seekable_buffer.h"
52 class AudioManagerMac
;
55 class AUAudioInputStream
: public AudioInputStreamImpl
{
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();
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
;
75 // Returns the current hardware sample rate for the default input device.
76 MEDIA_EXPORT
static int HardwareSampleRate();
78 bool started() const { return started_
; }
79 AudioUnit
audio_unit() { return audio_unit_
; }
80 AudioBufferList
* audio_buffer_list() { return &audio_buffer_list_
; }
83 // AudioOutputUnit callback.
84 static OSStatus
InputProc(void* user_data
,
85 AudioUnitRenderActionFlags
* flags
,
86 const AudioTimeStamp
* time_stamp
,
88 UInt32 number_of_frames
,
89 AudioBufferList
* io_data
);
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
);
95 // Gets the fixed capture hardware latency and store it during initialization.
96 // Returns 0 if not available.
97 double GetHardwareLatency();
99 // Gets the current capture delay value.
100 double GetCaptureLatency(const AudioTimeStamp
* input_time_stamp
);
102 // Gets the number of channels for a stream of audio data.
103 int GetNumberOfChannelsFromStream();
105 // Issues the OnError() callback to the |sink_|.
106 void HandleError(OSStatus err
);
108 // Helper function to check if the volume control is avialable on specific
110 bool IsVolumeSettableOnChannel(int channel
);
112 // Our creator, the audio manager needs to be notified when we close.
113 AudioManagerMac
* manager_
;
115 // Contains the desired number of audio frames in each callback.
116 size_t number_of_frames_
;
118 // Pointer to the object that will receive the recorded audio samples.
119 AudioInputCallback
* sink_
;
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_
;
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_
;
130 // The UID refers to the current input audio device.
131 AudioDeviceID input_device_id_
;
133 // Provides a mechanism for encapsulating one or more buffers of audio data.
134 AudioBufferList audio_buffer_list_
;
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_array
<uint8
> audio_data_buffer_
;
140 // True after successfull Start(), false after successful Stop().
143 // Fixed capture hardware latency in frames.
144 double hardware_latency_frames_
;
146 // The number of channels in each frame of audio data, which is used
147 // when querying the volume of each channel.
148 int number_of_channels_in_frame_
;
150 // Accumulates recorded data packets until the requested size has been stored.
151 scoped_ptr
<media::SeekableBuffer
> fifo_
;
153 // Intermediate storage of data from the FIFO before sending it to the
154 // client using the OnData() callback.
155 scoped_refptr
<media::DataBuffer
> data_
;
157 // The client requests that the recorded data shall be delivered using
158 // OnData() callbacks where each callback contains this amount of bytes.
159 int requested_size_bytes_
;
161 DISALLOW_COPY_AND_ASSIGN(AUAudioInputStream
);
166 #endif // MEDIA_AUDIO_MAC_AUDIO_LOW_LATENCY_INPUT_MAC_H_