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