0
votes

I a button that records audio when isNotRecording is false and plays audio when isNotRecording is true. Here is my code in the viewDidLoad function:

NSArray *pathComponents = [NSArray arrayWithObjects:
                           [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
                           @"MyAudioMemo.m4a",
                           nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];

// Setup audio session
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

// Define the recorder setting
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];

[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];

// Initiate and prepare the recorder
recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:NULL];
recorder.delegate = self;
recorder.meteringEnabled = YES;
[recorder prepareToRecord];

Here is my code to play the sound or record:

if (isNotRecording==NO){

    if (player.playing) {
        [player stop];
    }

    if (!recorder.recording) {
        AVAudioSession *session = [AVAudioSession sharedInstance];
        [session setActive:YES error:nil];

        // Start recording
        [recorder record];


    }


}

else{
    if (!recorder.recording){
        player = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:nil];
        [player setDelegate:self];
        [player play];
    }


}

And here is my code to stop the playing/recording:

[recorder stop];
[player stop];

Now, everything works almost perfectly (i.e. I can record and play sounds fine). However, there are two issues. The major one is that after I close out the app and try to play the sound, it does not have a sound to play. I want it to play the previous recording. That is my main issue, but it would also be great if I could reduce the lag from when I press the button and the sound plays. Sometimes, if I press the button and release it very fast, no sound plays at all. Any suggestions are greatly appreciated. However, again, the main issue I need fixed is that the recording doesn't save after I close out the app.

1

1 Answers

0
votes

I think what's happening is that when you initialize your AVAudioRecorder when the view loads then that will delete any existing file at the target location, irrespective of whether you start recording at that stage. So I think that's how the file is going missing.

Simplest may be just not to call [recorder prepareToRecord]; when you do, as I suspect that's when your recording is getting deleted.

Or you might want to use a temporary file while recording and move it to the final location when you're notified that the recording is finished, in order to avoid that issue. Code is something like:

NSArray *pathComponents = [NSArray arrayWithObjects:
                           [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
                           @"MyAudioMemoTemp.m4a",
                           nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];

// Setup audio session
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

// Define the recorder setting
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];

[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];

// Initiate and prepare the recorder
recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:NULL];
recorder.delegate = self;
recorder.meteringEnabled = YES;
[recorder prepareToRecord];

if (isNotRecording==NO){

    if (player.playing) {
        [player stop];
    }

    if (!recorder.recording) {
        AVAudioSession *session = [AVAudioSession sharedInstance];
        [session setActive:YES error:nil];

        // Start recording
        [recorder record];
    }
}

else{
    if (!recorder.recording){
        NSArray *pathComponents = [NSArray arrayWithObjects:
                                [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
                                @"MyAudioMemo.m4a",
                                nil];
        NSURL *inputFileURL = [NSURL fileURLWithPathComponents:pathComponents];

        player = [[AVAudioPlayer alloc] initWithContentsOfURL:inputFileURL error:nil];
        [player setDelegate:self];
        [player play];
    }

}

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder
                               successfully:(BOOL)flag
{
    if (successfully) {

        // Copy temp file used during recording to replace that used when playing
        //
        pathComponents =  [NSArray arrayWithObjects:
                            [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
                            @"MyAudioMemo.m4a",
                            nil];
        NSURL *targetFileURL = [NSURL fileURLWithPathComponents:pathComponents];

        NSError *error = nil;
        [[NSFileManager defaultManager] removeItemAtURL:targetFileURL error:&error];

        error = nil;
        [[NSFileManager defaultManager] copyItemAtURL:recorder.url toURL:targetFileURL error:&error];

    }

}