iosswiftaudioavaudioengineavaudioplayernode

Playing an audio file repeatedly with AVAudioEngine


I'm working on an iOS app with Swift and Xcode 6. What I would like to do is play an audio file using an AVAudioEngine, and until this point everything OK. But how can I play it without stopping, I mean, that when it ends playing it starts again?

This is my code:

/*==================== CONFIGURATES THE AVAUDIOENGINE ===========*/
    audioEngine.reset() //Resets any previous configuration on AudioEngine

    let audioPlayerNode = AVAudioPlayerNode() //The node that will play the actual sound
    audioEngine.attachNode(audioPlayerNode) //Attachs the node to the audioengine

    audioEngine.connect(audioPlayerNode, to: audioEngine.outputNode, format: nil) //Connects the applause playback node to the sound output
    audioPlayerNode.scheduleFile(applause.applauseFile, atTime: nil, completionHandler: nil)

    audioEngine.startAndReturnError(nil)
    audioPlayerNode.play() //Plays the sound

Before saying me that I should use AVAudioPlayer for this, I can't because later I will have to use some effects and play three audio files at the same time, also repeatedly.


Solution

  • I found the solution in another question, asked and also auto-answered by @CarveDrone , so I've just copied the code he used:

    class aboutViewController: UIViewController {
    
    
        var audioEngine: AVAudioEngine = AVAudioEngine()
        var audioFilePlayer: AVAudioPlayerNode = AVAudioPlayerNode()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let filePath: String = NSBundle.mainBundle().pathForResource("chimes", ofType: "wav")!
            println("\(filePath)")
            let fileURL: NSURL = NSURL(fileURLWithPath: filePath)!
            let audioFile = AVAudioFile(forReading: fileURL, error: nil)
            let audioFormat = audioFile.processingFormat
            let audioFrameCount = UInt32(audioFile.length)
            let audioFileBuffer = AVAudioPCMBuffer(PCMFormat: audioFormat, frameCapacity: audioFrameCount)
            audioFile.readIntoBuffer(audioFileBuffer, error: nil)
    
            var mainMixer = audioEngine.mainMixerNode
            audioEngine.attachNode(audioFilePlayer)
            audioEngine.connect(audioFilePlayer, to:mainMixer, format: audioFileBuffer.format)
            audioEngine.startAndReturnError(nil)
    
            audioFilePlayer.play()
            audioFilePlayer.scheduleBuffer(audioFileBuffer, atTime: nil, options:.Loops, completionHandler: nil)
        }
    

    The only thing you have to change is the filePath constant. Here is the link to the original answer: Having AVAudioEngine repeat a sound