Playing the same sound at the same time? (swift, spritekit) - iphone

Im trying to play a pop sound whenever a ball is touched but if the ball is touched again, before the pop sound ends, the sound will not play. I want the pop sound to cut out and start playing again if the ball is touched over and over again. The code i have now is below...
let popSound = NSBundle.mainBundle().URLForResource("pop",withExtension: "wav")
let Pop = AVAudioPlayer(contentsOfURL: popSound, error: nil)
////this is in the touches begin function/////
if touchedNode==ball{
Pop.play()
}
//////////////////////////////////

I fixed it with the help of this post. AVAudioPlayer stop a sound and play it from the beginning
I needed to set the Pop.currentTime to = 0
if touchedNode==ball{
Pop.currentTime=0
Pop.play()
}

Related

How to loop through background music at specific time in SwiftUI

Is it possible to loop through a background song but skip the first 30 seconds when the song loops the next iterations? So during the first run, the entire song gets played, but from the second loop onwards, the loop skips the first 30 seconds of the song. This is for a game and the first 30 seconds is simply to get the user excited but the following loops is just the causal background music.
Currently I've found on stackoverflow:
var AudioPlayer = AVAudioPlayer()
let AssortedMusics = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("backgroundMusic", ofType: "mp3")!)
AudioPlayer = try! AVAudioPlayer(contentsOfURL: AssortedMusics)
AudioPlayer.prepareToPlay()
AudioPlayer.numberOfLoops = -1
AudioPlayer.play()
For SwiftUI I'm guessing to put that into a function and run it inside an onAppear() when the game starts. But how'd I be able to play the beginning of the song only in the first loop?
Just play it first time and then loop with
'AudioPlayer.currentTime += 30'

Stop crashing when AVAudioPlayer URL is nil?

I'm still a beginner in coding but I'm working on a very basic music player to get an idea of how Swift works.
////Functions
//Play chosen file function
func playChosenFile() {
//Set up the music file URL.
let musicFilePathURL = MenuBarModel.mainMenu.URL
if musicFilePathURL != nil {
//Initialize audioPlayer with safety.
do {
try audioPlayer = AVAudioPlayer(contentsOfURL: musicFilePathURL!)
}
catch {
}
}
else if musicFilePathURL == nil {
//Some code that will make the player do nothing.
}
}
//Play function
func play() {
playChosenFile()
audioPlayer.play()
}
So musicFilePathURL gets initialized with a URL if I choose an audio file using NSOpenPanel().
If I do select a file using NSOpenPanel(), then musicFilePathURL has the location of the selected file and is then passed to AVAudioPlayer. Once I press the Play button, the function "play()" executes and then it executes playChosenFile() and audioPlayer.play().
The music player plays the song if I do this before pressing the play button.
If I press the play button before selecting any file to play, then the program crashes because musicFilePathURL is nil.
I'm confused on how to make the program not crash if there is no file selected before pressing the play button. As an example, if you open VLC, if you press the Play button, it prompts to pick a file, but if you decide to press cancel, the player does nothing.
How can I make my program do nothing if I press the play button with no audio file picked at startup?
You've got the right idea with the try/catch statements for the Audio Player, but you could probably use another one in the play() function.
That way when the audioPlayer attempts to play a null object, an exception will be caught and you can process it handle it on your own rather than having the app crash.
Perhaps something like this? I would try it, but unfortunately I left my Mac at home.
func play(){
do {
playChosenFile()
audioPlayer.play()
} catch {
print "Error Occurred (Did the user specify a file?)
}
}

SpriteKit overlaying audio file

I'm trying to set a background jingle for my game which is supposed to start at the Home scene and then loop continuously even while on the other scenes.
This is what my class looks like:
class AudioPlayer: AVAudioPlayer {
var audioPlayer: AVAudioPlayer? = AVAudioPlayer()
let ost = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("bkg", ofType: "mp3")!)
func playOst() {
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: ost)
}
catch {
audioPlayer = nil
}
audioPlayer?.prepareToPlay()
audioPlayer!.play()
audioPlayer!.numberOfLoops = -1
}
func stopOst() {
audioPlayer!.stop()
}
since I put the play method in the home scene, it will start playing a new track every time I load it, overlaying one track on another making it result in a big mess. How can I prevent it?
Make your audio player class a singleton, or let AppDelegate look after it. This will also allow you to control the music from any scene/screen in your app at any time.
Whenever your home screen loads check to see if music is already playing, if not, call playOst, otherwise do nothing.

Getting sounds to work right

I am trying to add sound effects to a game app I am making in Xcode 6. Here is the code that I am using to play the sounds:
var jumpSoundPlayer:AVAudioPlayer = AVAudioPlayer()
var jumpAudioPath:String = ""
var jumpSoundError: NSError? = nil
func setUpSoundPlayers(){
jumpAudioPath = NSBundle.mainBundle().pathForResource("Jump", ofType: "mp3")!
jumpSoundError = nil
jumpSoundPlayer = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: jumpAudioPath), fileTypeHint: "mp3", error: &jumpSoundError)
}
func playJumpSound(volume:Float = 1){
jumpSoundPlayer.volume = volume
jumpSoundPlayer.play()
}
I can get sounds to play, but it seems as though it will not play a sound until the one currently playing is finished. How can I get it so that multiple sounds can play at once and overlap each other?
Also, every time a sound plays it drops the frame rate down a little bit. Is there a way to fix that?
I believe you have to use
jumpSoundPlayer.prepareToPlay()
before using
jumpSoundPlayer.play()
Also the only solution to drop the frame rate a little less, is to set up all the AVAudioPlayers before using them or at the beginning of the game.

Audio Jump Forward Button

I've got the following code tied to a 'Jump Forward' button:
#IBAction func jumpForwardPressed(sender: AnyObject) {
var currentTime = audioPlayer.currentTime
var playForwardSkip = NSTimeInterval()
audioPlayer.stop()
audioPlayer.prepareToPlay()
playForwardSkip = 3.0 // skip forward 3 seconds
var skipF = currentTime + playForwardSkip
println("currentTime:\(currentTime) and playForwardSkip:\(playForwardSkip) and skipF:\(skipF)")
audioPlayer.playAtTime(skipF)
When button is pressed, audio stops, console reads out correct 'skipF' to skip to but audio does not play at that new point in time. It does not play at all.
Any pointers as to what might be wrong with my code?
You have misread the docs. playAtTime: does not seek to a later time in a sound file. It delays the start of playing the sound file (from the start).
To play from the middle of a sound file, set the player's currentTime and start playing.