I have an app that uses an avaudio player for two things. One of them is to play an explosion sound when a uiimageview collision is detected, and the other is to play a lazer sound when a button is pressed. I declared the audioplayer in the .h class, and I call it each time the button is clicked by doing this:
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"/lazer"
ofType:#"mp3"]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:&error];
if (error)
{
NSLog(#"Error in audioPlayer: %#",
[error localizedDescription]);
} else {
[audioPlayer prepareToPlay];
}
[audioPlayer play];
This works fine, but after many uses of the game, the audio will stop play when i hit the button, and when a collision is detected, the game crashes. Here is my crash log:
2013-09-18 18:09:19.618 BattleShip[506:907] 18:09:19.617 shm_open failed: "AppleAudioQueue.41.2619" (23) flags=0x2 errno=24 (lldb)
Suggestions? Could there be something to do with repeatedly creating an audio player? Alternatives maybe?
Related
I recently implemented sounds into my game. Every time the user touches the screen, an arrow is shot, and a sound is played. I am using the following code to play the sound:
- (void)arrowShoot {
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/arrow.mp3", [[NSBundle mainBundle] resourcePath]]];
arrowShootPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
if (arrowShootPlayer != nil) {
[arrowShootPlayer play];
}
}
The reason I was allocating memory to the arrowShootPlayer every time is because the user can tap the screen rapidly, and I want the sounds to overlap. Otherwise, the sound only plays once the previous one has finished playing.
Anyway, I am getting this error:
<com.apple.main-thread> shm_open failed: "AppleAudioQueue.36.5755" (23) flags=0x2 errno=24
Once I get this error, the sounds stop being played. Everything else is fine, just the arrow sounds stop playing.
Is there a better way of playing 'overlapping' sounds like this on the iPhone, or is there a way around this error??
Thanks
if it is the same audio always, use the playing from memory buffer instead of opening the files. Declare some local buffer:
NSData* data;
then in your method:
if(!data) {
data = [NSData dataWithContentsOfURL:url options:NSDataReadingMappedIfSafe error:&err];
}
arrowShootPlayer = [[AVAudioPlayer alloc] initWithData:data error:nil];
if (arrowShootPlayer) {
[arrowShootPlayer play];
}
I'm working on a game, that at first seem too run fine, but.......
after it runs a long time the sound first stops to work,
[[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error]; returns a null and a little while later when I try to set a view equal to a new image, by view.image=, I get a error in my console that says to many files open,
ImageIO: CGImageRead_mapData 'open' failed '/Users/deno/Library/Application Support/iPhone Simulator/5.1/Applications/5A0C777C-70D1-4AA0-8D7B-04A1F734C932/cPetCakes.app/twinkles04fin32.png'
error = 24 (Too many open files)
right now I creat a new I'm creating a new AVAudioPlayer object each time a sound is played. Should I be re-using the object or some how freeing it??? Since I was not using a alloc, I was thinking that the object would be freed automatcly???
Code for sound
-(void) PlaySound: (NSString *) name
{
NSURL *url;
if ( [name compare:#"chasdog"]==0)
url = [[NSBundle mainBundle]
URLForResource:name
withExtension:#"wav"];
else
url = [[NSBundle mainBundle]
URLForResource:name
withExtension:#"mp3"];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.volume=1.0;
audioPlayer.numberOfLoops= 0;
[audioPlayer play];
audioPlayer.delegate = self;
}
code that no longer loads in new images
self.image=gPetCakeB[gGame->mPetCakeId];
In the player delegate it's needed to release the player once it's stopped playing:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
[player release];
}
The following code is supposed to play a sound and won't stop the music playing by iPad's Music/iPod. (on iOS 5.1, the iPod app became the Music app).
It is using AVAudioSessionCategoryAmbient instead of AVAudioSessionCategorySoloAmbient. But it actually stopped the music in either case. Is there something wrong with the use of AVAudioSessionCategoryAmbient?
NSURL *sound0URL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"0" ofType:#"aiff"]];
audioPlayer0 = [[AVAudioPlayer alloc] initWithContentsOfURL:sound0URL error:nil];
audioPlayer0.delegate = self;
[audioPlayer0 prepareToPlay];
NSError *setCategoryErr = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&setCategoryErr];
NSLog(#"%#", setCategoryErr);
audioPlayer0.currentTime = 0;
[audioPlayer0 play];
the setCategoryErr is printed as (null) so there should be no error.
As I said in my comment, it seems the solution is to set the AVAudioSession category BEFORE calling prepareToPlay on the AVAudioPlayer.
I am trying to play an in app audio with ipod the code I am using to play the audio file is:
Code:
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil];
UInt32 doSetProperty = 1;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doSetProperty), &doSetProperty);
[[AVAudioSession sharedInstance] setActive: YES error: nil];
if(error)
{
NSLog(#"Some error happened");
}
NSString *path = [[NSBundle mainBundle] pathForResource:effect ofType:type];
myPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
myPlayer.delegate = self;
myPlayer.numberOfLoops = -2;
myPlayer.volume = 1.0f;
[myPlayer play];
and to play the ipod music I am using
Code:
player = [MPMusicPlayerController iPodMusicPlayer];
My ipod plays fine until the audio starts playing but once the audio stops I am not able to get back to the ipod to play. I am using
Code:
NSString *value = [[NSUserDefaults standardUserDefaults] stringForKey:#"sound"];
if([value compare:#"ON"] == NSOrderedSame && myPlayer != nil)
{
[myPlayer stop];
[myPlayer release];
myPlayer = nil;
}
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&error];
if(error)
{
NSLog(#"Some error happened");
}
to stop the audio and then just call
Code:
[player play];
to play the ipod music but it does not play the music, it says the title to be null.
I would really appreciate if some one could help me with this.
Regards,
Ankur
I suggest moving the audio session setup (including the Ambient category) to your application delegate's didFinishLaunchingWithOptions and not using the Playback category at all. You can still play AVAudio sounds just fine with the Ambient setting.
If you want to kill iPod music whenever you play AV sounds, then you should only be using the Playback category. (I'm not exactly sure what you're trying to do.)
The error that you're getting when you try to resume the iPod music suggests that your MPMusicPlayerController object resets its song queue when it is stopped by the AVAudio sounds, and that you'll have to set up the MP player again. "Title is null" definitely sounds like a dangling pointer or the like in the MP player.
It's not possible to play iPod audio in AVAudioPlayer. You need to convert the library Asset link from ipod, using *AVURLAsset to an mp3 or wav and save it to the documents library. IOS.5 currently has a bug in the conversion (AudioExportSession) from ipod to mp3 file, so it's NOT POSSIBLE. Sorry.
You need to resume iPod player after myPlayer finish playing.
-(void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
[player play];
}
Hey guys how can I make an app keep playing an mp3 after pressed the hold/power button.
Here is the code I use for preparing the AVAudioPlayer:
- (void)PrepareAudio:(int)index
{
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#",[_Audio objectAtIndex:Game]] ofType:#"mp3"];
NSURL *newURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
MusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: newURL error: nil];
[newURL release];
[MusicPlayer setVolume: 1.5];
}
And this is the code when I press the button play:
- (IBAction)PushPlay: (id)sender
{
if(!MusicPlayer.playing)
[MusicPlayer play];
}
Best Regards
Carlos Vargas
If you are holding long enough to turn the device off, then there is no way. If you are pressing the button to lock the screen, the music can be played. Why don't you put some code up and let us see what you have tried. Hint: The answer lies within the Audio playback categories.