AudioKit MacOS麦克风配置异常:PitchTap无法获取有效音高数据
AudioKit MacOS麦克风监听与PitchTap修复方案
问题诊断
你的代码中麦克风输入未正常工作的核心原因是音频会话配置缺失和输入节点未被正确纳入活跃音频流,即使权限已授权,MacOS的AVAudioSession默认类别可能仅允许播放,导致麦克风输入流被静默。
极简MacOS麦克风+PitchTap示例
以下是可直接运行的最简实现,包含所有必要配置:
import AudioKit import AVFoundation class MicPitchTracker { private let engine = AudioEngine() private let mic: AudioEngine.InputNode private var pitchTap: PitchTap? init() throws { // 确保麦克风设备存在 guard let inputNode = engine.input else { throw NSError(domain: "AudioKitError", code: 1001, userInfo: [NSLocalizedDescriptionKey: "无可用麦克风输入"]) } mic = inputNode // 将麦克风接入音频图(即使静音,也要让引擎处理数据流) engine.output = Fader(mic, gain: 0.0) // 初始化PitchTap回调 pitchTap = PitchTap(mic) { frequencies, amplitudes in guard let frequency = frequencies.first, let amplitude = amplitudes.first else { return } print("频率: \(String(format: "%.1f", frequency)) Hz | 振幅: \(amplitude)") } } func startTracking() throws { // 配置并激活音频会话(关键步骤) let session = AVAudioSession.sharedInstance() try session.setCategory(.playAndRecord, options: .defaultToSpeaker) try session.activate(options: .notifyOthersOnDeactivation) // 启动引擎与PitchTap try engine.start() pitchTap?.start() } func stopTracking() { pitchTap?.stop() engine.stop() try? AVAudioSession.sharedInstance().deactivate() } } // 使用示例 // do { // let tracker = try MicPitchTracker() // try tracker.startTracking() // // 运行后说话测试,控制台会输出频率与振幅 // } catch { // print(error.localizedDescription) // }
麦克风输入关键配置要点
AVAudioSession 强制配置
- 必须设置category为
.playAndRecord:同时支持播放(MIDISampler)和录音(麦克风),MacOS默认category为.playback会禁用输入 - 添加
.defaultToSpeaker选项:避免MacOS默认切换到听筒输出,确保播放与录音通路同时激活 - 显式调用
activate():启动引擎前必须激活会话,仅申请权限不足以激活输入流
- 必须设置category为
音频图节点连接
- 麦克风输入节点必须接入音频输出链:即使通过
Fader(gain:0)静音,也要让引擎将麦克风纳入处理流程,否则PitchTap无法获取有效数据流 - 避免孤立节点:PitchTap依赖节点的活跃数据流,未接入音频图的节点不会产生数据
- 麦克风输入节点必须接入音频输出链:即使通过
权限与系统设置
- Info.plist必须添加
NSMicrophoneUsageDescription条目,描述麦克风使用目的 - MacOS系统偏好设置→安全性与隐私→麦克风中,确认应用已被授权
- 代码中需检查权限状态,仅在
AVAuthorizationStatus.authorized时启动音频功能
- Info.plist必须添加
启动顺序
正确顺序:检查权限 → 配置并激活AVAudioSession → 启动AudioEngine → 启动PitchTap
你的代码修复建议
在原startAudioEngine()方法中添加AVAudioSession配置:
func startAudioEngine() throws { print("### Start engine") // 新增会话配置 let session = AVAudioSession.sharedInstance() try session.setCategory(.playAndRecord, options: .defaultToSpeaker) try session.activate() try engine.start() pitchTracker.start() }
内容的提问来源于stack exchange,提问作者Benjohn
相关产品推荐
相关产品推荐

