Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AUGraph stops running after phone call interrupt in iOS

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!

like image 824
James Andrews Avatar asked Apr 05 '13 23:04

James Andrews


1 Answers

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!

like image 116
Todd Avatar answered Sep 28 '22 08:09

Todd