audio_device_mac.h revision 2550988baaf3a50a2eb1a595c26bc7912ad99b30
1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_MAC_H
12#define WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_MAC_H
13
14#include "audio_device_generic.h"
15#include "critical_section_wrapper.h"
16#include "audio_mixer_manager_mac.h"
17
18#include <CoreAudio/CoreAudio.h>
19#include <AudioToolbox/AudioConverter.h>
20#include <mach/semaphore.h>
21
22struct PaUtilRingBuffer;
23
24namespace webrtc
25{
26class EventWrapper;
27class ThreadWrapper;
28
29const uint32_t N_REC_SAMPLES_PER_SEC = 48000;
30const uint32_t N_PLAY_SAMPLES_PER_SEC = 48000;
31
32const uint32_t N_REC_CHANNELS = 1; // default is mono recording
33const uint32_t N_PLAY_CHANNELS = 2; // default is stereo playout
34const uint32_t N_DEVICE_CHANNELS = 8;
35
36const uint32_t ENGINE_REC_BUF_SIZE_IN_SAMPLES = (N_REC_SAMPLES_PER_SEC / 100);
37const uint32_t ENGINE_PLAY_BUF_SIZE_IN_SAMPLES = (N_PLAY_SAMPLES_PER_SEC / 100);
38
39enum
40{
41    N_BLOCKS_IO = 2
42};
43enum
44{
45    N_BUFFERS_IN = 10
46};
47enum
48{
49    N_BUFFERS_OUT = 3
50}; // Must be at least N_BLOCKS_IO
51
52const uint32_t TIMER_PERIOD_MS = (2 * 10 * N_BLOCKS_IO * 1000000);
53
54const uint32_t REC_BUF_SIZE_IN_SAMPLES = (ENGINE_REC_BUF_SIZE_IN_SAMPLES
55    * N_DEVICE_CHANNELS * N_BUFFERS_IN);
56const uint32_t PLAY_BUF_SIZE_IN_SAMPLES =
57    (ENGINE_PLAY_BUF_SIZE_IN_SAMPLES * N_PLAY_CHANNELS * N_BUFFERS_OUT);
58
59class AudioDeviceMac: public AudioDeviceGeneric
60{
61public:
62    AudioDeviceMac(const int32_t id);
63    ~AudioDeviceMac();
64
65    // Retrieve the currently utilized audio layer
66    virtual int32_t
67        ActiveAudioLayer(AudioDeviceModule::AudioLayer& audioLayer) const;
68
69    // Main initializaton and termination
70    virtual int32_t Init();
71    virtual int32_t Terminate();
72    virtual bool Initialized() const;
73
74    // Device enumeration
75    virtual int16_t PlayoutDevices();
76    virtual int16_t RecordingDevices();
77    virtual int32_t PlayoutDeviceName(
78        uint16_t index,
79        char name[kAdmMaxDeviceNameSize],
80        char guid[kAdmMaxGuidSize]);
81    virtual int32_t RecordingDeviceName(
82        uint16_t index,
83        char name[kAdmMaxDeviceNameSize],
84        char guid[kAdmMaxGuidSize]);
85
86    // Device selection
87    virtual int32_t SetPlayoutDevice(uint16_t index);
88    virtual int32_t SetPlayoutDevice(
89        AudioDeviceModule::WindowsDeviceType device);
90    virtual int32_t SetRecordingDevice(uint16_t index);
91    virtual int32_t SetRecordingDevice(
92        AudioDeviceModule::WindowsDeviceType device);
93
94    // Audio transport initialization
95    virtual int32_t PlayoutIsAvailable(bool& available);
96    virtual int32_t InitPlayout();
97    virtual bool PlayoutIsInitialized() const;
98    virtual int32_t RecordingIsAvailable(bool& available);
99    virtual int32_t InitRecording();
100    virtual bool RecordingIsInitialized() const;
101
102    // Audio transport control
103    virtual int32_t StartPlayout();
104    virtual int32_t StopPlayout();
105    virtual bool Playing() const;
106    virtual int32_t StartRecording();
107    virtual int32_t StopRecording();
108    virtual bool Recording() const;
109
110    // Microphone Automatic Gain Control (AGC)
111    virtual int32_t SetAGC(bool enable);
112    virtual bool AGC() const;
113
114    // Volume control based on the Windows Wave API (Windows only)
115    virtual int32_t SetWaveOutVolume(uint16_t volumeLeft, uint16_t volumeRight);
116    virtual int32_t WaveOutVolume(uint16_t& volumeLeft,
117                                  uint16_t& volumeRight) const;
118
119    // Audio mixer initialization
120    virtual int32_t SpeakerIsAvailable(bool& available);
121    virtual int32_t InitSpeaker();
122    virtual bool SpeakerIsInitialized() const;
123    virtual int32_t MicrophoneIsAvailable(bool& available);
124    virtual int32_t InitMicrophone();
125    virtual bool MicrophoneIsInitialized() const;
126
127    // Speaker volume controls
128    virtual int32_t SpeakerVolumeIsAvailable(bool& available);
129    virtual int32_t SetSpeakerVolume(uint32_t volume);
130    virtual int32_t SpeakerVolume(uint32_t& volume) const;
131    virtual int32_t MaxSpeakerVolume(uint32_t& maxVolume) const;
132    virtual int32_t MinSpeakerVolume(uint32_t& minVolume) const;
133    virtual int32_t SpeakerVolumeStepSize(uint16_t& stepSize) const;
134
135    // Microphone volume controls
136    virtual int32_t MicrophoneVolumeIsAvailable(bool& available);
137    virtual int32_t SetMicrophoneVolume(uint32_t volume);
138    virtual int32_t MicrophoneVolume(uint32_t& volume) const;
139    virtual int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const;
140    virtual int32_t MinMicrophoneVolume(uint32_t& minVolume) const;
141    virtual int32_t
142        MicrophoneVolumeStepSize(uint16_t& stepSize) const;
143
144    // Microphone mute control
145    virtual int32_t MicrophoneMuteIsAvailable(bool& available);
146    virtual int32_t SetMicrophoneMute(bool enable);
147    virtual int32_t MicrophoneMute(bool& enabled) const;
148
149    // Speaker mute control
150    virtual int32_t SpeakerMuteIsAvailable(bool& available);
151    virtual int32_t SetSpeakerMute(bool enable);
152    virtual int32_t SpeakerMute(bool& enabled) const;
153
154    // Microphone boost control
155    virtual int32_t MicrophoneBoostIsAvailable(bool& available);
156    virtual int32_t SetMicrophoneBoost(bool enable);
157    virtual int32_t MicrophoneBoost(bool& enabled) const;
158
159    // Stereo support
160    virtual int32_t StereoPlayoutIsAvailable(bool& available);
161    virtual int32_t SetStereoPlayout(bool enable);
162    virtual int32_t StereoPlayout(bool& enabled) const;
163    virtual int32_t StereoRecordingIsAvailable(bool& available);
164    virtual int32_t SetStereoRecording(bool enable);
165    virtual int32_t StereoRecording(bool& enabled) const;
166
167    // Delay information and control
168    virtual int32_t
169        SetPlayoutBuffer(const AudioDeviceModule::BufferType type,
170                         uint16_t sizeMS);
171    virtual int32_t PlayoutBuffer(AudioDeviceModule::BufferType& type,
172                                  uint16_t& sizeMS) const;
173    virtual int32_t PlayoutDelay(uint16_t& delayMS) const;
174    virtual int32_t RecordingDelay(uint16_t& delayMS) const;
175
176    // CPU load
177    virtual int32_t CPULoad(uint16_t& load) const;
178
179public:
180    virtual bool PlayoutWarning() const;
181    virtual bool PlayoutError() const;
182    virtual bool RecordingWarning() const;
183    virtual bool RecordingError() const;
184    virtual void ClearPlayoutWarning();
185    virtual void ClearPlayoutError();
186    virtual void ClearRecordingWarning();
187    virtual void ClearRecordingError();
188
189public:
190    virtual void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer);
191
192private:
193    void Lock()
194    {
195        _critSect.Enter();
196    }
197    ;
198    void UnLock()
199    {
200        _critSect.Leave();
201    }
202    ;
203    int32_t Id()
204    {
205        return _id;
206    }
207
208    static void AtomicSet32(int32_t* theValue, int32_t newValue);
209    static int32_t AtomicGet32(int32_t* theValue);
210
211    static void logCAMsg(const TraceLevel level,
212                         const TraceModule module,
213                         const int32_t id, const char *msg,
214                         const char *err);
215
216    int32_t GetNumberDevices(const AudioObjectPropertyScope scope,
217                             AudioDeviceID scopedDeviceIds[],
218                             const uint32_t deviceListLength);
219
220    int32_t GetDeviceName(const AudioObjectPropertyScope scope,
221                          const uint16_t index, char* name);
222
223    int32_t InitDevice(uint16_t userDeviceIndex,
224                       AudioDeviceID& deviceId, bool isInput);
225
226    static OSStatus
227        objectListenerProc(AudioObjectID objectId, UInt32 numberAddresses,
228                           const AudioObjectPropertyAddress addresses[],
229                           void* clientData);
230
231    OSStatus
232        implObjectListenerProc(AudioObjectID objectId, UInt32 numberAddresses,
233                               const AudioObjectPropertyAddress addresses[]);
234
235    int32_t HandleDeviceChange();
236
237    int32_t
238        HandleStreamFormatChange(AudioObjectID objectId,
239                                 AudioObjectPropertyAddress propertyAddress);
240
241    int32_t
242        HandleDataSourceChange(AudioObjectID objectId,
243                               AudioObjectPropertyAddress propertyAddress);
244
245    int32_t
246        HandleProcessorOverload(AudioObjectPropertyAddress propertyAddress);
247
248private:
249    static OSStatus deviceIOProc(AudioDeviceID device,
250                                 const AudioTimeStamp *now,
251                                 const AudioBufferList *inputData,
252                                 const AudioTimeStamp *inputTime,
253                                 AudioBufferList *outputData,
254                                 const AudioTimeStamp* outputTime,
255                                 void *clientData);
256
257    static OSStatus
258        outConverterProc(AudioConverterRef audioConverter,
259                         UInt32 *numberDataPackets, AudioBufferList *data,
260                         AudioStreamPacketDescription **dataPacketDescription,
261                         void *userData);
262
263    static OSStatus inDeviceIOProc(AudioDeviceID device,
264                                   const AudioTimeStamp *now,
265                                   const AudioBufferList *inputData,
266                                   const AudioTimeStamp *inputTime,
267                                   AudioBufferList *outputData,
268                                   const AudioTimeStamp *outputTime,
269                                   void *clientData);
270
271    static OSStatus
272        inConverterProc(AudioConverterRef audioConverter,
273                        UInt32 *numberDataPackets, AudioBufferList *data,
274                        AudioStreamPacketDescription **dataPacketDescription,
275                        void *inUserData);
276
277    OSStatus implDeviceIOProc(const AudioBufferList *inputData,
278                              const AudioTimeStamp *inputTime,
279                              AudioBufferList *outputData,
280                              const AudioTimeStamp *outputTime);
281
282    OSStatus implOutConverterProc(UInt32 *numberDataPackets,
283                                  AudioBufferList *data);
284
285    OSStatus implInDeviceIOProc(const AudioBufferList *inputData,
286                                const AudioTimeStamp *inputTime);
287
288    OSStatus implInConverterProc(UInt32 *numberDataPackets,
289                                 AudioBufferList *data);
290
291    static bool RunCapture(void*);
292    static bool RunRender(void*);
293    bool CaptureWorkerThread();
294    bool RenderWorkerThread();
295
296private:
297    AudioDeviceBuffer* _ptrAudioBuffer;
298
299    CriticalSectionWrapper& _critSect;
300
301    EventWrapper& _stopEventRec;
302    EventWrapper& _stopEvent;
303
304    ThreadWrapper* _captureWorkerThread;
305    ThreadWrapper* _renderWorkerThread;
306    uint32_t _captureWorkerThreadId;
307    uint32_t _renderWorkerThreadId;
308
309    int32_t _id;
310
311    AudioMixerManagerMac _mixerManager;
312
313    uint16_t _inputDeviceIndex;
314    uint16_t _outputDeviceIndex;
315    AudioDeviceID _inputDeviceID;
316    AudioDeviceID _outputDeviceID;
317#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
318    AudioDeviceIOProcID _inDeviceIOProcID;
319    AudioDeviceIOProcID _deviceIOProcID;
320#endif
321    bool _inputDeviceIsSpecified;
322    bool _outputDeviceIsSpecified;
323
324    uint8_t _recChannels;
325    uint8_t _playChannels;
326
327    Float32* _captureBufData;
328    SInt16* _renderBufData;
329
330    SInt16 _renderConvertData[PLAY_BUF_SIZE_IN_SAMPLES];
331
332    AudioDeviceModule::BufferType _playBufType;
333
334private:
335    bool _initialized;
336    bool _isShutDown;
337    bool _recording;
338    bool _playing;
339    bool _recIsInitialized;
340    bool _playIsInitialized;
341    bool _AGC;
342
343    // Atomically set varaibles
344    int32_t _renderDeviceIsAlive;
345    int32_t _captureDeviceIsAlive;
346
347    bool _twoDevices;
348    bool _doStop; // For play if not shared device or play+rec if shared device
349    bool _doStopRec; // For rec if not shared device
350    bool _macBookPro;
351    bool _macBookProPanRight;
352
353    AudioConverterRef _captureConverter;
354    AudioConverterRef _renderConverter;
355
356    AudioStreamBasicDescription _outStreamFormat;
357    AudioStreamBasicDescription _outDesiredFormat;
358    AudioStreamBasicDescription _inStreamFormat;
359    AudioStreamBasicDescription _inDesiredFormat;
360
361    uint32_t _captureLatencyUs;
362    uint32_t _renderLatencyUs;
363
364    // Atomically set variables
365    mutable int32_t _captureDelayUs;
366    mutable int32_t _renderDelayUs;
367
368    int32_t _renderDelayOffsetSamples;
369
370private:
371    uint16_t _playBufDelayFixed; // fixed playback delay
372
373    uint16_t _playWarning;
374    uint16_t _playError;
375    uint16_t _recWarning;
376    uint16_t _recError;
377
378    PaUtilRingBuffer* _paCaptureBuffer;
379    PaUtilRingBuffer* _paRenderBuffer;
380
381    semaphore_t _renderSemaphore;
382    semaphore_t _captureSemaphore;
383
384    uint32_t _captureBufSizeSamples;
385    uint32_t _renderBufSizeSamples;
386};
387
388} //  namespace webrtc
389
390#endif  // MODULES_AUDIO_DEVICE_MAIN_SOURCE_MAC_AUDIO_DEVICE_MAC_H_
391