Reputation: 465
There shouldn't be lags, because I set up and preload each sound in viewDidLoad()
, before playing.
class GameViewController: UIViewController {
private var sounds = [String: SCNAudioSource]()
override func viewDidLoad() {
super.viewDidLoad()
loadAllSounds()
}
}
extension GameViewController {
private func loadSound(name: String, path: String) {
if let sound = SCNAudioSource(fileNamed: path) {
sound.isPositional = false
sound.volume = 0.8
sound.shouldStream = false
// Loads audio data from the source and prepares it for playing
sound.load()
sounds[name] = sound
}
}
private func loadAllSounds() {
loadSound(name: "Whoosh", path: "whoosh.wav")
loadSound(name: "Pop", path: "pop.wav")
loadSound(name: "Slide", path: "slide.wav")
}
}
For playing sounds, I have a function playSound()
. This function is called depending on the events in the game. For example, when a player jumps. So, lag occurs only the first time each sound is played.
private func playSound(withName name: String, atNode node: SCNNode) {
let playAudio = SCNAction.playAudio(sounds[name]!, waitForCompletion: false)
node.runAction(playAudio)
}
Looks like SCNAudioSource.load() doesn't load or prepare sounds. Either I'm doing something wrong.
I'd be happy to have any help. Thank you!
Upvotes: 2
Views: 418
Reputation: 31
I had the same problem when working with SCNAction.playAudio() in SceneKit. After days of playing with my sound file (changing codec, bitrate, etc.) I analyzed the issue using Instruments and concluded, that SceneKit will only initialize its Audio-Engine when you tell it to play a sound. I'm aware that this is not a great solution, but I could not figure out a more elegant one:
static func prepareSoundEngine(rootNode: SCNNode) {
let sound = SCNAudioSource(named: "init.mp3")!
sound.load()
let player = SCNAudioPlayer(source: sound)
player.didFinishPlayback = {
rootNode.removeAudioPlayer(player)
}
rootNode.addAudioPlayer(player)
}
'init.mp3' is just a one second long completely empty sound file. Check out this GitHub page to download such a file: https://github.com/anars/blank-audio
I then call this function as soon as my scene is visible and every SCNAction.playSound() will play without lag.
Upvotes: 3