blob: e797a05b4b86410af99585368e0fbafa42e0e06f [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;
17extern NSInteger const kRTCAudioSessionErrorLockRequired;
18
19@class RTCAudioSession;
20
21// Surfaces AVAudioSession events. WebRTC will listen directly for notifications
22// from AVAudioSession and handle them before calling these delegate methods,
23// at which point applications can perform additional processing if required.
24@protocol RTCAudioSessionDelegate <NSObject>
25
26/** Called when AVAudioSession starts an interruption event. */
27- (void)audioSessionDidBeginInterruption:(RTCAudioSession *)session;
28
29/** Called when AVAudioSession ends an interruption event. */
30- (void)audioSessionDidEndInterruption:(RTCAudioSession *)session
31 shouldResumeSession:(BOOL)shouldResumeSession;
32
33/** Called when AVAudioSession changes the route. */
34- (void)audioSessionDidChangeRoute:(RTCAudioSession *)session
35 reason:(AVAudioSessionRouteChangeReason)reason
36 previousRoute:(AVAudioSessionRouteDescription *)previousRoute;
37
38/** Called when AVAudioSession media server terminates. */
39- (void)audioSessionMediaServicesWereLost:(RTCAudioSession *)session;
40
41/** Called when AVAudioSession media server restarts. */
42- (void)audioSessionMediaServicesWereReset:(RTCAudioSession *)session;
43
44// TODO(tkchin): Maybe handle SilenceSecondaryAudioHintNotification.
45
46@end
47
48/** Proxy class for AVAudioSession that adds a locking mechanism similar to
49 * AVCaptureDevice. This is used to that interleaving configurations between
50 * WebRTC and the application layer are avoided. Only setter methods are
51 * currently proxied. Getters can be accessed directly off AVAudioSession.
52 *
53 * RTCAudioSession also coordinates activation so that the audio session is
54 * activated only once. See |setActive:error:|.
55 */
56@interface RTCAudioSession : NSObject
57
58/** Convenience property to access the AVAudioSession singleton. Callers should
59 * not call setters on AVAudioSession directly, but other method invocations
60 * are fine.
61 */
62@property(nonatomic, readonly) AVAudioSession *session;
63
64/** Our best guess at whether the session is active based on results of calls to
65 * AVAudioSession.
66 */
67@property(nonatomic, readonly) BOOL isActive;
68/** Whether RTCAudioSession is currently locked for configuration. */
69@property(nonatomic, readonly) BOOL isLocked;
70
71// Proxy properties.
72@property(readonly) NSString *category;
73@property(readonly) AVAudioSessionCategoryOptions categoryOptions;
74@property(readonly) NSString *mode;
75@property(readonly) BOOL secondaryAudioShouldBeSilencedHint;
76@property(readonly) AVAudioSessionRouteDescription *currentRoute;
77@property(readonly) NSInteger maximumInputNumberOfChannels;
78@property(readonly) NSInteger maximumOutputNumberOfChannels;
79@property(readonly) float inputGain;
80@property(readonly) BOOL inputGainSettable;
81@property(readonly) BOOL inputAvailable;
82@property(readonly, nullable)
83 NSArray<AVAudioSessionDataSourceDescription *> * inputDataSources;
84@property(readonly, nullable)
85 AVAudioSessionDataSourceDescription *inputDataSource;
86@property(readonly, nullable)
87 NSArray<AVAudioSessionDataSourceDescription *> * outputDataSources;
88@property(readonly, nullable)
89 AVAudioSessionDataSourceDescription *outputDataSource;
90@property(readonly) double sampleRate;
91@property(readonly) NSInteger inputNumberOfChannels;
92@property(readonly) NSInteger outputNumberOfChannels;
93@property(readonly) float outputVolume;
94@property(readonly) NSTimeInterval inputLatency;
95@property(readonly) NSTimeInterval outputLatency;
96@property(readonly) NSTimeInterval IOBufferDuration;
97
98/** Default constructor. Do not call init. */
99+ (instancetype)sharedInstance;
100
101/** Adds a delegate, which is held weakly. Even though it's held weakly, callers
102 * should still call |removeDelegate| when it's no longer required to ensure
103 * proper dealloc. This is due to internal use of an NSHashTable.
104 */
105- (void)addDelegate:(id<RTCAudioSessionDelegate>)delegate;
106/** Removes an added delegate. */
107- (void)removeDelegate:(id<RTCAudioSessionDelegate>)delegate;
108
109/** Request exclusive access to the audio session for configuration. This call
110 * will block if the lock is held by another object.
111 */
112- (void)lockForConfiguration;
113/** Relinquishes exclusive access to the audio session. */
114- (void)unlockForConfiguration;
115
116/** If |active|, activates the audio session if it isn't already active.
117 * Successful calls must be balanced with a setActive:NO when activation is no
118 * longer required. If not |active|, deactivates the audio session if one is
119 * active and this is the last balanced call. When deactivating, the
120 * AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation option is passed to
121 * AVAudioSession.
122 */
123- (BOOL)setActive:(BOOL)active
124 error:(NSError **)outError;
125
126// The following methods are proxies for the associated methods on
127// AVAudioSession. |lockForConfiguration| must be called before using them
128// otherwise they will fail with kRTCAudioSessionErrorLockRequired.
129
130- (BOOL)setCategory:(NSString *)category
131 withOptions:(AVAudioSessionCategoryOptions)options
132 error:(NSError **)outError;
133- (BOOL)setMode:(NSString *)mode error:(NSError **)outError;
134- (BOOL)setInputGain:(float)gain error:(NSError **)outError;
135- (BOOL)setPreferredSampleRate:(double)sampleRate error:(NSError **)outError;
136- (BOOL)setPreferredIOBufferDuration:(NSTimeInterval)duration
137 error:(NSError **)outError;
138- (BOOL)setPreferredInputNumberOfChannels:(NSInteger)count
139 error:(NSError **)outError;
140- (BOOL)setPreferredOutputNumberOfChannels:(NSInteger)count
141 error:(NSError **)outError;
142- (BOOL)overrideOutputAudioPort:(AVAudioSessionPortOverride)portOverride
143 error:(NSError **)outError;
144- (BOOL)setPreferredInput:(AVAudioSessionPortDescription *)inPort
145 error:(NSError **)outError;
146- (BOOL)setInputDataSource:(AVAudioSessionDataSourceDescription *)dataSource
147 error:(NSError **)outError;
148- (BOOL)setOutputDataSource:(AVAudioSessionDataSourceDescription *)dataSource
149 error:(NSError **)outError;
150
151@end
152
153NS_ASSUME_NONNULL_END