AVAudioEngineでフォルダ内の音声ファイルを再生する

はじめに

音を再生する場合AVAudioPlayerで再生しがちですが、AVAudioEngineを触ったことがなかったので試してみました

class ViewController: UIViewController {
    let audioEngine = AVAudioEngine()
    let playerNode = AVAudioPlayerNode()

    var isPlaying: Bool = false

    override func viewDidLoad() {
        super.viewDidLoad()

        audioEngine.attach(playerNode)

        audioEngine.connect(playerNode, to: audioEngine.outputNode, format: nil)
        try? audioEngine.start()
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)

        if isPlaying {
            playerNode.stop()
        } else {
            guard let fileURL = Bundle.main.url(forResource: "sample", withExtension: "mp3")  else {
                fatalError("ファイルに参照できません")
            }

            let file = try! AVAudioFile(forReading: fileURL)
            playerNode.scheduleFile(file, at: nil)
            playerNode.play()
        }

        isPlaying.toggle()
    }
}

内部

AVAudioEngineの仕組みとして以下のようにPlayerやEffectなどに接続した上で音を鳴らすようです。

今回はEffectなどは使わずにPlayerだけAVAudioEngineに接続します。

audioEngine.attach(playerNode)

AVAudioEngineに接続した後に画像の→の矢印部分の流れを作るためにconnectメソッドで処理を繋いでいきます。

今回はシンプルにplayerNodeから出力のaudioEngine.outputNodeに繋いでいます。

audioEngine.connect(playerNode, to: audioEngine.outputNode, format: nil)

再生する際にはplayメソッドを呼び出すだけではなくスケジューリングして再生する対象を指定した後にplayで鳴らします

playerNode.scheduleFile(file, at: nil)
playerNode.play()