iOS: Initial work on interruption detection.

This commit is contained in:
David Reid
2021-12-29 13:56:55 +10:00
parent d077e92f5c
commit afc0fc107b
+42 -36
View File
@@ -5781,19 +5781,19 @@ typedef struct
{ {
struct struct
{ {
int __unused; int _unused;
} started; } started;
struct struct
{ {
int __unused; int _unused;
} stopped; } stopped;
struct struct
{ {
int __unused; int _unused;
} rerouted; } rerouted;
struct struct
{ {
int __unused; int _unused;
} interruption; } interruption;
} data; } data;
} ma_device_notification; } ma_device_notification;
@@ -6906,7 +6906,7 @@ struct ma_device
ma_bool32 isDefaultCaptureDevice; ma_bool32 isDefaultCaptureDevice;
ma_bool32 isSwitchingPlaybackDevice; /* <-- Set to true when the default device has changed and miniaudio is in the process of switching. */ ma_bool32 isSwitchingPlaybackDevice; /* <-- Set to true when the default device has changed and miniaudio is in the process of switching. */
ma_bool32 isSwitchingCaptureDevice; /* <-- Set to true when the default device has changed and miniaudio is in the process of switching. */ ma_bool32 isSwitchingCaptureDevice; /* <-- Set to true when the default device has changed and miniaudio is in the process of switching. */
void* pRouteChangeHandler; /* Only used on mobile platforms. Obj-C object for handling route changes. */ void* pNotificationHandler; /* Only used on mobile platforms. Obj-C object for handling route changes. */
} coreaudio; } coreaudio;
#endif #endif
#ifdef MA_SUPPORT_SNDIO #ifdef MA_SUPPORT_SNDIO
@@ -30922,7 +30922,7 @@ static ma_result ma_device_realloc_AudioBufferList__coreaudio(ma_device* pDevice
AudioBufferList* pNewAudioBufferList; AudioBufferList* pNewAudioBufferList;
pNewAudioBufferList = ma_allocate_AudioBufferList__coreaudio(sizeInFrames, format, channels, layout, &pDevice->pContext->allocationCallbacks); pNewAudioBufferList = ma_allocate_AudioBufferList__coreaudio(sizeInFrames, format, channels, layout, &pDevice->pContext->allocationCallbacks);
if (pNewAudioBufferList != NULL) { if (pNewAudioBufferList == NULL) {
return MA_OUT_OF_MEMORY; return MA_OUT_OF_MEMORY;
} }
@@ -31052,6 +31052,9 @@ static OSStatus ma_on_input__coreaudio(void* pUserData, AudioUnitRenderActionFla
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "Failed to allocate AudioBufferList for capture."); ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_DEBUG, "Failed to allocate AudioBufferList for capture.");
return noErr; return noErr;
} }
pRenderedBufferList = (AudioBufferList*)pDevice->coreaudio.pAudioBufferList;
MA_ASSERT(pRenderedBufferList);
/* /*
When you call AudioUnitRender(), Core Audio tries to be helpful by setting the mDataByteSize to the number of bytes When you call AudioUnitRender(), Core Audio tries to be helpful by setting the mDataByteSize to the number of bytes
@@ -31424,19 +31427,23 @@ static ma_result ma_device__untrack__coreaudio(ma_device* pDevice)
#endif #endif
#if defined(MA_APPLE_MOBILE) #if defined(MA_APPLE_MOBILE)
@interface ma_router_change_handler:NSObject { @interface ma_ios_notification_handler:NSObject {
ma_device* m_pDevice; ma_device* m_pDevice;
} }
@end @end
@implementation ma_router_change_handler @implementation ma_ios_notification_handler
-(id)init:(ma_device*)pDevice -(id)init:(ma_device*)pDevice
{ {
self = [super init]; self = [super init];
m_pDevice = pDevice; m_pDevice = pDevice;
/* For route changes. */
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handle_route_change:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handle_route_change:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];
/* For interruptions. */
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handle_interruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
return self; return self;
} }
@@ -31448,6 +31455,26 @@ static ma_result ma_device__untrack__coreaudio(ma_device* pDevice)
-(void)remove_handler -(void)remove_handler
{ {
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVAudioSessionRouteChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:AVAudioSessionRouteChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVAudioSessionInterruptionNotification object:nil];
}
-(void)handle_interruption:(NSNotification*)pNotification
{
NSInteger type = [[[pNotification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey] integerValue];
switch (type)
{
case AVAudioSessionInterruptionTypeBegan:
{
ma_log_postf(ma_device_get_log(m_pDevice), MA_LOG_LEVEL_DEBUG, "[Core Audio] Interruption: AVAudioSessionInterruptionTypeBegan\n");
ma_device__on_notification_interruption_began(m_pDevice);
} break;
case AVAudioSessionInterruptionTypeEnded:
{
ma_log_postf(ma_device_get_log(m_pDevice), MA_LOG_LEVEL_DEBUG, "[Core Audio] Interruption: AVAudioSessionInterruptionTypeEnded\n");
ma_device__on_notification_interruption_ended(m_pDevice);
} break;
}
} }
-(void)handle_route_change:(NSNotification*)pNotification -(void)handle_route_change:(NSNotification*)pNotification
@@ -31495,30 +31522,9 @@ static ma_result ma_device__untrack__coreaudio(ma_device* pDevice)
} }
ma_log_postf(ma_device_get_log(m_pDevice), MA_LOG_LEVEL_DEBUG, "[Core Audio] Changing Route. inputNumberChannels=%d; outputNumberOfChannels=%d\n", (int)pSession.inputNumberOfChannels, (int)pSession.outputNumberOfChannels); ma_log_postf(ma_device_get_log(m_pDevice), MA_LOG_LEVEL_DEBUG, "[Core Audio] Changing Route. inputNumberChannels=%d; outputNumberOfChannels=%d\n", (int)pSession.inputNumberOfChannels, (int)pSession.outputNumberOfChannels);
/* Temporarily disabling this section of code because it appears to be causing errors. */ /* Let the application know about the route change. */
#if 0 ma_device__on_notification_rerouted(m_pDevice);
ma_uint32 previousState = ma_device_get_state(m_pDevice);
if (previousState == ma_device_state_started) {
ma_device_stop(m_pDevice);
}
if (m_pDevice->type == ma_device_type_capture || m_pDevice->type == ma_device_type_duplex) {
m_pDevice->capture.internalChannels = (ma_uint32)pSession.inputNumberOfChannels;
m_pDevice->capture.internalSampleRate = (ma_uint32)pSession.sampleRate;
ma_device__post_init_setup(m_pDevice, ma_device_type_capture);
}
if (m_pDevice->type == ma_device_type_playback || m_pDevice->type == ma_device_type_duplex) {
m_pDevice->playback.internalChannels = (ma_uint32)pSession.outputNumberOfChannels;
m_pDevice->playback.internalSampleRate = (ma_uint32)pSession.sampleRate;
ma_device__post_init_setup(m_pDevice, ma_device_type_playback);
}
if (previousState == ma_device_state_started) {
ma_device_start(m_pDevice);
}
#endif
} }
@end @end
#endif #endif
@@ -31536,9 +31542,9 @@ static ma_result ma_device_uninit__coreaudio(ma_device* pDevice)
ma_device__untrack__coreaudio(pDevice); ma_device__untrack__coreaudio(pDevice);
#endif #endif
#if defined(MA_APPLE_MOBILE) #if defined(MA_APPLE_MOBILE)
if (pDevice->coreaudio.pRouteChangeHandler != NULL) { if (pDevice->coreaudio.pNotificationHandler != NULL) {
ma_router_change_handler* pRouteChangeHandler = (MA_BRIDGE_TRANSFER ma_router_change_handler*)pDevice->coreaudio.pRouteChangeHandler; ma_ios_notification_handler* pNotificationHandler = (MA_BRIDGE_TRANSFER ma_ios_notification_handler*)pDevice->coreaudio.pNotificationHandler;
[pRouteChangeHandler remove_handler]; [pNotificationHandler remove_handler];
} }
#endif #endif
@@ -32212,7 +32218,7 @@ static ma_result ma_device_init__coreaudio(ma_device* pDevice, const ma_device_c
differently on non-Desktop Apple platforms. differently on non-Desktop Apple platforms.
*/ */
#if defined(MA_APPLE_MOBILE) #if defined(MA_APPLE_MOBILE)
pDevice->coreaudio.pRouteChangeHandler = (MA_BRIDGE_RETAINED void*)[[ma_router_change_handler alloc] init:pDevice]; pDevice->coreaudio.pNotificationHandler = (MA_BRIDGE_RETAINED void*)[[ma_ios_notification_handler alloc] init:pDevice];
#endif #endif
return MA_SUCCESS; return MA_SUCCESS;