gpt4 book ai didi

avaudioengine - 动态重新连接 AVAudioEngine 节点而不停止声音

转载 作者:行者123 更新时间:2023-12-05 05:09:03 25 4
gpt4 key购买 nike

我正在尝试动态修改附加到 AVAudioEngine 的节点图,但该图在每次重新连接后输出静音。

在下面的示例中,我想将 player 动态连接到 engine.mainMixerNode,但是每当我调用 toggleBypass 时,我都会沉默.

是否可以在不暂停 AVAudioPlayerNode 播放的情况下执行此重新布线?

class Sample: UIViewController {

let engine = AVAudioEngine()
let player = AVAudioPlayerNode()
let effectNode = AVAudioUnitDelay()

@objc func toggleBypass() {
if effectNode.numberOfInputs == 0 {
engine.connect(player, to: effectNode, format: file.processingFormat)
engine.connect(effectNode, to: engine.mainMixerNode, format: file.processingFormat)
} else {
engine.connect(player, to: engine.mainMixerNode, format: file.processingFormat)
}
}

override func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = .red

view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(toggleBypass)))

try! AVAudioSession.sharedInstance().setCategory(.playback)
try! AVAudioSession.sharedInstance().setPreferredIOBufferDuration(0.005)
try! AVAudioSession.sharedInstance().setActive(true, options: [])

do {

engine.attach(player)
engine.attach(effectNode)

engine.connect(player, to: effectNode, format: file.processingFormat)
engine.connect(effectNode, to: engine.mainMixerNode, format: file.processingFormat)

player.scheduleBuffer(buffer, at: nil, options: .loops, completionHandler: nil)

engine.prepare()

try engine.start()

player.play()

} catch {
assertionFailure(String(describing: error))
}
}

lazy var file: AVAudioFile = {
let fileURL = Bundle.main.url(forResource: "beber", withExtension: "mp3")!
return try! AVAudioFile(forReading: fileURL)
}()

lazy var buffer: AVAudioPCMBuffer = {
let buffer = AVAudioPCMBuffer(pcmFormat: file.processingFormat, frameCapacity: UInt32(file.length))!
try! file.read(into: buffer)
return buffer
}()

}

(是的,我知道我可以更新效果的 bypass 属性,但我很想知道动态重新连接图形的步骤是什么)

最佳答案

经过进一步研究,我意识到(从 iOS 13 开始)如果不暂停 AVAudioPlayerNode 的播放就无法执行此重新布线。

重新连接播放器节点使用 connect(_:to:fromBus:toBus:format:)方法,首先断开节点与之前连接的节点的连接,从而停止播放。

但是,您可以使用不同的连接方法(connect(_:to:fromBus:format:) 将播放器连接到多种效果以及通过以下方式播放的混音器:

let engine = AVAudioEngine()
let player = AVAudioPlayerNode()
let effectOne = AVAudioUnitTimePitch()
let effectTwo = AVAudioUnitReverb()
let mixerThru = AVAudioMixerNode()
let mixerOne = AVAudioMixerNode()
let mixerTwo = AVAudioMixerNode()

engine.attach(player)
engine.attach(effectOne)
engine.attach(effectTwo)
engine.attach(mixerThru)
engine.attach(mixerOne)
engine.attach(mixerTwo)

player.scheduleBuffer(buffer, at: nil, options: .loops, completionHandler: nil)

let effectThruConnectionPoint = AVAudioConnectionPoint(node: mixerThru, bus: 0)
let effectOneConnectionPoint = AVAudioConnectionPoint(node: effectOne, bus: 0)
let effectTwoConnectionPoint = AVAudioConnectionPoint(node: effectTwo, bus: 0)

engine.connect(player, to: [effectThruConnectionPoint, effectOneConnectionPoint, effectTwoConnectionPoint], fromBus: 0, format: nil)

engine.connect(effectOne, to: mixerOne, format: file.processingFormat)
engine.connect(effectTwo, to: mixerTwo, format: file.processingFormat)
engine.connect(mixerThru, to: engine.mainMixerNode, format: file.processingFormat)
engine.connect(mixerOne, to: engine.mainMixerNode, format: file.processingFormat)
engine.connect(mixerTwo, to: engine.mainMixerNode, format: file.processingFormat)

mixerTwo.outputVolume = 0
mixerThru.outputVolume = 0

(对 RH 的想法和代码的支持)

关于avaudioengine - 动态重新连接 AVAudioEngine 节点而不停止声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57808459/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com