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