Playing Sound Effects while in Background Mode - iphone

I have a need to play some sporadic sound effects in the background of an iPhone app. From everything I've read and experienced with iOS 4, I can keep my app running in the background as long as I am running GPS by specifying "location" as a background mode. That actually works. But at times I want to play a sound effect...in other words, it's not "continuous" sound which I see reference to.
But the app is running, so why can't I just use AVAudioPlayer to play some sound effects? Would another sound API work?
GAHHH!
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"BEEP" ofType:#"aiff"];
NSURL *fileURL = [[[NSURL alloc] initFileURLWithPath: soundFilePath] autorelease];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
player.volume = 1.0;
[player prepareToPlay];
// play
[player play];

I think it is important to clarify that your application is not running in the background. Rather, your application is 'put to sleep'. The info.plist background process value that you specify tells the OS that it should wake your application and allow it to respond to specific types of events. From the Apple Documentation
Each of the preceding values [audio, location, voip] lets the system know that your application should be woken up at appropriate times to respond to relevant events.
In your case, your application is frozen and is only able to respond to the type of event that you specify (location, or GPS).
You don't make it clear what context this code is in, so at this point it's difficult to tell you why the audio is not playing. Also, you need to make sure that your application is running in the background for the specified purpose. If you are using the location mechanism and not using GPS in your app, you may get rejected when you submit your application.
You may also want to refer to the Checklist for Supporting Multitasking to ensure the structure of your application implements their requirements.

[EDIT]
You have a good example of background playback while monitoring GPS position here :
http://www.informit.com/articles/article.aspx?p=1646438&seqNum=5
And it's using AudioToolbox rather than AVAudioPlayer
I've managed to do it using the AVAudioPlayer.
did you also add the audio value in the info.plist for key UIBackgroundModes ?

The answer is that it won't work with AVAudioPlayer. Use the AudioServicesPlaySystemSound API instead.

Related

iPhone app that responds when running in background

I know that you can for example play music in you app and it would be running in background but it looks like it's not working. I've this code when my application starts on iPhone:
pathToAudio = [[NSBundle mainBundle] pathForResource:#"silence" ofType:#"mp3"];
audioURL = [NSURL fileURLWithPath:pathToAudio];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:NULL];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:NULL];
audioPlayer.numberOfLoops = -1;
[audioPlayer play];
Result is that it plays music when I send app to background but other activities doesnt run. For example in my app I'm listening to socket and although music plays in background my app doesnt respond to incomming messages (it normally responds when app is in foreground). What do I do wrong? I've read that you can do other activities when playing music when app is in background but it looks like it doesn't work...
Edit: I have jailbroken iPhone so any unconventional methods are welcome. I know that Apple would reject my app if I was playing silent audio in background and I dont care about it. I just want to know how to make app running in background when playing music or in any other way... Maybe I need to have iPhone 4? I have iPhone 3G.
Nothing, it's only possible to run audio in background (aside with some special cases like geoloc notifs & VoIP), not other stuff.
You'll need to provide a specification for the info.plist file like the UIBackgroundModes.

Make AVFoundation not stop iPod music

Im using the AVFoundation framework to play sound files. The problem im having is that its stopping music from playing when the audio file gets used, im not saying play both files continuously, but play the sound file, then pick up the ipod music right where it left off. Is there any way i can use AVFoundation is this kind of way? or is there a better framework for it?
Here is what my code looks like:
click = [NSURL fileURLWithPath:[NSString stringWithFormat:#"#/Click.WAV", [[NSBundle mainBundle] resourcePath]]];
audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:click error:nil];
audioPlayer.numberOfLoops = 1;
[click release];
[audioPlayer play];
This code works completely fine, i had to type it out so ignore any problems that there might be with it.
Thanks,
Jacob
You can use the AVAudioSession class to change the audio "category" of your app: thus you can allow it to play on top of the iPod music. Use the -setCategory:error: method, and you will probably want to use AVAudioSessionCategoryAmbient. More info can be found in the Audio Session Programming Guide.

Streaming with an AVAudioplayer

In order to load a sound file, I have the following code in my application :
- (id) init:(NSString*)a_filename ext:(NSString*)a_ext
{
...
NSString *t_soundFilePath = [CFileLoader getPathForResource:filename WithExtension:ext];
NSURL *t_fileURL = [[[NSURL alloc] initFileURLWithPath: t_soundFilePath] autorelease];
player = [[AVAudioPlayer alloc] initWithContentsOfURL: t_fileURL error: nil];
[player prepareToPlay];
...
}
All the sounds that I load are in my bundle, so I would like to know if the method "initwithcontentsofurl" stream the sound file or if all the file is cached.
I have a lot of sprites in my app so I want to minimize memory space used for sounds.
thx for your help
I used AVPlayer (not AVAudioPlayer) to stream background audio.
Sounds that are played using the AVAudioPlayer are streamed real time from storage. The drawback being that you can occasionally notice a small lag when it is due to start up. If you use OpenAL the sounds are loaded entirely into memory.
There's a good discussion of this sort of thing in the ObjectAL documentation - a library that is meant to simplify the playing of sounds and effects on the iPhone.
If you want to stream audio in your app you can use the following player instead of using AVAudioPlayer
https://github.com/mattgallagher/AudioStreamer
For this player you don't need to put sound files in your bundle, you can put them at server and use url to stream audio.
Hope, this wil help you.
" The AVAudioPlayer class does not provide support for streaming audio
based on HTTP URL's. The URL used with initWithContentsOfURL: must be
a File URL (file://). That is, a local path".
https://developer.apple.com/library/ios/qa/qa1634/_index.html
But you can work around - for example write asynchronously to local file, and init AVAudioPlayer with this file URL, it will work.

How do you implement seeking using the AudioStreamer sample application as a base?

I need to play some audio streaming contents on iPhone, but there are some options and problems I can't solve:
1. http://cocoawithlove.com/2009/06/revisiting-old-post-streaming-and.html
It is a library provided by Matt Gallagher, but I saw the Limited scope, and I would play
a single song, not a radio station.
2. Suggestion from zonble
NSURL *URL = [NSURL URLWithString:#"http://zonble.net/MIDI/orz.mp3"];
NSData *data = [NSData dataWithContentsOfURL:URL];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithData:data error:nil];
But I need streaming for each "single song".
3. Using MPMoviePlayerController to wrapper.
Since the Class update new method, and
#interface MyAudioStreamer : UIViewController {
MPMoviePlayerController *mp ;
}
instead of [self addSubview:mp.view] I use my own xib file to implement play and
stop methods, but in this case, I have no idea to implement seekForward or seekBackward.
Is there any good idea to do AudioStreamer?
==== Update ====
after google 'AVPlayer' ,i used 3. Using MPMoviePlayerController to wrapper. to implement a auidoStreamer-like player ,there is something to share :
1.'playbackDidFinished' state
there're 2 conditions : a song did finished and play next song or a song interrupt by user press stop or exception, i used enum to filter my state.
2 multi-task playing your song in background
reference from https:// devforums.apple.com/message/264397
and if iOS SDK update, the solution might be changed because method would be diplicated. so i suggest to read library provided by Matt Gallagher.
anyone who konws when the library have no codec match download item (for example, my item encode by .AAC 128-bit and the library not support or at most .AAC 64-bit), what happen would the player be ?
You can either parse the icy meta data yourself, or if you're using iOS 4.0 you can playback using an AVPlayer and observe the timed metadata to discover the song boundaries and titles.

Multiple audio sounds in iPhone app?

I've gotten to play a single sound in the iPhone app I've started, but I now desire to play multiple sounds based on a button. To create a separate set of .m and .h files for each audio sounds, and then including them all, doesn't seem the most efficient way to tackle this in terms of coding...then again, I'm just starting out with Cocoa and only just completed my first app ever.
Any help is appreciated. The key here is multiple sounds, each triggered by its own button or image. Thanks.
If the files are MP3 or AAC format, then you can only play one at a time. This is a limitation of core audio on the iPhone.
In terms of playing multiple sounds at once, that's easy, just create a new player instance for every one that you want to play (and remember to release them when you're done)
NSString *path = [[NSBundle mainBundle] pathForResource:#"dream" ofType:#"m4a"];
AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
To convert an MP3 into something like IMA4 (which you can play more than one at once) you would run the following (in terminal, in leopard):
/usr/bin/afconvert -f caff -d ima4 sound.mp3 sound.caf
The above code is firmware 2.2 only, but you can do the same with the AudioQueue files if you want to support older firmwares (it's just a lot more complex, so I haven't listed the code here).
If you have access to the iPhone developer network, then there are a bunch of code samples that show you how to play audio.
All you need to do is make one class that has a function called
-(void)Play:(NSString*)sSoundFile {
// play sound file here
}
I don't have any direct experience with iPhone development, but in theory could you create a single large sound file with all your sounds in it? Each sound could be separated by just enough silence to be individually accessed by a time index. Of course, the downside is that you'd have to load the entire file into memory, unless you could figure out a way to load chunks in a random-access fashion...
#rustyshelf - does this work in the simulator? I'm using that code, and using #import but neither audioPlayerDidFinishPlaying nor audioPlayerDecodeErrorDidOccur ever get called. Very annoying to try to debug.
http://www.icodeblog.com/2009/05/04/iphone-game-programming-tutorial-part-4-basic-game-audio/
in this example in ios5 you have to put
CFURLRef soundurl=(__bridge CFURLRef)[NSURL fileURLWithPath:objstring];
in place of
CFURLRef soundurl=(CFURLRef)[NSURL fileURLWithPath:objstring];
Hardik Mamtora