Index: webrtc/modules/audio_device/ios/objc/RTCAudioSession+Configuration.mm |
diff --git a/webrtc/modules/audio_device/ios/objc/RTCAudioSession+Configuration.mm b/webrtc/modules/audio_device/ios/objc/RTCAudioSession+Configuration.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..93c18db11e275d56e943db256e46a56c4c52533c |
--- /dev/null |
+++ b/webrtc/modules/audio_device/ios/objc/RTCAudioSession+Configuration.mm |
@@ -0,0 +1,169 @@ |
+ /* |
+ * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
+ * |
+ * Use of this source code is governed by a BSD-style license |
+ * that can be found in the LICENSE file in the root of the source |
+ * tree. An additional intellectual property rights grant can be found |
+ * in the file PATENTS. All contributing project authors may |
+ * be found in the AUTHORS file in the root of the source tree. |
+ */ |
+ |
+#import "webrtc/modules/audio_device/ios/objc/RTCAudioSession.h" |
+ |
+#import "webrtc/base/objc/RTCLogging.h" |
+#import "webrtc/modules/audio_device/ios/objc/RTCAudioSession+Private.h" |
+#import "webrtc/modules/audio_device/ios/objc/RTCAudioSessionConfiguration.h" |
+ |
+@implementation RTCAudioSession (Configuration) |
+ |
+- (BOOL)isConfiguredForWebRTC { |
+ // Ensure that the device currently supports audio input. |
+ if (!self.inputAvailable) { |
+ RTCLogError(@"No audio input path is available!"); |
+ return NO; |
+ } |
+ |
+ // Only check a minimal list of requirements for whether we have |
+ // what we want. |
+ RTCAudioSessionConfiguration *currentConfig = |
+ [RTCAudioSessionConfiguration currentConfiguration]; |
+ RTCAudioSessionConfiguration *webRTCConfig = |
+ [RTCAudioSessionConfiguration webRTCConfiguration]; |
+ |
+ if (![currentConfig.category isEqualToString:webRTCConfig.category]) { |
+ RTCLog(@"Current category %@ does not match %@", |
+ currentConfig.category, |
+ webRTCConfig.category); |
+ return NO; |
+ } |
+ |
+ if (![currentConfig.mode isEqualToString:webRTCConfig.mode]) { |
+ RTCLog(@"Current mode %@ does not match %@", |
+ currentConfig.mode, |
+ webRTCConfig.mode); |
+ return NO; |
+ } |
+ |
+ return YES; |
+} |
+ |
+- (BOOL)setConfiguration:(RTCAudioSessionConfiguration *)configuration |
+ active:(BOOL)active |
+ error:(NSError **)outError { |
+ if (![self checkLock:outError]) { |
+ return NO; |
+ } |
+ // Provide an error even if there isn't one so we can log it. We will not |
henrika_webrtc
2016/03/10 14:42:12
Nit, you have space above comment on lines 25 and
tkchin_webrtc
2016/03/10 23:07:09
Done.
|
+ // return immediately on error in this function and instead try to set |
+ // everything we can. |
+ NSError *error = nil; |
+ if (outError) { |
+ error = *outError; |
Chuck
2016/03/10 21:16:37
I might be reasoning about this incorrectly, but w
tkchin_webrtc
2016/03/10 23:07:09
Done.
|
+ } |
+ |
+ if (self.category != configuration.category || |
+ self.categoryOptions != configuration.categoryOptions) { |
+ error = nil; |
+ if (![self setCategory:configuration.category |
+ withOptions:configuration.categoryOptions |
+ error:&error]) { |
+ RTCLogError(@"Failed to set category: %@", error.localizedDescription); |
+ } |
+ } |
+ |
+ if (self.mode != configuration.mode) { |
+ error = nil; |
+ if (![self setMode:configuration.mode error:&error]) { |
+ RTCLogError(@"Failed to set mode: %@", error.localizedDescription); |
+ } |
+ } |
+ |
+ if (self.sampleRate != configuration.sampleRate) { |
+ error = nil; |
+ if (![self setPreferredSampleRate:configuration.sampleRate |
+ error:&error]) { |
+ RTCLogError(@"Failed to set preferred sample rate: %@", |
+ error.localizedDescription); |
+ } |
+ } |
+ |
+ if (self.IOBufferDuration != configuration.ioBufferDuration) { |
+ error = nil; |
+ if (![self setPreferredIOBufferDuration:configuration.ioBufferDuration |
+ error:&error]) { |
+ RTCLogError(@"Failed to set preferred IO buffer duration: %@", |
+ error.localizedDescription); |
+ } |
+ } |
+ |
+ error = nil; |
Chuck
2016/03/10 21:16:37
This pattern is different than the other blocks of
tkchin_webrtc
2016/03/10 23:07:09
Yup. Always forcing the active.
|
+ if (![self setActive:active error:&error]) { |
+ RTCLogError(@"Failed to setActive to %d: %@", |
+ active, error.localizedDescription); |
+ } |
+ |
+ if (self.isActive) { |
+ // Try to set the preferred number of hardware audio channels. These calls |
+ // must be done after setting the audio session’s category and mode and |
+ // activating the session. |
+ NSInteger inputNumberOfChannels = configuration.inputNumberOfChannels; |
+ if (self.inputNumberOfChannels != inputNumberOfChannels) { |
+ error = nil; |
+ if (![self setPreferredInputNumberOfChannels:inputNumberOfChannels |
+ error:&error]) { |
+ RTCLogError(@"Failed to set preferred input number of channels: %@", |
+ error.localizedDescription); |
+ } |
+ } |
+ NSInteger outputNumberOfChannels = configuration.outputNumberOfChannels; |
+ if (self.outputNumberOfChannels != outputNumberOfChannels) { |
+ error = nil; |
+ if (![self setPreferredOutputNumberOfChannels:outputNumberOfChannels |
+ error:&error]) { |
+ RTCLogError(@"Failed to set preferred output number of channels: %@", |
+ error.localizedDescription); |
+ } |
+ } |
+ } |
+ |
+ return YES; |
+} |
+ |
+- (BOOL)configureWebRTCSession:(NSError **)outError { |
+ if (![self checkLock:outError]) { |
+ return NO; |
+ } |
+ RTCLog(@"Configuring audio session for WebRTC."); |
+ |
+ // Provide an error even if there isn't one so we can log it. |
+ NSError *error = nil; |
+ if (outError) { |
+ error = *outError; |
+ } |
+ |
+ RTCAudioSessionConfiguration *currentConfig = |
+ [RTCAudioSessionConfiguration currentConfiguration]; |
+ RTCAudioSessionConfiguration *webRTCConfig = |
+ [RTCAudioSessionConfiguration webRTCConfiguration]; |
+ if (![self setConfiguration:webRTCConfig active:YES error:&error]) { |
+ RTCLogError(@"Failed to set WebRTC audio configuration: %@", |
+ error.localizedDescription); |
+ // Attempt to restore previous state. |
+ [self setConfiguration:currentConfig active:NO error:nil]; |
+ return NO; |
+ } |
+ |
+ // Ensure that the active audio session has the correct category and mode. |
+ if (![self isConfiguredForWebRTC]) { |
+ // This should never happen - this means that we succeeded earlier but |
+ // somehow the settings didn't apply. |
+ RTCLogError(@"Failed to configure audio session."); |
+ // Attempt to restore previous state. |
+ [self setConfiguration:currentConfig active:NO error:nil]; |
+ return NO; |
+ } |
+ |
+ return YES; |
+} |
+ |
+@end |