| 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
|
| index 83320b62f08d52a5f4bf5c23a78a30b7d8dcfb54..06ddddd9bce4679ffa9da5210d4932a03f0bbe20 100644
|
| --- a/webrtc/modules/audio_device/ios/objc/RTCAudioSession+Configuration.mm
|
| +++ b/webrtc/modules/audio_device/ios/objc/RTCAudioSession+Configuration.mm
|
| @@ -16,9 +16,17 @@
|
|
|
| @implementation RTCAudioSession (Configuration)
|
|
|
| +- (BOOL)isConfiguredForWebRTC {
|
| + return self.savedConfiguration != nil;
|
| +}
|
| +
|
| - (BOOL)setConfiguration:(RTCAudioSessionConfiguration *)configuration
|
| active:(BOOL)active
|
| error:(NSError **)outError {
|
| + NSParameterAssert(configuration);
|
| + if (outError) {
|
| + *outError = nil;
|
| + }
|
| if (![self checkLock:outError]) {
|
| return NO;
|
| }
|
| @@ -37,6 +45,8 @@
|
| RTCLogError(@"Failed to set category: %@",
|
| categoryError.localizedDescription);
|
| error = categoryError;
|
| + } else {
|
| + RTCLog(@"Set category to: %@", configuration.category);
|
| }
|
| }
|
|
|
| @@ -46,6 +56,8 @@
|
| RTCLogError(@"Failed to set mode: %@",
|
| modeError.localizedDescription);
|
| error = modeError;
|
| + } else {
|
| + RTCLog(@"Set mode to: %@", configuration.mode);
|
| }
|
| }
|
|
|
| @@ -57,6 +69,9 @@
|
| RTCLogError(@"Failed to set preferred sample rate: %@",
|
| sampleRateError.localizedDescription);
|
| error = sampleRateError;
|
| + } else {
|
| + RTCLog(@"Set preferred sample rate to: %.2f",
|
| + configuration.sampleRate);
|
| }
|
| }
|
|
|
| @@ -69,6 +84,9 @@
|
| RTCLogError(@"Failed to set preferred IO buffer duration: %@",
|
| bufferDurationError.localizedDescription);
|
| error = bufferDurationError;
|
| + } else {
|
| + RTCLog(@"Set preferred IO buffer duration to: %f",
|
| + configuration.ioBufferDuration);
|
| }
|
| }
|
|
|
| @@ -79,7 +97,9 @@
|
| error = activeError;
|
| }
|
|
|
| - if (self.isActive) {
|
| + if (self.isActive &&
|
| + // TODO(tkchin): Figure out which category/mode numChannels is valid for.
|
| + [self.mode isEqualToString:AVAudioSessionModeVoiceChat]) {
|
| // 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.
|
| @@ -91,6 +111,9 @@
|
| RTCLogError(@"Failed to set preferred input number of channels: %@",
|
| inputChannelsError.localizedDescription);
|
| error = inputChannelsError;
|
| + } else {
|
| + RTCLog(@"Set input number of channels to: %ld",
|
| + (long)inputNumberOfChannels);
|
| }
|
| }
|
| NSInteger outputNumberOfChannels = configuration.outputNumberOfChannels;
|
| @@ -101,6 +124,9 @@
|
| RTCLogError(@"Failed to set preferred output number of channels: %@",
|
| outputChannelsError.localizedDescription);
|
| error = outputChannelsError;
|
| + } else {
|
| + RTCLog(@"Set output number of channels to: %ld",
|
| + (long)outputNumberOfChannels);
|
| }
|
| }
|
| }
|
| @@ -113,75 +139,82 @@
|
| }
|
|
|
| - (BOOL)configureWebRTCSession:(NSError **)outError {
|
| + if (outError) {
|
| + *outError = nil;
|
| + }
|
| if (![self checkLock:outError]) {
|
| return NO;
|
| }
|
| RTCLog(@"Configuring audio session for WebRTC.");
|
|
|
| + if (self.isConfiguredForWebRTC) {
|
| + RTCLogError(@"Already configured.");
|
| + if (outError) {
|
| + *outError =
|
| + [self configurationErrorWithDescription:@"Already configured."];
|
| + }
|
| + return NO;
|
| + }
|
| +
|
| + // Configure the AVAudioSession and activate it.
|
| // Provide an error even if there isn't one so we can log it.
|
| - BOOL hasSucceeded = YES;
|
| NSError *error = nil;
|
| RTCAudioSessionConfiguration *currentConfig =
|
| [RTCAudioSessionConfiguration currentConfiguration];
|
| RTCAudioSessionConfiguration *webRTCConfig =
|
| [RTCAudioSessionConfiguration webRTCConfiguration];
|
| + self.savedConfiguration = currentConfig;
|
| 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];
|
| - hasSucceeded = NO;
|
| - } else if (![self isConfiguredForWebRTC]) {
|
| - // Ensure that the active audio session has the correct category and mode.
|
| - // 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];
|
| - error =
|
| - [[NSError alloc] initWithDomain:kRTCAudioSessionErrorDomain
|
| - code:kRTCAudioSessionErrorConfiguration
|
| - userInfo:nil];
|
| - hasSucceeded = NO;
|
| - }
|
| -
|
| - if (outError) {
|
| - *outError = error;
|
| + [self unconfigureWebRTCSession:nil];
|
| + if (outError) {
|
| + *outError = error;
|
| + }
|
| + return NO;
|
| }
|
|
|
| - return hasSucceeded;
|
| -}
|
| -
|
| -#pragma mark - Private
|
| -
|
| -- (BOOL)isConfiguredForWebRTC {
|
| // Ensure that the device currently supports audio input.
|
| + // TODO(tkchin): Figure out if this is really necessary.
|
| if (!self.inputAvailable) {
|
| RTCLogError(@"No audio input path is available!");
|
| + [self unconfigureWebRTCSession:nil];
|
| + if (outError) {
|
| + *outError = [self configurationErrorWithDescription:@"No input path."];
|
| + }
|
| return NO;
|
| }
|
|
|
| - // Only check a minimal list of requirements for whether we have
|
| - // what we want.
|
| - RTCAudioSessionConfiguration *currentConfig =
|
| - [RTCAudioSessionConfiguration currentConfiguration];
|
| - RTCAudioSessionConfiguration *webRTCConfig =
|
| - [RTCAudioSessionConfiguration webRTCConfiguration];
|
| + // Give delegates a chance to process the event. In particular, the audio
|
| + // devices listening to this event will initialize their audio units.
|
| + [self notifyDidConfigure];
|
|
|
| - if (![currentConfig.category isEqualToString:webRTCConfig.category]) {
|
| - RTCLog(@"Current category %@ does not match %@",
|
| - currentConfig.category,
|
| - webRTCConfig.category);
|
| + return YES;
|
| +}
|
| +
|
| +- (BOOL)unconfigureWebRTCSession:(NSError **)outError {
|
| + if (outError) {
|
| + *outError = nil;
|
| + }
|
| + if (![self checkLock:outError]) {
|
| return NO;
|
| }
|
| + RTCLog(@"Unconfiguring audio session for WebRTC.");
|
|
|
| - if (![currentConfig.mode isEqualToString:webRTCConfig.mode]) {
|
| - RTCLog(@"Current mode %@ does not match %@",
|
| - currentConfig.mode,
|
| - webRTCConfig.mode);
|
| + if (!self.isConfiguredForWebRTC) {
|
| + RTCLogError(@"Already unconfigured.");
|
| + if (outError) {
|
| + *outError =
|
| + [self configurationErrorWithDescription:@"Already unconfigured."];
|
| + }
|
| return NO;
|
| }
|
|
|
| + [self setConfiguration:self.savedConfiguration active:NO error:outError];
|
| + self.savedConfiguration = nil;
|
| +
|
| + [self notifyDidUnconfigure];
|
| +
|
| return YES;
|
| }
|
|
|
|
|