First time audio playing getting slow my Sprite Kit game? - ios

I'm new with Sprite Kit, I have a short sound effect to play in a function. I have tried AVFoundation and SKAudioNode like below in that function. But I discovered It triggers some stuck for my SKActions. How Can I solve this playing problem. It looks waiting for completion or something different?
let audioNode = SKAudioNode(fileNamed: "catch")
audioNode.autoplayLooped = false
self.addChild(audioNode)
let playAction = SKAction.play()
audioNode.run(playAction)

There is another action for playing sound file,
you can use
SKAction.playSoundFileNamed("catch", waitForCompletion: false)
instead of SKAction.play().
There is a complete explanation of what waitForCompletion is doing in Apple Documentation

Related

How can I pause SCNAudioPlayer playback in ARKit?

I'm trying to implement a play/pause button for positional audio attached to a node in an ARKit scene. I want the user to be able to pause the audio, then resume it from the paused point at a later time. So removeAudioPlayer() is no good, as this resets the audio back to the start when it is reattached.
The only pause method associated with SCNAudioPlayers that I can find is buried deep down in:
myAudioPlayer.audioNode?.engine?.pause()
But this doesn't seem to have any effect. Strangely
myAudioPlayer.audioNode?.engine?.stop()
Does stop the audio from playing, but then you can't start it again afterwards!
My code for creating the audioPlayer is as follows:
audioSource = SCNAudioSource(fileNamed: "audio.caf")!
audioSource.loops = false
audioSource.isPositional = true
audioSource.shouldStream = false
audioSource.load()
// then a bit later...
audioPlayer = SCNAudioPlayer(source: audioSource)
myARNode.addAudioPlayer(audioPlayer)
Notice that no 'play' method is needed. The audio just starts playing as soon as you attach it to the node. And the lack of straight play() and pause() methods as top-level properties of SCNAudioPlayer makes me wonder if it's possible at all. This seems slightly crazy however, as it's a pretty rudimentary aspect of working with audio.
Does anyone know if this can be done?
Thanks in advance.
To stop audio engine use 2 sec delay. Pause doesn't work here (I'm using Xcode 12.2).
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
player.audioNode?.engine?.stop()
}

Sprite Kit: Why does playing sound return error?

I upgraded my Sprite Kit game to X-Code 8.0 and Swift 3 yesterday. Deployment target is currently set to iOS 9.3.
I play sound effects the following way:
self.run(SKAction.playSoundFileNamed("click.caf", waitForCompletion: false))
The sound effect is not played correctly (only about the half of the samples) and I get the following error (since upgrade to X-Code 8.0 and Swift 3):
SKAction: Error playing sound resource
Any ideas ?
The problem disappeared when I removed this preload code. Do you have something similar? But now I get a short delay the first time a sound is played. Don't know how I shall handle that.
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Preload sounds
[SKAction playSoundFileNamed:#"coinBlip.wav" waitForCompletion:NO];
[SKAction playSoundFileNamed:#"bonus.wav" waitForCompletion:NO];
:
My bug report (28350796) has been fixed now, and I've verified it on
iOS 10.2 in beta simulator. So add a new bug report if your problems
still exist on iOS 10.2!
I found a solution that works with me. I use a computed SKAction sound property instead of preloaded sounds:
var enemyCollisionSound: SKAction { return SKAction.playSoundFileNamed("hitCatLady.wav", waitForCompletion: false) }
I'm also having this issue and I've tracked it down to if a node is trying to play a sound and it has created an instance of another object within its code and that object has preloaded audio code, the node that created the other will not play its sounds.
Having had the same issue, getting an error “SKAction: Error playing sound resource” the first time certain sounds are played, I found that assigning the sound’s SKAction to an empty variable in “didMoveToView” completely solved the issue for me.
Declare the sound action in the normal simplest way:
let waterDropSoundAction = SKAction.playSoundFileNamed("WaterDrop.caf", waitForCompletion: false)
Then to load the sound action without actually playing it in didMoveToView:
let _ = waterDropSoundAction

SpriteKit background music not looping forever

I'm making a simple SpriteKit game with two scenes, and I want the background music to loop unconditionally through both scenes. Right now, I'm using
if soundIsPlaying == false {
runAction(SKAction.repeatActionForever(backgroundMusicEffect), withKey: "backgroundMusic")
soundIsPlaying = true
}
in my menu scene where backgroundMusicEffect is a global variable
let backgroundMusicEffect = SKAction.playSoundFileNamed("content/divertimentoK131.mp3", waitForCompletion: true)
When I play my game, the music never loops. It always stops after one play. If I remove the if-else statement, the music plays over itself every time I reenter the menu.
Is there a better way to play background music? What am I doing wrong?
I believe that the way you are doing it, after the first time looping, every iteration after is "complete" since the sound is finished. You would need to create a new SKAction instance every time if you want to get this to loop.
This of course is a bad idea, since playSoundFileNamed is designed to only play a sound file once with as little over head as possible.
As #Alessandro Omano has commented, use SKAudioNode to get sound playing in a loop. This is my preferred way of doing in, but you limit yourself to >= iOS 9 users.
If you have to support iOS 8 users (At this point I would say why bother) then you need to look into the AVFoundation sections of the libs to get audio going, or use OpenAL.

SKAction plays sound loop with a pause

Loop is playing fine, except one thing: a little pause between iterations. Code:
var bgMusic = SKAction.repeatActionForever(SKAction.playSoundFileNamed("MenuSound.mp3", waitForCompletion: true))
Your pause is probably caused by a silent period at the end of your music/sound file. Use a sound editor app to cut out the dead air at the end of the file.

Looped sound Hiccups

I have a sound file I wish to loop like the engine of a vehicle.
The sound I have is 1 second long and it is a .wav file.
I'm quite certain the file is cut to be seamless,
it loops perfectly in Audacity.
I'm calling the sound with this code:
let playEngineSound = SKAction.playSoundFileNamed("engine.wav", waitForCompletion: true)
let engineSoundLoop = SKAction.repeatActionForever(playEngineSound)
self.runAction(EngineSoundLoop, withKey: "engine sound")
I use "withKey" to be able to cancel it later.
The Sound comes out fine but there is a small but distinctive hiccup where the sound seems to be reloading or waiting for the other to stop completely before starting the new loop.
Any help would be much appreciated!
Edit: After trying the AVAudioPlayer route, it plays flawlessly, someone knows anything about the behaviour? I still want to go purely SKAction if possible.

Resources