blob: c81ce1b9163650926a78211d5f85ee4f2d65fd77 [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
16@implementation RTCAudioSession (Configuration)
17
tkchind2511962016-05-06 18:54:15 -070018- (BOOL)setConfiguration:(RTCAudioSessionConfiguration *)configuration
19 error:(NSError **)outError {
20 return [self setConfiguration:configuration
21 active:NO
22 shouldSetActive:NO
23 error:outError];
Tze Kwang Chin307a0922016-03-21 13:57:40 -070024}
25
tkchin9f987d32016-03-12 20:06:28 -080026- (BOOL)setConfiguration:(RTCAudioSessionConfiguration *)configuration
27 active:(BOOL)active
28 error:(NSError **)outError {
tkchind2511962016-05-06 18:54:15 -070029 return [self setConfiguration:configuration
30 active:active
31 shouldSetActive:YES
32 error:outError];
33}
34
35#pragma mark - Private
36
37- (BOOL)setConfiguration:(RTCAudioSessionConfiguration *)configuration
38 active:(BOOL)active
39 shouldSetActive:(BOOL)shouldSetActive
40 error:(NSError **)outError {
Tze Kwang Chin307a0922016-03-21 13:57:40 -070041 NSParameterAssert(configuration);
42 if (outError) {
43 *outError = nil;
44 }
tkchin9f987d32016-03-12 20:06:28 -080045 if (![self checkLock:outError]) {
46 return NO;
47 }
48
49 // Provide an error even if there isn't one so we can log it. We will not
50 // return immediately on error in this function and instead try to set
51 // everything we can.
52 NSError *error = nil;
53
54 if (self.category != configuration.category ||
55 self.categoryOptions != configuration.categoryOptions) {
56 NSError *categoryError = nil;
57 if (![self setCategory:configuration.category
58 withOptions:configuration.categoryOptions
59 error:&categoryError]) {
60 RTCLogError(@"Failed to set category: %@",
61 categoryError.localizedDescription);
62 error = categoryError;
Tze Kwang Chin307a0922016-03-21 13:57:40 -070063 } else {
64 RTCLog(@"Set category to: %@", configuration.category);
tkchin9f987d32016-03-12 20:06:28 -080065 }
66 }
67
68 if (self.mode != configuration.mode) {
69 NSError *modeError = nil;
70 if (![self setMode:configuration.mode error:&modeError]) {
71 RTCLogError(@"Failed to set mode: %@",
72 modeError.localizedDescription);
73 error = modeError;
Tze Kwang Chin307a0922016-03-21 13:57:40 -070074 } else {
75 RTCLog(@"Set mode to: %@", configuration.mode);
tkchin9f987d32016-03-12 20:06:28 -080076 }
77 }
78
tkchind2511962016-05-06 18:54:15 -070079 // Sometimes category options don't stick after setting mode.
80 if (self.categoryOptions != configuration.categoryOptions) {
81 NSError *categoryError = nil;
82 if (![self setCategory:configuration.category
83 withOptions:configuration.categoryOptions
84 error:&categoryError]) {
85 RTCLogError(@"Failed to set category options: %@",
86 categoryError.localizedDescription);
87 error = categoryError;
88 } else {
89 RTCLog(@"Set category options to: %ld",
90 (long)configuration.categoryOptions);
91 }
92 }
93
94 if (self.preferredSampleRate != configuration.sampleRate) {
tkchin9f987d32016-03-12 20:06:28 -080095 NSError *sampleRateError = nil;
96 if (![self setPreferredSampleRate:configuration.sampleRate
97 error:&sampleRateError]) {
98 RTCLogError(@"Failed to set preferred sample rate: %@",
99 sampleRateError.localizedDescription);
Joe Chen0c05b1a2019-05-07 10:46:22 -0700100 if (!self.ignoresPreferredAttributeConfigurationErrors) {
101 error = sampleRateError;
102 }
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700103 } else {
104 RTCLog(@"Set preferred sample rate to: %.2f",
105 configuration.sampleRate);
tkchin9f987d32016-03-12 20:06:28 -0800106 }
107 }
108
tkchind2511962016-05-06 18:54:15 -0700109 if (self.preferredIOBufferDuration != configuration.ioBufferDuration) {
tkchin9f987d32016-03-12 20:06:28 -0800110 NSError *bufferDurationError = nil;
111 if (![self setPreferredIOBufferDuration:configuration.ioBufferDuration
112 error:&bufferDurationError]) {
113 RTCLogError(@"Failed to set preferred IO buffer duration: %@",
114 bufferDurationError.localizedDescription);
Joe Chen0c05b1a2019-05-07 10:46:22 -0700115 if (!self.ignoresPreferredAttributeConfigurationErrors) {
116 error = bufferDurationError;
117 }
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700118 } else {
119 RTCLog(@"Set preferred IO buffer duration to: %f",
120 configuration.ioBufferDuration);
tkchin9f987d32016-03-12 20:06:28 -0800121 }
122 }
123
tkchind2511962016-05-06 18:54:15 -0700124 if (shouldSetActive) {
125 NSError *activeError = nil;
126 if (![self setActive:active error:&activeError]) {
127 RTCLogError(@"Failed to setActive to %d: %@",
128 active, activeError.localizedDescription);
129 error = activeError;
130 }
tkchin9f987d32016-03-12 20:06:28 -0800131 }
132
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700133 if (self.isActive &&
134 // TODO(tkchin): Figure out which category/mode numChannels is valid for.
135 [self.mode isEqualToString:AVAudioSessionModeVoiceChat]) {
tkchin9f987d32016-03-12 20:06:28 -0800136 // Try to set the preferred number of hardware audio channels. These calls
137 // must be done after setting the audio session’s category and mode and
138 // activating the session.
139 NSInteger inputNumberOfChannels = configuration.inputNumberOfChannels;
140 if (self.inputNumberOfChannels != inputNumberOfChannels) {
141 NSError *inputChannelsError = nil;
142 if (![self setPreferredInputNumberOfChannels:inputNumberOfChannels
143 error:&inputChannelsError]) {
144 RTCLogError(@"Failed to set preferred input number of channels: %@",
145 inputChannelsError.localizedDescription);
Joe Chen0c05b1a2019-05-07 10:46:22 -0700146 if (!self.ignoresPreferredAttributeConfigurationErrors) {
147 error = inputChannelsError;
148 }
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700149 } else {
150 RTCLog(@"Set input number of channels to: %ld",
151 (long)inputNumberOfChannels);
tkchin9f987d32016-03-12 20:06:28 -0800152 }
153 }
154 NSInteger outputNumberOfChannels = configuration.outputNumberOfChannels;
155 if (self.outputNumberOfChannels != outputNumberOfChannels) {
156 NSError *outputChannelsError = nil;
157 if (![self setPreferredOutputNumberOfChannels:outputNumberOfChannels
158 error:&outputChannelsError]) {
159 RTCLogError(@"Failed to set preferred output number of channels: %@",
160 outputChannelsError.localizedDescription);
Joe Chen0c05b1a2019-05-07 10:46:22 -0700161 if (!self.ignoresPreferredAttributeConfigurationErrors) {
162 error = outputChannelsError;
163 }
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700164 } else {
165 RTCLog(@"Set output number of channels to: %ld",
166 (long)outputNumberOfChannels);
tkchin9f987d32016-03-12 20:06:28 -0800167 }
168 }
169 }
170
171 if (outError) {
172 *outError = error;
173 }
174
175 return error == nil;
176}
177
tkchin9f987d32016-03-12 20:06:28 -0800178@end