blob: 73ba0c01fa08b7db1f557ec11410a75323685fcd [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
30/** Called when AVAudioSession starts an interruption event. */
31- (void)audioSessionDidBeginInterruption:(RTCAudioSession *)session;
32
33/** Called when AVAudioSession ends an interruption event. */
34- (void)audioSessionDidEndInterruption:(RTCAudioSession *)session
35 shouldResumeSession:(BOOL)shouldResumeSession;
36
37/** Called when AVAudioSession changes the route. */
38- (void)audioSessionDidChangeRoute:(RTCAudioSession *)session
39 reason:(AVAudioSessionRouteChangeReason)reason
40 previousRoute:(AVAudioSessionRouteDescription *)previousRoute;
41
42/** Called when AVAudioSession media server terminates. */
43- (void)audioSessionMediaServicesWereLost:(RTCAudioSession *)session;
44
45/** Called when AVAudioSession media server restarts. */
46- (void)audioSessionMediaServicesWereReset:(RTCAudioSession *)session;
47
tkchin9f987d32016-03-12 20:06:28 -080048/** Called when WebRTC needs to take over audio. Applications should call
49 * -[RTCAudioSession configure] to allow WebRTC to play and record audio.
50 * TODO(tkchin): Implement this behavior in RTCAudioSession.
51 */
52- (void)audioSessionShouldConfigure:(RTCAudioSession *)session;
53
54/** Called when WebRTC no longer requires audio. Applications should restore
55 * their audio state at this point.
56 * TODO(tkchin): Implement this behavior in RTCAudioSession.
57 */
58- (void)audioSessionShouldUnconfigure:(RTCAudioSession *)session;
59
Zeke Chinb3fb71c2016-02-18 15:44:07 -080060// TODO(tkchin): Maybe handle SilenceSecondaryAudioHintNotification.
61
62@end
63
64/** Proxy class for AVAudioSession that adds a locking mechanism similar to
65 * AVCaptureDevice. This is used to that interleaving configurations between
66 * WebRTC and the application layer are avoided. Only setter methods are
67 * currently proxied. Getters can be accessed directly off AVAudioSession.
68 *
69 * RTCAudioSession also coordinates activation so that the audio session is
70 * activated only once. See |setActive:error:|.
71 */
72@interface RTCAudioSession : NSObject
73
74/** Convenience property to access the AVAudioSession singleton. Callers should
75 * not call setters on AVAudioSession directly, but other method invocations
76 * are fine.
77 */
78@property(nonatomic, readonly) AVAudioSession *session;
79
80/** Our best guess at whether the session is active based on results of calls to
81 * AVAudioSession.
82 */
83@property(nonatomic, readonly) BOOL isActive;
84/** Whether RTCAudioSession is currently locked for configuration. */
85@property(nonatomic, readonly) BOOL isLocked;
86
tkchin9f987d32016-03-12 20:06:28 -080087/** If YES, WebRTC will not initialize the audio unit automatically when an
88 * audio track is ready for playout or recording. Instead, applications should
89 * listen to the delegate method |audioSessionShouldConfigure| and configure
90 * the session manually. This should be set before making WebRTC media calls.
91 * TODO(tkchin): Implement behavior. Currently this just stores a BOOL.
92 */
93@property(nonatomic, assign) BOOL shouldDelayAudioConfiguration;
94
Zeke Chinb3fb71c2016-02-18 15:44:07 -080095// Proxy properties.
96@property(readonly) NSString *category;
97@property(readonly) AVAudioSessionCategoryOptions categoryOptions;
98@property(readonly) NSString *mode;
99@property(readonly) BOOL secondaryAudioShouldBeSilencedHint;
100@property(readonly) AVAudioSessionRouteDescription *currentRoute;
101@property(readonly) NSInteger maximumInputNumberOfChannels;
102@property(readonly) NSInteger maximumOutputNumberOfChannels;
103@property(readonly) float inputGain;
104@property(readonly) BOOL inputGainSettable;
105@property(readonly) BOOL inputAvailable;
106@property(readonly, nullable)
107 NSArray<AVAudioSessionDataSourceDescription *> * inputDataSources;
108@property(readonly, nullable)
109 AVAudioSessionDataSourceDescription *inputDataSource;
110@property(readonly, nullable)
111 NSArray<AVAudioSessionDataSourceDescription *> * outputDataSources;
112@property(readonly, nullable)
113 AVAudioSessionDataSourceDescription *outputDataSource;
114@property(readonly) double sampleRate;
115@property(readonly) NSInteger inputNumberOfChannels;
116@property(readonly) NSInteger outputNumberOfChannels;
117@property(readonly) float outputVolume;
118@property(readonly) NSTimeInterval inputLatency;
119@property(readonly) NSTimeInterval outputLatency;
120@property(readonly) NSTimeInterval IOBufferDuration;
121
122/** Default constructor. Do not call init. */
123+ (instancetype)sharedInstance;
124
tkchine54467f2016-03-15 16:54:03 -0700125/** Adds a delegate, which is held weakly. */
Zeke Chinb3fb71c2016-02-18 15:44:07 -0800126- (void)addDelegate:(id<RTCAudioSessionDelegate>)delegate;
127/** Removes an added delegate. */
128- (void)removeDelegate:(id<RTCAudioSessionDelegate>)delegate;
129
130/** Request exclusive access to the audio session for configuration. This call
131 * will block if the lock is held by another object.
132 */
133- (void)lockForConfiguration;
134/** Relinquishes exclusive access to the audio session. */
135- (void)unlockForConfiguration;
136
137/** If |active|, activates the audio session if it isn't already active.
138 * Successful calls must be balanced with a setActive:NO when activation is no
139 * longer required. If not |active|, deactivates the audio session if one is
140 * active and this is the last balanced call. When deactivating, the
141 * AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation option is passed to
142 * AVAudioSession.
143 */
144- (BOOL)setActive:(BOOL)active
145 error:(NSError **)outError;
146
147// The following methods are proxies for the associated methods on
148// AVAudioSession. |lockForConfiguration| must be called before using them
149// otherwise they will fail with kRTCAudioSessionErrorLockRequired.
150
151- (BOOL)setCategory:(NSString *)category
152 withOptions:(AVAudioSessionCategoryOptions)options
153 error:(NSError **)outError;
154- (BOOL)setMode:(NSString *)mode error:(NSError **)outError;
155- (BOOL)setInputGain:(float)gain error:(NSError **)outError;
156- (BOOL)setPreferredSampleRate:(double)sampleRate error:(NSError **)outError;
157- (BOOL)setPreferredIOBufferDuration:(NSTimeInterval)duration
158 error:(NSError **)outError;
159- (BOOL)setPreferredInputNumberOfChannels:(NSInteger)count
160 error:(NSError **)outError;
161- (BOOL)setPreferredOutputNumberOfChannels:(NSInteger)count
162 error:(NSError **)outError;
163- (BOOL)overrideOutputAudioPort:(AVAudioSessionPortOverride)portOverride
164 error:(NSError **)outError;
165- (BOOL)setPreferredInput:(AVAudioSessionPortDescription *)inPort
166 error:(NSError **)outError;
167- (BOOL)setInputDataSource:(AVAudioSessionDataSourceDescription *)dataSource
168 error:(NSError **)outError;
169- (BOOL)setOutputDataSource:(AVAudioSessionDataSourceDescription *)dataSource
170 error:(NSError **)outError;
171
172@end
173
tkchin9f987d32016-03-12 20:06:28 -0800174@interface RTCAudioSession (Configuration)
175
176/** Applies the configuration to the current session. Attempts to set all
177 * properties even if previous ones fail. Only the last error will be
178 * returned. Also calls setActive with |active|.
179 * |lockForConfiguration| must be called first.
180 */
181- (BOOL)setConfiguration:(RTCAudioSessionConfiguration *)configuration
182 active:(BOOL)active
183 error:(NSError **)outError;
184
185/** Configure the audio session for WebRTC. On failure, we will attempt to
186 * restore the previously used audio session configuration.
187 * |lockForConfiguration| must be called first.
188 */
189- (BOOL)configureWebRTCSession:(NSError **)outError;
190
191@end
192
Zeke Chinb3fb71c2016-02-18 15:44:07 -0800193NS_ASSUME_NONNULL_END