EXC_BAD_ACCESS in AudioRingBuffer :: GetTimeBounds

Ok, here is the scenario: I have a real-time recording application using ExtAudioFileWriteAsync designed for iOS 4.3. The first time I record an application, it works fine. If I click on the stop and then record again, better than half the time when I get EXC_BAD_ACCESS in AudioRingBuffer :: GetTimeBounds right at the start of recording.

That is, ExtAudioFileWriteAsync fails on GetTimeBounds when the second record starts. Here is a bit of code that runs when recording starts, which creates an ExtAudioFile link:

- (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; } 

Does anyone have any thoughts on what might be causing this? I believe, given that EXC_BAD_ACCESS, that this is a memory leak or some number of links that have been knocked down from scratch, but I can’t understand for a lifetime that this could be, and Google draws a complete space. I posted the same topic on the Apple dev forum for CoreAudio, but not a single soul regretted me, even to make a lasting comment. HALP!

EDIT: Problem detected. The error occurred when ExtAudioFileWriteAsync tried to write a new file before the old file was “optimized”. Little love with a mutex solved the problem.

+6
source share
2 answers

I have almost the same problem in a recording application, can anyone explain how to solve the problem with a bit of love for mutexes? EDIT

Tnx so Chris Randall I can solve my problems. Here's how I implemented the mutex:

 #include <pthread.h> static pthread_mutex_t outputAudioFileLock; 

then in my init:

 pthread_mutex_init(&outputAudioFileLock,NULL); 

and in the callback:

 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); } } 

finally, in the stopRecord method:

 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 is back for help again, hope this saves time.

+5
source

Include pthread.h and define pthread_mutex_t outputAudioFileLock in your constructor. Then in your sound callback, when you want to write, do something like this (adjusting the variables according to what you are using):

 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 checks if a thread is blocked (and therefore "optimization"). If it is not, then it allows you to write. Then I wrap both the audio file setup (as shown above) and the audio file cleanup, so that the stream is blocked when the file system does something that can cause the AudioRingBuffer BAD_ACCESS error:

 pthread_mutex_lock(&outputAudioFileLock); OSStatus setupErr; setupErr = ExtAudioFileDispose(mOutputAudioFile); mOutputAudioFile = NULL; pthread_mutex_unlock(&outputAudioFileLock); NSAssert(setupErr == noErr, @"Couldn't dispose audio file"); 

This blocks the tuning and cleaning threads, so you cannot write a file that is "optimized", which is the source of the error. Hope this helps!

EDIT: I am performing my callback on the Obj-C part of the audio controller; if you do it in the C ++ part, it will be structured in a completely different way; maybe someone can answer that?

+2
source

Source: https://habr.com/ru/post/900472/


All Articles