Benr783
Benr783

Reputation: 2890

Swift - Have an audio repeat, but it plays in intervals?

In Swift, I play a song, it plays at the viewDidLoad. It is 16 seconds long, and it plays all 16 seconds. I want it to repeat forever. I made an NSTimer where every 16 seconds, it plays the song. But, it plays 16 seconds when the app loads, stops for 16 seconds, plays, etc.

The line println("just doing some dandy debugging here.") does print every 16 seconds.

How is this fixed?

CODE:

 //these var's are created on the top of the file.
 var soundTimer: NSTimer = NSTimer()
    var audioPlayer2 = AVAudioPlayer()
 var soundTwo = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("sound", ofType: "wav"))
 //this stuff is in the viewDidLoad function.
 audioPlayer2 = AVAudioPlayer(contentsOfURL: soundTwo, error: nil)
        audioPlayer2.prepareToPlay()
        audioPlayer2.play()
 soundTimer = NSTimer.scheduledTimerWithTimeInterval(16, target: self, selector: Selector("soundTimerPlayed"), userInfo: nil, repeats: true)
    func soundTimerPlayed() {
        println("just doing some dandy debugging here.")
        audioPlayer2.stop()
        audioPlayer2.prepareToPlay()
        audioPlayer2.play()
}

Upvotes: 0

Views: 4110

Answers (1)

Matt Gibson
Matt Gibson

Reputation: 38238

Just do it the easy, official way, instead. From the documentation of the numberOfLoops property:

Set any negative integer value to loop the sound indefinitely until you call the stop method.

But your actual problem is almost certainly because you're stopping playback a little early:

The stop method does not reset the value of the currentTime property to 0. In other words, if you call stop during playback and then call play, playback resumes at the point where it left off.

What's happening is that you're stopping the sound playback just a little before the actual end of the sample—your timer is set to just too short a time. The first time the timer is triggered, the "play" is playing the tiny amount of quiet or silent sound that's left at the end, and then stopping. The next time, the currentTime has been reset because the sample has successfully reached the end of playback, so on the next timer interval, after another 16 seconds, playback starts successfully from the beginning. And repeat.

As Jack observes in his comment, this is why there's a delegate callback to give you a kick when the playback has actually finished, but I'd still just set numberOfLoops and not bother with the complicated stuff, if you only need the sound to loop indefinitely.

(If you desperately want to repeat on your exact timer event, then just set currentTime to 0 before you play it again.)

Upvotes: 2

Related Questions