Chelseawillrecover
Chelseawillrecover

Reputation: 2644

Swift: Unable to play each sound sequence based on array

I am been trying to figure out how to play a sequence of sounds based on values in an array using switch case statement. So far it only plays the last integer corresponding sound.

What I am looking to achieve is when I click Play button, it loops through the soundSeq array values each and play corresponding sound before it stops. But in this case, it only plays the sound for tagid 5.

import UIKit
import AVFoundation

class UIController: UIViewController {
    var audioPlayer : AVAudioPlayer!

    let soundSeq = [2,4,5]

    func playSoundSeq() {
        for tag in soundSeq {
            switch tag {
            case 1 : loopSoundSeq(tagid: tag)
            case 2 : loopSoundSeq(tagid: tag)
            case 3 : loopSoundSeq(tagid: tag)
            case 4 : loopSoundSeq(tagid: tag)
            case 5 : loopSoundSeq(tagid: tag)
            case 6 : loopSoundSeq(tagid: tag)
            case 7 : loopSoundSeq(tagid: tag)
            default : print("no sound played")
            }
        }
    }

    @IBAction func playButton(_ sender: UIButton) {
        playSoundSeq()
    }

    func loopSoundSeq(tagid: Int) {
        var soundURl = Bundle.main.url(forResource: "minisound\(tagid)", withExtension: "wav")

        //machinePlay.append(sender.tag)

        do {
            audioPlayer = try AVAudioPlayer(contentsOf: soundURl!)
        }
        catch {
            print(soundURl)
        }

        audioPlayer.play()
    }
}

Upvotes: 0

Views: 131

Answers (1)

vacawama
vacawama

Reputation: 154593

You need to wait for each sound to finish playing before starting the next. Have your class adopt AVAudioPlayerDelegate and implement the AVAudioPlayerDelegate method audioPlayerDidFinishPlaying(_:successfully:) and trigger the next sound in the sequence:

import UIKit
import AVFoundation

class UIController: UIViewController, AVAudioPlayerDelegate {
    var audioPlayer: AVAudioPlayer!

    let soundSeq = [2, 4, 5]
    var index = 0

    func playSoundSeq() {
        if index < soundSeq.count {
            loopSoundSeq(tagid: soundSeq[index])
            index += 1
        }
    }

    @IBAction func playButton(_ sender: UIButton) {
        index = 0
        playSoundSeq()
    }

    func loopSoundSeq(tagid: Int) {
        let soundURL = Bundle.main.url(forResource: "minisound\(tagid)", withExtension: "wav")!

        //machinePlay.append(sender.tag)

        do {
            audioPlayer = try AVAudioPlayer(contentsOf: soundURL)
            audioPlayer.delegate = self
        }
        catch {
            print(soundURL)
        }

        audioPlayer.play()
    }

    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        if flag {
            playSoundSeq()
        }
    }
}

Upvotes: 2

Related Questions