blob: 0ece5926a8f479aed6e043ff438d94668b2e7a7a [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);
100 error = sampleRateError;
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);
113 error = bufferDurationError;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700114 } else {
115 RTCLog(@"Set preferred IO buffer duration to: %f",
116 configuration.ioBufferDuration);
tkchin9f987d32016-03-12 20:06:28 -0800117 }
118 }
119
tkchind2511962016-05-06 18:54:15 -0700120 if (shouldSetActive) {
121 NSError *activeError = nil;
122 if (![self setActive:active error:&activeError]) {
123 RTCLogError(@"Failed to setActive to %d: %@",
124 active, activeError.localizedDescription);
125 error = activeError;
126 }
tkchin9f987d32016-03-12 20:06:28 -0800127 }
128
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700129 if (self.isActive &&
130 // TODO(tkchin): Figure out which category/mode numChannels is valid for.
131 [self.mode isEqualToString:AVAudioSessionModeVoiceChat]) {
tkchin9f987d32016-03-12 20:06:28 -0800132 // Try to set the preferred number of hardware audio channels. These calls
133 // must be done after setting the audio session’s category and mode and
134 // activating the session.
135 NSInteger inputNumberOfChannels = configuration.inputNumberOfChannels;
136 if (self.inputNumberOfChannels != inputNumberOfChannels) {
137 NSError *inputChannelsError = nil;
138 if (![self setPreferredInputNumberOfChannels:inputNumberOfChannels
139 error:&inputChannelsError]) {
140 RTCLogError(@"Failed to set preferred input number of channels: %@",
141 inputChannelsError.localizedDescription);
142 error = inputChannelsError;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700143 } else {
144 RTCLog(@"Set input number of channels to: %ld",
145 (long)inputNumberOfChannels);
tkchin9f987d32016-03-12 20:06:28 -0800146 }
147 }
148 NSInteger outputNumberOfChannels = configuration.outputNumberOfChannels;
149 if (self.outputNumberOfChannels != outputNumberOfChannels) {
150 NSError *outputChannelsError = nil;
151 if (![self setPreferredOutputNumberOfChannels:outputNumberOfChannels
152 error:&outputChannelsError]) {
153 RTCLogError(@"Failed to set preferred output number of channels: %@",
154 outputChannelsError.localizedDescription);
155 error = outputChannelsError;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700156 } else {
157 RTCLog(@"Set output number of channels to: %ld",
158 (long)outputNumberOfChannels);
tkchin9f987d32016-03-12 20:06:28 -0800159 }
160 }
161 }
162
163 if (outError) {
164 *outError = error;
165 }
166
167 return error == nil;
168}
169
tkchin9f987d32016-03-12 20:06:28 -0800170@end