0

I’m trying to get some audio to be able to have the pitch adjusted whilst playing. I’m very new to Swift and iOS, but my initial attempt was to just change timePitchNode.pitch whilst it was playing; however, it wouldn’t update whilst playing. My current attempt is to reset audioEngine, and have it just resume from where it was playing (below). How do I determine where the audio currently is, and how do I get it to resume from there?

var audioFile: AVAudioFile?
var audioEngine: AVAudioEngine?
var audioPlayerNode: AVAudioPlayerNode?
var pitch: Int = 1 {
    didSet {
        playResumeAudio()
    }
}

…

func playResumeAudio() {
    var currentTime: AVAudioTime? = nil

    if audioPlayerNode != nil {
        let nodeTime = audioPlayerNode!.lastRenderTime!
        currentTime = audioPlayerNode!.playerTimeForNodeTime(nodeTime)
    }

    if audioEngine != nil {
        audioEngine!.stop()
        audioEngine!.reset()
    }

    audioEngine = AVAudioEngine()

    audioPlayerNode = AVAudioPlayerNode()
    audioEngine!.attachNode(audioPlayerNode!)

    let timePitchNode = AVAudioUnitTimePitch()
    timePitchNode.pitch = Float(pitch * 100)
    timePitchNode.rate = rate
    audioEngine!.attachNode(timePitchNode)

    audioEngine!.connect(audioPlayerNode!, to: timePitchNode, format: nil)
    audioEngine!.connect(timePitchNode, to: audioEngine!.outputNode, format: nil)

    audioPlayerNode!.scheduleFile(audioFile!, atTime: nil, completionHandler: nil)
    let _ = try? audioEngine?.start()

    audioPlayerNode!.playAtTime(currentTime)
}
Jacob
  • 1,204
  • 1
  • 12
  • 25

1 Answers1

0

I was being dumb apparently. You can modify the pitch during playback, and it does update. No need to reset any audio, just mutate the node as it’s playing, and it’ll work.

Jacob
  • 1,204
  • 1
  • 12
  • 25