I´m making a music app for iOS. I want to play 5 files simultaneously. This already works with help of this thread: How to play multiple sounds from buffer simultaneously using nodes connected to AVAudioEngine's mixer
Now I need to play all the files a little faster using AVAudioUnitVarispeed. I cannot get this to work.
Here is the code:
import AVFoundation
class Audio {
// MARK: AUDIO VARIABLEN
var engineFirst: AVAudioEngine = AVAudioEngine()
var audioFilePlayer = [AVAudioPlayerNode]()
var noteFilePath = [String]()
// Speed
var speedControl = [AVAudioUnitVarispeed]()
var noteFileURL = [URL]()
var noteAudioFile = [AVAudioFile]()
var noteAudioFileBuffer = [AVAudioPCMBuffer]()
let tonAnzahl = 5
let latency = 0.03
var playing = false
// MARK: PLAY SOUND
func playSound() {
playing = true
for i in 0...tonAnzahl - 1 {
audioFilePlayer[i].scheduleBuffer(noteAudioFileBuffer[i], at: nil, completionHandler: nil)
audioFilePlayer[i].play()
}
}
// MARK: STOP SOUND
func stopSound() {
playing = false
for i in 0...tonAnzahl - 1 {
audioFilePlayer[i].volume = 0
}
DispatchQueue.main.asyncAfter(deadline: .now() + latency, execute: {
for i in 0...self.tonAnzahl - 1 {
self.audioFilePlayer[i].stop()
}
})
}
// MARK: SETUP AUDIO ENGINE
func setupAudioEngine(bassFile: String, terzFile: String, septimeFile: String, tensionOneFile: String, tensionTwoFile: String) {
do {
noteAudioFile.removeAll()
noteFileURL.removeAll()
// For each note, read the note URL into an AVAudioFile,
// setup the AVAudioPCMBuffer using data read from the file,
// and read the AVAudioFile into the corresponding buffer
for i in 0...tonAnzahl - 1 {
noteFilePath = [
Bundle.main.path(forResource: bassFile, ofType: "mp3")!,
Bundle.main.path(forResource: terzFile, ofType: "mp3")!,
Bundle.main.path(forResource: septimeFile, ofType: "mp3")!,
Bundle.main.path(forResource: tensionOneFile, ofType: "mp3")!,
Bundle.main.path(forResource: tensionTwoFile, ofType: "mp3")!]
noteFileURL.append(URL(fileURLWithPath: noteFilePath[i]))
try noteAudioFile.append(AVAudioFile(forReading: noteFileURL[i]))
let noteAudioFormat = noteAudioFile[i].processingFormat
let noteAudioFrameCount = UInt32(noteAudioFile[i].length)
noteAudioFileBuffer.append(AVAudioPCMBuffer(pcmFormat: noteAudioFormat, frameCapacity: noteAudioFrameCount)!)
try noteAudioFile[i].read(into: noteAudioFileBuffer[i])
}
// For each note, attach the corresponding node to the engineFirst, and connect the node to the engineFirst's mixer.
for i in 0...tonAnzahl - 1 {
audioFilePlayer.append(AVAudioPlayerNode())
engineFirst.attach(audioFilePlayer[i])
// HERE IS THE PROBLEM
speedControl.append(AVAudioUnitVarispeed())
speedControl[i].rate = 2
engineFirst.attach(speedControl[i])
engineFirst.connect(audioFilePlayer[i], to: speedControl[i], fromBus: 0, toBus: i, format: noteAudioFileBuffer[i].format)
engineFirst.connect(speedControl[i], to: engineFirst.mainMixerNode, fromBus: 0, toBus: i, format: noteAudioFileBuffer[i].format)
}
// Audio Engine Start
try engineFirst.start()
// Setup the audio session to play sound in the app, and activate the audio session
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.soloAmbient)
try AVAudioSession.sharedInstance().setMode(AVAudioSession.Mode.default)
try AVAudioSession.sharedInstance().setActive(true)
}
catch let error {
print(error.localizedDescription)
}
}
}
This code plays 5 notes simultaneously if I replace
// HERE IS THE PROBLEM
speedControl.append(AVAudioUnitVarispeed())
speedControl[i].rate = 2
engineFirst.attach(speedControl[i])
engineFirst.connect(audioFilePlayer[i], to: speedControl[i], fromBus: 0, toBus: i, format: noteAudioFileBuffer[i].format)
engineFirst.connect(speedControl[i], to: engineFirst.mainMixerNode, fromBus: 0, toBus: i, format: noteAudioFileBuffer[i].format)
with
engineFirst.connect(audioFilePlayer[i], to: engineFirst.mainMixerNode, fromBus: 0, toBus: i, format: noteAudioFileBuffer[i].format)
... and call playSound().
But then I don't have the AVAudioUnitVarispeed (speedControl) implemented...
So, how to add the code for AVAudioUnitVarispeed?
Thank you for your help.