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