How to change audio pitch during playback? (Swift 4)
Actually, I got the answer from reddit. All I had to do was to declare the pitch
and speed
variables outside of the Play()
function, along with the pitch.pitch = speedIncrement * (-500)
and speed.rate = speedIncrement
expressions. I knew I was missing something simple...
Swift change Pitch and Speed of recorded audio
Turns out this was simpler than I had thought using @AppStorage
and conditionals to integrate the desired player. Thanks!
Changing the pitch of a sound in realtime (Swift)
If you use the Audio Unit API, the iOS built-in kAudioUnitSubType_NewTimePitch Audio Unit component can be used to change pitch while playing audio at the same speed. e.g. the kNewTimePitchParam_Rate and kNewTimePitchParam_Pitch parameters are independent.
The Audio Unit framework has a (currently non-deprecated) C API, but one can call C API functions from Swift code.
Changing Audio Pitch of sounder
You'll use the AVAudioEngine
to attach the AVAudioPlayerNode
to the AVAudioUnitTimePitch
effect. I checked Apple's AudioUnitV3Example sample code and cobbled together a working example from it. You'll want to implement more state and error handling that you can find in there. Anyway, here goes:
Define some private variables at the top of your class:
/// Playback engine.
private let audioEngine = AVAudioEngine()
/// Engine's player node.
private let pitchPlayer = AVAudioPlayerNode()
private let timePitch = AVAudioUnitTimePitch()
/// File to play.
private var audioFile: AVAudioFile?
Check for a valid audio file:
override func viewDidLoad() {
super.viewDidLoad()
if let filePath = Bundle.main.path(forResource: "Sound1", ofType:
"mp3") {
let filePathURL = URL(fileURLWithPath: filePath)
setPlayerFile(filePathURL)
}
}
private func setPlayerFile(_ fileURL: URL) {
do {
let file = try AVAudioFile(forReading: fileURL)
self.audioFile = file
} catch {
fatalError("Could not create AVAudioFile instance. error: \(error).")
}
}
@IBAction func verySlowPlayback(sender: UIButton) {
timePitch.pitch = -300
timePitch.rate = 0.5
audioEngine.attach(pitchPlayer)
audioEngine.attach(timePitch)
audioEngine.connect(pitchPlayer, to: timePitch, format: audioFile?.processingFormat)
audioEngine.connect(timePitch, to: audioEngine.outputNode, format: audioFile?.processingFormat)
pitchPlayer.scheduleFile(audioFile!, at: nil, completionHandler: nil)
// Start the engine.
do {
try audioEngine.start()
} catch {
fatalError("Could not start engine. error: \(error).")
}
pitchPlayer.play()
}
Related Topics
Swift 3/Macos: Open Window on Certain Screen
Use Different Googleservice-Info.Plist for Single Project in Xcode Using Swift4
Alamofire 3 Custom Encoding to Alamofire 4 Custom Encoding
How to Migrate Core Data's Data to App Group's Data
How to Check Whether an Object Is Kind of a Dynamic Class Type in Swift
How to Call a Generic Swift Function When None of the Arguments Provides the Generic Type
Implementing Reconnection with Urlsession Publisher and Combine
Correct Way to Call "Realloc" in Swift with a Float Array
Safari App Extension Crashes After a Few Seconds for Hello World Project
How to Understand What Is Causing a Crash Involving '_Nstouchbarfinderobservation'
Swift Get Nsdata of a Video from Photos Library
Curl with Alamofire - Swift - Multipart/Form-Data
Loop Over Multiple Uialertcontroller'S
Swiftui Sheet Not Updating Variable
Dynamic Uicollectionview Inside Dynamic Uitableviewcell
Not Getting Expected Delegate Calls When Trying to Restore In-App Purchases with Storekit
How to Prevent a Spacer to Make a VStack Greedly Grow Beyond Necessary