| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 } | 72 } |
| 73 } | 73 } |
| 74 } | 74 } |
| 75 | 75 |
| 76 // CoreAudio errors are best interpreted as four character strings. | 76 // CoreAudio errors are best interpreted as four character strings. |
| 77 void AudioDeviceMac::logCAMsg(const TraceLevel level, | 77 void AudioDeviceMac::logCAMsg(const TraceLevel level, |
| 78 const TraceModule module, | 78 const TraceModule module, |
| 79 const int32_t id, | 79 const int32_t id, |
| 80 const char* msg, | 80 const char* msg, |
| 81 const char* err) { | 81 const char* err) { |
| 82 RTC_DCHECK(msg != NULL); | 82 RTC_DCHECK(msg != nullptr); |
| 83 RTC_DCHECK(err != NULL); | 83 RTC_DCHECK(err != nullptr); |
| 84 | 84 |
| 85 #ifdef WEBRTC_ARCH_BIG_ENDIAN | 85 #ifdef WEBRTC_ARCH_BIG_ENDIAN |
| 86 WEBRTC_TRACE(level, module, id, "%s: %.4s", msg, err); | 86 WEBRTC_TRACE(level, module, id, "%s: %.4s", msg, err); |
| 87 #else | 87 #else |
| 88 // We need to flip the characters in this case. | 88 // We need to flip the characters in this case. |
| 89 WEBRTC_TRACE(level, module, id, "%s: %.1s%.1s%.1s%.1s", msg, err + 3, err + 2, | 89 WEBRTC_TRACE(level, module, id, "%s: %.1s%.1s%.1s%.1s", msg, err + 3, err + 2, |
| 90 err + 1, err); | 90 err + 1, err); |
| 91 #endif | 91 #endif |
| 92 } | 92 } |
| 93 | 93 |
| 94 AudioDeviceMac::AudioDeviceMac(const int32_t id) | 94 AudioDeviceMac::AudioDeviceMac(const int32_t id) |
| 95 : _ptrAudioBuffer(NULL), | 95 : _ptrAudioBuffer(nullptr), |
| 96 _critSect(*CriticalSectionWrapper::CreateCriticalSection()), | 96 _critSect(*CriticalSectionWrapper::CreateCriticalSection()), |
| 97 _stopEventRec(*EventWrapper::Create()), | 97 _stopEventRec(*EventWrapper::Create()), |
| 98 _stopEvent(*EventWrapper::Create()), | 98 _stopEvent(*EventWrapper::Create()), |
| 99 _id(id), | 99 _id(id), |
| 100 _mixerManager(id), | 100 _mixerManager(id), |
| 101 _inputDeviceIndex(0), | 101 _inputDeviceIndex(0), |
| 102 _outputDeviceIndex(0), | 102 _outputDeviceIndex(0), |
| 103 _inputDeviceID(kAudioObjectUnknown), | 103 _inputDeviceID(kAudioObjectUnknown), |
| 104 _outputDeviceID(kAudioObjectUnknown), | 104 _outputDeviceID(kAudioObjectUnknown), |
| 105 _inputDeviceIsSpecified(false), | 105 _inputDeviceIsSpecified(false), |
| 106 _outputDeviceIsSpecified(false), | 106 _outputDeviceIsSpecified(false), |
| 107 _recChannels(N_REC_CHANNELS), | 107 _recChannels(N_REC_CHANNELS), |
| 108 _playChannels(N_PLAY_CHANNELS), | 108 _playChannels(N_PLAY_CHANNELS), |
| 109 _captureBufData(NULL), | 109 _captureBufData(nullptr), |
| 110 _renderBufData(NULL), | 110 _renderBufData(nullptr), |
| 111 _playBufType(AudioDeviceModule::kFixedBufferSize), | 111 _playBufType(AudioDeviceModule::kFixedBufferSize), |
| 112 _initialized(false), | 112 _initialized(false), |
| 113 _isShutDown(false), | 113 _isShutDown(false), |
| 114 _recording(false), | 114 _recording(false), |
| 115 _playing(false), | 115 _playing(false), |
| 116 _recIsInitialized(false), | 116 _recIsInitialized(false), |
| 117 _playIsInitialized(false), | 117 _playIsInitialized(false), |
| 118 _AGC(false), | 118 _AGC(false), |
| 119 _renderDeviceIsAlive(1), | 119 _renderDeviceIsAlive(1), |
| 120 _captureDeviceIsAlive(1), | 120 _captureDeviceIsAlive(1), |
| 121 _twoDevices(true), | 121 _twoDevices(true), |
| 122 _doStop(false), | 122 _doStop(false), |
| 123 _doStopRec(false), | 123 _doStopRec(false), |
| 124 _macBookPro(false), | 124 _macBookPro(false), |
| 125 _macBookProPanRight(false), | 125 _macBookProPanRight(false), |
| 126 _captureLatencyUs(0), | 126 _captureLatencyUs(0), |
| 127 _renderLatencyUs(0), | 127 _renderLatencyUs(0), |
| 128 _captureDelayUs(0), | 128 _captureDelayUs(0), |
| 129 _renderDelayUs(0), | 129 _renderDelayUs(0), |
| 130 _renderDelayOffsetSamples(0), | 130 _renderDelayOffsetSamples(0), |
| 131 _playBufDelayFixed(20), | 131 _playBufDelayFixed(20), |
| 132 _playWarning(0), | 132 _playWarning(0), |
| 133 _playError(0), | 133 _playError(0), |
| 134 _recWarning(0), | 134 _recWarning(0), |
| 135 _recError(0), | 135 _recError(0), |
| 136 _paCaptureBuffer(NULL), | 136 _paCaptureBuffer(nullptr), |
| 137 _paRenderBuffer(NULL), | 137 _paRenderBuffer(nullptr), |
| 138 _captureBufSizeSamples(0), | 138 _captureBufSizeSamples(0), |
| 139 _renderBufSizeSamples(0), | 139 _renderBufSizeSamples(0), |
| 140 prev_key_state_(), | 140 prev_key_state_(), |
| 141 get_mic_volume_counter_ms_(0) { | 141 get_mic_volume_counter_ms_(0) { |
| 142 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, id, "%s created", __FUNCTION__); | 142 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, id, "%s created", __FUNCTION__); |
| 143 | 143 |
| 144 RTC_DCHECK(&_stopEvent != NULL); | 144 RTC_DCHECK(&_stopEvent); |
| 145 RTC_DCHECK(&_stopEventRec != NULL); | 145 RTC_DCHECK(&_stopEventRec); |
| 146 | 146 |
| 147 memset(_renderConvertData, 0, sizeof(_renderConvertData)); | 147 memset(_renderConvertData, 0, sizeof(_renderConvertData)); |
| 148 memset(&_outStreamFormat, 0, sizeof(AudioStreamBasicDescription)); | 148 memset(&_outStreamFormat, 0, sizeof(AudioStreamBasicDescription)); |
| 149 memset(&_outDesiredFormat, 0, sizeof(AudioStreamBasicDescription)); | 149 memset(&_outDesiredFormat, 0, sizeof(AudioStreamBasicDescription)); |
| 150 memset(&_inStreamFormat, 0, sizeof(AudioStreamBasicDescription)); | 150 memset(&_inStreamFormat, 0, sizeof(AudioStreamBasicDescription)); |
| 151 memset(&_inDesiredFormat, 0, sizeof(AudioStreamBasicDescription)); | 151 memset(&_inDesiredFormat, 0, sizeof(AudioStreamBasicDescription)); |
| 152 } | 152 } |
| 153 | 153 |
| 154 AudioDeviceMac::~AudioDeviceMac() { | 154 AudioDeviceMac::~AudioDeviceMac() { |
| 155 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s destroyed", | 155 WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s destroyed", |
| 156 __FUNCTION__); | 156 __FUNCTION__); |
| 157 | 157 |
| 158 if (!_isShutDown) { | 158 if (!_isShutDown) { |
| 159 Terminate(); | 159 Terminate(); |
| 160 } | 160 } |
| 161 | 161 |
| 162 RTC_DCHECK(!capture_worker_thread_.get()); | 162 RTC_DCHECK(!capture_worker_thread_.get()); |
| 163 RTC_DCHECK(!render_worker_thread_.get()); | 163 RTC_DCHECK(!render_worker_thread_.get()); |
| 164 | 164 |
| 165 if (_paRenderBuffer) { | 165 if (_paRenderBuffer) { |
| 166 delete _paRenderBuffer; | 166 delete _paRenderBuffer; |
| 167 _paRenderBuffer = NULL; | 167 _paRenderBuffer = nullptr; |
| 168 } | 168 } |
| 169 | 169 |
| 170 if (_paCaptureBuffer) { | 170 if (_paCaptureBuffer) { |
| 171 delete _paCaptureBuffer; | 171 delete _paCaptureBuffer; |
| 172 _paCaptureBuffer = NULL; | 172 _paCaptureBuffer = nullptr; |
| 173 } | 173 } |
| 174 | 174 |
| 175 if (_renderBufData) { | 175 if (_renderBufData) { |
| 176 delete[] _renderBufData; | 176 delete[] _renderBufData; |
| 177 _renderBufData = NULL; | 177 _renderBufData = nullptr; |
| 178 } | 178 } |
| 179 | 179 |
| 180 if (_captureBufData) { | 180 if (_captureBufData) { |
| 181 delete[] _captureBufData; | 181 delete[] _captureBufData; |
| 182 _captureBufData = NULL; | 182 _captureBufData = nullptr; |
| 183 } | 183 } |
| 184 | 184 |
| 185 kern_return_t kernErr = KERN_SUCCESS; | 185 kern_return_t kernErr = KERN_SUCCESS; |
| 186 kernErr = semaphore_destroy(mach_task_self(), _renderSemaphore); | 186 kernErr = semaphore_destroy(mach_task_self(), _renderSemaphore); |
| 187 if (kernErr != KERN_SUCCESS) { | 187 if (kernErr != KERN_SUCCESS) { |
| 188 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 188 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, |
| 189 " semaphore_destroy() error: %d", kernErr); | 189 " semaphore_destroy() error: %d", kernErr); |
| 190 } | 190 } |
| 191 | 191 |
| 192 kernErr = semaphore_destroy(mach_task_self(), _captureSemaphore); | 192 kernErr = semaphore_destroy(mach_task_self(), _captureSemaphore); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 | 227 |
| 228 if (_initialized) { | 228 if (_initialized) { |
| 229 return InitStatus::OK; | 229 return InitStatus::OK; |
| 230 } | 230 } |
| 231 | 231 |
| 232 OSStatus err = noErr; | 232 OSStatus err = noErr; |
| 233 | 233 |
| 234 _isShutDown = false; | 234 _isShutDown = false; |
| 235 | 235 |
| 236 // PortAudio ring buffers require an elementCount which is a power of two. | 236 // PortAudio ring buffers require an elementCount which is a power of two. |
| 237 if (_renderBufData == NULL) { | 237 if (_renderBufData == nullptr) { |
| 238 UInt32 powerOfTwo = 1; | 238 UInt32 powerOfTwo = 1; |
| 239 while (powerOfTwo < PLAY_BUF_SIZE_IN_SAMPLES) { | 239 while (powerOfTwo < PLAY_BUF_SIZE_IN_SAMPLES) { |
| 240 powerOfTwo <<= 1; | 240 powerOfTwo <<= 1; |
| 241 } | 241 } |
| 242 _renderBufSizeSamples = powerOfTwo; | 242 _renderBufSizeSamples = powerOfTwo; |
| 243 _renderBufData = new SInt16[_renderBufSizeSamples]; | 243 _renderBufData = new SInt16[_renderBufSizeSamples]; |
| 244 } | 244 } |
| 245 | 245 |
| 246 if (_paRenderBuffer == NULL) { | 246 if (_paRenderBuffer == nullptr) { |
| 247 _paRenderBuffer = new PaUtilRingBuffer; | 247 _paRenderBuffer = new PaUtilRingBuffer; |
| 248 PaRingBufferSize bufSize = -1; | 248 PaRingBufferSize bufSize = -1; |
| 249 bufSize = PaUtil_InitializeRingBuffer( | 249 bufSize = PaUtil_InitializeRingBuffer( |
| 250 _paRenderBuffer, sizeof(SInt16), _renderBufSizeSamples, _renderBufData); | 250 _paRenderBuffer, sizeof(SInt16), _renderBufSizeSamples, _renderBufData); |
| 251 if (bufSize == -1) { | 251 if (bufSize == -1) { |
| 252 WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id, | 252 WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id, |
| 253 " PaUtil_InitializeRingBuffer() error"); | 253 " PaUtil_InitializeRingBuffer() error"); |
| 254 return InitStatus::PLAYOUT_ERROR; | 254 return InitStatus::PLAYOUT_ERROR; |
| 255 } | 255 } |
| 256 } | 256 } |
| 257 | 257 |
| 258 if (_captureBufData == NULL) { | 258 if (_captureBufData == nullptr) { |
| 259 UInt32 powerOfTwo = 1; | 259 UInt32 powerOfTwo = 1; |
| 260 while (powerOfTwo < REC_BUF_SIZE_IN_SAMPLES) { | 260 while (powerOfTwo < REC_BUF_SIZE_IN_SAMPLES) { |
| 261 powerOfTwo <<= 1; | 261 powerOfTwo <<= 1; |
| 262 } | 262 } |
| 263 _captureBufSizeSamples = powerOfTwo; | 263 _captureBufSizeSamples = powerOfTwo; |
| 264 _captureBufData = new Float32[_captureBufSizeSamples]; | 264 _captureBufData = new Float32[_captureBufSizeSamples]; |
| 265 } | 265 } |
| 266 | 266 |
| 267 if (_paCaptureBuffer == NULL) { | 267 if (_paCaptureBuffer == nullptr) { |
| 268 _paCaptureBuffer = new PaUtilRingBuffer; | 268 _paCaptureBuffer = new PaUtilRingBuffer; |
| 269 PaRingBufferSize bufSize = -1; | 269 PaRingBufferSize bufSize = -1; |
| 270 bufSize = | 270 bufSize = |
| 271 PaUtil_InitializeRingBuffer(_paCaptureBuffer, sizeof(Float32), | 271 PaUtil_InitializeRingBuffer(_paCaptureBuffer, sizeof(Float32), |
| 272 _captureBufSizeSamples, _captureBufData); | 272 _captureBufSizeSamples, _captureBufData); |
| 273 if (bufSize == -1) { | 273 if (bufSize == -1) { |
| 274 WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id, | 274 WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id, |
| 275 " PaUtil_InitializeRingBuffer() error"); | 275 " PaUtil_InitializeRingBuffer() error"); |
| 276 return InitStatus::RECORDING_ERROR; | 276 return InitStatus::RECORDING_ERROR; |
| 277 } | 277 } |
| 278 } | 278 } |
| 279 | 279 |
| 280 kern_return_t kernErr = KERN_SUCCESS; | 280 kern_return_t kernErr = KERN_SUCCESS; |
| 281 kernErr = semaphore_create(mach_task_self(), &_renderSemaphore, | 281 kernErr = semaphore_create(mach_task_self(), &_renderSemaphore, |
| 282 SYNC_POLICY_FIFO, 0); | 282 SYNC_POLICY_FIFO, 0); |
| 283 if (kernErr != KERN_SUCCESS) { | 283 if (kernErr != KERN_SUCCESS) { |
| 284 WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id, | 284 WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id, |
| 285 " semaphore_create() error: %d", kernErr); | 285 " semaphore_create() error: %d", kernErr); |
| 286 return InitStatus::OTHER_ERROR; | 286 return InitStatus::OTHER_ERROR; |
| 287 } | 287 } |
| 288 | 288 |
| 289 kernErr = semaphore_create(mach_task_self(), &_captureSemaphore, | 289 kernErr = semaphore_create(mach_task_self(), &_captureSemaphore, |
| 290 SYNC_POLICY_FIFO, 0); | 290 SYNC_POLICY_FIFO, 0); |
| 291 if (kernErr != KERN_SUCCESS) { | 291 if (kernErr != KERN_SUCCESS) { |
| 292 WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id, | 292 WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id, |
| 293 " semaphore_create() error: %d", kernErr); | 293 " semaphore_create() error: %d", kernErr); |
| 294 return InitStatus::OTHER_ERROR; | 294 return InitStatus::OTHER_ERROR; |
| 295 } | 295 } |
| 296 | 296 |
| 297 // Setting RunLoop to NULL here instructs HAL to manage its own thread for | 297 // Setting RunLoop to null here instructs HAL to manage its own thread for |
| 298 // notifications. This was the default behaviour on OS X 10.5 and earlier, | 298 // notifications. This was the default behaviour on OS X 10.5 and earlier, |
| 299 // but now must be explicitly specified. HAL would otherwise try to use the | 299 // but now must be explicitly specified. HAL would otherwise try to use the |
| 300 // main thread to issue notifications. | 300 // main thread to issue notifications. |
| 301 AudioObjectPropertyAddress propertyAddress = { | 301 AudioObjectPropertyAddress propertyAddress = { |
| 302 kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, | 302 kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, |
| 303 kAudioObjectPropertyElementMaster}; | 303 kAudioObjectPropertyElementMaster}; |
| 304 CFRunLoopRef runLoop = NULL; | 304 CFRunLoopRef runLoop = nullptr; |
| 305 UInt32 size = sizeof(CFRunLoopRef); | 305 UInt32 size = sizeof(CFRunLoopRef); |
| 306 int aoerr = AudioObjectSetPropertyData( | 306 int aoerr = AudioObjectSetPropertyData( |
| 307 kAudioObjectSystemObject, &propertyAddress, 0, NULL, size, &runLoop); | 307 kAudioObjectSystemObject, &propertyAddress, 0, nullptr, size, &runLoop); |
| 308 if (aoerr != noErr) { | 308 if (aoerr != noErr) { |
| 309 LOG(LS_ERROR) << "Error in AudioObjectSetPropertyData: " | 309 LOG(LS_ERROR) << "Error in AudioObjectSetPropertyData: " |
| 310 << (const char*)&aoerr; | 310 << (const char*)&aoerr; |
| 311 return InitStatus::OTHER_ERROR; | 311 return InitStatus::OTHER_ERROR; |
| 312 } | 312 } |
| 313 | 313 |
| 314 // Listen for any device changes. | 314 // Listen for any device changes. |
| 315 propertyAddress.mSelector = kAudioHardwarePropertyDevices; | 315 propertyAddress.mSelector = kAudioHardwarePropertyDevices; |
| 316 WEBRTC_CA_LOG_ERR(AudioObjectAddPropertyListener( | 316 WEBRTC_CA_LOG_ERR(AudioObjectAddPropertyListener( |
| 317 kAudioObjectSystemObject, &propertyAddress, &objectListenerProc, this)); | 317 kAudioObjectSystemObject, &propertyAddress, &objectListenerProc, this)); |
| 318 | 318 |
| 319 // Determine if this is a MacBook Pro | 319 // Determine if this is a MacBook Pro |
| 320 _macBookPro = false; | 320 _macBookPro = false; |
| 321 _macBookProPanRight = false; | 321 _macBookProPanRight = false; |
| 322 char buf[128]; | 322 char buf[128]; |
| 323 size_t length = sizeof(buf); | 323 size_t length = sizeof(buf); |
| 324 memset(buf, 0, length); | 324 memset(buf, 0, length); |
| 325 | 325 |
| 326 int intErr = sysctlbyname("hw.model", buf, &length, NULL, 0); | 326 int intErr = sysctlbyname("hw.model", buf, &length, nullptr, 0); |
| 327 if (intErr != 0) { | 327 if (intErr != 0) { |
| 328 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 328 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, |
| 329 " Error in sysctlbyname(): %d", err); | 329 " Error in sysctlbyname(): %d", err); |
| 330 } else { | 330 } else { |
| 331 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, " Hardware model: %s", | 331 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, " Hardware model: %s", |
| 332 buf); | 332 buf); |
| 333 if (strncmp(buf, "MacBookPro", 10) == 0) { | 333 if (strncmp(buf, "MacBookPro", 10) == 0) { |
| 334 _macBookPro = true; | 334 _macBookPro = true; |
| 335 } | 335 } |
| 336 } | 336 } |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 931 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, |
| 932 "WindowsDeviceType not supported"); | 932 "WindowsDeviceType not supported"); |
| 933 return -1; | 933 return -1; |
| 934 } | 934 } |
| 935 | 935 |
| 936 int32_t AudioDeviceMac::PlayoutDeviceName(uint16_t index, | 936 int32_t AudioDeviceMac::PlayoutDeviceName(uint16_t index, |
| 937 char name[kAdmMaxDeviceNameSize], | 937 char name[kAdmMaxDeviceNameSize], |
| 938 char guid[kAdmMaxGuidSize]) { | 938 char guid[kAdmMaxGuidSize]) { |
| 939 const uint16_t nDevices(PlayoutDevices()); | 939 const uint16_t nDevices(PlayoutDevices()); |
| 940 | 940 |
| 941 if ((index > (nDevices - 1)) || (name == NULL)) { | 941 if ((index > (nDevices - 1)) || (name == nullptr)) { |
| 942 return -1; | 942 return -1; |
| 943 } | 943 } |
| 944 | 944 |
| 945 memset(name, 0, kAdmMaxDeviceNameSize); | 945 memset(name, 0, kAdmMaxDeviceNameSize); |
| 946 | 946 |
| 947 if (guid != NULL) { | 947 if (guid != nullptr) { |
| 948 memset(guid, 0, kAdmMaxGuidSize); | 948 memset(guid, 0, kAdmMaxGuidSize); |
| 949 } | 949 } |
| 950 | 950 |
| 951 return GetDeviceName(kAudioDevicePropertyScopeOutput, index, name); | 951 return GetDeviceName(kAudioDevicePropertyScopeOutput, index, name); |
| 952 } | 952 } |
| 953 | 953 |
| 954 int32_t AudioDeviceMac::RecordingDeviceName(uint16_t index, | 954 int32_t AudioDeviceMac::RecordingDeviceName(uint16_t index, |
| 955 char name[kAdmMaxDeviceNameSize], | 955 char name[kAdmMaxDeviceNameSize], |
| 956 char guid[kAdmMaxGuidSize]) { | 956 char guid[kAdmMaxGuidSize]) { |
| 957 const uint16_t nDevices(RecordingDevices()); | 957 const uint16_t nDevices(RecordingDevices()); |
| 958 | 958 |
| 959 if ((index > (nDevices - 1)) || (name == NULL)) { | 959 if ((index > (nDevices - 1)) || (name == nullptr)) { |
| 960 return -1; | 960 return -1; |
| 961 } | 961 } |
| 962 | 962 |
| 963 memset(name, 0, kAdmMaxDeviceNameSize); | 963 memset(name, 0, kAdmMaxDeviceNameSize); |
| 964 | 964 |
| 965 if (guid != NULL) { | 965 if (guid != nullptr) { |
| 966 memset(guid, 0, kAdmMaxGuidSize); | 966 memset(guid, 0, kAdmMaxGuidSize); |
| 967 } | 967 } |
| 968 | 968 |
| 969 return GetDeviceName(kAudioDevicePropertyScopeInput, index, name); | 969 return GetDeviceName(kAudioDevicePropertyScopeInput, index, name); |
| 970 } | 970 } |
| 971 | 971 |
| 972 int16_t AudioDeviceMac::RecordingDevices() { | 972 int16_t AudioDeviceMac::RecordingDevices() { |
| 973 AudioDeviceID recDevices[MaxNumberDevices]; | 973 AudioDeviceID recDevices[MaxNumberDevices]; |
| 974 return GetNumberDevices(kAudioDevicePropertyScopeInput, recDevices, | 974 return GetNumberDevices(kAudioDevicePropertyScopeInput, recDevices, |
| 975 MaxNumberDevices); | 975 MaxNumberDevices); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1099 AudioObjectPropertyAddress propertyAddress = { | 1099 AudioObjectPropertyAddress propertyAddress = { |
| 1100 kAudioDevicePropertyDataSource, kAudioDevicePropertyScopeOutput, 0}; | 1100 kAudioDevicePropertyDataSource, kAudioDevicePropertyScopeOutput, 0}; |
| 1101 if (_macBookPro) { | 1101 if (_macBookPro) { |
| 1102 _macBookProPanRight = false; | 1102 _macBookProPanRight = false; |
| 1103 Boolean hasProperty = | 1103 Boolean hasProperty = |
| 1104 AudioObjectHasProperty(_outputDeviceID, &propertyAddress); | 1104 AudioObjectHasProperty(_outputDeviceID, &propertyAddress); |
| 1105 if (hasProperty) { | 1105 if (hasProperty) { |
| 1106 UInt32 dataSource = 0; | 1106 UInt32 dataSource = 0; |
| 1107 size = sizeof(dataSource); | 1107 size = sizeof(dataSource); |
| 1108 WEBRTC_CA_LOG_WARN(AudioObjectGetPropertyData( | 1108 WEBRTC_CA_LOG_WARN(AudioObjectGetPropertyData( |
| 1109 _outputDeviceID, &propertyAddress, 0, NULL, &size, &dataSource)); | 1109 _outputDeviceID, &propertyAddress, 0, nullptr, &size, &dataSource)); |
| 1110 | 1110 |
| 1111 if (dataSource == 'ispk') { | 1111 if (dataSource == 'ispk') { |
| 1112 _macBookProPanRight = true; | 1112 _macBookProPanRight = true; |
| 1113 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1113 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
| 1114 "MacBook Pro using internal speakers; stereo" | 1114 "MacBook Pro using internal speakers; stereo" |
| 1115 " panning right"); | 1115 " panning right"); |
| 1116 } else { | 1116 } else { |
| 1117 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 1117 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
| 1118 "MacBook Pro not using internal speakers"); | 1118 "MacBook Pro not using internal speakers"); |
| 1119 } | 1119 } |
| 1120 | 1120 |
| 1121 // Add a listener to determine if the status changes. | 1121 // Add a listener to determine if the status changes. |
| 1122 WEBRTC_CA_LOG_WARN(AudioObjectAddPropertyListener( | 1122 WEBRTC_CA_LOG_WARN(AudioObjectAddPropertyListener( |
| 1123 _outputDeviceID, &propertyAddress, &objectListenerProc, this)); | 1123 _outputDeviceID, &propertyAddress, &objectListenerProc, this)); |
| 1124 } | 1124 } |
| 1125 } | 1125 } |
| 1126 | 1126 |
| 1127 // Get current stream description | 1127 // Get current stream description |
| 1128 propertyAddress.mSelector = kAudioDevicePropertyStreamFormat; | 1128 propertyAddress.mSelector = kAudioDevicePropertyStreamFormat; |
| 1129 memset(&_outStreamFormat, 0, sizeof(_outStreamFormat)); | 1129 memset(&_outStreamFormat, 0, sizeof(_outStreamFormat)); |
| 1130 size = sizeof(_outStreamFormat); | 1130 size = sizeof(_outStreamFormat); |
| 1131 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 1131 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 1132 _outputDeviceID, &propertyAddress, 0, NULL, &size, &_outStreamFormat)); | 1132 _outputDeviceID, &propertyAddress, 0, nullptr, &size, &_outStreamFormat)); |
| 1133 | 1133 |
| 1134 if (_outStreamFormat.mFormatID != kAudioFormatLinearPCM) { | 1134 if (_outStreamFormat.mFormatID != kAudioFormatLinearPCM) { |
| 1135 logCAMsg(kTraceError, kTraceAudioDevice, _id, | 1135 logCAMsg(kTraceError, kTraceAudioDevice, _id, |
| 1136 "Unacceptable output stream format -> mFormatID", | 1136 "Unacceptable output stream format -> mFormatID", |
| 1137 (const char*)&_outStreamFormat.mFormatID); | 1137 (const char*)&_outStreamFormat.mFormatID); |
| 1138 return -1; | 1138 return -1; |
| 1139 } | 1139 } |
| 1140 | 1140 |
| 1141 if (_outStreamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) { | 1141 if (_outStreamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) { |
| 1142 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1142 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 _captureLatencyUs = 0; | 1239 _captureLatencyUs = 0; |
| 1240 _captureDeviceIsAlive = 1; | 1240 _captureDeviceIsAlive = 1; |
| 1241 _doStopRec = false; | 1241 _doStopRec = false; |
| 1242 | 1242 |
| 1243 // Get current stream description | 1243 // Get current stream description |
| 1244 AudioObjectPropertyAddress propertyAddress = { | 1244 AudioObjectPropertyAddress propertyAddress = { |
| 1245 kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeInput, 0}; | 1245 kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeInput, 0}; |
| 1246 memset(&_inStreamFormat, 0, sizeof(_inStreamFormat)); | 1246 memset(&_inStreamFormat, 0, sizeof(_inStreamFormat)); |
| 1247 size = sizeof(_inStreamFormat); | 1247 size = sizeof(_inStreamFormat); |
| 1248 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 1248 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 1249 _inputDeviceID, &propertyAddress, 0, NULL, &size, &_inStreamFormat)); | 1249 _inputDeviceID, &propertyAddress, 0, nullptr, &size, &_inStreamFormat)); |
| 1250 | 1250 |
| 1251 if (_inStreamFormat.mFormatID != kAudioFormatLinearPCM) { | 1251 if (_inStreamFormat.mFormatID != kAudioFormatLinearPCM) { |
| 1252 logCAMsg(kTraceError, kTraceAudioDevice, _id, | 1252 logCAMsg(kTraceError, kTraceAudioDevice, _id, |
| 1253 "Unacceptable input stream format -> mFormatID", | 1253 "Unacceptable input stream format -> mFormatID", |
| 1254 (const char*)&_inStreamFormat.mFormatID); | 1254 (const char*)&_inStreamFormat.mFormatID); |
| 1255 return -1; | 1255 return -1; |
| 1256 } | 1256 } |
| 1257 | 1257 |
| 1258 if (_inStreamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) { | 1258 if (_inStreamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) { |
| 1259 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1259 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1335 _inStreamFormat.mFramesPerPacket; | 1335 _inStreamFormat.mFramesPerPacket; |
| 1336 } | 1336 } |
| 1337 } | 1337 } |
| 1338 | 1338 |
| 1339 // Ensure the buffer size is within the acceptable range provided by the | 1339 // Ensure the buffer size is within the acceptable range provided by the |
| 1340 // device. | 1340 // device. |
| 1341 propertyAddress.mSelector = kAudioDevicePropertyBufferSizeRange; | 1341 propertyAddress.mSelector = kAudioDevicePropertyBufferSizeRange; |
| 1342 AudioValueRange range; | 1342 AudioValueRange range; |
| 1343 size = sizeof(range); | 1343 size = sizeof(range); |
| 1344 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 1344 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 1345 _inputDeviceID, &propertyAddress, 0, NULL, &size, &range)); | 1345 _inputDeviceID, &propertyAddress, 0, nullptr, &size, &range)); |
| 1346 if (range.mMinimum > bufByteCount) { | 1346 if (range.mMinimum > bufByteCount) { |
| 1347 bufByteCount = range.mMinimum; | 1347 bufByteCount = range.mMinimum; |
| 1348 } else if (range.mMaximum < bufByteCount) { | 1348 } else if (range.mMaximum < bufByteCount) { |
| 1349 bufByteCount = range.mMaximum; | 1349 bufByteCount = range.mMaximum; |
| 1350 } | 1350 } |
| 1351 | 1351 |
| 1352 propertyAddress.mSelector = kAudioDevicePropertyBufferSize; | 1352 propertyAddress.mSelector = kAudioDevicePropertyBufferSize; |
| 1353 size = sizeof(bufByteCount); | 1353 size = sizeof(bufByteCount); |
| 1354 WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData( | 1354 WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData( |
| 1355 _inputDeviceID, &propertyAddress, 0, NULL, size, &bufByteCount)); | 1355 _inputDeviceID, &propertyAddress, 0, nullptr, size, &bufByteCount)); |
| 1356 | 1356 |
| 1357 // Get capture device latency | 1357 // Get capture device latency |
| 1358 propertyAddress.mSelector = kAudioDevicePropertyLatency; | 1358 propertyAddress.mSelector = kAudioDevicePropertyLatency; |
| 1359 UInt32 latency = 0; | 1359 UInt32 latency = 0; |
| 1360 size = sizeof(UInt32); | 1360 size = sizeof(UInt32); |
| 1361 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 1361 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 1362 _inputDeviceID, &propertyAddress, 0, NULL, &size, &latency)); | 1362 _inputDeviceID, &propertyAddress, 0, nullptr, &size, &latency)); |
| 1363 _captureLatencyUs = (UInt32)((1.0e6 * latency) / _inStreamFormat.mSampleRate); | 1363 _captureLatencyUs = (UInt32)((1.0e6 * latency) / _inStreamFormat.mSampleRate); |
| 1364 | 1364 |
| 1365 // Get capture stream latency | 1365 // Get capture stream latency |
| 1366 propertyAddress.mSelector = kAudioDevicePropertyStreams; | 1366 propertyAddress.mSelector = kAudioDevicePropertyStreams; |
| 1367 AudioStreamID stream = 0; | 1367 AudioStreamID stream = 0; |
| 1368 size = sizeof(AudioStreamID); | 1368 size = sizeof(AudioStreamID); |
| 1369 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 1369 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 1370 _inputDeviceID, &propertyAddress, 0, NULL, &size, &stream)); | 1370 _inputDeviceID, &propertyAddress, 0, nullptr, &size, &stream)); |
| 1371 propertyAddress.mSelector = kAudioStreamPropertyLatency; | 1371 propertyAddress.mSelector = kAudioStreamPropertyLatency; |
| 1372 size = sizeof(UInt32); | 1372 size = sizeof(UInt32); |
| 1373 latency = 0; | 1373 latency = 0; |
| 1374 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 1374 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 1375 _inputDeviceID, &propertyAddress, 0, NULL, &size, &latency)); | 1375 _inputDeviceID, &propertyAddress, 0, nullptr, &size, &latency)); |
| 1376 _captureLatencyUs += | 1376 _captureLatencyUs += |
| 1377 (UInt32)((1.0e6 * latency) / _inStreamFormat.mSampleRate); | 1377 (UInt32)((1.0e6 * latency) / _inStreamFormat.mSampleRate); |
| 1378 | 1378 |
| 1379 // Listen for format changes | 1379 // Listen for format changes |
| 1380 // TODO(xians): should we be using kAudioDevicePropertyDeviceHasChanged? | 1380 // TODO(xians): should we be using kAudioDevicePropertyDeviceHasChanged? |
| 1381 propertyAddress.mSelector = kAudioDevicePropertyStreamFormat; | 1381 propertyAddress.mSelector = kAudioDevicePropertyStreamFormat; |
| 1382 WEBRTC_CA_LOG_WARN(AudioObjectAddPropertyListener( | 1382 WEBRTC_CA_LOG_WARN(AudioObjectAddPropertyListener( |
| 1383 _inputDeviceID, &propertyAddress, &objectListenerProc, this)); | 1383 _inputDeviceID, &propertyAddress, &objectListenerProc, this)); |
| 1384 | 1384 |
| 1385 // Listen for processor overloads | 1385 // Listen for processor overloads |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1727 int32_t AudioDeviceMac::GetNumberDevices(const AudioObjectPropertyScope scope, | 1727 int32_t AudioDeviceMac::GetNumberDevices(const AudioObjectPropertyScope scope, |
| 1728 AudioDeviceID scopedDeviceIds[], | 1728 AudioDeviceID scopedDeviceIds[], |
| 1729 const uint32_t deviceListLength) { | 1729 const uint32_t deviceListLength) { |
| 1730 OSStatus err = noErr; | 1730 OSStatus err = noErr; |
| 1731 | 1731 |
| 1732 AudioObjectPropertyAddress propertyAddress = { | 1732 AudioObjectPropertyAddress propertyAddress = { |
| 1733 kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, | 1733 kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, |
| 1734 kAudioObjectPropertyElementMaster}; | 1734 kAudioObjectPropertyElementMaster}; |
| 1735 UInt32 size = 0; | 1735 UInt32 size = 0; |
| 1736 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyDataSize( | 1736 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyDataSize( |
| 1737 kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size)); | 1737 kAudioObjectSystemObject, &propertyAddress, 0, nullptr, &size)); |
| 1738 if (size == 0) { | 1738 if (size == 0) { |
| 1739 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "No devices"); | 1739 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, "No devices"); |
| 1740 return 0; | 1740 return 0; |
| 1741 } | 1741 } |
| 1742 | 1742 |
| 1743 AudioDeviceID* deviceIds = (AudioDeviceID*)malloc(size); | 1743 AudioDeviceID* deviceIds = (AudioDeviceID*)malloc(size); |
| 1744 UInt32 numberDevices = size / sizeof(AudioDeviceID); | 1744 UInt32 numberDevices = size / sizeof(AudioDeviceID); |
| 1745 AudioBufferList* bufferList = NULL; | 1745 AudioBufferList* bufferList = nullptr; |
| 1746 UInt32 numberScopedDevices = 0; | 1746 UInt32 numberScopedDevices = 0; |
| 1747 | 1747 |
| 1748 // First check if there is a default device and list it | 1748 // First check if there is a default device and list it |
| 1749 UInt32 hardwareProperty = 0; | 1749 UInt32 hardwareProperty = 0; |
| 1750 if (scope == kAudioDevicePropertyScopeOutput) { | 1750 if (scope == kAudioDevicePropertyScopeOutput) { |
| 1751 hardwareProperty = kAudioHardwarePropertyDefaultOutputDevice; | 1751 hardwareProperty = kAudioHardwarePropertyDefaultOutputDevice; |
| 1752 } else { | 1752 } else { |
| 1753 hardwareProperty = kAudioHardwarePropertyDefaultInputDevice; | 1753 hardwareProperty = kAudioHardwarePropertyDefaultInputDevice; |
| 1754 } | 1754 } |
| 1755 | 1755 |
| 1756 AudioObjectPropertyAddress propertyAddressDefault = { | 1756 AudioObjectPropertyAddress propertyAddressDefault = { |
| 1757 hardwareProperty, kAudioObjectPropertyScopeGlobal, | 1757 hardwareProperty, kAudioObjectPropertyScopeGlobal, |
| 1758 kAudioObjectPropertyElementMaster}; | 1758 kAudioObjectPropertyElementMaster}; |
| 1759 | 1759 |
| 1760 AudioDeviceID usedID; | 1760 AudioDeviceID usedID; |
| 1761 UInt32 uintSize = sizeof(UInt32); | 1761 UInt32 uintSize = sizeof(UInt32); |
| 1762 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(kAudioObjectSystemObject, | 1762 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 1763 &propertyAddressDefault, 0, | 1763 kAudioObjectSystemObject, &propertyAddressDefault, 0, nullptr, &uintSize, |
| 1764 NULL, &uintSize, &usedID)); | 1764 &usedID)); |
| 1765 if (usedID != kAudioDeviceUnknown) { | 1765 if (usedID != kAudioDeviceUnknown) { |
| 1766 scopedDeviceIds[numberScopedDevices] = usedID; | 1766 scopedDeviceIds[numberScopedDevices] = usedID; |
| 1767 numberScopedDevices++; | 1767 numberScopedDevices++; |
| 1768 } else { | 1768 } else { |
| 1769 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 1769 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
| 1770 "GetNumberDevices(): Default device unknown"); | 1770 "GetNumberDevices(): Default device unknown"); |
| 1771 } | 1771 } |
| 1772 | 1772 |
| 1773 // Then list the rest of the devices | 1773 // Then list the rest of the devices |
| 1774 bool listOK = true; | 1774 bool listOK = true; |
| 1775 | 1775 |
| 1776 WEBRTC_CA_LOG_ERR(AudioObjectGetPropertyData( | 1776 WEBRTC_CA_LOG_ERR(AudioObjectGetPropertyData(kAudioObjectSystemObject, |
| 1777 kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, deviceIds)); | 1777 &propertyAddress, 0, nullptr, |
| 1778 &size, deviceIds)); |
| 1778 if (err != noErr) { | 1779 if (err != noErr) { |
| 1779 listOK = false; | 1780 listOK = false; |
| 1780 } else { | 1781 } else { |
| 1781 propertyAddress.mSelector = kAudioDevicePropertyStreamConfiguration; | 1782 propertyAddress.mSelector = kAudioDevicePropertyStreamConfiguration; |
| 1782 propertyAddress.mScope = scope; | 1783 propertyAddress.mScope = scope; |
| 1783 propertyAddress.mElement = 0; | 1784 propertyAddress.mElement = 0; |
| 1784 for (UInt32 i = 0; i < numberDevices; i++) { | 1785 for (UInt32 i = 0; i < numberDevices; i++) { |
| 1785 // Check for input channels | 1786 // Check for input channels |
| 1786 WEBRTC_CA_LOG_ERR(AudioObjectGetPropertyDataSize( | 1787 WEBRTC_CA_LOG_ERR(AudioObjectGetPropertyDataSize( |
| 1787 deviceIds[i], &propertyAddress, 0, NULL, &size)); | 1788 deviceIds[i], &propertyAddress, 0, nullptr, &size)); |
| 1788 if (err == kAudioHardwareBadDeviceError) { | 1789 if (err == kAudioHardwareBadDeviceError) { |
| 1789 // This device doesn't actually exist; continue iterating. | 1790 // This device doesn't actually exist; continue iterating. |
| 1790 continue; | 1791 continue; |
| 1791 } else if (err != noErr) { | 1792 } else if (err != noErr) { |
| 1792 listOK = false; | 1793 listOK = false; |
| 1793 break; | 1794 break; |
| 1794 } | 1795 } |
| 1795 | 1796 |
| 1796 bufferList = (AudioBufferList*)malloc(size); | 1797 bufferList = (AudioBufferList*)malloc(size); |
| 1797 WEBRTC_CA_LOG_ERR(AudioObjectGetPropertyData( | 1798 WEBRTC_CA_LOG_ERR(AudioObjectGetPropertyData( |
| 1798 deviceIds[i], &propertyAddress, 0, NULL, &size, bufferList)); | 1799 deviceIds[i], &propertyAddress, 0, nullptr, &size, bufferList)); |
| 1799 if (err != noErr) { | 1800 if (err != noErr) { |
| 1800 listOK = false; | 1801 listOK = false; |
| 1801 break; | 1802 break; |
| 1802 } | 1803 } |
| 1803 | 1804 |
| 1804 if (bufferList->mNumberBuffers > 0) { | 1805 if (bufferList->mNumberBuffers > 0) { |
| 1805 if (numberScopedDevices >= deviceListLength) { | 1806 if (numberScopedDevices >= deviceListLength) { |
| 1806 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1807 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, |
| 1807 "Device list is not long enough"); | 1808 "Device list is not long enough"); |
| 1808 listOK = false; | 1809 listOK = false; |
| 1809 break; | 1810 break; |
| 1810 } | 1811 } |
| 1811 | 1812 |
| 1812 scopedDeviceIds[numberScopedDevices] = deviceIds[i]; | 1813 scopedDeviceIds[numberScopedDevices] = deviceIds[i]; |
| 1813 numberScopedDevices++; | 1814 numberScopedDevices++; |
| 1814 } | 1815 } |
| 1815 | 1816 |
| 1816 free(bufferList); | 1817 free(bufferList); |
| 1817 bufferList = NULL; | 1818 bufferList = nullptr; |
| 1818 } // for | 1819 } // for |
| 1819 } | 1820 } |
| 1820 | 1821 |
| 1821 if (!listOK) { | 1822 if (!listOK) { |
| 1822 if (deviceIds) { | 1823 if (deviceIds) { |
| 1823 free(deviceIds); | 1824 free(deviceIds); |
| 1824 deviceIds = NULL; | 1825 deviceIds = nullptr; |
| 1825 } | 1826 } |
| 1826 | 1827 |
| 1827 if (bufferList) { | 1828 if (bufferList) { |
| 1828 free(bufferList); | 1829 free(bufferList); |
| 1829 bufferList = NULL; | 1830 bufferList = nullptr; |
| 1830 } | 1831 } |
| 1831 | 1832 |
| 1832 return -1; | 1833 return -1; |
| 1833 } | 1834 } |
| 1834 | 1835 |
| 1835 // Happy ending | 1836 // Happy ending |
| 1836 if (deviceIds) { | 1837 if (deviceIds) { |
| 1837 free(deviceIds); | 1838 free(deviceIds); |
| 1838 deviceIds = NULL; | 1839 deviceIds = nullptr; |
| 1839 } | 1840 } |
| 1840 | 1841 |
| 1841 return numberScopedDevices; | 1842 return numberScopedDevices; |
| 1842 } | 1843 } |
| 1843 | 1844 |
| 1844 int32_t AudioDeviceMac::GetDeviceName(const AudioObjectPropertyScope scope, | 1845 int32_t AudioDeviceMac::GetDeviceName(const AudioObjectPropertyScope scope, |
| 1845 const uint16_t index, | 1846 const uint16_t index, |
| 1846 char* name) { | 1847 char* name) { |
| 1847 OSStatus err = noErr; | 1848 OSStatus err = noErr; |
| 1848 UInt32 len = kAdmMaxDeviceNameSize; | 1849 UInt32 len = kAdmMaxDeviceNameSize; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1866 UInt32 hardwareProperty = 0; | 1867 UInt32 hardwareProperty = 0; |
| 1867 if (scope == kAudioDevicePropertyScopeOutput) { | 1868 if (scope == kAudioDevicePropertyScopeOutput) { |
| 1868 hardwareProperty = kAudioHardwarePropertyDefaultOutputDevice; | 1869 hardwareProperty = kAudioHardwarePropertyDefaultOutputDevice; |
| 1869 } else { | 1870 } else { |
| 1870 hardwareProperty = kAudioHardwarePropertyDefaultInputDevice; | 1871 hardwareProperty = kAudioHardwarePropertyDefaultInputDevice; |
| 1871 } | 1872 } |
| 1872 AudioObjectPropertyAddress propertyAddress = { | 1873 AudioObjectPropertyAddress propertyAddress = { |
| 1873 hardwareProperty, kAudioObjectPropertyScopeGlobal, | 1874 hardwareProperty, kAudioObjectPropertyScopeGlobal, |
| 1874 kAudioObjectPropertyElementMaster}; | 1875 kAudioObjectPropertyElementMaster}; |
| 1875 UInt32 size = sizeof(UInt32); | 1876 UInt32 size = sizeof(UInt32); |
| 1876 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 1877 WEBRTC_CA_RETURN_ON_ERR( |
| 1877 kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, &usedID)); | 1878 AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, |
| 1879 0, nullptr, &size, &usedID)); |
| 1878 if (usedID == kAudioDeviceUnknown) { | 1880 if (usedID == kAudioDeviceUnknown) { |
| 1879 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 1881 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
| 1880 "GetDeviceName(): Default device unknown"); | 1882 "GetDeviceName(): Default device unknown"); |
| 1881 } else { | 1883 } else { |
| 1882 isDefaultDevice = true; | 1884 isDefaultDevice = true; |
| 1883 } | 1885 } |
| 1884 } | 1886 } |
| 1885 | 1887 |
| 1886 AudioObjectPropertyAddress propertyAddress = {kAudioDevicePropertyDeviceName, | 1888 AudioObjectPropertyAddress propertyAddress = {kAudioDevicePropertyDeviceName, |
| 1887 scope, 0}; | 1889 scope, 0}; |
| 1888 | 1890 |
| 1889 if (isDefaultDevice) { | 1891 if (isDefaultDevice) { |
| 1890 char devName[len]; | 1892 char devName[len]; |
| 1891 | 1893 |
| 1892 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(usedID, &propertyAddress, | 1894 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 1893 0, NULL, &len, devName)); | 1895 usedID, &propertyAddress, 0, nullptr, &len, devName)); |
| 1894 | 1896 |
| 1895 sprintf(name, "default (%s)", devName); | 1897 sprintf(name, "default (%s)", devName); |
| 1896 } else { | 1898 } else { |
| 1897 if (index < numberDevices) { | 1899 if (index < numberDevices) { |
| 1898 usedID = deviceIds[index]; | 1900 usedID = deviceIds[index]; |
| 1899 } else { | 1901 } else { |
| 1900 usedID = index; | 1902 usedID = index; |
| 1901 } | 1903 } |
| 1902 | 1904 |
| 1903 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(usedID, &propertyAddress, | 1905 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(usedID, &propertyAddress, |
| 1904 0, NULL, &len, name)); | 1906 0, nullptr, &len, name)); |
| 1905 } | 1907 } |
| 1906 | 1908 |
| 1907 return 0; | 1909 return 0; |
| 1908 } | 1910 } |
| 1909 | 1911 |
| 1910 int32_t AudioDeviceMac::InitDevice(const uint16_t userDeviceIndex, | 1912 int32_t AudioDeviceMac::InitDevice(const uint16_t userDeviceIndex, |
| 1911 AudioDeviceID& deviceId, | 1913 AudioDeviceID& deviceId, |
| 1912 const bool isInput) { | 1914 const bool isInput) { |
| 1913 OSStatus err = noErr; | 1915 OSStatus err = noErr; |
| 1914 UInt32 size = 0; | 1916 UInt32 size = 0; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1937 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 1939 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, |
| 1938 "InitDevice(): No devices"); | 1940 "InitDevice(): No devices"); |
| 1939 return -1; | 1941 return -1; |
| 1940 } | 1942 } |
| 1941 | 1943 |
| 1942 bool isDefaultDevice = false; | 1944 bool isDefaultDevice = false; |
| 1943 deviceId = kAudioDeviceUnknown; | 1945 deviceId = kAudioDeviceUnknown; |
| 1944 if (userDeviceIndex == 0) { | 1946 if (userDeviceIndex == 0) { |
| 1945 // Try to use default system device | 1947 // Try to use default system device |
| 1946 size = sizeof(AudioDeviceID); | 1948 size = sizeof(AudioDeviceID); |
| 1947 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 1949 WEBRTC_CA_RETURN_ON_ERR( |
| 1948 kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, &deviceId)); | 1950 AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, |
| 1951 0, nullptr, &size, &deviceId)); |
| 1949 if (deviceId == kAudioDeviceUnknown) { | 1952 if (deviceId == kAudioDeviceUnknown) { |
| 1950 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 1953 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
| 1951 " No default device exists"); | 1954 " No default device exists"); |
| 1952 } else { | 1955 } else { |
| 1953 isDefaultDevice = true; | 1956 isDefaultDevice = true; |
| 1954 } | 1957 } |
| 1955 } | 1958 } |
| 1956 | 1959 |
| 1957 if (!isDefaultDevice) { | 1960 if (!isDefaultDevice) { |
| 1958 deviceId = deviceIds[userDeviceIndex]; | 1961 deviceId = deviceIds[userDeviceIndex]; |
| 1959 } | 1962 } |
| 1960 | 1963 |
| 1961 // Obtain device name and manufacturer for logging. | 1964 // Obtain device name and manufacturer for logging. |
| 1962 // Also use this as a test to ensure a user-set device ID is valid. | 1965 // Also use this as a test to ensure a user-set device ID is valid. |
| 1963 char devName[128]; | 1966 char devName[128]; |
| 1964 char devManf[128]; | 1967 char devManf[128]; |
| 1965 memset(devName, 0, sizeof(devName)); | 1968 memset(devName, 0, sizeof(devName)); |
| 1966 memset(devManf, 0, sizeof(devManf)); | 1969 memset(devManf, 0, sizeof(devManf)); |
| 1967 | 1970 |
| 1968 propertyAddress.mSelector = kAudioDevicePropertyDeviceName; | 1971 propertyAddress.mSelector = kAudioDevicePropertyDeviceName; |
| 1969 propertyAddress.mScope = deviceScope; | 1972 propertyAddress.mScope = deviceScope; |
| 1970 propertyAddress.mElement = 0; | 1973 propertyAddress.mElement = 0; |
| 1971 size = sizeof(devName); | 1974 size = sizeof(devName); |
| 1972 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(deviceId, &propertyAddress, | 1975 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 1973 0, NULL, &size, devName)); | 1976 deviceId, &propertyAddress, 0, nullptr, &size, devName)); |
| 1974 | 1977 |
| 1975 propertyAddress.mSelector = kAudioDevicePropertyDeviceManufacturer; | 1978 propertyAddress.mSelector = kAudioDevicePropertyDeviceManufacturer; |
| 1976 size = sizeof(devManf); | 1979 size = sizeof(devManf); |
| 1977 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(deviceId, &propertyAddress, | 1980 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 1978 0, NULL, &size, devManf)); | 1981 deviceId, &propertyAddress, 0, nullptr, &size, devManf)); |
| 1979 | 1982 |
| 1980 if (isInput) { | 1983 if (isInput) { |
| 1981 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, " Input device: %s %s", | 1984 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, " Input device: %s %s", |
| 1982 devManf, devName); | 1985 devManf, devName); |
| 1983 } else { | 1986 } else { |
| 1984 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, " Output device: %s %s", | 1987 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, " Output device: %s %s", |
| 1985 devManf, devName); | 1988 devManf, devName); |
| 1986 } | 1989 } |
| 1987 | 1990 |
| 1988 return 0; | 1991 return 0; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2035 } | 2038 } |
| 2036 } | 2039 } |
| 2037 | 2040 |
| 2038 // Ensure the buffer size is within the range provided by the device. | 2041 // Ensure the buffer size is within the range provided by the device. |
| 2039 AudioObjectPropertyAddress propertyAddress = { | 2042 AudioObjectPropertyAddress propertyAddress = { |
| 2040 kAudioDevicePropertyDataSource, kAudioDevicePropertyScopeOutput, 0}; | 2043 kAudioDevicePropertyDataSource, kAudioDevicePropertyScopeOutput, 0}; |
| 2041 propertyAddress.mSelector = kAudioDevicePropertyBufferSizeRange; | 2044 propertyAddress.mSelector = kAudioDevicePropertyBufferSizeRange; |
| 2042 AudioValueRange range; | 2045 AudioValueRange range; |
| 2043 UInt32 size = sizeof(range); | 2046 UInt32 size = sizeof(range); |
| 2044 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 2047 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 2045 _outputDeviceID, &propertyAddress, 0, NULL, &size, &range)); | 2048 _outputDeviceID, &propertyAddress, 0, nullptr, &size, &range)); |
| 2046 if (range.mMinimum > bufByteCount) { | 2049 if (range.mMinimum > bufByteCount) { |
| 2047 bufByteCount = range.mMinimum; | 2050 bufByteCount = range.mMinimum; |
| 2048 } else if (range.mMaximum < bufByteCount) { | 2051 } else if (range.mMaximum < bufByteCount) { |
| 2049 bufByteCount = range.mMaximum; | 2052 bufByteCount = range.mMaximum; |
| 2050 } | 2053 } |
| 2051 | 2054 |
| 2052 propertyAddress.mSelector = kAudioDevicePropertyBufferSize; | 2055 propertyAddress.mSelector = kAudioDevicePropertyBufferSize; |
| 2053 size = sizeof(bufByteCount); | 2056 size = sizeof(bufByteCount); |
| 2054 WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData( | 2057 WEBRTC_CA_RETURN_ON_ERR(AudioObjectSetPropertyData( |
| 2055 _outputDeviceID, &propertyAddress, 0, NULL, size, &bufByteCount)); | 2058 _outputDeviceID, &propertyAddress, 0, nullptr, size, &bufByteCount)); |
| 2056 | 2059 |
| 2057 // Get render device latency. | 2060 // Get render device latency. |
| 2058 propertyAddress.mSelector = kAudioDevicePropertyLatency; | 2061 propertyAddress.mSelector = kAudioDevicePropertyLatency; |
| 2059 UInt32 latency = 0; | 2062 UInt32 latency = 0; |
| 2060 size = sizeof(UInt32); | 2063 size = sizeof(UInt32); |
| 2061 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 2064 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 2062 _outputDeviceID, &propertyAddress, 0, NULL, &size, &latency)); | 2065 _outputDeviceID, &propertyAddress, 0, nullptr, &size, &latency)); |
| 2063 _renderLatencyUs = | 2066 _renderLatencyUs = |
| 2064 static_cast<uint32_t>((1.0e6 * latency) / _outStreamFormat.mSampleRate); | 2067 static_cast<uint32_t>((1.0e6 * latency) / _outStreamFormat.mSampleRate); |
| 2065 | 2068 |
| 2066 // Get render stream latency. | 2069 // Get render stream latency. |
| 2067 propertyAddress.mSelector = kAudioDevicePropertyStreams; | 2070 propertyAddress.mSelector = kAudioDevicePropertyStreams; |
| 2068 AudioStreamID stream = 0; | 2071 AudioStreamID stream = 0; |
| 2069 size = sizeof(AudioStreamID); | 2072 size = sizeof(AudioStreamID); |
| 2070 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 2073 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 2071 _outputDeviceID, &propertyAddress, 0, NULL, &size, &stream)); | 2074 _outputDeviceID, &propertyAddress, 0, nullptr, &size, &stream)); |
| 2072 propertyAddress.mSelector = kAudioStreamPropertyLatency; | 2075 propertyAddress.mSelector = kAudioStreamPropertyLatency; |
| 2073 size = sizeof(UInt32); | 2076 size = sizeof(UInt32); |
| 2074 latency = 0; | 2077 latency = 0; |
| 2075 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 2078 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 2076 _outputDeviceID, &propertyAddress, 0, NULL, &size, &latency)); | 2079 _outputDeviceID, &propertyAddress, 0, nullptr, &size, &latency)); |
| 2077 _renderLatencyUs += | 2080 _renderLatencyUs += |
| 2078 static_cast<uint32_t>((1.0e6 * latency) / _outStreamFormat.mSampleRate); | 2081 static_cast<uint32_t>((1.0e6 * latency) / _outStreamFormat.mSampleRate); |
| 2079 | 2082 |
| 2080 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 2083 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
| 2081 " initial playout status: _renderDelayOffsetSamples=%d," | 2084 " initial playout status: _renderDelayOffsetSamples=%d," |
| 2082 " _renderDelayUs=%d, _renderLatencyUs=%d", | 2085 " _renderDelayUs=%d, _renderLatencyUs=%d", |
| 2083 _renderDelayOffsetSamples, _renderDelayUs, _renderLatencyUs); | 2086 _renderDelayOffsetSamples, _renderDelayUs, _renderLatencyUs); |
| 2084 return 0; | 2087 return 0; |
| 2085 } | 2088 } |
| 2086 | 2089 |
| 2087 OSStatus AudioDeviceMac::objectListenerProc( | 2090 OSStatus AudioDeviceMac::objectListenerProc( |
| 2088 AudioObjectID objectId, | 2091 AudioObjectID objectId, |
| 2089 UInt32 numberAddresses, | 2092 UInt32 numberAddresses, |
| 2090 const AudioObjectPropertyAddress addresses[], | 2093 const AudioObjectPropertyAddress addresses[], |
| 2091 void* clientData) { | 2094 void* clientData) { |
| 2092 AudioDeviceMac* ptrThis = (AudioDeviceMac*)clientData; | 2095 AudioDeviceMac* ptrThis = (AudioDeviceMac*)clientData; |
| 2093 RTC_DCHECK(ptrThis != NULL); | 2096 RTC_DCHECK(ptrThis != nullptr); |
| 2094 | 2097 |
| 2095 ptrThis->implObjectListenerProc(objectId, numberAddresses, addresses); | 2098 ptrThis->implObjectListenerProc(objectId, numberAddresses, addresses); |
| 2096 | 2099 |
| 2097 // AudioObjectPropertyListenerProc functions are supposed to return 0 | 2100 // AudioObjectPropertyListenerProc functions are supposed to return 0 |
| 2098 return 0; | 2101 return 0; |
| 2099 } | 2102 } |
| 2100 | 2103 |
| 2101 OSStatus AudioDeviceMac::implObjectListenerProc( | 2104 OSStatus AudioDeviceMac::implObjectListenerProc( |
| 2102 const AudioObjectID objectId, | 2105 const AudioObjectID objectId, |
| 2103 const UInt32 numberAddresses, | 2106 const UInt32 numberAddresses, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2126 WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, | 2129 WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, |
| 2127 "kAudioHardwarePropertyDevices"); | 2130 "kAudioHardwarePropertyDevices"); |
| 2128 | 2131 |
| 2129 // A device has changed. Check if our registered devices have been removed. | 2132 // A device has changed. Check if our registered devices have been removed. |
| 2130 // Ensure the devices have been initialized, meaning the IDs are valid. | 2133 // Ensure the devices have been initialized, meaning the IDs are valid. |
| 2131 if (MicrophoneIsInitialized()) { | 2134 if (MicrophoneIsInitialized()) { |
| 2132 AudioObjectPropertyAddress propertyAddress = { | 2135 AudioObjectPropertyAddress propertyAddress = { |
| 2133 kAudioDevicePropertyDeviceIsAlive, kAudioDevicePropertyScopeInput, 0}; | 2136 kAudioDevicePropertyDeviceIsAlive, kAudioDevicePropertyScopeInput, 0}; |
| 2134 UInt32 deviceIsAlive = 1; | 2137 UInt32 deviceIsAlive = 1; |
| 2135 UInt32 size = sizeof(UInt32); | 2138 UInt32 size = sizeof(UInt32); |
| 2136 err = AudioObjectGetPropertyData(_inputDeviceID, &propertyAddress, 0, NULL, | 2139 err = AudioObjectGetPropertyData(_inputDeviceID, &propertyAddress, 0, |
| 2137 &size, &deviceIsAlive); | 2140 nullptr, &size, &deviceIsAlive); |
| 2138 | 2141 |
| 2139 if (err == kAudioHardwareBadDeviceError || deviceIsAlive == 0) { | 2142 if (err == kAudioHardwareBadDeviceError || deviceIsAlive == 0) { |
| 2140 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 2143 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
| 2141 "Capture device is not alive (probably removed)"); | 2144 "Capture device is not alive (probably removed)"); |
| 2142 AtomicSet32(&_captureDeviceIsAlive, 0); | 2145 AtomicSet32(&_captureDeviceIsAlive, 0); |
| 2143 _mixerManager.CloseMicrophone(); | 2146 _mixerManager.CloseMicrophone(); |
| 2144 if (_recError == 1) { | 2147 if (_recError == 1) { |
| 2145 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 2148 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
| 2146 " pending recording error exists"); | 2149 " pending recording error exists"); |
| 2147 } | 2150 } |
| 2148 _recError = 1; // triggers callback from module process thread | 2151 _recError = 1; // triggers callback from module process thread |
| 2149 } else if (err != noErr) { | 2152 } else if (err != noErr) { |
| 2150 logCAMsg(kTraceError, kTraceAudioDevice, _id, | 2153 logCAMsg(kTraceError, kTraceAudioDevice, _id, |
| 2151 "Error in AudioDeviceGetProperty()", (const char*)&err); | 2154 "Error in AudioDeviceGetProperty()", (const char*)&err); |
| 2152 return -1; | 2155 return -1; |
| 2153 } | 2156 } |
| 2154 } | 2157 } |
| 2155 | 2158 |
| 2156 if (SpeakerIsInitialized()) { | 2159 if (SpeakerIsInitialized()) { |
| 2157 AudioObjectPropertyAddress propertyAddress = { | 2160 AudioObjectPropertyAddress propertyAddress = { |
| 2158 kAudioDevicePropertyDeviceIsAlive, kAudioDevicePropertyScopeOutput, 0}; | 2161 kAudioDevicePropertyDeviceIsAlive, kAudioDevicePropertyScopeOutput, 0}; |
| 2159 UInt32 deviceIsAlive = 1; | 2162 UInt32 deviceIsAlive = 1; |
| 2160 UInt32 size = sizeof(UInt32); | 2163 UInt32 size = sizeof(UInt32); |
| 2161 err = AudioObjectGetPropertyData(_outputDeviceID, &propertyAddress, 0, NULL, | 2164 err = AudioObjectGetPropertyData(_outputDeviceID, &propertyAddress, 0, |
| 2162 &size, &deviceIsAlive); | 2165 nullptr, &size, &deviceIsAlive); |
| 2163 | 2166 |
| 2164 if (err == kAudioHardwareBadDeviceError || deviceIsAlive == 0) { | 2167 if (err == kAudioHardwareBadDeviceError || deviceIsAlive == 0) { |
| 2165 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 2168 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
| 2166 "Render device is not alive (probably removed)"); | 2169 "Render device is not alive (probably removed)"); |
| 2167 AtomicSet32(&_renderDeviceIsAlive, 0); | 2170 AtomicSet32(&_renderDeviceIsAlive, 0); |
| 2168 _mixerManager.CloseSpeaker(); | 2171 _mixerManager.CloseSpeaker(); |
| 2169 if (_playError == 1) { | 2172 if (_playError == 1) { |
| 2170 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 2173 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
| 2171 " pending playout error exists"); | 2174 " pending playout error exists"); |
| 2172 } | 2175 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2189 WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, "Stream format changed"); | 2192 WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, "Stream format changed"); |
| 2190 | 2193 |
| 2191 if (objectId != _inputDeviceID && objectId != _outputDeviceID) { | 2194 if (objectId != _inputDeviceID && objectId != _outputDeviceID) { |
| 2192 return 0; | 2195 return 0; |
| 2193 } | 2196 } |
| 2194 | 2197 |
| 2195 // Get the new device format | 2198 // Get the new device format |
| 2196 AudioStreamBasicDescription streamFormat; | 2199 AudioStreamBasicDescription streamFormat; |
| 2197 UInt32 size = sizeof(streamFormat); | 2200 UInt32 size = sizeof(streamFormat); |
| 2198 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 2201 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 2199 objectId, &propertyAddress, 0, NULL, &size, &streamFormat)); | 2202 objectId, &propertyAddress, 0, nullptr, &size, &streamFormat)); |
| 2200 | 2203 |
| 2201 if (streamFormat.mFormatID != kAudioFormatLinearPCM) { | 2204 if (streamFormat.mFormatID != kAudioFormatLinearPCM) { |
| 2202 logCAMsg(kTraceError, kTraceAudioDevice, _id, | 2205 logCAMsg(kTraceError, kTraceAudioDevice, _id, |
| 2203 "Unacceptable input stream format -> mFormatID", | 2206 "Unacceptable input stream format -> mFormatID", |
| 2204 (const char*)&streamFormat.mFormatID); | 2207 (const char*)&streamFormat.mFormatID); |
| 2205 return -1; | 2208 return -1; |
| 2206 } | 2209 } |
| 2207 | 2210 |
| 2208 if (streamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) { | 2211 if (streamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) { |
| 2209 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 2212 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2282 OSStatus err = noErr; | 2285 OSStatus err = noErr; |
| 2283 | 2286 |
| 2284 if (_macBookPro && | 2287 if (_macBookPro && |
| 2285 propertyAddress.mScope == kAudioDevicePropertyScopeOutput) { | 2288 propertyAddress.mScope == kAudioDevicePropertyScopeOutput) { |
| 2286 WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, "Data source changed"); | 2289 WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, "Data source changed"); |
| 2287 | 2290 |
| 2288 _macBookProPanRight = false; | 2291 _macBookProPanRight = false; |
| 2289 UInt32 dataSource = 0; | 2292 UInt32 dataSource = 0; |
| 2290 UInt32 size = sizeof(UInt32); | 2293 UInt32 size = sizeof(UInt32); |
| 2291 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( | 2294 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData( |
| 2292 objectId, &propertyAddress, 0, NULL, &size, &dataSource)); | 2295 objectId, &propertyAddress, 0, nullptr, &size, &dataSource)); |
| 2293 if (dataSource == 'ispk') { | 2296 if (dataSource == 'ispk') { |
| 2294 _macBookProPanRight = true; | 2297 _macBookProPanRight = true; |
| 2295 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 2298 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
| 2296 "MacBook Pro using internal speakers; stereo panning right"); | 2299 "MacBook Pro using internal speakers; stereo panning right"); |
| 2297 } else { | 2300 } else { |
| 2298 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 2301 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
| 2299 "MacBook Pro not using internal speakers"); | 2302 "MacBook Pro not using internal speakers"); |
| 2300 } | 2303 } |
| 2301 } | 2304 } |
| 2302 | 2305 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2330 // ============================================================================ | 2333 // ============================================================================ |
| 2331 | 2334 |
| 2332 OSStatus AudioDeviceMac::deviceIOProc(AudioDeviceID, | 2335 OSStatus AudioDeviceMac::deviceIOProc(AudioDeviceID, |
| 2333 const AudioTimeStamp*, | 2336 const AudioTimeStamp*, |
| 2334 const AudioBufferList* inputData, | 2337 const AudioBufferList* inputData, |
| 2335 const AudioTimeStamp* inputTime, | 2338 const AudioTimeStamp* inputTime, |
| 2336 AudioBufferList* outputData, | 2339 AudioBufferList* outputData, |
| 2337 const AudioTimeStamp* outputTime, | 2340 const AudioTimeStamp* outputTime, |
| 2338 void* clientData) { | 2341 void* clientData) { |
| 2339 AudioDeviceMac* ptrThis = (AudioDeviceMac*)clientData; | 2342 AudioDeviceMac* ptrThis = (AudioDeviceMac*)clientData; |
| 2340 RTC_DCHECK(ptrThis != NULL); | 2343 RTC_DCHECK(ptrThis != nullptr); |
| 2341 | 2344 |
| 2342 ptrThis->implDeviceIOProc(inputData, inputTime, outputData, outputTime); | 2345 ptrThis->implDeviceIOProc(inputData, inputTime, outputData, outputTime); |
| 2343 | 2346 |
| 2344 // AudioDeviceIOProc functions are supposed to return 0 | 2347 // AudioDeviceIOProc functions are supposed to return 0 |
| 2345 return 0; | 2348 return 0; |
| 2346 } | 2349 } |
| 2347 | 2350 |
| 2348 OSStatus AudioDeviceMac::outConverterProc(AudioConverterRef, | 2351 OSStatus AudioDeviceMac::outConverterProc(AudioConverterRef, |
| 2349 UInt32* numberDataPackets, | 2352 UInt32* numberDataPackets, |
| 2350 AudioBufferList* data, | 2353 AudioBufferList* data, |
| 2351 AudioStreamPacketDescription**, | 2354 AudioStreamPacketDescription**, |
| 2352 void* userData) { | 2355 void* userData) { |
| 2353 AudioDeviceMac* ptrThis = (AudioDeviceMac*)userData; | 2356 AudioDeviceMac* ptrThis = (AudioDeviceMac*)userData; |
| 2354 RTC_DCHECK(ptrThis != NULL); | 2357 RTC_DCHECK(ptrThis != nullptr); |
| 2355 | 2358 |
| 2356 return ptrThis->implOutConverterProc(numberDataPackets, data); | 2359 return ptrThis->implOutConverterProc(numberDataPackets, data); |
| 2357 } | 2360 } |
| 2358 | 2361 |
| 2359 OSStatus AudioDeviceMac::inDeviceIOProc(AudioDeviceID, | 2362 OSStatus AudioDeviceMac::inDeviceIOProc(AudioDeviceID, |
| 2360 const AudioTimeStamp*, | 2363 const AudioTimeStamp*, |
| 2361 const AudioBufferList* inputData, | 2364 const AudioBufferList* inputData, |
| 2362 const AudioTimeStamp* inputTime, | 2365 const AudioTimeStamp* inputTime, |
| 2363 AudioBufferList*, | 2366 AudioBufferList*, |
| 2364 const AudioTimeStamp*, | 2367 const AudioTimeStamp*, |
| 2365 void* clientData) { | 2368 void* clientData) { |
| 2366 AudioDeviceMac* ptrThis = (AudioDeviceMac*)clientData; | 2369 AudioDeviceMac* ptrThis = (AudioDeviceMac*)clientData; |
| 2367 RTC_DCHECK(ptrThis != NULL); | 2370 RTC_DCHECK(ptrThis != nullptr); |
| 2368 | 2371 |
| 2369 ptrThis->implInDeviceIOProc(inputData, inputTime); | 2372 ptrThis->implInDeviceIOProc(inputData, inputTime); |
| 2370 | 2373 |
| 2371 // AudioDeviceIOProc functions are supposed to return 0 | 2374 // AudioDeviceIOProc functions are supposed to return 0 |
| 2372 return 0; | 2375 return 0; |
| 2373 } | 2376 } |
| 2374 | 2377 |
| 2375 OSStatus AudioDeviceMac::inConverterProc( | 2378 OSStatus AudioDeviceMac::inConverterProc( |
| 2376 AudioConverterRef, | 2379 AudioConverterRef, |
| 2377 UInt32* numberDataPackets, | 2380 UInt32* numberDataPackets, |
| 2378 AudioBufferList* data, | 2381 AudioBufferList* data, |
| 2379 AudioStreamPacketDescription** /*dataPacketDescription*/, | 2382 AudioStreamPacketDescription** /*dataPacketDescription*/, |
| 2380 void* userData) { | 2383 void* userData) { |
| 2381 AudioDeviceMac* ptrThis = static_cast<AudioDeviceMac*>(userData); | 2384 AudioDeviceMac* ptrThis = static_cast<AudioDeviceMac*>(userData); |
| 2382 RTC_DCHECK(ptrThis != NULL); | 2385 RTC_DCHECK(ptrThis != nullptr); |
| 2383 | 2386 |
| 2384 return ptrThis->implInConverterProc(numberDataPackets, data); | 2387 return ptrThis->implInConverterProc(numberDataPackets, data); |
| 2385 } | 2388 } |
| 2386 | 2389 |
| 2387 OSStatus AudioDeviceMac::implDeviceIOProc(const AudioBufferList* inputData, | 2390 OSStatus AudioDeviceMac::implDeviceIOProc(const AudioBufferList* inputData, |
| 2388 const AudioTimeStamp* inputTime, | 2391 const AudioTimeStamp* inputTime, |
| 2389 AudioBufferList* outputData, | 2392 AudioBufferList* outputData, |
| 2390 const AudioTimeStamp* outputTime) { | 2393 const AudioTimeStamp* outputTime) { |
| 2391 OSStatus err = noErr; | 2394 OSStatus err = noErr; |
| 2392 UInt64 outputTimeNs = AudioConvertHostTimeToNanos(outputTime->mHostTime); | 2395 UInt64 outputTimeNs = AudioConvertHostTimeToNanos(outputTime->mHostTime); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2427 // timeout when capturing is stopped. | 2430 // timeout when capturing is stopped. |
| 2428 return 0; | 2431 return 0; |
| 2429 } | 2432 } |
| 2430 | 2433 |
| 2431 RTC_DCHECK(_outStreamFormat.mBytesPerFrame != 0); | 2434 RTC_DCHECK(_outStreamFormat.mBytesPerFrame != 0); |
| 2432 UInt32 size = | 2435 UInt32 size = |
| 2433 outputData->mBuffers->mDataByteSize / _outStreamFormat.mBytesPerFrame; | 2436 outputData->mBuffers->mDataByteSize / _outStreamFormat.mBytesPerFrame; |
| 2434 | 2437 |
| 2435 // TODO(xians): signal an error somehow? | 2438 // TODO(xians): signal an error somehow? |
| 2436 err = AudioConverterFillComplexBuffer(_renderConverter, outConverterProc, | 2439 err = AudioConverterFillComplexBuffer(_renderConverter, outConverterProc, |
| 2437 this, &size, outputData, NULL); | 2440 this, &size, outputData, nullptr); |
| 2438 if (err != noErr) { | 2441 if (err != noErr) { |
| 2439 if (err == 1) { | 2442 if (err == 1) { |
| 2440 // This is our own error. | 2443 // This is our own error. |
| 2441 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 2444 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, |
| 2442 " Error in AudioConverterFillComplexBuffer()"); | 2445 " Error in AudioConverterFillComplexBuffer()"); |
| 2443 return 1; | 2446 return 1; |
| 2444 } else { | 2447 } else { |
| 2445 logCAMsg(kTraceError, kTraceAudioDevice, _id, | 2448 logCAMsg(kTraceError, kTraceAudioDevice, _id, |
| 2446 "Error in AudioConverterFillComplexBuffer()", (const char*)&err); | 2449 "Error in AudioConverterFillComplexBuffer()", (const char*)&err); |
| 2447 return 1; | 2450 return 1; |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2674 UInt32 size = ENGINE_REC_BUF_SIZE_IN_SAMPLES; | 2677 UInt32 size = ENGINE_REC_BUF_SIZE_IN_SAMPLES; |
| 2675 | 2678 |
| 2676 AudioBufferList engineBuffer; | 2679 AudioBufferList engineBuffer; |
| 2677 engineBuffer.mNumberBuffers = 1; // Interleaved channels. | 2680 engineBuffer.mNumberBuffers = 1; // Interleaved channels. |
| 2678 engineBuffer.mBuffers->mNumberChannels = _inDesiredFormat.mChannelsPerFrame; | 2681 engineBuffer.mBuffers->mNumberChannels = _inDesiredFormat.mChannelsPerFrame; |
| 2679 engineBuffer.mBuffers->mDataByteSize = | 2682 engineBuffer.mBuffers->mDataByteSize = |
| 2680 _inDesiredFormat.mBytesPerPacket * noRecSamples; | 2683 _inDesiredFormat.mBytesPerPacket * noRecSamples; |
| 2681 engineBuffer.mBuffers->mData = recordBuffer; | 2684 engineBuffer.mBuffers->mData = recordBuffer; |
| 2682 | 2685 |
| 2683 err = AudioConverterFillComplexBuffer(_captureConverter, inConverterProc, | 2686 err = AudioConverterFillComplexBuffer(_captureConverter, inConverterProc, |
| 2684 this, &size, &engineBuffer, NULL); | 2687 this, &size, &engineBuffer, nullptr); |
| 2685 if (err != noErr) { | 2688 if (err != noErr) { |
| 2686 if (err == 1) { | 2689 if (err == 1) { |
| 2687 // This is our own error. | 2690 // This is our own error. |
| 2688 return false; | 2691 return false; |
| 2689 } else { | 2692 } else { |
| 2690 logCAMsg(kTraceError, kTraceAudioDevice, _id, | 2693 logCAMsg(kTraceError, kTraceAudioDevice, _id, |
| 2691 "Error in AudioConverterFillComplexBuffer()", (const char*)&err); | 2694 "Error in AudioConverterFillComplexBuffer()", (const char*)&err); |
| 2692 return false; | 2695 return false; |
| 2693 } | 2696 } |
| 2694 } | 2697 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2769 bool keyState = | 2772 bool keyState = |
| 2770 CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key_index); | 2773 CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key_index); |
| 2771 // A false -> true change in keymap means a key is pressed. | 2774 // A false -> true change in keymap means a key is pressed. |
| 2772 key_down |= (keyState && !prev_key_state_[key_index]); | 2775 key_down |= (keyState && !prev_key_state_[key_index]); |
| 2773 // Save current state. | 2776 // Save current state. |
| 2774 prev_key_state_[key_index] = keyState; | 2777 prev_key_state_[key_index] = keyState; |
| 2775 } | 2778 } |
| 2776 return key_down; | 2779 return key_down; |
| 2777 } | 2780 } |
| 2778 } // namespace webrtc | 2781 } // namespace webrtc |
| OLD | NEW |