AudioKit v5中如何在单个Node上使用多个Tap获取振幅与频谱数据
问题本质
AudioKit 5 的 Tap 底层依赖 Core Audio 的
AVAudioNode接口设计,同一个节点的同一输出总线最多只能挂载1个Tap,因此在同一个AudioPlayer上先后启动两个Tap时,后启动的Tap会覆盖之前的Tap。
解决方案
方案1:添加透传节点拆分Tap挂载点
改造成本最低,无需修改原有Tap的业务逻辑,只需要在音频链路中新增一个无副作用的透传节点(如Fader,增益设为1,不会修改音频输出效果),两个Tap分别挂载在不同节点即可:
player = AudioPlayer(file: fileToPlay)! // 新增透传Fader节点,增益为1,不对音频做任何修改 let passthroughFader = Fader(player, gain: 1.0) // 后续输出链路连接透传节点 engine.output = passthroughFader // 两个Tap分别挂载到不同的节点 fftTap = FFTTap(player, bufferSize: 4096, handler: { _ in }) ampTap = AmplitudeTap(passthroughFader) ampTap.analysisMode = .peak do { try engine.start() fftTap.start() ampTap.start() } catch { print("Could not start engine: \(error)") return }
方案2:单Tap内同时处理两种分析逻辑
如果想要减少冗余节点和资源占用,可以只保留一个FFTTap,在其回调中同时完成频谱分析和振幅计算,无需单独挂载AmplitudeTap:
player = AudioPlayer(file: fileToPlay)! engine.output = player fftTap = FFTTap(player, bufferSize: 4096, handler: { fftData in // 原有FFT频谱处理逻辑 // 新增振幅计算逻辑,替代AmplitudeTap的能力 guard let pcmBuffer = fftData.floatBufferData else { return } let peakAmplitude = pcmBuffer.max() ?? 0.0 // 此处可直接使用计算得到的峰值振幅做后续业务处理 }) do { try engine.start() fftTap.start() } catch { print("Could not start engine: \(error)") return }
内容的提问来源于stack exchange,提问作者PaperEdge
相关产品推荐
相关产品推荐

