How to get notified when AVAudioPlayer loops back to the beginning? - iphone

I'm playing a sound file in a loop and need to restart an animation with it every time the loop starts from the beginning.
I couldn't find a delegate method for it in the documentation. Is there a way to get notified when the player loops around to the beginning?
My approach was to use a timer which checks current play time every few milliseconds but this sounds like a horrible solution.

No, AFAIK your solution is the only one which works. The finishedPlaying method is not called whilst looping so sampling the position is the only technique.
I'm updating some inherited code to add looping and came to this conclusion under iOS8.

You can set up a delegate for the avaudioplayer instance. Then the delegate will be notified whenever the sound has successfully finished playing. Then you can probably restart the player to play again and restart your animation. Just off the top of my head. Look here for more information.

Related

AVAudioPlayerNode - Get Player State?

In an iOS-project I am using the AVAudioPlayerNode in conjunction with the AVAudioEngine and an AVAudioUnitTimePitch. Everything works peachy. However, I was wondering if there is a way to figure out what the current player's state (e.g. isPlaying, isPaused) or at least the playback position is.
While AVAudioPlayer at least allows you to get the currentTime-parameter, I could not yet figure out how to get that information with AVAudioPlayerNode. I tried playing around with the nodeTimeForPlayerTime and playerTimeForNodeTime methods described in the swift documentation but I couldn't make any progress.
Any help would be highly appreciated.
Since the AVAudioPlayerNode is designed as an audio stream, it doesn't necessarily keep track of the time within a particular file. However, the AVAudioPlayerNode does keep a running time of how long its been playing all audio. This timer doesn't reset with each file, in order to change it, you must explicitly tell it where you want to start counting from.
So to find the current time the player has been playing you must do the following:
player.lastRenderTime.sampleTime / file.fileFormat.sampleRate
Now in order to get the timer to reset after each file, you must explicitly reset the players current time. To do this use the player.playAtTime: function.
If you would like an example, check one out here: https://github.com/danielmj/AEAudioPlayer

Using AVAudioPlayer, my sounds (sporadically!) play weird

I've done a simple audio playback GUI implemented using AVAudioPlayer.
When playing my sound, I use a UISlider to provide playback feedback...
Here's where it gets weird.
I have a problem that happens very (very) sporadically - and mostly it doesn't happen, making it really hard to debug.
The problem is that sometime, once the sound ends, and I play it again, it's as if it starts looping (as if I set numberOfLoops to -1), without ever calling audioPlayerDidFinishPlaying.
Now, no where is my code do I "touch" numberOfLoops - it defaults to 0, and I leave it that way.
To make the problem weirder, then once this problem happens, I don't "hear" the audio - though it does appear to play (i have a timer function that provides the visual feedback, and it checks the sound is playing...)
Any ideas? Directions?
I faced the same issue once and I got around the issue by increasing the updating timer interval to .25 seconds,which was earlier .1 seconds. Also I tried to avoid files with very small duration. Hope this helps you to some extend. Please try it and let me know if it worked for you.

Playing multiple sounds simultaneously with AVAudioPlayer

Could someone help me with a function that fires multiple AVAudioPlayers at the same time? Right now I am trying to get a total of twelve AVAudioPlayers to fire at once if twelve buttons are activated, but there is a delay and it sounds like someone is running their finger down a piano instead of hitting all the keys at once.
I've looked at Audio Queue Services and can't understand how to actually implement that into code, but it says it can play synchronized sounds. I'm not sure sure how to set all of it up. I'm trying to remake a Tone Grid app.
Why don't you use http://www.hollance.com/2011/02/soundbankplayer-using-openal-to-play-musical-instruments-in-your-ios-app/
There you have a polyphonic player, beautifully coded and ready to rock!
I used it in my first app a while back: http://itunes.apple.com/gb/app/chordwheel-pro/id406836326?mt=8
Are you calling the method prepareToPlay on all 12 AVAudioPlayer instances. From the docs: "Calling this method, preloads the buffers and acquires hardware, to minimize delay."
See the AVAudioPlayer class reference.

syncing sound with CCAnimation

I have a CCSpeed that contains a CCAnimation that dynamically changes it's speed based on stuff that's going on in the game. Is there any way i can get the animation to call a selector each time the animation "ticks" (switches frame), in this specific case, in order to play a sound?
Edit: Other solutions to sync the animation ticks with sound are welcome as well
I wonder if QuartzCore/CADisplayLink might be what you're looking for.
You can create one with -[UIScreen - displayLinkWithTarget:selector: ]
You can get a callback for every screen refresh (VBL) cycle.

How to use NSOperation and NSOperationQueue

I made an app which plays the song on clicking on the image of artist.(see image attached). Each artist image is implemented on button and on clicking this button, a function is being called which first downloads and then plays the song. I passed this method(function) in a thread but problem is that every time when I click on the image of artist(button) new threads starts running and then multiple songs gets started playing concurrently. How can I use "NSOperation and NSOperationQueue" so that only one song will run at a time . Please help.
Thanks in advance
NSOperation and NSOperationQueue aren't going to directly solve your problem.
If I were pursuing a dead simple approach, I would have a global AudioPlayer object that has a method startPlaying: whose argument is the song to play (represented however needed; URL, NSData, whatever you need).
In that method, I'd stop playing whatever is currently playing and start the new track.
If I remember correctly, I don't think you even need a thread for this; the audio APIs are generally quite adept at taking care of playback in the background.
In any case, if you do need a thread, then I'd hide that thread in my AudioPlayer object and let it take care of telling the music to stop/start playing in said thread. A queue of some kind -- operation or GCD -- could be used for that, yes.