AVAudioPlayer Help: Playing multiple sounds simultaneously, stopping them all at once, and working around Automatic Reference Counting

audio, avaudioplayer, ios, iphone, objective-c

Solution

First off, put the declaration and alloc/init of `audioplayer` on the same line. Also, you can only play one sound per `AVAudioPlayer` BUT you can make as many as you want simultaneously. And then to stop all of the sounds, maybe use a `NSMutableArray`, add all of the players to it, and then iterate though and `[audioplayer stop];`

//Add this to the top of your file
NSMutableArray *soundsArray;

//Add this to viewDidLoad
soundsArray = [NSMutableArray new]

//Add this to your stop method
for (AVAudioPlayer *a in soundsArray) [a stop];

//Modified playSound method
-(IBAction)playSound:(id)sender {
     NSString *soundFile = [[NSBundle mainBundle] pathForResource:@"Hello" ofType:@"wav"];
     AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:soundFile] error:nil];
     [soundsArray addObject:audioPlayer];
     [audioPlayer prepareToPlay];
     [audioPlayer play];
  }

That should do what you need.

Problem

I am trying to create buttons that `play` single sound files and one `button` that `stops` all of the sounds that are currently playing. If the user clicks multiple buttons or the same `button` in a short amount of time, the app should be playing all of the sounds simultaneously. I have accomplished this without much difficulty using the System Sound Services of iOS. However, the System Sound Services play the sounds through the `volume` that the `iPhone's` ringer is set to. I am now trying to use the `AVAudioPlayer` so that users can `play` the sounds through the media volume. Here is the code that I am currently (yet unsuccessfully) using the play the sounds: ``` -(IBAction)playSound:(id)sender { AVAudioPlayer *audioPlayer; NSString *soundFile = [[NSBundle mainBundle] pathForResource:@"Hello" ofType:@"wav"]; audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:soundFile] error:nil]; [audioPlayer prepareToPlay]; [audioPlayer play]; } ``` Whenever I run this code in the iPhone Simulator, it does not play the sound but does display a ton of output. When I run this on my iPhone, the sound simply does not play. After doing some research and testing, I found that the `audioPlayer` variable is being released by Automatic Reference Counting. Also, this code works when the audioPlayer variable is defined as an instance variable and a property in my interface file, but it does not allow me to play multiple sounds at once. First thing's first: How can I play an infinite number of sounds at once using the `AVAudioPlayer` and sticking with Automatic Reference Counting? Also: When these sounds are playing, how can I implement a second `IBAction` method to stop playing all of them?

Original source