Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qcoreaudiosessionmanager.mm
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#import <AVFoundation/AVAudioSession.h>
6#import <Foundation/Foundation.h>
7
9
10@interface CoreAudioSessionObserver : NSObject
11{
13 AVAudioSession *m_audioSession;
14}
15
16@property (readonly, getter=sessionManager) CoreAudioSessionManager *m_sessionManager;
17@property (readonly, getter=audioSession) AVAudioSession *m_audioSession;
18
19-(CoreAudioSessionObserver *)initWithAudioSessionManager:(CoreAudioSessionManager *)sessionManager;
20
21-(BOOL)activateAudio;
22-(BOOL)deactivateAudio;
23
24//Notification handlers
25-(void)audioSessionInterruption:(NSNotification *)notification;
26-(void)audioSessionRouteChange:(NSNotification *)notification;
27-(void)audioSessionMediaServicesWereReset:(NSNotification *)notification;
28
29@end //interface CoreAudioSessionObserver
30
31@implementation CoreAudioSessionObserver
32
34
35-(CoreAudioSessionObserver *)initWithAudioSessionManager:(CoreAudioSessionManager *)sessionManager
36{
37 if (!(self = [super init]))
38 return nil;
39
40 self->m_sessionManager = sessionManager;
41 self->m_audioSession = [AVAudioSession sharedInstance];
42
43 //Set up observers
44 [[NSNotificationCenter defaultCenter] addObserver:self
45 selector:@selector(audioSessionInterruption:)
46 name:AVAudioSessionInterruptionNotification
47 object:self->m_audioSession];
48 [[NSNotificationCenter defaultCenter] addObserver:self
49 selector:@selector(audioSessionMediaServicesWereReset:)
50 name:AVAudioSessionMediaServicesWereResetNotification
51 object:self->m_audioSession];
52 [[NSNotificationCenter defaultCenter] addObserver:self
53 selector:@selector(audioSessionRouteChange:)
54 name:AVAudioSessionRouteChangeNotification
55 object:self->m_audioSession];
56
57 return self;
58}
59
60-(void)dealloc
61{
62#ifdef QT_DEBUG_COREAUDIO
64#endif
65
66 [[NSNotificationCenter defaultCenter] removeObserver:self
67 name:AVAudioSessionInterruptionNotification
68 object:self->m_audioSession];
69 [[NSNotificationCenter defaultCenter] removeObserver:self
70 name:AVAudioSessionMediaServicesWereResetNotification
71 object:self->m_audioSession];
72 [[NSNotificationCenter defaultCenter] removeObserver:self
73 name:AVAudioSessionRouteChangeNotification
74 object:self->m_audioSession];
75
76 [super dealloc];
77}
78
79-(BOOL)activateAudio
80{
81 NSError *error = nil;
82 BOOL success = [self->m_audioSession setActive:YES error:&error];
83 if (![self->m_audioSession setActive:YES error:&error]) {
84#ifdef QT_DEBUG_COREAUDIO
85 qDebug("audio session activation failed: %s", [[error localizedDescription] UTF8String]);
86 } else {
87 qDebug("audio session activated");
88#endif
89 }
90
91 return success;
92}
93
94-(BOOL)deactivateAudio
95{
96 NSError *error = nil;
97 BOOL success = [m_audioSession setActive:NO error:&error];
98#ifdef QT_DEBUG_COREAUDIO
99 if (!success) {
100 qDebug("%s", [[error localizedDescription] UTF8String]);
101 }
102#endif
103 return success;
104}
105
106-(void)audioSessionInterruption:(NSNotification *)notification
107{
108 NSNumber *type = [[notification userInfo] valueForKey:AVAudioSessionInterruptionTypeKey];
109 if ([type intValue] == AVAudioSessionInterruptionTypeBegan) {
110#ifdef QT_DEBUG_COREAUDIO
111 qDebug("audioSession Interuption begain");
112#endif
113 } else if ([type intValue] == AVAudioSessionInterruptionTypeEnded) {
114#ifdef QT_DEBUG_COREAUDIO
115 qDebug("audioSession Interuption ended");
116#endif
117 NSNumber *option = [[notification userInfo] valueForKey:AVAudioSessionInterruptionOptionKey];
118 if ([option intValue] == AVAudioSessionInterruptionOptionShouldResume) {
119#ifdef QT_DEBUG_COREAUDIO
120 qDebug("audioSession is active and immediately ready to be used.");
121#endif
122 } else {
123 [self activateAudio];
124 }
125 }
126}
127
128-(void)audioSessionMediaServicesWereReset:(NSNotification *)notification
129{
130 Q_UNUSED(notification);
131#ifdef QT_DEBUG_COREAUDIO
132 qDebug("audioSession Media Services were reset");
133#endif
134 //Reactivate audio when this occurs
135 [self activateAudio];
136}
137
138-(void)audioSessionRouteChange:(NSNotification *)notification
139{
140 NSNumber *reason = [[notification userInfo] valueForKey:AVAudioSessionRouteChangeReasonKey];
141 NSUInteger reasonEnum = [reason intValue];
142
143 if (reasonEnum == AVAudioSessionRouteChangeReasonUnknown) {
144#ifdef QT_DEBUG_COREAUDIO
145 qDebug("audioSession route changed. reason: unknown");
146#endif
147 } else if (reasonEnum == AVAudioSessionRouteChangeReasonNewDeviceAvailable) {
148#ifdef QT_DEBUG_COREAUDIO
149 qDebug("audioSession route changed. reason: new device available");
150#endif
151 } else if (reasonEnum == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
152#ifdef QT_DEBUG_COREAUDIO
153 qDebug("audioSession route changed. reason: old device unavailable");
154#endif
155 } else if (reasonEnum == AVAudioSessionRouteChangeReasonCategoryChange) {
156#ifdef QT_DEBUG_COREAUDIO
157 qDebug("audioSession route changed. reason: category changed");
158#endif
159 } else if (reasonEnum == AVAudioSessionRouteChangeReasonOverride) {
160#ifdef QT_DEBUG_COREAUDIO
161 qDebug("audioSession route changed. reason: override");
162#endif
163 } else if (reasonEnum == AVAudioSessionRouteChangeReasonWakeFromSleep) {
164#ifdef QT_DEBUG_COREAUDIO
165 qDebug("audioSession route changed. reason: woken from sleep");
166#endif
167 } else if (reasonEnum == AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory) {
168#ifdef QT_DEBUG_COREAUDIO
169 qDebug("audioSession route changed. reason: no suitable route for category");
170#endif
171 }
172
174}
175
176@end //implementation CoreAudioSessionObserver
177
178CoreAudioSessionManager::CoreAudioSessionManager() :
179 QObject(0)
180{
181 m_sessionObserver = [[CoreAudioSessionObserver alloc] initWithAudioSessionManager:this];
182}
183
184CoreAudioSessionManager::~CoreAudioSessionManager()
185{
186#ifdef QT_DEBUG_COREAUDIO
187 qDebug() << Q_FUNC_INFO;
188#endif
189 [m_sessionObserver release];
190}
191
192
198
200{
201 if (active) {
203 } else {
205 }
206}
207
209{
210 NSString *targetCategory = nil;
211
212 switch (category) {
214 targetCategory = AVAudioSessionCategoryAmbient;
215 break;
217 targetCategory = AVAudioSessionCategorySoloAmbient;
218 break;
220 targetCategory = AVAudioSessionCategoryPlayback;
221 break;
223 targetCategory = AVAudioSessionCategoryRecord;
224 break;
226 targetCategory = AVAudioSessionCategoryPlayAndRecord;
227 break;
229#ifndef Q_OS_TVOS
230 targetCategory = AVAudioSessionCategoryAudioProcessing;
231#endif
232 break;
234 targetCategory = AVAudioSessionCategoryMultiRoute;
235 break;
236 }
237
238 if (targetCategory == nil)
239 return false;
240
241 return [[m_sessionObserver audioSession] setCategory:targetCategory
242 withOptions:(AVAudioSessionCategoryOptions)options
243 error:nil];
244}
245
247{
248 NSString *targetMode = nil;
249 switch (mode) {
251 targetMode = AVAudioSessionModeDefault;
252 break;
254 targetMode = AVAudioSessionModeVoiceChat;
255 break;
257 targetMode = AVAudioSessionModeGameChat;
258 break;
260 targetMode = AVAudioSessionModeVideoRecording;
261 break;
263 targetMode = AVAudioSessionModeMeasurement;
264 break;
266 targetMode = AVAudioSessionModeMoviePlayback;
267 break;
268 }
269
270 if (targetMode == nil)
271 return false;
272
273 return [[m_sessionObserver audioSession] setMode:targetMode error:nil];
274
275}
276
278{
279 NSString *category = [[m_sessionObserver audioSession] category];
280 AudioSessionCategorys localCategory = Ambient;
281
282 if (category == AVAudioSessionCategoryAmbient) {
283 localCategory = Ambient;
284 } else if (category == AVAudioSessionCategorySoloAmbient) {
285 localCategory = SoloAmbient;
286 } else if (category == AVAudioSessionCategoryPlayback) {
287 localCategory = Playback;
288 } else if (category == AVAudioSessionCategoryRecord) {
289 localCategory = Record;
290 } else if (category == AVAudioSessionCategoryPlayAndRecord) {
291 localCategory = PlayAndRecord;
292#ifndef Q_OS_TVOS
293 } else if (category == AVAudioSessionCategoryAudioProcessing) {
294 localCategory = AudioProcessing;
295#endif
296 } else if (category == AVAudioSessionCategoryMultiRoute) {
297 localCategory = MultiRoute;
298 }
299
300 return localCategory;
301}
302
304{
305 NSString *mode = [[m_sessionObserver audioSession] mode];
306 AudioSessionModes localMode = Default;
307
308 if (mode == AVAudioSessionModeDefault) {
309 localMode = Default;
310 } else if (mode == AVAudioSessionModeVoiceChat) {
311 localMode = VoiceChat;
312 } else if (mode == AVAudioSessionModeGameChat) {
313 localMode = GameChat;
314 } else if (mode == AVAudioSessionModeVideoRecording) {
315 localMode = VideoRecording;
316 } else if (mode == AVAudioSessionModeMeasurement) {
317 localMode = Measurement;
318 } else if (mode == AVAudioSessionModeMoviePlayback) {
319 localMode = MoviePlayback;
320 }
321
322 return localMode;
323}
324
326{
327 //TODO: Add support for USB input devices
328 //Right now the default behavior on iOS is to have only one input route
329 //at a time.
330 QList<QByteArray> inputDevices;
331 inputDevices << "default";
332 return inputDevices;
333}
334
336{
337 //TODO: Add support for USB output devices
338 //Right now the default behavior on iOS is to have only one output route
339 //at a time.
340 QList<QByteArray> outputDevices;
341 outputDevices << "default";
342 return outputDevices;
343}
344
346{
347 return [[m_sessionObserver audioSession] IOBufferDuration];
348}
349
351{
352 return [[m_sessionObserver audioSession] preferredSampleRate];
353}
354
355#ifdef QT_DEBUG_COREAUDIO
357{
358 QDebug output = dbg.nospace();
359 switch (category) {
361 output << "AudioSessionCategoryAmbient";
362 break;
364 output << "AudioSessionCategorySoloAmbient";
365 break;
367 output << "AudioSessionCategoryPlayback";
368 break;
370 output << "AudioSessionCategoryRecord";
371 break;
373 output << "AudioSessionCategoryPlayAndRecord";
374 break;
376 output << "AudioSessionCategoryAudioProcessing";
377 break;
379 output << "AudioSessionCategoryMultiRoute";
380 break;
381 }
382 return output;
383}
384
386{
387 QDebug output = dbg.nospace();
388 switch (option) {
390 output << "AudioSessionCategoryOptionNone";
391 break;
393 output << "AudioSessionCategoryOptionMixWithOthers";
394 break;
396 output << "AudioSessionCategoryOptionDuckOthers";
397 break;
399 output << "AudioSessionCategoryOptionAllowBluetooth";
400 break;
402 output << "AudioSessionCategoryOptionDefaultToSpeaker";
403 break;
404 }
405 return output;
406}
407
409{
410 QDebug output = dbg.nospace();
411 switch (mode) {
413 output << "AudioSessionModeDefault";
414 break;
416 output << "AudioSessionModeVoiceChat";
417 break;
419 output << "AudioSessionModeGameChat";
420 break;
422 output << "AudioSessionModeVideoRecording";
423 break;
425 output << "AudioSessionModeMeasurement";
426 break;
428 output << "AudioSessionModeMoviePlayback";
429 break;
430 }
431 return output;
432}
433#endif
434
436
437#include "moc_qcoreaudiosessionmanager_p.cpp"
QList< QByteArray > outputDevices()
AudioSessionCategorys category()
bool setCategory(AudioSessionCategorys category, AudioSessionCategoryOptions options=None)
bool setMode(AudioSessionModes mode)
static CoreAudioSessionManager & instance()
\inmodule QtCore
\inmodule QtCore
Definition qobject.h:103
const QLoggingCategory & category()
[1]
CoreAudioSessionManager * m_sessionManager
Combined button and popup list for selecting options.
QString self
Definition language.cpp:58
unsigned long NSUInteger
#define Q_FUNC_INFO
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
DBusConnection const char DBusError * error
#define qDebug
[1]
Definition qlogging.h:164
GLenum mode
GLenum type
GLuint GLenum option
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
#define Q_UNUSED(x)
QT_BEGIN_NAMESPACE typedef uchar * output
QDataStream & operator<<(QDataStream &out, const MyClass &myObj)
[4]