I am developing an Audio effects application on OSX using Swift, and I'm interested in integrating a pitch-shift effect.
I would like in real-time, to change the tone up or down an octave. Currently I am only getting a dry signal.
I am not sure if this is possible at all and would like to know if this is even possible or any help or suggestions anyone may have.
Current code relevant to the problem is as follows:
import Cocoa
import AVFoundation
class ViewController: NSViewController {
var engine = AVAudioEngine()
var timePitch = AVAudioUnitTimePitch()
override func viewDidLoad() {
timePitch.pitch = 1200
// Setup engine and node instances
var mixer = engine.mainMixerNode
var input = engine.inputNode
var output = engine.outputNode
var format = input.inputFormatForBus(0)
var error:NSError?
engine.attachNode(timePitch)
engine.connect(input, to: timePitch, format: format)
engine.connect(timePitch, to: output, format: format)
engine.startAndReturnError(&error)
super.viewDidLoad()
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
}
timePitch.pitch = -500 //Rude man voice
timePitch.rate = 1.5 //In 1.5 times faster
Check this tutorial. And direct link to example from tutorial for more info.
Example for Swift 2.0:
import UIKit
import AVFoundation
class ViewController: UIViewController {
var engine: AVAudioEngine!
var player: AVAudioPlayerNode!
var file = AVAudioFile()
override func viewDidLoad() {
super.viewDidLoad()
engine = AVAudioEngine()
player = AVAudioPlayerNode()
player.volume = 1.0
let path = NSBundle.mainBundle().pathForResource("in", ofType: "caf")!
let url = NSURL.fileURLWithPath(path)
let file = try? AVAudioFile(forReading: url)
let buffer = AVAudioPCMBuffer(PCMFormat: file!.processingFormat, frameCapacity: AVAudioFrameCount(file!.length))
do {
try file!.readIntoBuffer(buffer)
} catch _ {
}
let pitch = AVAudioUnitTimePitch()
//
pitch.pitch = -500 //Distortion
pitch.rate = 1.5 //Voice speed
//
engine.attachNode(player)
engine.attachNode(pitch)
engine.connect(player, to: pitch, format: buffer.format)
engine.connect(pitch, to: engine.mainMixerNode, format: buffer.format)
player.scheduleBuffer(buffer, atTime: nil, options: AVAudioPlayerNodeBufferOptions.Loops, completionHandler: nil)
engine.prepare()
do {
try engine.start()
} catch _ {
}
player.play()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With