Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Seemingly random file corruption using AVAudioRecorder (Sometimes the file can't be played back) - iOS

In an app I'm currently developing, I've more or less hit a brick wall. In the application you can enter a view which lists all locally saved audio files in a standard table view. From here you can click on them to play them, or hit a record button below to make a new recording, which will afterwards automatically get saved to the apps sandbox.

Now all of this actually works perfectly fine, most of the time. I can sit and make recordings and play them back. I can sit and test this on and on for around 45 with no problems whatsoever. Then suddenly at random times I will hit a very odd problem. The problem is that the recorder all of the sudden starts to save nothing but corrupt files which can't be played back and are exactly 4096 bytes in size, no matter how long you recorder for.

I use the AVAudioRecorder in a totally standard fashion, setting it up like this:

// Specific settings for the audio recording
NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithInt:AVAudioQualityMin],
    AVEncoderAudioQualityKey,
    [NSNumber numberWithInt:8], 
    AVEncoderBitRateKey,
    [NSNumber numberWithInt: 2], 
    AVNumberOfChannelsKey,
    [NSNumber numberWithFloat:22000.0], 
    AVSampleRateKey,
    nil];

NSError *error = nil;
audioRecorder = [[AVAudioRecorder alloc]
    initWithURL:contentURL
    settings:recordSettings
    error:&error];
audioRecorder.delegate = self;

I start the recording like this:

if (!isRecording) {
    isRecording = YES;
    [audioRecorder record];

    // Start the timer
    recordTiming = [NSDate date];

    timeCheck = [NSTimer
        scheduledTimerWithTimeInterval:1.0f
        target:self
        selector:@selector(timeCheck)
        userInfo:nil
        repeats:YES];
}

And then stopping it with this:

if (isRecording) {
    [audioRecorder stop];

    // Stop the timer
    [timeCheck invalidate];
}

I have no idea what could cause this problem to happen. So far I've tried almost everything. I've check to make sure that the recorder object is recycled properly (so you have a new instance for each now recording), and that the old reference is deallocated and so on, to make sure it has nothing to do with interfering objects, but nothing solves it.

Is there anyone who have a slight idea of what could cause problems with corrupted files?

like image 930
CodingBeagle Avatar asked Mar 14 '12 15:03

CodingBeagle


1 Answers

Note: Since the OP is inactive for some days and I guess this question should be answered for public's future reference, thus I post this answer.

The AVAudioSession has to be obtained before start recording.

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err){
   NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
   return;
}
err = nil;
[audioSession setActive:YES error:&err];
if(err){
   NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
   return;
}

Reference: https://stackoverflow.com/a/9706731/188331

like image 123
Raptor Avatar answered Oct 31 '22 21:10

Raptor