I am trying to develop a simple iPhone app. I need to play sound within a loop.
How can Play Audio file in loop without any interruption ?
Take a look at the new AVAudioPlayer class in the 2.2 release:
http://developer.apple.com/iphone/library/documentation/AVFoundation/Reference/AVAudioPlayerClassReference/Reference/Reference.html
It has functionality for looping sounds.
I really don't know the iPhone SDK at all, but this should be quick: try making the sound itself looping. That way, you should be able to play it with just a single call, and won't need to worry about timing the repeat properly to restart it at the exact right moment.
For instance, WAV files have very flexible support for looping, and any decent audio editor should let you set looping points.
The AVAudioPlayer has numberOfLoops property where you can specify the number of times you want the audio to loop.
Related
I have large looping background music files of up to 10 minutes length. The sounds are looped perfectly and if the player introduces no delay you would not notice where the loop point is.
Can AVAudioPlayer play them without that the user will hear a gap caused by latency or other problems with looping?
You might be hearing a delay because your music is compressed (mp3 for example). AVAudioPlayer has to decode the mp3 as it streams. If you had the same music in an uncompressed format, it would take significantly more disk space, but would loop seamlessly.
As long as you don't stop/start it at the end and you set numberOfLoops to a negative integer, it should work.
I had problems trying to create seamless loops. I tried using the numberOfLoops property, with no success. I tried switching to uncompressed audio files, with no success. I even tried switching to an AVAudioQueuePlayer, queued with multiple instances of the same asset, with no success. In the end I solved the problem by creating two instances of AVAudioPlayer (player1 & player2) and switching between them. I began playback of player1 and used player2's prepareToPlay method, and the play(atTime time:) method setting the TimeInterval to player1.deviceCurrentTime - player1.currentTime + player1.duration.
I then used the delegate method audioPlayerDidFinishPlaying to prepare player1 to restart playback after player2 was done. To be honest, I don't know why this approach worked and simply setting numberOfLoops to -1 did not. But it may work for you also
I have a recording that has some unuseful voices at the beginning, and at the end.
How can I play just the middle part of the sound?
I have AL_SEC_OFFSET, that is suitable for the entry point, I already use it, but what about the endpoint?
Is there any smart OpenAL settings for this? Hopeso.
Thanks.
There could be a workaround that fires a timer that stops playing before end.
Any simplier?
OpenAL doesn't have built-in support for stopping playback at a specific sample point. A timer is your best bet in this case, even though it will be somewhat inaccurate.
If you want sample-perfect stopping, you could just load the middle part of the audio file into an ALBuffer rather than the entire thing. I have some code which does that here:
https://github.com/kstenerud/ObjectAL-for-iPhone/blob/master/ObjectAL/ObjectAL/Support/OALAudioFile.m#L188
I am developing an iOS application which resembles a musical instrument.
I am trying to loop the sound samples to make them last infinitely. Simple looping is not sufficient in this case, as the samples have an "attack" section: Each sample has a part at the beginning which should not be looped. Therefore, I need some way to loop only a certain part of the sound sample.
I found a few iOS sound libraries (e.g. ObjectAL), but they all seem to support only simple looping, without an option to set loop-in and loop-out points.
Are they any iOS audio libraries which support this feature? Otherwise, what would be the best method to implement it? (Audio units? Audio queues? Some other trick with existing libraries?)
Thanks!
I can't say if it's the best solution, but for my loops that have an intro / outro... I use multiple .caf files that blend together: one for the intro, one for the loop, and one for the outro.
After the intro, the loop starts and plays until an event fires that makes the sound stop looping and finish, and then the outro immediately plays once the loop sound finishes.
I use Audacity to edit the sound files to make sure that they blend together perfectly.
Edit:
My application uses cocos2d, so I'm using the cocosDehension audio library since it is built in to cocos2d. As long as the sound file has been properly edited, it loops cleanly with no clicks or pops.
Here's a link to the technique that I used in Audacity to make sure the file looped without clicks:
http://forum.audacityteam.org/viewtopic.php?f=13&t=2820#p11073
I need to play sounds (~5 seconds each) throughout my iphone application. When they're triggered, they need to play immediately.
For the moment I'm using AudioServices and (as you probably know) the first time you play a sound it lags, then every time there after it's perfect. Is there some code available that's clever enough to preload an AudioServices sound (by playing it silently maybe?). I've read adjusting the system volume programmatically will get your app rejected, so that's not an option. Seems AudioServices isn't made for volume correction from what I can see.
I've looked into OpenAL and while feasible seems a little over kill. AVAudioPlayer seems like a little bit of a better option, I'm using that for background music at present. Extending my music player to handle a 'sound board' might be my last resort.
On the topic of OpenAL, does anyone know of a place with a decent (app store friendly) OpenAL wrapper for the iPhone?
Thanks in advance
Finch could be perfect for you. It’s a tiny wrapper around OpenAL with very low latency and simple API. See also all SO questions tagged ‘Finch’.
If you use an AVAudioPlayer, you can call prepareToPlay when you initialize the object to reduce the delay between calling play and having the audio start.
I have a bunch of sounds I want to play. Right now I'm using AVAudioPlayer. A new sound should start when the user clicks a button. The url property of AVAudioPlayer is read-only. I'd rather not have to release and re-alloc the object every time I want a new sound played. What would be the best way to do this? Is there a different class I need to use?
The absolute easiest way to play sound is Playing UI Sound Effects or Invoking Vibration Using System Sound Services. Essentially you call AudioServicesCreateSystemSoundID() and AudioServicesPlaySystemSound(). Creating a system sound is relatively expensive and playback stops when it's disposed with AudioServicesDisposeSystemSoundID() anyway, so you really want to cache them:
Create them at app launch (or possibly the first time the sound is played). You can keep them in an NSDictionary keyed by sound file name and store the sound ID in an NSValue, or so.
If you can be bothered, dispose them when your app exits, is backgrounded, or on a memory warning.
The biggest caveat is that only a few sound formats are supported for "system sounds"; apple seems to recommend IMA4 (afconvert -f caff -d ima4 input.file output.caf and optionally -c 1 if you're happy with mono).
That said, it's pretty much perfect for playing short sounds provided you don't mind one-at-a-time sounds (it restarts playback if you play a sound while it's already playing). I suspect it's also played directly by the kernel (you can set a flag to make it continue playback when your app exits), which probably means it's more efficient CPU-wise. It might mix with sounds played by AVAudioPlayer.