OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2017 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #import <AVFoundation/AVFoundation.h> | 11 #import "webrtc/sdk/objc/Framework/Headers/WebRTC/RTCAudioSession.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 /** Called when the AVAudioSession output volume value changes. */ | |
78 - (void)audioSession:(RTCAudioSession *)audioSession | |
79 didChangeOutputVolume:(float)outputVolume; | |
80 | |
81 @end | |
82 | |
83 /** This is a protocol used to inform RTCAudioSession when the audio session | |
84 * activation state has changed outside of RTCAudioSession. The current known u
se | |
85 * case of this is when CallKit activates the audio session for the application | |
86 */ | |
87 RTC_EXPORT | |
88 @protocol RTCAudioSessionActivationDelegate <NSObject> | |
89 | |
90 /** Called when the audio session is activated outside of the app by iOS. */ | |
91 - (void)audioSessionDidActivate:(AVAudioSession *)session; | |
92 | |
93 /** Called when the audio session is deactivated outside of the app by iOS. */ | |
94 - (void)audioSessionDidDeactivate:(AVAudioSession *)session; | |
95 | |
96 @end | |
97 | |
98 /** Proxy class for AVAudioSession that adds a locking mechanism similar to | |
99 * AVCaptureDevice. This is used to that interleaving configurations between | |
100 * WebRTC and the application layer are avoided. | |
101 * | |
102 * RTCAudioSession also coordinates activation so that the audio session is | |
103 * activated only once. See |setActive:error:|. | |
104 */ | |
105 RTC_EXPORT | |
106 @interface RTCAudioSession : NSObject <RTCAudioSessionActivationDelegate> | |
107 | |
108 /** Convenience property to access the AVAudioSession singleton. Callers should | |
109 * not call setters on AVAudioSession directly, but other method invocations | |
110 * are fine. | |
111 */ | |
112 @property(nonatomic, readonly) AVAudioSession *session; | |
113 | |
114 /** Our best guess at whether the session is active based on results of calls to | |
115 * AVAudioSession. | |
116 */ | |
117 @property(nonatomic, readonly) BOOL isActive; | |
118 /** Whether RTCAudioSession is currently locked for configuration. */ | |
119 @property(nonatomic, readonly) BOOL isLocked; | |
120 | |
121 /** If YES, WebRTC will not initialize the audio unit automatically when an | |
122 * audio track is ready for playout or recording. Instead, applications should | |
123 * call setIsAudioEnabled. If NO, WebRTC will initialize the audio unit | |
124 * as soon as an audio track is ready for playout or recording. | |
125 */ | |
126 @property(nonatomic, assign) BOOL useManualAudio; | |
127 | |
128 /** This property is only effective if useManualAudio is YES. | |
129 * Represents permission for WebRTC to initialize the VoIP audio unit. | |
130 * When set to NO, if the VoIP audio unit used by WebRTC is active, it will be | |
131 * stopped and uninitialized. This will stop incoming and outgoing audio. | |
132 * When set to YES, WebRTC will initialize and start the audio unit when it is | |
133 * needed (e.g. due to establishing an audio connection). | |
134 * This property was introduced to work around an issue where if an AVPlayer is | |
135 * playing audio while the VoIP audio unit is initialized, its audio would be | |
136 * either cut off completely or played at a reduced volume. By preventing | |
137 * the audio unit from being initialized until after the audio has completed, | |
138 * we are able to prevent the abrupt cutoff. | |
139 */ | |
140 @property(nonatomic, assign) BOOL isAudioEnabled; | |
141 | |
142 // Proxy properties. | |
143 @property(readonly) NSString *category; | |
144 @property(readonly) AVAudioSessionCategoryOptions categoryOptions; | |
145 @property(readonly) NSString *mode; | |
146 @property(readonly) BOOL secondaryAudioShouldBeSilencedHint; | |
147 @property(readonly) AVAudioSessionRouteDescription *currentRoute; | |
148 @property(readonly) NSInteger maximumInputNumberOfChannels; | |
149 @property(readonly) NSInteger maximumOutputNumberOfChannels; | |
150 @property(readonly) float inputGain; | |
151 @property(readonly) BOOL inputGainSettable; | |
152 @property(readonly) BOOL inputAvailable; | |
153 @property(readonly, nullable) | |
154 NSArray<AVAudioSessionDataSourceDescription *> * inputDataSources; | |
155 @property(readonly, nullable) | |
156 AVAudioSessionDataSourceDescription *inputDataSource; | |
157 @property(readonly, nullable) | |
158 NSArray<AVAudioSessionDataSourceDescription *> * outputDataSources; | |
159 @property(readonly, nullable) | |
160 AVAudioSessionDataSourceDescription *outputDataSource; | |
161 @property(readonly) double sampleRate; | |
162 @property(readonly) double preferredSampleRate; | |
163 @property(readonly) NSInteger inputNumberOfChannels; | |
164 @property(readonly) NSInteger outputNumberOfChannels; | |
165 @property(readonly) float outputVolume; | |
166 @property(readonly) NSTimeInterval inputLatency; | |
167 @property(readonly) NSTimeInterval outputLatency; | |
168 @property(readonly) NSTimeInterval IOBufferDuration; | |
169 @property(readonly) NSTimeInterval preferredIOBufferDuration; | |
170 | |
171 /** Default constructor. */ | |
172 + (instancetype)sharedInstance; | |
173 - (instancetype)init NS_UNAVAILABLE; | |
174 | |
175 /** Adds a delegate, which is held weakly. */ | |
176 - (void)addDelegate:(id<RTCAudioSessionDelegate>)delegate; | |
177 /** Removes an added delegate. */ | |
178 - (void)removeDelegate:(id<RTCAudioSessionDelegate>)delegate; | |
179 | |
180 /** Request exclusive access to the audio session for configuration. This call | |
181 * will block if the lock is held by another object. | |
182 */ | |
183 - (void)lockForConfiguration; | |
184 /** Relinquishes exclusive access to the audio session. */ | |
185 - (void)unlockForConfiguration; | |
186 | |
187 /** If |active|, activates the audio session if it isn't already active. | |
188 * Successful calls must be balanced with a setActive:NO when activation is no | |
189 * longer required. If not |active|, deactivates the audio session if one is | |
190 * active and this is the last balanced call. When deactivating, the | |
191 * AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation option is passed to | |
192 * AVAudioSession. | |
193 */ | |
194 - (BOOL)setActive:(BOOL)active | |
195 error:(NSError **)outError; | |
196 | |
197 // The following methods are proxies for the associated methods on | |
198 // AVAudioSession. |lockForConfiguration| must be called before using them | |
199 // otherwise they will fail with kRTCAudioSessionErrorLockRequired. | |
200 | |
201 - (BOOL)setCategory:(NSString *)category | |
202 withOptions:(AVAudioSessionCategoryOptions)options | |
203 error:(NSError **)outError; | |
204 - (BOOL)setMode:(NSString *)mode error:(NSError **)outError; | |
205 - (BOOL)setInputGain:(float)gain error:(NSError **)outError; | |
206 - (BOOL)setPreferredSampleRate:(double)sampleRate error:(NSError **)outError; | |
207 - (BOOL)setPreferredIOBufferDuration:(NSTimeInterval)duration | |
208 error:(NSError **)outError; | |
209 - (BOOL)setPreferredInputNumberOfChannels:(NSInteger)count | |
210 error:(NSError **)outError; | |
211 - (BOOL)setPreferredOutputNumberOfChannels:(NSInteger)count | |
212 error:(NSError **)outError; | |
213 - (BOOL)overrideOutputAudioPort:(AVAudioSessionPortOverride)portOverride | |
214 error:(NSError **)outError; | |
215 - (BOOL)setPreferredInput:(AVAudioSessionPortDescription *)inPort | |
216 error:(NSError **)outError; | |
217 - (BOOL)setInputDataSource:(AVAudioSessionDataSourceDescription *)dataSource | |
218 error:(NSError **)outError; | |
219 - (BOOL)setOutputDataSource:(AVAudioSessionDataSourceDescription *)dataSource | |
220 error:(NSError **)outError; | |
221 @end | |
222 | |
223 @interface RTCAudioSession (Configuration) | |
224 | |
225 /** Applies the configuration to the current session. Attempts to set all | |
226 * properties even if previous ones fail. Only the last error will be | |
227 * returned. | |
228 * |lockForConfiguration| must be called first. | |
229 */ | |
230 - (BOOL)setConfiguration:(RTCAudioSessionConfiguration *)configuration | |
231 error:(NSError **)outError; | |
232 | |
233 /** Convenience method that calls both setConfiguration and setActive. | |
234 * |lockForConfiguration| must be called first. | |
235 */ | |
236 - (BOOL)setConfiguration:(RTCAudioSessionConfiguration *)configuration | |
237 active:(BOOL)active | |
238 error:(NSError **)outError; | |
239 | |
240 @end | |
241 | |
242 NS_ASSUME_NONNULL_END | |
OLD | NEW |