IOS AVAudioPlayer Strange Behavior

I have a series of short (1 seconds) sound clips that I need to play sequentially. A class is being developed for this purpose. I am using the following code:

- (void) playClip: (NSData *)clipToPlay { NSError *error = nil; AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithData: clipToPlay error:&error]; audioPlayer.numberOfLoops = 0; audioPlayer.volume = 1.0f; [audioPlayer prepareToPlay]; if (audioPlayer == nil) NSLog(@"%@", [error description]); else [audioPlayer play]; } 

As you can see, clipToPlay contains a sound clip like NSData . The behavior of this code is strange. If I run it in the debugger and set a breakpoint in the following line:

 [audioPlayer play]; 

The clip plays as expected - the debugger stops on the line, when you go through the line, the clip plays perfectly. If, however, I take a breakpoint, it does not play at all.

I tried first copying NSData to a file from scratch, with exactly the same result. I also copied clipToPlay to another variable (using a copy, not just a pointer assignment) with the same results (I thought that maybe the clip file was clamped somewhere). I am not getting an error message.

I really get stuck on why pausing the debugger in the playback method will make it happen like this. Any suggestions or ideas?

+4
source share
1 answer

Well, I found this problem, so I will answer my question, so maybe it will save someone else some time along the way.

The problem was that AVAudioPlayer was released before he had the opportunity to play sound. When stopped at a breakpoint, there was an obvious opportunity to play the sound before it was released.

In this case, since it was in its own subclass, I made audioPlayer ivar And I made a variable containing a reference to the ivar subclass in the controller of the calling view. This prevented the release until the sound was reproduced.

In the subclass, I will indicate the audioPlayer pointer in the delegate method:

 - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag 

I am not sure what the final form of this agreement will be, but that at least explained what caused the problem. The AVAudioPlayer instance must be in its volume until the sound ends or ARC releases it.

+5
source

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


All Articles