I'm using an AUGraph and an AUSampler to convert MIDI signals to audio. The app runs fine normally but there's a problem if the app is interrupted i.e. by a phone call or a timer. After the interruption the AUGraph stops running and there isn't any sound. The only way to get sound again is to restart the app. I'm using the standard method to handle the interruption:
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(handleInterruption:)
name: AVAudioSessionInterruptionNotification
object: [AVAudioSession sharedInstance]];
When there's an interruption the handleInterruption method is called:
// If the system interrupts the audio session - kill the volume
-(void) handleInterruption: (NSNotification *) notification {
NSDictionary *interuptionDict = notification.userInfo;
NSInteger interuptionType = [[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey] intValue];
if (interuptionType == AVAudioSessionInterruptionTypeBegan) {
[self setAudioSessionActive: NO];
[self stopAUGraph];
}
else if (interuptionType == AVAudioSessionInterruptionTypeEnded) {
[self setAudioSessionActive: YES];
[self startAUGraph];
}
}
Here are the methods to start and stop the AUGraph
-(void) startAUGraph {
CheckError(AUGraphStart(_audioGraph), "Failed to start Audio Graph");
}
-(void) stopAUGraph {
Boolean isRunning = false;
// Check to see if the graph is running.
CheckError(AUGraphIsRunning(_audioGraph, &isRunning), "Error trying querying whether graph is running");
// If the graph is running, stop it.
if (isRunning) {
CheckError(AUGraphStop(_audioGraph), "Failed to stop Audio Graph");
}
}
Here is the setAudioSessionActive method:
-(void) setAudioSessionActive: (BOOL) active {
NSError *audioSessionError = nil;
BOOL success = [_audioSession setActive:active error:&audioSessionError];
if (!success) {
NSLog (@"Error activating audio session!");
}
}
I've put a break point in a render callback so I can confirm that the AUGraph isn't running. Has anyone experienced this problem before? Is there something else I have to do to get the AUGraph running again? Thanks in advance!
I've also been having terrible troubles with this bug. I think I've found a workaround:
Since the NSNotifications don't trigger when returning after the call interruption, then in my AppDelegate's -applicationWillEnterForeground:
method I check to see if there was an interruption that caused it to enter the background (I set a flag when the AVAudioSessionInterruptionNotification
is posted with AVAudioSessionInterruptionTypeBegan
as the interruption type key) and if so I call a method in the object controlling the AUGraph that runs the following:
Boolean isRun = FALSE;
AUGraphIsRunning(myAUGraph, &isRun);
if (isRun) {
NSLog(@"END INTERRUPTION BUT AUGRAPH IS RUNNING");
AUGraphStop(myAUGraph);// Kick start the AUGraph!
AUGraphStart(myAUGraph); //Restart immediately
Boolean isInit = FALSE;
AUGraphIsInitialized(processingGraph, &isInit);
if (!isInit) {
NSLog(@"augraph not initd'");
OSStatus result = AUGraphInitialize(processingGraph);
if (result != noErr) {
NSLog(@">>can't init graph");
}
}
}
else
{
NSLog(@"END INTERRUPTION BUT AUGRAPH IS NOT RUNNING");
}
The key seems to be stopping and then immediately restarting the AUGraph. So far, it operates correctly when a call comes in or when another app takes over the loudspeaker/mic I can pick up where I left off in my app.
The re-initialising of the AUGraph never seems to be executed nor is isRun
anything but TRUE
but I've left it in anyway. Hope that helps your situation, it took me days to crack this one and I'm hoping it continues to work instead of just being a coincidence! 4 hours and counting so far!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With