当我添加一束(20-40)的样本同时在演奏和彼此重叠时,有时会开始变形,然后开始出现一些波动,振荡和咔嗒声。当样本正在播放时,应用程序崩溃时会发生类似的声音-听起来像是突然的,嘎吱作响的停止。
注意起伏在0:05到0:10之间开始;讨厌的点击从0:15开始。
Listen Here
如何使它更平滑?我正在生成播放4-8秒的.wav文件的AKPlayer对象(从4.1开始)。这些进入AKBoosters,再进入AKMixer,再进入最终的AKMixer进行输出。
编辑:
许多PenAudioNodes被插入到AudioReceiver单例的混音器中。
这是我的AudioReceiver单例:
class AudioReceiver {
static var sharedInstance = AudioReceiver()
private var audioNodes = [UUID : AudioNode]()
private let mixer = AKMixer()
private let queue = DispatchQueue(label: "audio-queue")
//MARK: - Setup & Teardown
init() {
AudioKit.output = mixer //peakLimiter
AudioKit.start()
}
//MARK: - Public
func audioNodeBegan(_ message : AudioNodeMessage) {
queue.async {
var audioNode: AudioNode?
switch message.senderType {
case .pen:
audioNode = PenAudioNode()
case .home:
audioNode = LoopingAudioNode(with: AudioHelper.homeLoopFile())
default:
break
}
if let audioNode = audioNode {
self.audioNodes[message.senderId] = audioNode
self.mixer.connect(input: audioNode.output)
audioNode.start(message)
}
}
}
func audioNodeMoved(_ message : AudioNodeMessage) {
queue.async {
if let audioNode = self.audioNodes[message.senderId] {
audioNode.update(message)
}
}
}
func audioNodeEnded(_ message : AudioNodeMessage) {
queue.async {
if let audioNode = self.audioNodes[message.senderId] {
audioNode.stop(message)
}
self.audioNodes[message.senderId] = nil
}
}
}
这是我的PenAudioNode:
class PenAudioNode {
fileprivate var mixer: AKMixer?
fileprivate var playersBoosters = [AKPlayer : AKBooster]()
fileprivate var finalOutput: AKNode?
fileprivate let file: AKAudioFile = AudioHelper.randomBellSampleFile()
//MARK: - Setup & Teardown
init() {
mixer = AKMixer()
finalOutput = mixer!
}
}
extension PenAudioNode: AudioNode {
var output: AKNode {
return finalOutput!
}
func start(_ message: AudioNodeMessage) {
}
func update(_ message: AudioNodeMessage) {
if let velocity = message.velocity {
let newVolume = Swift.min((velocity / 50) + 0.1, 1)
mixer!.volume = newVolume
}
if let isClimactic = message.isClimactic, isClimactic {
let player = AKPlayer(audioFile: file)
player.completionHandler = { [weak self] in
self?.playerCompleted(player)
}
let booster = AKBooster(player)
playersBoosters[player] = booster
booster.rampTime = 1
booster.gain = 0
mixer!.connect(input: booster)
player.play()
booster.gain = 1
}
}
func stop(_ message: AudioNodeMessage) {
for (_, booster) in playersBoosters {
booster.gain = 0
}
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 1) {
self.mixer!.stop()
self.output.disconnectOutput()
}
}
private func playerCompleted(_ player: AKPlayer) {
playersBoosters.removeValue(forKey: player)
}
}
最佳答案
这听起来像您没有释放对象,并且最终使音频引擎过载,图中连接的处理节点实例过多。特别是不释放AKBoosters会引起这样的问题。我不能真正说出代码在做什么,但是如果生成对象而没有正确释放它们,则会导致音频混乱。
您希望尽可能节省对象,并确保使用的是基于AKNode的绝对最小数量的处理。
有多种调试方法,但是您可以首先打印出AVAudioEngine的当前状态:
AudioKit.engine.description
这将显示您在任何给定时刻在图中连接了多少个节点。