OLD | NEW |
| (Empty) |
1 /* | |
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 | |
14 #import "WebRTC/RTCMacros.h" | |
15 | |
16 NS_ASSUME_NONNULL_BEGIN | |
17 | |
18 extern NSString * const kRTCAudioSessionErrorDomain; | |
19 /** Method that requires lock was called without lock. */ | |
20 extern NSInteger const kRTCAudioSessionErrorLockRequired; | |
21 /** Unknown configuration error occurred. */ | |
22 extern NSInteger const kRTCAudioSessionErrorConfiguration; | |
23 | |
24 @class RTCAudioSession; | |
25 @class RTCAudioSessionConfiguration; | |
26 | |
27 // Surfaces AVAudioSession events. WebRTC will listen directly for notifications | |
28 // from AVAudioSession and handle them before calling these delegate methods, | |
29 // at which point applications can perform additional processing if required. | |
30 RTC_EXPORT | |
31 @protocol RTCAudioSessionDelegate <NSObject> | |
32 | |
33 @optional | |
34 /** Called on a system notification thread when AVAudioSession starts an | |
35 * interruption event. | |
36 */ | |
37 - (void)audioSessionDidBeginInterruption:(RTCAudioSession *)session; | |
38 | |
39 /** Called on a system notification thread when AVAudioSession ends an | |
40 * interruption event. | |
41 */ | |
42 - (void)audioSessionDidEndInterruption:(RTCAudioSession *)session | |
43 shouldResumeSession:(BOOL)shouldResumeSession; | |
44 | |
45 /** Called on a system notification thread when AVAudioSession changes the | |
46 * route. | |
47 */ | |
48 - (void)audioSessionDidChangeRoute:(RTCAudioSession *)session | |
49 reason:(AVAudioSessionRouteChangeReason)reason | |
50 previousRoute:(AVAudioSessionRouteDescription *)previousRoute; | |
51 | |
52 /** Called on a system notification thread when AVAudioSession media server | |
53 * terminates. | |
54 */ | |
55 - (void)audioSessionMediaServerTerminated:(RTCAudioSession *)session; | |
56 | |
57 /** Called on a system notification thread when AVAudioSession media server | |
58 * restarts. | |
59 */ | |
60 - (void)audioSessionMediaServerReset:(RTCAudioSession *)session; | |
61 | |
62 // TODO(tkchin): Maybe handle SilenceSecondaryAudioHintNotification. | |
63 | |
64 - (void)audioSession:(RTCAudioSession *)session | |
65 didChangeCanPlayOrRecord:(BOOL)canPlayOrRecord; | |
66 | |
67 /** Called on a WebRTC thread when the audio device is notified to begin | |
68 * playback or recording. | |
69 */ | |
70 - (void)audioSessionDidStartPlayOrRecord:(RTCAudioSession *)session; | |
71 | |
72 /** Called on a WebRTC thread when the audio device is notified to stop | |
73 * playback or recording. | |
74 */ | |
75 - (void)audioSessionDidStopPlayOrRecord:(RTCAudioSession *)session; | |
76 | |
77 @end | |
78 | |
79 /** This is a protocol used to inform RTCAudioSession when the audio session | |
80 * activation state has changed outside of RTCAudioSession. The current known u
se | |
81 * case of this is when CallKit activates the audio session for the application | |
82 */ | |
83 RTC_EXPORT | |
84 @protocol RTCAudioSessionActivationDelegate <NSObject> | |
85 | |
86 /** Called when the audio session is activated outside of the app by iOS. */ | |
87 - (void)audioSessionDidActivate:(AVAudioSession *)session; | |
88 | |
89 /** Called when the audio session is deactivated outside of the app by iOS. */ | |
90 - (void)audioSessionDidDeactivate:(AVAudioSession *)session; | |
91 | |
92 @end | |
93 | |
94 /** Proxy class for AVAudioSession that adds a locking mechanism similar to | |
95 * AVCaptureDevice. This is used to that interleaving configurations between | |
96 * WebRTC and the application layer are avoided. | |
97 * | |
98 * RTCAudioSession also coordinates activation so that the audio session is | |
99 * activated only once. See |setActive:error:|. | |
100 */ | |
101 RTC_EXPORT | |
102 @interface RTCAudioSession : NSObject <RTCAudioSessionActivationDelegate> | |
103 | |
104 /** Convenience property to access the AVAudioSession singleton. Callers should | |
105 * not call setters on AVAudioSession directly, but other method invocations | |
106 * are fine. | |
107 */ | |
108 @property(nonatomic, readonly) AVAudioSession *session; | |
109 | |
110 /** Our best guess at whether the session is active based on results of calls to | |
111 * AVAudioSession. | |
112 */ | |
113 @property(nonatomic, readonly) BOOL isActive; | |
114 /** Whether RTCAudioSession is currently locked for configuration. */ | |
115 @property(nonatomic, readonly) BOOL isLocked; | |
116 | |
117 /** If YES, WebRTC will not initialize the audio unit automatically when an | |
118 * audio track is ready for playout or recording. Instead, applications should | |
119 * call setIsAudioEnabled. If NO, WebRTC will initialize the audio unit | |
120 * as soon as an audio track is ready for playout or recording. | |
121 */ | |
122 @property(nonatomic, assign) BOOL useManualAudio; | |
123 | |
124 /** This property is only effective if useManualAudio is YES. | |
125 * Represents permission for WebRTC to initialize the VoIP audio unit. | |
126 * When set to NO, if the VoIP audio unit used by WebRTC is active, it will be | |
127 * stopped and uninitialized. This will stop incoming and outgoing audio. | |
128 * When set to YES, WebRTC will initialize and start the audio unit when it is | |
129 * needed (e.g. due to establishing an audio connection). | |
130 * This property was introduced to work around an issue where if an AVPlayer is | |
131 * playing audio while the VoIP audio unit is initialized, its audio would be | |
132 * either cut off completely or played at a reduced volume. By preventing | |
133 * the audio unit from being initialized until after the audio has completed, | |
134 * we are able to prevent the abrupt cutoff. | |
135 */ | |
136 @property(nonatomic, assign) BOOL isAudioEnabled; | |
137 | |
138 // Proxy properties. | |
139 @property(readonly) NSString *category; | |
140 @property(readonly) AVAudioSessionCategoryOptions categoryOptions; | |
141 @property(readonly) NSString *mode; | |
142 @property(readonly) BOOL secondaryAudioShouldBeSilencedHint; | |
143 @property(readonly) AVAudioSessionRouteDescription *currentRoute; | |
144 @property(readonly) NSInteger maximumInputNumberOfChannels; | |
145 @property(readonly) NSInteger maximumOutputNumberOfChannels; | |
146 @property(readonly) float inputGain; | |
147 @property(readonly) BOOL inputGainSettable; | |
148 @property(readonly) BOOL inputAvailable; | |
149 @property(readonly, nullable) | |
150 NSArray<AVAudioSessionDataSourceDescription *> * inputDataSources; | |
151 @property(readonly, nullable) | |
152 AVAudioSessionDataSourceDescription *inputDataSource; | |
153 @property(readonly, nullable) | |
154 NSArray<AVAudioSessionDataSourceDescription *> * outputDataSources; | |
155 @property(readonly, nullable) | |
156 AVAudioSessionDataSourceDescription *outputDataSource; | |
157 @property(readonly) double sampleRate; | |
158 @property(readonly) double preferredSampleRate; | |
159 @property(readonly) NSInteger inputNumberOfChannels; | |
160 @property(readonly) NSInteger outputNumberOfChannels; | |
161 @property(readonly) float outputVolume; | |
162 @property(readonly) NSTimeInterval inputLatency; | |
163 @property(readonly) NSTimeInterval outputLatency; | |
164 @property(readonly) NSTimeInterval IOBufferDuration; | |
165 @property(readonly) NSTimeInterval preferredIOBufferDuration; | |
166 | |
167 /** Default constructor. */ | |
168 + (instancetype)sharedInstance; | |
169 - (instancetype)init NS_UNAVAILABLE; | |
170 | |
171 /** Adds a delegate, which is held weakly. */ | |
172 - (void)addDelegate:(id<RTCAudioSessionDelegate>)delegate; | |
173 /** Removes an added delegate. */ | |
174 - (void)removeDelegate:(id<RTCAudioSessionDelegate>)delegate; | |
175 | |
176 /** Request exclusive access to the audio session for configuration. This call | |
177 * will block if the lock is held by another object. | |
178 */ | |
179 - (void)lockForConfiguration; | |
180 /** Relinquishes exclusive access to the audio session. */ | |
181 - (void)unlockForConfiguration; | |
182 | |
183 /** If |active|, activates the audio session if it isn't already active. | |
184 * Successful calls must be balanced with a setActive:NO when activation is no | |
185 * longer required. If not |active|, deactivates the audio session if one is | |
186 * active and this is the last balanced call. When deactivating, the | |
187 * AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation option is passed to | |
188 * AVAudioSession. | |
189 */ | |
190 - (BOOL)setActive:(BOOL)active | |
191 error:(NSError **)outError; | |
192 | |
193 // The following methods are proxies for the associated methods on | |
194 // AVAudioSession. |lockForConfiguration| must be called before using them | |
195 // otherwise they will fail with kRTCAudioSessionErrorLockRequired. | |
196 | |
197 - (BOOL)setCategory:(NSString *)category | |
198 withOptions:(AVAudioSessionCategoryOptions)options | |
199 error:(NSError **)outError; | |
200 - (BOOL)setMode:(NSString *)mode error:(NSError **)outError; | |
201 - (BOOL)setInputGain:(float)gain error:(NSError **)outError; | |
202 - (BOOL)setPreferredSampleRate:(double)sampleRate error:(NSError **)outError; | |
203 - (BOOL)setPreferredIOBufferDuration:(NSTimeInterval)duration | |
204 error:(NSError **)outError; | |
205 - (BOOL)setPreferredInputNumberOfChannels:(NSInteger)count | |
206 error:(NSError **)outError; | |
207 - (BOOL)setPreferredOutputNumberOfChannels:(NSInteger)count | |
208 error:(NSError **)outError; | |
209 - (BOOL)overrideOutputAudioPort:(AVAudioSessionPortOverride)portOverride | |
210 error:(NSError **)outError; | |
211 - (BOOL)setPreferredInput:(AVAudioSessionPortDescription *)inPort | |
212 error:(NSError **)outError; | |
213 - (BOOL)setInputDataSource:(AVAudioSessionDataSourceDescription *)dataSource | |
214 error:(NSError **)outError; | |
215 - (BOOL)setOutputDataSource:(AVAudioSessionDataSourceDescription *)dataSource | |
216 error:(NSError **)outError; | |
217 @end | |
218 | |
219 @interface RTCAudioSession (Configuration) | |
220 | |
221 /** Applies the configuration to the current session. Attempts to set all | |
222 * properties even if previous ones fail. Only the last error will be | |
223 * returned. | |
224 * |lockForConfiguration| must be called first. | |
225 */ | |
226 - (BOOL)setConfiguration:(RTCAudioSessionConfiguration *)configuration | |
227 error:(NSError **)outError; | |
228 | |
229 /** Convenience method that calls both setConfiguration and setActive. | |
230 * |lockForConfiguration| must be called first. | |
231 */ | |
232 - (BOOL)setConfiguration:(RTCAudioSessionConfiguration *)configuration | |
233 active:(BOOL)active | |
234 error:(NSError **)outError; | |
235 | |
236 @end | |
237 | |
238 NS_ASSUME_NONNULL_END | |
OLD | NEW |