blob: b2753f282edabfefc40f15c0a70c6c4bcd45bf8a [file] [log] [blame]
Anders Carlsson7bca8ca2018-08-30 09:30:29 +02001/*
tkchin9f987d32016-03-12 20:06:28 -08002 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
denicija59ee91b2017-06-05 05:48:47 -070011#import "RTCAudioSession+Private.h"
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020012#import "RTCAudioSessionConfiguration.h"
denicija59ee91b2017-06-05 05:48:47 -070013
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020014#import "base/RTCLogging.h"
tkchin9f987d32016-03-12 20:06:28 -080015
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020016@implementation RTC_OBJC_TYPE (RTCAudioSession)
17(Configuration)
tkchin9f987d32016-03-12 20:06:28 -080018
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020019 - (BOOL)setConfiguration : (RTC_OBJC_TYPE(RTCAudioSessionConfiguration) *)configuration error
20 : (NSError **)outError {
tkchind2511962016-05-06 18:54:15 -070021 return [self setConfiguration:configuration
22 active:NO
23 shouldSetActive:NO
24 error:outError];
Tze Kwang Chin307a0922016-03-21 13:57:40 -070025}
26
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020027- (BOOL)setConfiguration:(RTC_OBJC_TYPE(RTCAudioSessionConfiguration) *)configuration
tkchin9f987d32016-03-12 20:06:28 -080028 active:(BOOL)active
29 error:(NSError **)outError {
tkchind2511962016-05-06 18:54:15 -070030 return [self setConfiguration:configuration
31 active:active
32 shouldSetActive:YES
33 error:outError];
34}
35
36#pragma mark - Private
37
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020038- (BOOL)setConfiguration:(RTC_OBJC_TYPE(RTCAudioSessionConfiguration) *)configuration
tkchind2511962016-05-06 18:54:15 -070039 active:(BOOL)active
40 shouldSetActive:(BOOL)shouldSetActive
41 error:(NSError **)outError {
Tze Kwang Chin307a0922016-03-21 13:57:40 -070042 NSParameterAssert(configuration);
43 if (outError) {
44 *outError = nil;
45 }
tkchin9f987d32016-03-12 20:06:28 -080046 if (![self checkLock:outError]) {
47 return NO;
48 }
49
50 // Provide an error even if there isn't one so we can log it. We will not
51 // return immediately on error in this function and instead try to set
52 // everything we can.
53 NSError *error = nil;
54
55 if (self.category != configuration.category ||
56 self.categoryOptions != configuration.categoryOptions) {
57 NSError *categoryError = nil;
58 if (![self setCategory:configuration.category
59 withOptions:configuration.categoryOptions
60 error:&categoryError]) {
61 RTCLogError(@"Failed to set category: %@",
62 categoryError.localizedDescription);
63 error = categoryError;
Tze Kwang Chin307a0922016-03-21 13:57:40 -070064 } else {
65 RTCLog(@"Set category to: %@", configuration.category);
tkchin9f987d32016-03-12 20:06:28 -080066 }
67 }
68
69 if (self.mode != configuration.mode) {
70 NSError *modeError = nil;
71 if (![self setMode:configuration.mode error:&modeError]) {
72 RTCLogError(@"Failed to set mode: %@",
73 modeError.localizedDescription);
74 error = modeError;
Tze Kwang Chin307a0922016-03-21 13:57:40 -070075 } else {
76 RTCLog(@"Set mode to: %@", configuration.mode);
tkchin9f987d32016-03-12 20:06:28 -080077 }
78 }
79
tkchind2511962016-05-06 18:54:15 -070080 // Sometimes category options don't stick after setting mode.
81 if (self.categoryOptions != configuration.categoryOptions) {
82 NSError *categoryError = nil;
83 if (![self setCategory:configuration.category
84 withOptions:configuration.categoryOptions
85 error:&categoryError]) {
86 RTCLogError(@"Failed to set category options: %@",
87 categoryError.localizedDescription);
88 error = categoryError;
89 } else {
90 RTCLog(@"Set category options to: %ld",
91 (long)configuration.categoryOptions);
92 }
93 }
94
95 if (self.preferredSampleRate != configuration.sampleRate) {
tkchin9f987d32016-03-12 20:06:28 -080096 NSError *sampleRateError = nil;
97 if (![self setPreferredSampleRate:configuration.sampleRate
98 error:&sampleRateError]) {
99 RTCLogError(@"Failed to set preferred sample rate: %@",
100 sampleRateError.localizedDescription);
Joe Chen0c05b1a2019-05-07 10:46:22 -0700101 if (!self.ignoresPreferredAttributeConfigurationErrors) {
102 error = sampleRateError;
103 }
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700104 } else {
105 RTCLog(@"Set preferred sample rate to: %.2f",
106 configuration.sampleRate);
tkchin9f987d32016-03-12 20:06:28 -0800107 }
108 }
109
tkchind2511962016-05-06 18:54:15 -0700110 if (self.preferredIOBufferDuration != configuration.ioBufferDuration) {
tkchin9f987d32016-03-12 20:06:28 -0800111 NSError *bufferDurationError = nil;
112 if (![self setPreferredIOBufferDuration:configuration.ioBufferDuration
113 error:&bufferDurationError]) {
114 RTCLogError(@"Failed to set preferred IO buffer duration: %@",
115 bufferDurationError.localizedDescription);
Joe Chen0c05b1a2019-05-07 10:46:22 -0700116 if (!self.ignoresPreferredAttributeConfigurationErrors) {
117 error = bufferDurationError;
118 }
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700119 } else {
120 RTCLog(@"Set preferred IO buffer duration to: %f",
121 configuration.ioBufferDuration);
tkchin9f987d32016-03-12 20:06:28 -0800122 }
123 }
124
tkchind2511962016-05-06 18:54:15 -0700125 if (shouldSetActive) {
126 NSError *activeError = nil;
127 if (![self setActive:active error:&activeError]) {
128 RTCLogError(@"Failed to setActive to %d: %@",
129 active, activeError.localizedDescription);
130 error = activeError;
131 }
tkchin9f987d32016-03-12 20:06:28 -0800132 }
133
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700134 if (self.isActive &&
135 // TODO(tkchin): Figure out which category/mode numChannels is valid for.
136 [self.mode isEqualToString:AVAudioSessionModeVoiceChat]) {
tkchin9f987d32016-03-12 20:06:28 -0800137 // Try to set the preferred number of hardware audio channels. These calls
138 // must be done after setting the audio session’s category and mode and
139 // activating the session.
140 NSInteger inputNumberOfChannels = configuration.inputNumberOfChannels;
141 if (self.inputNumberOfChannels != inputNumberOfChannels) {
142 NSError *inputChannelsError = nil;
143 if (![self setPreferredInputNumberOfChannels:inputNumberOfChannels
144 error:&inputChannelsError]) {
145 RTCLogError(@"Failed to set preferred input number of channels: %@",
146 inputChannelsError.localizedDescription);
Joe Chen0c05b1a2019-05-07 10:46:22 -0700147 if (!self.ignoresPreferredAttributeConfigurationErrors) {
148 error = inputChannelsError;
149 }
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700150 } else {
151 RTCLog(@"Set input number of channels to: %ld",
152 (long)inputNumberOfChannels);
tkchin9f987d32016-03-12 20:06:28 -0800153 }
154 }
155 NSInteger outputNumberOfChannels = configuration.outputNumberOfChannels;
156 if (self.outputNumberOfChannels != outputNumberOfChannels) {
157 NSError *outputChannelsError = nil;
158 if (![self setPreferredOutputNumberOfChannels:outputNumberOfChannels
159 error:&outputChannelsError]) {
160 RTCLogError(@"Failed to set preferred output number of channels: %@",
161 outputChannelsError.localizedDescription);
Joe Chen0c05b1a2019-05-07 10:46:22 -0700162 if (!self.ignoresPreferredAttributeConfigurationErrors) {
163 error = outputChannelsError;
164 }
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700165 } else {
166 RTCLog(@"Set output number of channels to: %ld",
167 (long)outputNumberOfChannels);
tkchin9f987d32016-03-12 20:06:28 -0800168 }
169 }
170 }
171
172 if (outError) {
173 *outError = error;
174 }
175
176 return error == nil;
177}
178
tkchin9f987d32016-03-12 20:06:28 -0800179@end