• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
50 namespace media {
51 
52 class AudioManagerMac;
53 class DataBuffer;
54 
55 class 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& input_params,
61                      const AudioParameters& output_params,
62                      AudioDeviceID audio_device_id);
63   // The dtor is typically called by the AudioManager only and it is usually
64   // triggered by calling AudioInputStream::Close().
65   virtual ~AUAudioInputStream();
66 
67   // Implementation of AudioInputStream.
68   virtual bool Open() OVERRIDE;
69   virtual void Start(AudioInputCallback* callback) OVERRIDE;
70   virtual void Stop() OVERRIDE;
71   virtual void Close() OVERRIDE;
72   virtual double GetMaxVolume() OVERRIDE;
73   virtual void SetVolume(double volume) OVERRIDE;
74   virtual double GetVolume() OVERRIDE;
75 
76   // Returns the current hardware sample rate for the default input device.
77   MEDIA_EXPORT static int HardwareSampleRate();
78 
started()79   bool started() const { return started_; }
audio_unit()80   AudioUnit audio_unit() { return audio_unit_; }
audio_buffer_list()81   AudioBufferList* audio_buffer_list() { return &audio_buffer_list_; }
82 
83  private:
84   // AudioOutputUnit callback.
85   static OSStatus InputProc(void* user_data,
86                             AudioUnitRenderActionFlags* flags,
87                             const AudioTimeStamp* time_stamp,
88                             UInt32 bus_number,
89                             UInt32 number_of_frames,
90                             AudioBufferList* io_data);
91 
92   // Pushes recorded data to consumer of the input audio stream.
93   OSStatus Provide(UInt32 number_of_frames, AudioBufferList* io_data,
94                    const AudioTimeStamp* time_stamp);
95 
96   // Gets the fixed capture hardware latency and store it during initialization.
97   // Returns 0 if not available.
98   double GetHardwareLatency();
99 
100   // Gets the current capture delay value.
101   double GetCaptureLatency(const AudioTimeStamp* input_time_stamp);
102 
103   // Gets the number of channels for a stream of audio data.
104   int GetNumberOfChannelsFromStream();
105 
106   // Issues the OnError() callback to the |sink_|.
107   void HandleError(OSStatus err);
108 
109   // Helper function to check if the volume control is avialable on specific
110   // channel.
111   bool IsVolumeSettableOnChannel(int channel);
112 
113   // Our creator, the audio manager needs to be notified when we close.
114   AudioManagerMac* manager_;
115 
116   // Contains the desired number of audio frames in each callback.
117   size_t number_of_frames_;
118 
119   // Pointer to the object that will receive the recorded audio samples.
120   AudioInputCallback* sink_;
121 
122   // Structure that holds the desired output format of the stream.
123   // Note that, this format can differ from the device(=input) format.
124   AudioStreamBasicDescription format_;
125 
126   // The special Audio Unit called AUHAL, which allows us to pass audio data
127   // directly from a microphone, through the HAL, and to our application.
128   // The AUHAL also enables selection of non default devices.
129   AudioUnit audio_unit_;
130 
131   // The UID refers to the current input audio device.
132   AudioDeviceID input_device_id_;
133 
134   // Provides a mechanism for encapsulating one or more buffers of audio data.
135   AudioBufferList audio_buffer_list_;
136 
137   // Temporary storage for recorded data. The InputProc() renders into this
138   // array as soon as a frame of the desired buffer size has been recorded.
139   scoped_ptr<uint8[]> audio_data_buffer_;
140 
141   // True after successfull Start(), false after successful Stop().
142   bool started_;
143 
144   // Fixed capture hardware latency in frames.
145   double hardware_latency_frames_;
146 
147   // Delay due to the FIFO in bytes.
148   int fifo_delay_bytes_;
149 
150   // The number of channels in each frame of audio data, which is used
151   // when querying the volume of each channel.
152   int number_of_channels_in_frame_;
153 
154   // Accumulates recorded data packets until the requested size has been stored.
155   scoped_ptr<media::SeekableBuffer> fifo_;
156 
157    // Intermediate storage of data from the FIFO before sending it to the
158    // client using the OnData() callback.
159   scoped_refptr<media::DataBuffer> data_;
160 
161   // The client requests that the recorded data shall be delivered using
162   // OnData() callbacks where each callback contains this amount of bytes.
163   int requested_size_bytes_;
164 
165   DISALLOW_COPY_AND_ASSIGN(AUAudioInputStream);
166 };
167 
168 }  // namespace media
169 
170 #endif  // MEDIA_AUDIO_MAC_AUDIO_LOW_LATENCY_INPUT_MAC_H_
171