| /* | |
| * 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 "RTCAudioSession+Private.h" | |
| #import "RTCAudioSessionConfiguration.h" | |
| #import "base/RTCLogging.h" | |
| @implementation RTC_OBJC_TYPE (RTCAudioSession) | |
| (Configuration) | |
| - (BOOL)setConfiguration | |
| : (RTC_OBJC_TYPE(RTCAudioSessionConfiguration) *)configuration error | |
| : (NSError **)outError { | |
| return [self setConfiguration:configuration | |
| active:NO | |
| shouldSetActive:NO | |
| error:outError]; | |
| } | |
| - (BOOL)setConfiguration: | |
| (RTC_OBJC_TYPE(RTCAudioSessionConfiguration) *)configuration | |
| active:(BOOL)active | |
| error:(NSError **)outError { | |
| return [self setConfiguration:configuration | |
| active:active | |
| shouldSetActive:YES | |
| error:outError]; | |
| } | |
| #pragma mark - Private | |
| - (BOOL)setConfiguration: | |
| (RTC_OBJC_TYPE(RTCAudioSessionConfiguration) *)configuration | |
| active:(BOOL)active | |
| shouldSetActive:(BOOL)shouldSetActive | |
| error:(NSError **)outError { | |
| NSParameterAssert(configuration); | |
| if (outError) { | |
| *outError = nil; | |
| } | |
| // Provide an error even if there isn't one so we can log it. We will not | |
| // return immediately on error in this function and instead try to set | |
| // everything we can. | |
| NSError *error = nil; | |
| if (self.category != configuration.category || | |
| self.mode != configuration.mode || | |
| self.categoryOptions != configuration.categoryOptions) { | |
| NSError *configuringError = nil; | |
| if (![self setCategory:configuration.category | |
| mode:configuration.mode | |
| options:configuration.categoryOptions | |
| error:&configuringError]) { | |
| RTCLogError(@"Failed to set category and mode: %@", | |
| configuringError.localizedDescription); | |
| error = configuringError; | |
| } else { | |
| RTCLog(@"Set category to: %@, mode: %@", | |
| configuration.category, | |
| configuration.mode); | |
| } | |
| } | |
| if (self.preferredSampleRate != configuration.sampleRate) { | |
| NSError *sampleRateError = nil; | |
| if (![self setPreferredSampleRate:configuration.sampleRate | |
| error:&sampleRateError]) { | |
| RTCLogError(@"Failed to set preferred sample rate: %@", | |
| sampleRateError.localizedDescription); | |
| if (!self.ignoresPreferredAttributeConfigurationErrors) { | |
| error = sampleRateError; | |
| } | |
| } else { | |
| RTCLog(@"Set preferred sample rate to: %.2f", configuration.sampleRate); | |
| } | |
| } | |
| if (self.preferredIOBufferDuration != configuration.ioBufferDuration) { | |
| NSError *bufferDurationError = nil; | |
| if (![self setPreferredIOBufferDuration:configuration.ioBufferDuration | |
| error:&bufferDurationError]) { | |
| RTCLogError(@"Failed to set preferred IO buffer duration: %@", | |
| bufferDurationError.localizedDescription); | |
| if (!self.ignoresPreferredAttributeConfigurationErrors) { | |
| error = bufferDurationError; | |
| } | |
| } else { | |
| RTCLog(@"Set preferred IO buffer duration to: %f", | |
| configuration.ioBufferDuration); | |
| } | |
| } | |
| if (shouldSetActive) { | |
| NSError *activeError = nil; | |
| if (![self setActive:active error:&activeError]) { | |
| RTCLogError(@"Failed to setActive to %d: %@", | |
| active, | |
| activeError.localizedDescription); | |
| error = activeError; | |
| } | |
| } | |
| 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. | |
| NSInteger inputNumberOfChannels = configuration.inputNumberOfChannels; | |
| if (self.inputNumberOfChannels != inputNumberOfChannels) { | |
| NSError *inputChannelsError = nil; | |
| if (![self setPreferredInputNumberOfChannels:inputNumberOfChannels | |
| error:&inputChannelsError]) { | |
| RTCLogError(@"Failed to set preferred input number of channels: %@", | |
| inputChannelsError.localizedDescription); | |
| if (!self.ignoresPreferredAttributeConfigurationErrors) { | |
| error = inputChannelsError; | |
| } | |
| } else { | |
| RTCLog(@"Set input number of channels to: %ld", | |
| (long)inputNumberOfChannels); | |
| } | |
| } | |
| NSInteger outputNumberOfChannels = configuration.outputNumberOfChannels; | |
| if (self.outputNumberOfChannels != outputNumberOfChannels) { | |
| NSError *outputChannelsError = nil; | |
| if (![self setPreferredOutputNumberOfChannels:outputNumberOfChannels | |
| error:&outputChannelsError]) { | |
| RTCLogError(@"Failed to set preferred output number of channels: %@", | |
| outputChannelsError.localizedDescription); | |
| if (!self.ignoresPreferredAttributeConfigurationErrors) { | |
| error = outputChannelsError; | |
| } | |
| } else { | |
| RTCLog(@"Set output number of channels to: %ld", | |
| (long)outputNumberOfChannels); | |
| } | |
| } | |
| } | |
| if (outError) { | |
| *outError = error; | |
| } | |
| return error == nil; | |
| } | |
| @end |