Reputation: 939
I needed to implement playing some .aiff sound 3 times in a row. Sound length is 0.1 ms and intervals between playing should be also 0.1 ms. So I decided to do it with NSTimer. This is my solution:
-(void)playSound{
timerCounter = 0;
timerForSound = [NSTimer scheduledTimerWithTimeInterval:0.2
target:self
selector:@selector(playSoundThreeTimes)
userInfo:nil
repeats:YES];
}
-(void)playSoundThreeTimes{
// play alert sound
AudioServicesPlaySystemSound(beepSound);
timerCounter++;
if(timerCounter == 3){ // sound played 3 times
[timerForSound invalidate];
timerCounter = 0;
}
}
The problem is that the sound lags sometimes, even if I set interval 0.25 (0.2 is because sound length + interval = 0.2).
Can anyone suggest a better way to do it or tell what the problem could be caused by.
Artem
Edit: Adding this to asynchronous thread also doesn't work:
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self playSound];
});
Upvotes: 4
Views: 855
Reputation: 3177
Two reasons: 1. NSTimer isn't 100% accurate. 2. You are firing events on the main thread which is where the rest of the UI is.
Like Adam says, you can put it on its own thread. Or maybe use something like CADisplayLink instead of NSTimer.
Edit: If you are right and the culprit is AudioSystemServices... I don't know if it will work but can you try creating 3 different beepSound references and then call beepSound1, beepSound2, beepSound3? Because I think it might be waiting for previous sound to stop. If it doesn't work, I think maybe you need to go with Audio Queue or OpenAL perhaps...
Upvotes: 2
Reputation: 2842
Try this:
-(void)playMyAudio {
//play audio method
if (loop<3) {
[self performSelector:@selector(playAudio) withObject:nil afterDelay:0.1];
loop++;
}
else {
loop = 0
}
}
if still lags, the only way i found is to create 3,4 avplayer and play in FIFO mode with AVAudioSession
Upvotes: 0
Reputation: 493
I could be wrong, but audio should be on it's own thread, however I'm not sure how to do about it in ObjC (I program audio in c++).
NSTimer is not always going to be accurate as (I think) it's a message thread. At high intervals (1 second+) it's not going to be noticeable, but at such short speeds, it's probably going to lag.
Upvotes: 3