Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: webrtc/modules/audio_device/ios/audio_device_ios.mm

Issue 1472833002: Resolves issue with multiple calls to audio unit initialization (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: nit Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | webrtc/modules/audio_device/ios/audio_device_unittest_ios.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 // VerifyAudioParametersForActiveAudioSession() for a mismatch between the 79 // VerifyAudioParametersForActiveAudioSession() for a mismatch between the
80 // preferred number of channels and the actual number of channels. 80 // preferred number of channels and the actual number of channels.
81 const int kPreferredNumberOfChannels = 1; 81 const int kPreferredNumberOfChannels = 1;
82 // Number of bytes per audio sample for 16-bit signed integer representation. 82 // Number of bytes per audio sample for 16-bit signed integer representation.
83 const UInt32 kBytesPerSample = 2; 83 const UInt32 kBytesPerSample = 2;
84 // Hardcoded delay estimates based on real measurements. 84 // Hardcoded delay estimates based on real measurements.
85 // TODO(henrika): these value is not used in combination with built-in AEC. 85 // TODO(henrika): these value is not used in combination with built-in AEC.
86 // Can most likely be removed. 86 // Can most likely be removed.
87 const UInt16 kFixedPlayoutDelayEstimate = 30; 87 const UInt16 kFixedPlayoutDelayEstimate = 30;
88 const UInt16 kFixedRecordDelayEstimate = 30; 88 const UInt16 kFixedRecordDelayEstimate = 30;
89 // Calls to AudioUnitInitialize() can fail if called back-to-back on different
90 // ADM instances. A fall-back solution is to allow multiple sequential calls
91 // with as small delay between each. This factor sets the max number of allowed
92 // initialization attempts.
93 const int kMaxNumberOfAudioUnitInitializeAttempts = 5;
94
89 95
90 using ios::CheckAndLogError; 96 using ios::CheckAndLogError;
91 97
92 // Verifies that the current audio session supports input audio and that the 98 // Verifies that the current audio session supports input audio and that the
93 // required category and mode are enabled. 99 // required category and mode are enabled.
94 static bool VerifyAudioSession(AVAudioSession* session) { 100 static bool VerifyAudioSession(AVAudioSession* session) {
95 LOG(LS_INFO) << "VerifyAudioSession"; 101 LOG(LS_INFO) << "VerifyAudioSession";
96 // Ensure that the device currently supports audio input. 102 // Ensure that the device currently supports audio input.
97 if (!session.isInputAvailable) { 103 if (!session.isInputAvailable) {
98 LOG(LS_ERROR) << "No audio input path is available!"; 104 LOG(LS_ERROR) << "No audio input path is available!";
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 LOGI() << "SetupAndInitializeVoiceProcessingAudioUnit"; 740 LOGI() << "SetupAndInitializeVoiceProcessingAudioUnit";
735 RTC_DCHECK(!vpio_unit_) << "VoiceProcessingIO audio unit already exists"; 741 RTC_DCHECK(!vpio_unit_) << "VoiceProcessingIO audio unit already exists";
736 // Create an audio component description to identify the Voice-Processing 742 // Create an audio component description to identify the Voice-Processing
737 // I/O audio unit. 743 // I/O audio unit.
738 AudioComponentDescription vpio_unit_description; 744 AudioComponentDescription vpio_unit_description;
739 vpio_unit_description.componentType = kAudioUnitType_Output; 745 vpio_unit_description.componentType = kAudioUnitType_Output;
740 vpio_unit_description.componentSubType = kAudioUnitSubType_VoiceProcessingIO; 746 vpio_unit_description.componentSubType = kAudioUnitSubType_VoiceProcessingIO;
741 vpio_unit_description.componentManufacturer = kAudioUnitManufacturer_Apple; 747 vpio_unit_description.componentManufacturer = kAudioUnitManufacturer_Apple;
742 vpio_unit_description.componentFlags = 0; 748 vpio_unit_description.componentFlags = 0;
743 vpio_unit_description.componentFlagsMask = 0; 749 vpio_unit_description.componentFlagsMask = 0;
750
744 // Obtain an audio unit instance given the description. 751 // Obtain an audio unit instance given the description.
745 AudioComponent found_vpio_unit_ref = 752 AudioComponent found_vpio_unit_ref =
746 AudioComponentFindNext(nullptr, &vpio_unit_description); 753 AudioComponentFindNext(nullptr, &vpio_unit_description);
747 754
748 // Create a Voice-Processing IO audio unit. 755 // Create a Voice-Processing IO audio unit.
749 OSStatus result = noErr; 756 OSStatus result = noErr;
750 result = AudioComponentInstanceNew(found_vpio_unit_ref, &vpio_unit_); 757 result = AudioComponentInstanceNew(found_vpio_unit_ref, &vpio_unit_);
751 if (result != noErr) { 758 if (result != noErr) {
752 vpio_unit_ = nullptr; 759 vpio_unit_ = nullptr;
753 LOG(LS_ERROR) << "AudioComponentInstanceNew failed: " << result; 760 LOG(LS_ERROR) << "AudioComponentInstanceNew failed: " << result;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 kAudioOutputUnitProperty_SetInputCallback, 876 kAudioOutputUnitProperty_SetInputCallback,
870 kAudioUnitScope_Global, input_bus, 877 kAudioUnitScope_Global, input_bus,
871 &input_callback, sizeof(input_callback)); 878 &input_callback, sizeof(input_callback));
872 if (result != noErr) { 879 if (result != noErr) {
873 DisposeAudioUnit(); 880 DisposeAudioUnit();
874 LOG(LS_ERROR) << "Failed to specify the input callback on the input bus: " 881 LOG(LS_ERROR) << "Failed to specify the input callback on the input bus: "
875 << result; 882 << result;
876 } 883 }
877 884
878 // Initialize the Voice-Processing I/O unit instance. 885 // Initialize the Voice-Processing I/O unit instance.
886 // Calls to AudioUnitInitialize() can fail if called back-to-back on
887 // different ADM instances. The error message in this case is -66635 which is
888 // undocumented. Tests have shown that calling AudioUnitInitialize a second
889 // time, after a short sleep, avoids this issue.
890 // See webrtc:5166 for details.
891 int failed_initalize_attempts = 0;
879 result = AudioUnitInitialize(vpio_unit_); 892 result = AudioUnitInitialize(vpio_unit_);
880 if (result != noErr) { 893 while (result != noErr) {
881 result = AudioUnitUninitialize(vpio_unit_);
882 if (result != noErr) {
883 LOG_F(LS_ERROR) << "AudioUnitUninitialize failed: " << result;
884 }
885 DisposeAudioUnit();
886 LOG(LS_ERROR) << "Failed to initialize the Voice-Processing I/O unit: " 894 LOG(LS_ERROR) << "Failed to initialize the Voice-Processing I/O unit: "
887 << result; 895 << result;
888 return false; 896 ++failed_initalize_attempts;
897 if (failed_initalize_attempts == kMaxNumberOfAudioUnitInitializeAttempts) {
898 // Max number of initialization attempts exceeded, hence abort.
899 LOG(LS_WARNING) << "Too many initialization attempts";
900 DisposeAudioUnit();
901 return false;
902 }
903 LOG(LS_INFO) << "pause 100ms and try audio unit initialization again...";
904 [NSThread sleepForTimeInterval:0.1f];
905 result = AudioUnitInitialize(vpio_unit_);
889 } 906 }
907 LOG(LS_INFO) << "Voice-Processing I/O unit is now initialized";
890 return true; 908 return true;
891 } 909 }
892 910
893 bool AudioDeviceIOS::RestartAudioUnitWithNewFormat(float sample_rate) { 911 bool AudioDeviceIOS::RestartAudioUnitWithNewFormat(float sample_rate) {
894 LOGI() << "RestartAudioUnitWithNewFormat(sample_rate=" << sample_rate << ")"; 912 LOGI() << "RestartAudioUnitWithNewFormat(sample_rate=" << sample_rate << ")";
895 // Stop the active audio unit. 913 // Stop the active audio unit.
896 LOG_AND_RETURN_IF_ERROR(AudioOutputUnitStop(vpio_unit_), 914 LOG_AND_RETURN_IF_ERROR(AudioOutputUnitStop(vpio_unit_),
897 "Failed to stop the the Voice-Processing I/O unit"); 915 "Failed to stop the the Voice-Processing I/O unit");
898 916
899 // The stream format is about to be changed and it requires that we first 917 // The stream format is about to be changed and it requires that we first
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 // Read decoded 16-bit PCM samples from WebRTC (using a size that matches 1095 // Read decoded 16-bit PCM samples from WebRTC (using a size that matches
1078 // the native I/O audio unit) to a preallocated intermediate buffer and 1096 // the native I/O audio unit) to a preallocated intermediate buffer and
1079 // copy the result to the audio buffer in the |io_data| destination. 1097 // copy the result to the audio buffer in the |io_data| destination.
1080 SInt8* source = playout_audio_buffer_.get(); 1098 SInt8* source = playout_audio_buffer_.get();
1081 fine_audio_buffer_->GetPlayoutData(source); 1099 fine_audio_buffer_->GetPlayoutData(source);
1082 memcpy(destination, source, dataSizeInBytes); 1100 memcpy(destination, source, dataSizeInBytes);
1083 return noErr; 1101 return noErr;
1084 } 1102 }
1085 1103
1086 } // namespace webrtc 1104 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/audio_device/ios/audio_device_unittest_ios.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698