Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVAudioPlayer produces lag despite prepareToPlay() in Swift

Playing a very short sound (~0.5s) produces a hiccup (like a lag) in my SpriteKit iOS game programmed in Swift. In other questions, I read that I should prepareToPlay() the sound, which I did.

I even used a variable (soundReady) to check if the sound is prepared before playing it. I also re-prepare the sound whenever it is finished playing (audioPlayerDidFinishPlaying()). Here are the relevant parts of the code:

class GameScene: SKScene, AVAudioPlayerDelegate {     var splashSound = NSURL()    var audioPlayer = AVAudioPlayer()    var soundReady = false     override func didMoveToView(view: SKView) {       let path = NSBundle.mainBundle().pathForResource("plopSound", ofType: "m4a")       splashSound = NSURL(fileURLWithPath: path)       audioPlayer = AVAudioPlayer(contentsOfURL: splashSound, error: nil)       audioPlayer.delegate = self       soundReady = audioPlayer.prepareToPlay()    }     func playSound(){       if(soundReady){          audioPlayer.play()          soundReady = false       }    }     func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool){       //Prepare to play after Sound finished playing       soundReady = audioPlayer.prepareToPlay()    } } 

I have no idea where I've gone wrong on this one. I feel like I have tried everything (including, but not limited to: only preparing once, preparing right after playing, not using a variable, but just prepareToPlay()).

Additional information:

  • The sound plays without delay.
  • How quickly the sound is played after the last finish does not seem to impact the lag.
like image 830
Timme Avatar asked Aug 26 '14 10:08

Timme


2 Answers

I ran into this same problem and played the sound in the backgroundQueue.

This is a good example: https://stackoverflow.com/a/25070476/586204.

let qualityOfServiceClass = QOS_CLASS_BACKGROUND let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0) dispatch_async(backgroundQueue, {     audioPlayer.play() }) 
like image 84
brilliantairic Avatar answered Sep 21 '22 10:09

brilliantairic


Just adding a Swift 3 version of the solution from @brilliantairic.

DispatchQueue.global().async {     audioPlayer.play() } 
like image 35
T R Bremm Avatar answered Sep 22 '22 10:09

T R Bremm