blob: ab8dbc8859e64bebc404ffebc52e5950a11e07e9 [file] [log] [blame]
Zeke Chinb3fb71c2016-02-18 15:44:07 -08001/*
2 * 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
11#import <AVFoundation/AVFoundation.h>
12#import <Foundation/Foundation.h>
13
14NS_ASSUME_NONNULL_BEGIN
15
16extern NSString * const kRTCAudioSessionErrorDomain;
tkchin9f987d32016-03-12 20:06:28 -080017/** Method that requires lock was called without lock. */
Zeke Chinb3fb71c2016-02-18 15:44:07 -080018extern NSInteger const kRTCAudioSessionErrorLockRequired;
tkchin9f987d32016-03-12 20:06:28 -080019/** Unknown configuration error occurred. */
20extern NSInteger const kRTCAudioSessionErrorConfiguration;
Zeke Chinb3fb71c2016-02-18 15:44:07 -080021
22@class RTCAudioSession;
tkchin9f987d32016-03-12 20:06:28 -080023@class RTCAudioSessionConfiguration;
Zeke Chinb3fb71c2016-02-18 15:44:07 -080024
25// Surfaces AVAudioSession events. WebRTC will listen directly for notifications
26// from AVAudioSession and handle them before calling these delegate methods,
27// at which point applications can perform additional processing if required.
28@protocol RTCAudioSessionDelegate <NSObject>
29
Tze Kwang Chin307a0922016-03-21 13:57:40 -070030@optional
31/** Called on a system notification thread when AVAudioSession starts an
32 * interruption event.
33 */
Zeke Chinb3fb71c2016-02-18 15:44:07 -080034- (void)audioSessionDidBeginInterruption:(RTCAudioSession *)session;
35
Tze Kwang Chin307a0922016-03-21 13:57:40 -070036/** Called on a system notification thread when AVAudioSession ends an
37 * interruption event.
38 */
Zeke Chinb3fb71c2016-02-18 15:44:07 -080039- (void)audioSessionDidEndInterruption:(RTCAudioSession *)session
40 shouldResumeSession:(BOOL)shouldResumeSession;
41
Tze Kwang Chin307a0922016-03-21 13:57:40 -070042/** Called on a system notification thread when AVAudioSession changes the
43 * route.
44 */
Zeke Chinb3fb71c2016-02-18 15:44:07 -080045- (void)audioSessionDidChangeRoute:(RTCAudioSession *)session
46 reason:(AVAudioSessionRouteChangeReason)reason
47 previousRoute:(AVAudioSessionRouteDescription *)previousRoute;
48
Tze Kwang Chin307a0922016-03-21 13:57:40 -070049/** Called on a system notification thread when AVAudioSession media server
50 * terminates.
51 */
Zeke Chinb3fb71c2016-02-18 15:44:07 -080052- (void)audioSessionMediaServicesWereLost:(RTCAudioSession *)session;
53
Tze Kwang Chin307a0922016-03-21 13:57:40 -070054/** Called on a system notification thread when AVAudioSession media server
55 * restarts.
56 */
Zeke Chinb3fb71c2016-02-18 15:44:07 -080057- (void)audioSessionMediaServicesWereReset:(RTCAudioSession *)session;
58
Tze Kwang Chin307a0922016-03-21 13:57:40 -070059// TODO(tkchin): Maybe handle SilenceSecondaryAudioHintNotification.
60
61/** Called on a WebRTC thread when WebRTC needs to take over audio. Applications
62 * should call -[RTCAudioSession configureWebRTCSession] to allow WebRTC to
63 * play and record audio. Will only occur if shouldDelayAudioConfiguration is
64 * set to YES.
tkchin9f987d32016-03-12 20:06:28 -080065 */
66- (void)audioSessionShouldConfigure:(RTCAudioSession *)session;
67
Tze Kwang Chin307a0922016-03-21 13:57:40 -070068/** Called on a WebRTC thread when WebRTC no longer requires audio. Applications
69 * should call -[RTCAudioSession unconfigureWebRTCSession] to restore their
70 * audio session settings. Will only occur if shouldDelayAudioConfiguration is
71 * set to YES.
tkchin9f987d32016-03-12 20:06:28 -080072 */
73- (void)audioSessionShouldUnconfigure:(RTCAudioSession *)session;
74
Tze Kwang Chin307a0922016-03-21 13:57:40 -070075/** Called on a WebRTC thread when WebRTC has configured the audio session for
76 * WebRTC audio.
77 */
78- (void)audioSessionDidConfigure:(RTCAudioSession *)session;
79
80/** Called on a WebRTC thread when WebRTC has unconfigured the audio session for
81 * WebRTC audio.
82 */
83- (void)audioSessionDidUnconfigure:(RTCAudioSession *)session;
Zeke Chinb3fb71c2016-02-18 15:44:07 -080084
85@end
86
87/** Proxy class for AVAudioSession that adds a locking mechanism similar to
88 * AVCaptureDevice. This is used to that interleaving configurations between
Tze Kwang Chin307a0922016-03-21 13:57:40 -070089 * WebRTC and the application layer are avoided.
Zeke Chinb3fb71c2016-02-18 15:44:07 -080090 *
91 * RTCAudioSession also coordinates activation so that the audio session is
92 * activated only once. See |setActive:error:|.
93 */
94@interface RTCAudioSession : NSObject
95
96/** Convenience property to access the AVAudioSession singleton. Callers should
97 * not call setters on AVAudioSession directly, but other method invocations
98 * are fine.
99 */
100@property(nonatomic, readonly) AVAudioSession *session;
101
102/** Our best guess at whether the session is active based on results of calls to
103 * AVAudioSession.
104 */
105@property(nonatomic, readonly) BOOL isActive;
106/** Whether RTCAudioSession is currently locked for configuration. */
107@property(nonatomic, readonly) BOOL isLocked;
108
tkchin9f987d32016-03-12 20:06:28 -0800109/** If YES, WebRTC will not initialize the audio unit automatically when an
110 * audio track is ready for playout or recording. Instead, applications should
111 * listen to the delegate method |audioSessionShouldConfigure| and configure
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700112 * the session manually. This should be set before making WebRTC media calls
113 * and should not be changed while a call is active.
tkchin9f987d32016-03-12 20:06:28 -0800114 */
115@property(nonatomic, assign) BOOL shouldDelayAudioConfiguration;
116
Zeke Chinb3fb71c2016-02-18 15:44:07 -0800117// Proxy properties.
118@property(readonly) NSString *category;
119@property(readonly) AVAudioSessionCategoryOptions categoryOptions;
120@property(readonly) NSString *mode;
121@property(readonly) BOOL secondaryAudioShouldBeSilencedHint;
122@property(readonly) AVAudioSessionRouteDescription *currentRoute;
123@property(readonly) NSInteger maximumInputNumberOfChannels;
124@property(readonly) NSInteger maximumOutputNumberOfChannels;
125@property(readonly) float inputGain;
126@property(readonly) BOOL inputGainSettable;
127@property(readonly) BOOL inputAvailable;
128@property(readonly, nullable)
129 NSArray<AVAudioSessionDataSourceDescription *> * inputDataSources;
130@property(readonly, nullable)
131 AVAudioSessionDataSourceDescription *inputDataSource;
132@property(readonly, nullable)
133 NSArray<AVAudioSessionDataSourceDescription *> * outputDataSources;
134@property(readonly, nullable)
135 AVAudioSessionDataSourceDescription *outputDataSource;
136@property(readonly) double sampleRate;
137@property(readonly) NSInteger inputNumberOfChannels;
138@property(readonly) NSInteger outputNumberOfChannels;
139@property(readonly) float outputVolume;
140@property(readonly) NSTimeInterval inputLatency;
141@property(readonly) NSTimeInterval outputLatency;
142@property(readonly) NSTimeInterval IOBufferDuration;
143
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700144/** Default constructor. */
Zeke Chinb3fb71c2016-02-18 15:44:07 -0800145+ (instancetype)sharedInstance;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700146- (instancetype)init NS_UNAVAILABLE;
Zeke Chinb3fb71c2016-02-18 15:44:07 -0800147
tkchine54467f2016-03-15 16:54:03 -0700148/** Adds a delegate, which is held weakly. */
Zeke Chinb3fb71c2016-02-18 15:44:07 -0800149- (void)addDelegate:(id<RTCAudioSessionDelegate>)delegate;
150/** Removes an added delegate. */
151- (void)removeDelegate:(id<RTCAudioSessionDelegate>)delegate;
152
153/** Request exclusive access to the audio session for configuration. This call
154 * will block if the lock is held by another object.
155 */
156- (void)lockForConfiguration;
157/** Relinquishes exclusive access to the audio session. */
158- (void)unlockForConfiguration;
159
160/** If |active|, activates the audio session if it isn't already active.
161 * Successful calls must be balanced with a setActive:NO when activation is no
162 * longer required. If not |active|, deactivates the audio session if one is
163 * active and this is the last balanced call. When deactivating, the
164 * AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation option is passed to
165 * AVAudioSession.
166 */
167- (BOOL)setActive:(BOOL)active
168 error:(NSError **)outError;
169
170// The following methods are proxies for the associated methods on
171// AVAudioSession. |lockForConfiguration| must be called before using them
172// otherwise they will fail with kRTCAudioSessionErrorLockRequired.
173
174- (BOOL)setCategory:(NSString *)category
175 withOptions:(AVAudioSessionCategoryOptions)options
176 error:(NSError **)outError;
177- (BOOL)setMode:(NSString *)mode error:(NSError **)outError;
178- (BOOL)setInputGain:(float)gain error:(NSError **)outError;
179- (BOOL)setPreferredSampleRate:(double)sampleRate error:(NSError **)outError;
180- (BOOL)setPreferredIOBufferDuration:(NSTimeInterval)duration
181 error:(NSError **)outError;
182- (BOOL)setPreferredInputNumberOfChannels:(NSInteger)count
183 error:(NSError **)outError;
184- (BOOL)setPreferredOutputNumberOfChannels:(NSInteger)count
185 error:(NSError **)outError;
186- (BOOL)overrideOutputAudioPort:(AVAudioSessionPortOverride)portOverride
187 error:(NSError **)outError;
188- (BOOL)setPreferredInput:(AVAudioSessionPortDescription *)inPort
189 error:(NSError **)outError;
190- (BOOL)setInputDataSource:(AVAudioSessionDataSourceDescription *)dataSource
191 error:(NSError **)outError;
192- (BOOL)setOutputDataSource:(AVAudioSessionDataSourceDescription *)dataSource
193 error:(NSError **)outError;
194
195@end
196
tkchin9f987d32016-03-12 20:06:28 -0800197@interface RTCAudioSession (Configuration)
198
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700199/** Whether or not |configureWebRTCSession| has been called without a balanced
200 * call to |unconfigureWebRTCSession|. This is not an indication of whether the
201 * audio session has the right settings.
202 */
203@property(readonly) BOOL isConfiguredForWebRTC;
204
tkchin9f987d32016-03-12 20:06:28 -0800205/** Applies the configuration to the current session. Attempts to set all
206 * properties even if previous ones fail. Only the last error will be
207 * returned. Also calls setActive with |active|.
208 * |lockForConfiguration| must be called first.
209 */
210- (BOOL)setConfiguration:(RTCAudioSessionConfiguration *)configuration
211 active:(BOOL)active
212 error:(NSError **)outError;
213
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700214/** Configure the audio session for WebRTC. This call will fail if the session
215 * is already configured. On other failures, we will attempt to restore the
216 * previously used audio session configuration.
tkchin9f987d32016-03-12 20:06:28 -0800217 * |lockForConfiguration| must be called first.
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700218 * Successful calls to configureWebRTCSession must be matched by calls to
219 * |unconfigureWebRTCSession|.
tkchin9f987d32016-03-12 20:06:28 -0800220 */
221- (BOOL)configureWebRTCSession:(NSError **)outError;
222
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700223/** Unconfigures the session for WebRTC. This will attempt to restore the
224 * audio session to the settings used before |configureWebRTCSession| was
225 * called.
226 * |lockForConfiguration| must be called first.
227 */
228- (BOOL)unconfigureWebRTCSession:(NSError **)outError;
229
tkchin9f987d32016-03-12 20:06:28 -0800230@end
231
Zeke Chinb3fb71c2016-02-18 15:44:07 -0800232NS_ASSUME_NONNULL_END