Using AVAudioPlayer, my sounds (sporadically!) play weird - iphone

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.

Related

NStimer and Dispatchqueue starts a little late when using the airpot

My app provides voice to AVPlayer and gives a little term using Timer in the middle of playback so that users can read along.
It works well on simulators and real devices.
However, when you pair the air pot, the timer starts about 0.2 seconds late.
Why does this happen and how can I fix it?
I used 'Timer.scheduler' and 'Dispatchqueue.Main.asyncAfter', but both had the same symptoms.
I gather that you are starting playback and simultaneously starting a timer, but when you do this with Bluetooth earphones, that they don’t seem in sync. If that’s the case, I might suggest not using your own timer, but rather let the AVPlayer tell you where it is.
For example, you might use addPeriodicTimeObserver(forInterval:queue:using:). The AVPlayer tell you when it got to a particular point in the playback.

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

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.

set seek time in AVQueuePlayer in iphone

I am developing an application in that I want to play two video at the same time, That is not possible using MPMoviePlayer. So I have used AVQueuePlayer To play video. As I am success to play video but the problem is in jumping to particular time. For that we have method call seekToTime and we need to variable of the CMTime datatype.
I am able to jump at time in 1,2,3 seconds etc, My problem that I want to jump at Time 1.2, 1.3 , 1.4 second etc. but I am not able to move the video at that time.
Can any one know the solution of this problem than please help me to solve the problem.
The seekToTime: method, however, is tuned for performance rather than precision. If you need to move the playhead precisely, instead you use seekToTime:toleranceBefore:toleranceAfter Reference
toleranceBefore: The accuracy of the time before to which you would like to move the playback cursor.
[time-beforeTolerance]
toleranceAfter: The accuracy of the time after to which you would like to move the playback cursor.
[time+afterTolerance]
Lets say both parameters represents the margin of in-accuracy.
I have seen other Question on SO using self.player.currentItem.asset.duration to get the duration.
Good Luck.

How to play sound at precise moments on iPhone?

I'm working on creating a simple metronome on the iPhone. What the app does right now is to run a timer, entering the timer's function every 1/1000th of second. Then it checks the current time vs time of starting the app (I'm using CACurrentMediaTime() function).
CFTimeInterval currentTime = CACurrentMediaTime();
if (self.beatingStartTime == 0) {
self.beatingStartTime = currentTime;
}
if ( (currentTime - self.beatingStartTime) >= self.timeIntevalBetweenTicks * self.internalTimerCounter ) {
self.internalTimerCounter ++;
// ...
}
If there is a good moment to play audio, the code using OpenAL to play it gets fired.
Basicly that's it. I checked the sounds played when running both in simulator as well as on 2 devices (iPad and jailbroken iPhone 3GS) and there is a problem - when I recorded the sound and reviewed the waveform in Reaper software, some sounds play a bit too late, and some of them - bit too early (even I could understand the "too late" part, I don't really get how it can play earlier then it should - since the app checks the number of seconds every time, it basicly can't be ealier then specified time - yet it is, according to my recods).
At the same time there are some metronome apps that are known for being "rock-solid" when it comes to timing, so I guess there is a way. I just wonder what I'm missing...
edit: Changing timer call from 1/1000th second to, for example 1/100th doesn't help.
edit 2: When I switched from timer to threads (and I put the thread to sleep for specified time) I still get a strange behavior. The tempo moves around and while I could understand a little lag and playing some sounds too late, the problem is some of them do play too early - it means time distance between 2 beats is less then the time that should pass.
The diffrence is about 3%, which translates to about 10-15 miliseconds, which is quite a lot for me. Anyone got an idea why the sound can play earlier? I tried it both on iPhone simulator and on iPad actual device, and my only guess is there's something wrong with the timer - CACurrentMediaTime() returning more seconds that it should. Is it even possible?
Try using an NSSound, and load it up as an instance variable and don't release it unless your metronome isn't running. Delays can be caused by loading the file into memory on the loop. The other thing to consider is that a metronome probably doesn't need to poll every 1/1000th of a second. If you do it less often, you're less likely to saturate the CPU and you might get more consistent results.
Lastly, check out how Apple's demo works: http://developer.apple.com/library/ios/#samplecode/Metronome/Introduction/Intro.html
Might give you a better idea how to accomplish what you're trying to do :)
What you want is COCOS DENSHION which is a simple reliable easy to use sound library, that we have found solves all problems.
I (just personally) don't like "Cocos2D" but you can just take and use CocosDenshion.
Secondly -- 1000th of a second is ridiculous for a timer. Just totally forget it.
Thirdly -- AVAudioPlayer is worthless as you found.
Note - "ObjectAL" is a new, perhaps better, alternative
to CocosDenshion. Check it out.

AudioServices (Easy), AVAudioPlayer (Medium), OpenAL (Hard & Overkill?)

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.