Question

I'm working with an AUGraph for my application and having some trouble stopping the Graph. In particular, when I reach the end of the audio file, I would like to notify a method on the main thread that calls AUGraphStop.

I've seen a similar problem with IOUnits in this thread, but no solution:

iOS - AudioOutputUnitStop results in app freeze and warning

When calling AUGraphStop via UI methods, I have no problem stopping the AUGraph immediately. However, when I call AUGraphStop from the render callback, the app hangs for a few moments and blocks user interaction. It also spits out a few warning messages to the console.

My code:

callback function:

static OSStatus playbackCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
                                 const AudioTimeStamp *inTimeStamp,
                                 UInt32 inBusNumber,
                                 UInt32 inNumberFrames,
                                 AudioBufferList *ioData)
{
//working audio playback code
//test for end of file
if(actualFramesRead == 0){
   currentMgr.endOfFile = YES; //currentMgr is reference to class managing AUGraph
   [currentMgr notifyAudioFinished]; //this method calls a main thread
    }
return noErr;
}

Notification method:

-(void) notifyAudioFinished {
    NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:     AUDIO_FINISHED], @"code",nil];
    [self performSelectorOnMainThread:@selector(stopEverything) withObject:nil waitUntilDone:YES];
}

And stopEverything is a class method that calls AUGraphStop.

The warning/error messages in the console are as follows:

WARNING:   [0x3c5d718c] 1225: AURemoteIO::Stop: error 0x10004003 calling TerminateOwnIOThread
ERROR:     [0x3830000] >aurioc> 1455: AURemoteIO@0x18077a20: IOThread exiting with error 0x10004002

My thinking here was to use performSelectorOnMainThread to actually stop the graph, since there is no hang up when I use the app UI, which runs on the main thread, to stop it. However, I think the problem might be related to launching this method from the render callback.

Any ideas, or suggestions on better practices for this would be appreciated.

Was it helpful?

Solution

So I appeared to have solved the problem, though it isn't totally clear to me.

In my class that manages reading the audio file, I have it post a notification to my class that manages the audio playback when it runs out of samples:

[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationEndOfAudioFile
                                                    object:self userInfo:nil];

In my playback class, I handle the notification like this:

-(void) endOfAudioFileNotification: (NSNotification *) notification{
    [self stopEverything];
}

The stopEverything method calls AUGraphStop with no hanging. Initially, I tried this with stopEverything called using performSelectorOnMainThread and the app continued to hang and spit out those console warnings.

So although, I'm not totally sure why, stopping the Graph outside of the Render callback with a notification seems to solve my issue. If anyone would like to provide some clarification, that would be great.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top