我正在为我的应用程序使用AUGraph并且在停止Graph时遇到一些麻烦。特别是,当我到达音频文件的末尾时,我想在主线程上通知一个调用AUGraphStop的方法。
我在这个帖子中看到了与IOUnits类似的问题,但没有解决方案:
iOS - AudioOutputUnitStop results in app freeze and warning
通过UI方法调用AUGraphStop时,我可以立即停止AUGraph。但是,当我从渲染回调中调用AUGraphStop时,应用程序会挂起一会儿并阻止用户交互。它还向控制台发出一些警告消息。
我的代码:
回调函数:
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;
}
通知方法:
-(void) notifyAudioFinished {
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: AUDIO_FINISHED], @"code",nil];
[self performSelectorOnMainThread:@selector(stopEverything) withObject:nil waitUntilDone:YES];
}
stopEverything
是一个调用AUGraphStop的类方法。
控制台中的警告/错误消息如下:
WARNING: [0x3c5d718c] 1225: AURemoteIO::Stop: error 0x10004003 calling TerminateOwnIOThread
ERROR: [0x3830000] >aurioc> 1455: AURemoteIO@0x18077a20: IOThread exiting with error 0x10004002
我的想法是使用performSelectorOnMainThread来实际停止图形,因为当我使用在主线程上运行的应用UI时,没有挂起来阻止它。但是,我认为问题可能与从render回调中启动此方法有关。
任何有关此更好做法的想法或建议都将受到赞赏。
答案 0 :(得分:0)
所以我似乎已经解决了这个问题,但对我来说并不完全清楚。
在我管理阅读音频文件的班级中,我发布了一个通知给我的班级,当一个样本用完时管理音频播放:
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationEndOfAudioFile
object:self userInfo:nil];
在我的播放课程中,我会像这样处理通知:
-(void) endOfAudioFileNotification: (NSNotification *) notification{
[self stopEverything];
}
stopEverything
方法调用AUGraphStop
而没有挂起。最初,我尝试使用stopEverything
使用performSelectorOnMainThread
进行调用,应用程序继续挂起并吐出控制台警告。
所以虽然,我不完全确定为什么,通过通知在Render回调之外停止图表似乎解决了我的问题。如果有人愿意提供一些澄清,那就太棒了。