salocinx salocinx - 11 months ago 237
iOS Question

iOS: How to play audio without fps drops?

I am in the process of developing a game for iOS 9+ using Sprite Kit and preferably using Swift libraries.

Currently I'm using a Singleton where I preload my audio files, each connected to a separate instance of AVAudioPlayer.

Here's a short code-snipped to get the idea:

import SpriteKit
import AudioToolbox
import AVFoundation

class AudioEngine {

static let sharedInstance = AudioEngine()

internal var sfxPing: AVAudioPlayer

private init() {

self.sfxPing = AVAudioPlayer()

if let path = NSBundle.mainBundle().pathForResource("ping", ofType: "m4a") {
do {
let url = NSURL(fileURLWithPath:path)
sfxPing = try AVAudioPlayer(contentsOfURL: url)
} catch {
print("ERROR: Can't load ping.m4a audio file.")



This Singleton is initialised during app start-up. In the game-loop I then just call the following line to play a specific audio file:

This basically works, but I always get glitches when a file is played and the frame rate drops from 60.0 to 56.0 on my iPad Air.

Someone any idea how to fix this performance issue with AVAudioPlayer ?

I also watched out for 3rd party libraries, namely:


  • Play a lot of very short samples (like shots, hits, etc..)

  • Play some motor effects (thus pitching would be nice)

  • Play some background / ambient sound in a loop

  • NO nasty glitches / frame rate drops !

Could you recommend any of the above mentioned libraries for my requirements ?


Playing short sounds with:

self.runAction(SKAction.playSoundFileNamed("sfx.caf", waitForCompletion: false))

does indeed improve the frame rate. I exported the audio files with Audiacity to the *.caf format (Apple's Core Audio Format). But in the tutorial, they export with "Signed 32-bit PCM" encoding which led to disturbed audio playback in my case. Using any of the other encoding options (32-bit float, U-Law, A-Law, etc..) worked fine for me.


According to your question, if you develop a game for iOS 9+, you can use the new iOS 9 library SKAudioNode (official Apple doc):

var backgroundMusic: SKAudioNode!

For example you can add this to didMoveToView():

if let musicURL = NSBundle.mainBundle().URLForResource("music", withExtension: "m4a") {
    backgroundMusic = SKAudioNode(URL: musicURL)

You can also use to play a simple effect:

let beep = SKAudioNode(fileNamed: "beep.wav")
beep.autoplayLooped = false

Finally, if you want to change the volume:

beep.runAction(SKAction.changeVolumeTo(0.4, duration: 0))