好的,这是场景:我有一个使用针对iOS 4.3的ExtAudioFileWriteAsync的实时录制应用程序。我第一次使用应用程序进行录制时,效果非常好。如果我按停止,然后再次录制,超过一半的时间我将在录制开始时在AudioRingBuffer :: GetTimeBounds中获得EXC_BAD_ACCESS。
也就是说,在开始第二次录制时,ExtAudioFileWriteAsync在GetTimeBounds上失败。以下是录制开始时触发的一些代码,它会创建ExtAudioFile引用:
- (void) setActive:(NSString *) file
{
if (mExtAFRef) {
ExtAudioFileDispose(mExtAFRef);
mExtAFRef = nil;
NSLog(@"mExtAFRef Disposed.");
}
if (mOutputAudioFile)
{
ExtAudioFileDispose(mOutputAudioFile);
mOutputAudioFile = nil;
NSLog(@"mOutputAudioFile Disposed.");
}
NSURL *outUrl = [NSURL fileURLWithPath:file];
OSStatus setupErr = ExtAudioFileCreateWithURL((CFURLRef)outUrl, kAudioFileWAVEType, &mOutputFormat, NULL, kAudioFileFlags_EraseFile, &mOutputAudioFile);
NSAssert(setupErr == noErr, @"Couldn't create file for writing");
setupErr = ExtAudioFileSetProperty(mOutputAudioFile, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &audioFormat);
NSAssert(setupErr == noErr, @"Couldn't create file for format");
setupErr = ExtAudioFileWriteAsync(mOutputAudioFile, 0, NULL);
NSAssert(setupErr == noErr, @"Couldn't initialize write buffers for audio file");
isActive = TRUE;
}
有没有人对可能导致此事的原因有任何想法?我假设,鉴于EXC_BAD_ACCESS,它是一个内存泄漏或者什么的引用计数被敲到零,但我不能为我的生活弄清楚它可能是什么,并且谷歌正在绘制一个完整的空白。我在CoreAudio的Apple开发论坛上发布了同样的东西,但是没有一个灵魂对我很同情,甚至做出了精辟的评论。 HALP!
编辑:发现问题。当ExtAudioFileWriteAsync尝试在旧文件“优化”之前写入新文件时发生错误。一点点的互斥爱解决了这个问题。
答案 0 :(得分:5)
我在录音应用程序上遇到了几乎相同的问题,任何人都可以解释如何用“一点互斥爱”来解决它吗? 的修改
Tnx对Chris Randall我确实设法解决了我的问题。这就是我实现互斥锁的方式:
#include <pthread.h>
static pthread_mutex_t outputAudioFileLock;
然后在我的init:
pthread_mutex_init(&outputAudioFileLock,NULL);
并在回调中:
if (THIS.mIsRecording) {
if (0 == pthread_mutex_trylock(&outputAudioFileLock)) {
OSStatus err = ExtAudioFileWriteAsync(THIS.mRecordFile, inNumberFrames, THIS.recordingBufferList);
if (noErr != err) {
NSLog(@"ExtAudioFileWriteAsync Failed: %ld!!!", err);
} else {
}
pthread_mutex_unlock(&outputAudioFileLock);
}
}
最后在stopRecord方法中:
if (mRecordFile) {
pthread_mutex_lock(&outputAudioFileLock);
OSStatus setupErr;
setupErr = ExtAudioFileDispose(mRecordFile);
mRecordFile = NULL;
pthread_mutex_unlock(&outputAudioFileLock);
NSAssert(setupErr == noErr, @"Couldn't dispose audio file");
NSLog(@"Stopping Record");
mIsRecording = NO;
}
Tnx再次寻求帮助,希望这能节省一些人的时间。
答案 1 :(得分:2)
包含pthread.h,并在构造函数中定义pthread_mutex_t outputAudioFileLock。然后,在你的音频回调中,当你想写时,做一些这样的事情(根据你正在使用的内容调整变量):
if (0 == pthread_mutex_trylock(&outputAudioFileLock)) {
OSStatus err = ExtAudioFileWriteAsync(mOutputAudioFile, frames, bufferList);
if (noErr != err) {
NSLog(@"ExtAudioFileWriteAsync Failed: %ld!!!", err);
} else {
}
pthread_mutex_unlock(&outputAudioFileLock);
}
pthread_mutex_trylock检查线程是否被锁定(从而“优化”)。如果不是,则允许写入。然后我将音频文件设置(如上所示)和音频文件清理一样包装,这样当文件系统执行任何会导致AudioRingBuffer BAD_ACCESS错误的事情时,线程就会被锁定:
pthread_mutex_lock(&outputAudioFileLock);
OSStatus setupErr;
setupErr = ExtAudioFileDispose(mOutputAudioFile);
mOutputAudioFile = NULL;
pthread_mutex_unlock(&outputAudioFileLock);
NSAssert(setupErr == noErr, @"Couldn't dispose audio file");
这将锁定设置和清理线程,以便您无法写入正在“优化”的文件,这是错误的来源。希望这有帮助!
编辑:我在音频控制器的Obj-C部分进行音频回调;如果你在C ++部分中这样做,那么结构将会有所不同;也许其他人可以回答这个问题?