diff --git a/webrtc/modules/audio_device/mac/audio_device_mac.cc b/webrtc/modules/audio_device/mac/audio_device_mac.cc index 78555bd74..a7e78baf0 100644 --- a/webrtc/modules/audio_device/mac/audio_device_mac.cc +++ b/webrtc/modules/audio_device/mac/audio_device_mac.cc @@ -373,10 +373,10 @@ int32_t AudioDeviceMac::Init() return -1; } - // Setting RunLoop to NULL here instructs HAL to manage its own thread for - // notifications. This was the default behaviour on OS X 10.5 and earlier, but now - // must be explicitly specified. HAL would otherwise try to use the main thread to - // issue notifications. + // Setting RunLoop to NULL here instructs HAL to manage its own thread for + // notifications. This was the default behaviour on OS X 10.5 and earlier, + // but now must be explicitly specified. HAL would otherwise try to use the + // main thread to issue notifications. AudioObjectPropertyAddress propertyAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, @@ -495,8 +495,8 @@ int32_t AudioDeviceMac::SpeakerIsAvailable(bool& available) return 0; } - // Given that InitSpeaker was successful, we know that a valid speaker exists - // + // Given that InitSpeaker was successful, we know that a valid speaker + // exists. available = true; // Close the initialized output mixer @@ -554,8 +554,8 @@ int32_t AudioDeviceMac::MicrophoneIsAvailable(bool& available) return 0; } - // Given that InitMicrophone was successful, we know that a valid microphone exists - // + // Given that InitMicrophone was successful, we know that a valid microphone + // exists. available = true; // Close the initialized input mixer @@ -1363,13 +1363,13 @@ int32_t AudioDeviceMac::InitPlayout() _id, "MacBook Pro not using internal speakers"); } - // Add a listener to determine if the status changes. + // Add a listener to determine if the status changes. WEBRTC_CA_LOG_WARN(AudioObjectAddPropertyListener(_outputDeviceID, &propertyAddress, &objectListenerProc, this)); } } - // Get current stream description + // Get current stream description propertyAddress.mSelector = kAudioDevicePropertyStreamFormat; memset(&_outStreamFormat, 0, sizeof(_outStreamFormat)); size = sizeof(_outStreamFormat); @@ -1387,8 +1387,8 @@ int32_t AudioDeviceMac::InitPlayout() if (_outStreamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) { WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, - "Too many channels on device -> mChannelsPerFrame = %d", - _outStreamFormat.mChannelsPerFrame); + "Too many channels on output device (mChannelsPerFrame = %d)", + _outStreamFormat.mChannelsPerFrame); return -1; } @@ -1415,13 +1415,12 @@ int32_t AudioDeviceMac::InitPlayout() _outStreamFormat.mBytesPerFrame, _outStreamFormat.mBitsPerChannel); WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, - "mFormatFlags = %u, mChannelsPerFrame = %u", - _outStreamFormat.mFormatFlags, - _outStreamFormat.mChannelsPerFrame); + "mFormatFlags = %u", + _outStreamFormat.mFormatFlags); logCAMsg(kTraceInfo, kTraceAudioDevice, _id, "mFormatID", (const char *) &_outStreamFormat.mFormatID); - // Our preferred format to work with + // Our preferred format to work with _outDesiredFormat.mSampleRate = N_PLAY_SAMPLES_PER_SEC; if (_outStreamFormat.mChannelsPerFrame >= 2 && (_playChannels == 2)) { @@ -1447,7 +1446,7 @@ int32_t AudioDeviceMac::InitPlayout() _outDesiredFormat.mBytesPerPacket = _outDesiredFormat.mChannelsPerFrame * sizeof(SInt16); - _outDesiredFormat.mFramesPerPacket = 1; // In uncompressed audio, + _outDesiredFormat.mFramesPerPacket = 1; // In uncompressed audio, // a packet is one frame. _outDesiredFormat.mBytesPerFrame = _outDesiredFormat.mChannelsPerFrame * sizeof(SInt16); @@ -1595,7 +1594,7 @@ int32_t AudioDeviceMac::InitRecording() _captureDeviceIsAlive = 1; _doStopRec = false; - // Get current stream description + // Get current stream description AudioObjectPropertyAddress propertyAddress = { kAudioDevicePropertyStreamFormat, kAudioDevicePropertyScopeInput, 0 }; @@ -1615,8 +1614,18 @@ int32_t AudioDeviceMac::InitRecording() if (_inStreamFormat.mChannelsPerFrame > N_DEVICE_CHANNELS) { WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, - ", Too many channels on device (mChannelsPerFrame = %d)", - _inStreamFormat.mChannelsPerFrame); + "Too many channels on input device (mChannelsPerFrame = %d)", + _inStreamFormat.mChannelsPerFrame); + return -1; + } + + const int io_block_size_samples = _inStreamFormat.mChannelsPerFrame * + _inStreamFormat.mSampleRate / 100 * N_BLOCKS_IO; + if (io_block_size_samples > _captureBufSizeSamples) + { + WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, + "Input IO block size (%d) is larger than ring buffer (%u)", + io_block_size_samples, _captureBufSizeSamples); return -1; } @@ -1634,9 +1643,8 @@ int32_t AudioDeviceMac::InitRecording() _inStreamFormat.mBytesPerFrame, _inStreamFormat.mBitsPerChannel); WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, - " mFormatFlags = %u, mChannelsPerFrame = %u", - _inStreamFormat.mFormatFlags, - _inStreamFormat.mChannelsPerFrame); + " mFormatFlags = %u", + _inStreamFormat.mFormatFlags); logCAMsg(kTraceInfo, kTraceAudioDevice, _id, "mFormatID", (const char *) &_inStreamFormat.mFormatID); @@ -1931,7 +1939,7 @@ bool AudioDeviceMac::PlayoutIsInitialized() const int32_t AudioDeviceMac::StartPlayout() { - + CriticalSectionScoped lock(&_critSect); if (!_playIsInitialized) @@ -2283,7 +2291,7 @@ AudioDeviceMac::GetNumberDevices(const AudioObjectPropertyScope scope, return -1; } - // Happy ending + // Happy ending if (deviceIds) { free(deviceIds); @@ -2435,7 +2443,7 @@ int32_t AudioDeviceMac::InitDevice(const uint16_t userDeviceIndex, } // Obtain device name and manufacturer for logging. - // Also use this as a test to ensure a user-set device ID is valid. + // Also use this as a test to ensure a user-set device ID is valid. char devName[128]; char devManf[128]; memset(devName, 0, sizeof(devName)); @@ -2488,7 +2496,7 @@ OSStatus AudioDeviceMac::implObjectListenerProc( { WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, "AudioDeviceMac::implObjectListenerProc()"); - + for (UInt32 i = 0; i < numberAddresses; i++) { if (addresses[i].mSelector == kAudioHardwarePropertyDevices) @@ -2545,7 +2553,7 @@ int32_t AudioDeviceMac::HandleDeviceChange() logCAMsg(kTraceError, kTraceAudioDevice, _id, "Error in AudioDeviceGetProperty()", (const char*) &err); return -1; - } + } } if (SpeakerIsInitialized()) @@ -2629,13 +2637,24 @@ int32_t AudioDeviceMac::HandleStreamFormatChange( "mBytesPerFrame = %u, mBitsPerChannel = %u", streamFormat.mBytesPerFrame, streamFormat.mBitsPerChannel); WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, - "mFormatFlags = %u, mChannelsPerFrame = %u", - streamFormat.mFormatFlags, streamFormat.mChannelsPerFrame); + "mFormatFlags = %u", + streamFormat.mFormatFlags); logCAMsg(kTraceInfo, kTraceAudioDevice, _id, "mFormatID", (const char *) &streamFormat.mFormatID); if (propertyAddress.mScope == kAudioDevicePropertyScopeInput) { + const int io_block_size_samples = streamFormat.mChannelsPerFrame * + streamFormat.mSampleRate / 100 * N_BLOCKS_IO; + if (io_block_size_samples > _captureBufSizeSamples) + { + WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, + "Input IO block size (%d) is larger than ring buffer (%u)", + io_block_size_samples, _captureBufSizeSamples); + return -1; + + } + memcpy(&_inStreamFormat, &streamFormat, sizeof(streamFormat)); if (_inStreamFormat.mChannelsPerFrame >= 2 && (_recChannels == 2)) diff --git a/webrtc/modules/audio_device/mac/audio_device_mac.h b/webrtc/modules/audio_device/mac/audio_device_mac.h index 258216c44..f5f573ca8 100644 --- a/webrtc/modules/audio_device/mac/audio_device_mac.h +++ b/webrtc/modules/audio_device/mac/audio_device_mac.h @@ -26,35 +26,26 @@ namespace webrtc class EventWrapper; class ThreadWrapper; -const uint32_t N_REC_SAMPLES_PER_SEC = 48000; -const uint32_t N_PLAY_SAMPLES_PER_SEC = 48000; +const int N_REC_SAMPLES_PER_SEC = 48000; +const int N_PLAY_SAMPLES_PER_SEC = 48000; -const uint32_t N_REC_CHANNELS = 1; // default is mono recording -const uint32_t N_PLAY_CHANNELS = 2; // default is stereo playout -const uint32_t N_DEVICE_CHANNELS = 8; +const int N_REC_CHANNELS = 1; // default is mono recording +const int N_PLAY_CHANNELS = 2; // default is stereo playout +const int N_DEVICE_CHANNELS = 64; -const uint32_t ENGINE_REC_BUF_SIZE_IN_SAMPLES = (N_REC_SAMPLES_PER_SEC / 100); -const uint32_t ENGINE_PLAY_BUF_SIZE_IN_SAMPLES = (N_PLAY_SAMPLES_PER_SEC / 100); +const int ENGINE_REC_BUF_SIZE_IN_SAMPLES = (N_REC_SAMPLES_PER_SEC / 100); +const int ENGINE_PLAY_BUF_SIZE_IN_SAMPLES = (N_PLAY_SAMPLES_PER_SEC / 100); -enum -{ - N_BLOCKS_IO = 2 -}; -enum -{ - N_BUFFERS_IN = 10 -}; -enum -{ - N_BUFFERS_OUT = 3 -}; // Must be at least N_BLOCKS_IO +const int N_BLOCKS_IO = 2; +const int N_BUFFERS_IN = 2; // Must be at least N_BLOCKS_IO. +const int N_BUFFERS_OUT = 3; // Must be at least N_BLOCKS_IO. -const uint32_t TIMER_PERIOD_MS = (2 * 10 * N_BLOCKS_IO * 1000000); +const int TIMER_PERIOD_MS = (2 * 10 * N_BLOCKS_IO * 1000000); -const uint32_t REC_BUF_SIZE_IN_SAMPLES = (ENGINE_REC_BUF_SIZE_IN_SAMPLES - * N_DEVICE_CHANNELS * N_BUFFERS_IN); -const uint32_t PLAY_BUF_SIZE_IN_SAMPLES = - (ENGINE_PLAY_BUF_SIZE_IN_SAMPLES * N_PLAY_CHANNELS * N_BUFFERS_OUT); +const int REC_BUF_SIZE_IN_SAMPLES = + ENGINE_REC_BUF_SIZE_IN_SAMPLES * N_DEVICE_CHANNELS * N_BUFFERS_IN; +const int PLAY_BUF_SIZE_IN_SAMPLES = + ENGINE_PLAY_BUF_SIZE_IN_SAMPLES * N_PLAY_CHANNELS * N_BUFFERS_OUT; class AudioDeviceMac: public AudioDeviceGeneric { @@ -384,8 +375,8 @@ private: semaphore_t _renderSemaphore; semaphore_t _captureSemaphore; - uint32_t _captureBufSizeSamples; - uint32_t _renderBufSizeSamples; + int _captureBufSizeSamples; + int _renderBufSizeSamples; }; } // namespace webrtc