blob: 449f31e9ddfcad996792ec619f4f908db502034b [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
47 // Provide an error even if there isn't one so we can log it. We will not
48 // return immediately on error in this function and instead try to set
49 // everything we can.
50 NSError *error = nil;
51
52 if (self.category != configuration.category ||
53 self.categoryOptions != configuration.categoryOptions) {
54 NSError *categoryError = nil;
55 if (![self setCategory:configuration.category
56 withOptions:configuration.categoryOptions
57 error:&categoryError]) {
58 RTCLogError(@"Failed to set category: %@",
59 categoryError.localizedDescription);
60 error = categoryError;
Tze Kwang Chin307a0922016-03-21 13:57:40 -070061 } else {
62 RTCLog(@"Set category to: %@", configuration.category);
tkchin9f987d32016-03-12 20:06:28 -080063 }
64 }
65
66 if (self.mode != configuration.mode) {
67 NSError *modeError = nil;
68 if (![self setMode:configuration.mode error:&modeError]) {
69 RTCLogError(@"Failed to set mode: %@",
70 modeError.localizedDescription);
71 error = modeError;
Tze Kwang Chin307a0922016-03-21 13:57:40 -070072 } else {
73 RTCLog(@"Set mode to: %@", configuration.mode);
tkchin9f987d32016-03-12 20:06:28 -080074 }
75 }
76
tkchind2511962016-05-06 18:54:15 -070077 // Sometimes category options don't stick after setting mode.
78 if (self.categoryOptions != configuration.categoryOptions) {
79 NSError *categoryError = nil;
80 if (![self setCategory:configuration.category
81 withOptions:configuration.categoryOptions
82 error:&categoryError]) {
83 RTCLogError(@"Failed to set category options: %@",
84 categoryError.localizedDescription);
85 error = categoryError;
86 } else {
87 RTCLog(@"Set category options to: %ld",
88 (long)configuration.categoryOptions);
89 }
90 }
91
92 if (self.preferredSampleRate != configuration.sampleRate) {
tkchin9f987d32016-03-12 20:06:28 -080093 NSError *sampleRateError = nil;
94 if (![self setPreferredSampleRate:configuration.sampleRate
95 error:&sampleRateError]) {
96 RTCLogError(@"Failed to set preferred sample rate: %@",
97 sampleRateError.localizedDescription);
Joe Chen0c05b1a2019-05-07 10:46:22 -070098 if (!self.ignoresPreferredAttributeConfigurationErrors) {
99 error = sampleRateError;
100 }
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700101 } else {
102 RTCLog(@"Set preferred sample rate to: %.2f",
103 configuration.sampleRate);
tkchin9f987d32016-03-12 20:06:28 -0800104 }
105 }
106
tkchind2511962016-05-06 18:54:15 -0700107 if (self.preferredIOBufferDuration != configuration.ioBufferDuration) {
tkchin9f987d32016-03-12 20:06:28 -0800108 NSError *bufferDurationError = nil;
109 if (![self setPreferredIOBufferDuration:configuration.ioBufferDuration
110 error:&bufferDurationError]) {
111 RTCLogError(@"Failed to set preferred IO buffer duration: %@",
112 bufferDurationError.localizedDescription);
Joe Chen0c05b1a2019-05-07 10:46:22 -0700113 if (!self.ignoresPreferredAttributeConfigurationErrors) {
114 error = bufferDurationError;
115 }
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700116 } else {
117 RTCLog(@"Set preferred IO buffer duration to: %f",
118 configuration.ioBufferDuration);
tkchin9f987d32016-03-12 20:06:28 -0800119 }
120 }
121
tkchind2511962016-05-06 18:54:15 -0700122 if (shouldSetActive) {
123 NSError *activeError = nil;
124 if (![self setActive:active error:&activeError]) {
125 RTCLogError(@"Failed to setActive to %d: %@",
126 active, activeError.localizedDescription);
127 error = activeError;
128 }
tkchin9f987d32016-03-12 20:06:28 -0800129 }
130
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700131 if (self.isActive &&
132 // TODO(tkchin): Figure out which category/mode numChannels is valid for.
133 [self.mode isEqualToString:AVAudioSessionModeVoiceChat]) {
tkchin9f987d32016-03-12 20:06:28 -0800134 // Try to set the preferred number of hardware audio channels. These calls
135 // must be done after setting the audio session’s category and mode and
136 // activating the session.
137 NSInteger inputNumberOfChannels = configuration.inputNumberOfChannels;
138 if (self.inputNumberOfChannels != inputNumberOfChannels) {
139 NSError *inputChannelsError = nil;
140 if (![self setPreferredInputNumberOfChannels:inputNumberOfChannels
141 error:&inputChannelsError]) {
142 RTCLogError(@"Failed to set preferred input number of channels: %@",
143 inputChannelsError.localizedDescription);
Joe Chen0c05b1a2019-05-07 10:46:22 -0700144 if (!self.ignoresPreferredAttributeConfigurationErrors) {
145 error = inputChannelsError;
146 }
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700147 } else {
148 RTCLog(@"Set input number of channels to: %ld",
149 (long)inputNumberOfChannels);
tkchin9f987d32016-03-12 20:06:28 -0800150 }
151 }
152 NSInteger outputNumberOfChannels = configuration.outputNumberOfChannels;
153 if (self.outputNumberOfChannels != outputNumberOfChannels) {
154 NSError *outputChannelsError = nil;
155 if (![self setPreferredOutputNumberOfChannels:outputNumberOfChannels
156 error:&outputChannelsError]) {
157 RTCLogError(@"Failed to set preferred output number of channels: %@",
158 outputChannelsError.localizedDescription);
Joe Chen0c05b1a2019-05-07 10:46:22 -0700159 if (!self.ignoresPreferredAttributeConfigurationErrors) {
160 error = outputChannelsError;
161 }
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700162 } else {
163 RTCLog(@"Set output number of channels to: %ld",
164 (long)outputNumberOfChannels);
tkchin9f987d32016-03-12 20:06:28 -0800165 }
166 }
167 }
168
169 if (outError) {
170 *outError = error;
171 }
172
173 return error == nil;
174}
175
tkchin9f987d32016-03-12 20:06:28 -0800176@end