EXC_BAD_ACCESS в AudioRingBuffer :: GetTimeBounds - PullRequest
6 голосов
/ 01 ноября 2011

Хорошо, вот сценарий: у меня есть приложение для записи в реальном времени, использующее ExtAudioFileWriteAsync, предназначенное для iOS 4.3.Первый раз, когда я записываю с приложением, оно работает отлично.Если я нажму «Стоп», а затем запишу снова, лучше, чем в половине случаев, я получу EXC_BAD_ACCESS в AudioRingBuffer :: GetTimeBounds сразу после начала записи.

Это означает, что 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, что это утечка памяти или что-то, что подсчет ссылок сбивается до нуля, но я не могу понять, что это может быть, и Googles рисуют полный пробел.Я разместил эту же вещь на форуме разработчиков Apple для CoreAudio, но ни одна душа не пожалела меня, даже чтобы сделать содержательный комментарий.HALP!

РЕДАКТИРОВАТЬ: Обнаружена проблема.Ошибка происходила, когда ExtAudioFileWriteAsync пытался записать новый файл, прежде чем старый файл был «оптимизирован».Небольшая любовь мьютекса решила проблему.

Ответы [ 2 ]

5 голосов
/ 13 мая 2012

У меня почти такая же проблема с записывающим приложением, кто-нибудь может объяснить, как решить ее с помощью "Немного мьютекса любви"? РЕДАКТИРОВАТЬ

Спасибо Крису Рэндаллу Мне удалось решить свои проблемы.Вот как я реализовал мьютекс:

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

Еще раз за помощь, надеюсь, это сэкономит кому-то время.

2 голосов
/ 15 мая 2012

Включите 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 ++, это было бы немного иначе; возможно кто-то еще может ответить на это?

...