Sounds playing over each other using AVAudioPlayer - ios

Right, sorry if i seem like a noob, but i'm new to xcode. I'm currently making a soundboard, and i've got all the buttons to work and play sounds from them.
However, if one sound is playing, when i press another button, rather than stopping the original sound, it just plays over it, so i was wandering if anyone knew how to fix this?
Here's the code i'm using for the buttons:
- (IBAction)playsound {
NSString *path = [[NSBundle mainBundle] pathForResource:#"Gold" ofType:#"mp3"];
AVAudioPlayer* myAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
myAudio.delegate = self;
myAudio.volume = 2.0;
myAudio.numberOfLoops = 0;
[myAudio play];
}
I'd be really grateful if someone could help me out.
Thanks.

If the other sound is still playing, you need to tell it to stop. You probably want to look into using the calling the stop method on the other AVAudioPlayer. So, something like where you have:
[myAudio play];
...insert a method call just before that to tell the other sound to stop.
[myOtherAudioThatsPlaying stop];
[myAudio play];
It might make sense to also browse the AVAudioPlayer documentation.

While bobtiki's answer is formally correct, it only makes sense to call the stop method if you want to do something useful with the sound after it has stopped, for example start playing it again. Since you just want to get rid of it, I recommend have the player just get deallocated, which automatically makes the sound stop playing.
So, instead of
AVAudioPlayer* myAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
add an instance variable to your class:
AVAudioPlayer* myAudio;
then just use
myAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
Everytime a new sound is played, myAudio gets assigned a new pointer and the old AVAudioPlayer just gets deallocated.

Related

Objective-C: Making AVPlayer plays in all the app controllers (or in the background)

I'm making a news iOS app, i want to implement a live audio streaming in all the pages like the picture below:
The orange view is a UIView that says "Live Streaming" (in Arabic), it exists in all the viewControllers, i want to let the AVPlayer plays when the user clicks on it and still plays even if the user navigates to other viewControllers.
I can't seem to find a good solution or tutorial about this, sorry if this is a noob question cause i'm new to iOS.
So how can i do that ? and where(in which viewController) should i put the AVPlayer declaration ?
Thanks in advance.
If you are testing in the simulator, the change of views will not continue the audio in the background. If it is not working your device try this:
NSURL *url = [NSURL URLWithString: yourURLHere];
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:avAsset];
AVPlayer *audioPlayer = [AVPlayer playerWithPlayerItem:playerItem];
//This enables background music playing
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[audioPlayer play];
Place this code in your viewDidLoad method, before [super viewDidLoad];
I found two links that exaplin some of the issues on this:
Play Music in Background
Play Audio from Internet
If this does not work, I would recommend placing a bounty on the question as it seems your issue's are a little more in depth than a simple solution.
I found the solution, i had to make a singleton class.
The singleton class allow only one object to be used in the entire iOS application by all the ViewControllers.
And i did put all the needed methods like play and pause in the singleton class and i accessed them from all the ViewControllers.
If anybody wants an example, please ask in the comments.

AVAudioPlayer makes my game look laggy

When I use AVAudioPlayers for sound effects in my game, they cause the game to look laggy. I'm not the only one facing this problem, but from what I've found on here/other sites they don't seem to come up with an answer to solve it. Therefore I'm asking once and for all... What can I do? I've tried to use prepareToPlay in the viewDidLoad, but it doesn't help.
Here's some code on how I use the AVAudioPlayer:
NSString *StartTap=[[NSBundle mainBundle]pathForResource:#"Tap" ofType:#"mp3"];
StartSound=[[AVAudioPlayer alloc]initWithContentsOfURL: [NSURL fileURLWithPath:StartTap] error:NULL];
StartSound.numberOfLoops=-0;
And then I call:
[StartSound play];

Is AVAudio autoreleased?

I'm new to playing sounds on iOS. I know that to play various sounds I should have a audio manager helper class keeping all the audios together.
Now, I'm wondering if it is OK to do this without memory leak:
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&err];
[newPlayer play];
Will the player get released after it finished playing? Or do I need to keep a pointer to it, call [newPlayer stop] when it finishes, then set the pointer to nil?
Actually it is the opposite of a leak. If you do not retain the player, it will be released immediately and will never play.
See my answer here for more info: Playing back audio using AVAudioPlayer iOS 7

Play audio file multiple times after a very short time?

I have an audio file that is 2 seconds long. Im trying to play that many times before it is done playing. But when I try it with AVAudioPlayer by creating a new instance of it, it sounds like it stops the audio that was played before and plays the new one instead of playing them at the same time. Should I use another way to play sounds or is this not achievable?
Code:
NSURL *url = [[NSBundle mainBundle] URLForResource:#"PistolShootSound" withExtension:#"mp3"];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[audioPlayer play];
audioPlayer is declared in the header file.
Have you used AVAudioPlayer's property numberOfLoops to play audio file repeatedly?
UPDATE: I didn't understand your goal before. If you want to play short files many times you could use AudioServices. Here is a good example of how to use it.

iOS: how to conveniently store and play many mp3 files

I have a program with about 2000 short mp3 files. I am now storing all those file into folder Supporting Files and when I want to play I call this function:
-(void)playSound:(NSString *)mySoundFileName{
NSString *filePath = [[NSBundle mainBundle] pathForResource:mySoundFileName ofType:#"mp3"];
if ([NSData dataWithContentsOfFile:filePath]) {
url = [NSURL fileURLWithPath:filePath];
audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:nil];
[audioPlayer play];
}
}
However, the first time I play the sound, it always takes long time to search/load the file. More specifically, after pressing "play sound" button to play sound, I have to wait for at least 5 seconds until it plays. It is OK to play other sound after that, i.e, it play almost immediately when I press "play sound" button. Do you have any suggestion to store and play those many files more efficiently? Thank you very much
It can sometimes take an undesirable amount of time for AVAudioPlayer to start playing initially. A good way to solve this is to make the initial alloc/init before you call play. This way the player is ready to play before the user presses the play button. Additionally, calling [player prepareToPlay]; before play will help improve performance slightly.

Resources