当我尝试将两个
AVAudioMixerNodes
连接到 AVAudioEngine
的麦克风输入时,出现崩溃。
我在网上找不到如何管理两个或多个节点到同一输入的文档。
处理多个节点监听麦克风的情况的正确方法是什么?
我在后台线程上调用这三个方法:
private func setupSession() {
let session = AVAudioSession.sharedInstance()
do {
try session.setCategory(.playAndRecord, options: [.mixWithOthers])
if session.isInputGainSettable {
try session.setInputGain(0.2)
}
try session.setActive(true, options: .notifyOthersOnDeactivation)
} catch let error as NSError {
LoggerManager.shared.error(error: error, message: "Error while setting up AVAudioSession Category/Active status")
}
}
private func setupMixerNodes() {
analyzerNode = AVAudioMixerNode()
analyzerNode.volume = 0
volumeNode = AVAudioMixerNode()
volumeNode.volume = 0
engine.attach(analyzerNode)
engine.attach(volumeNode)
}
private func makeConnections() {
/* input microphone */
let inputNode = engine.inputNode
let inputFormat = inputNode.outputFormat(forBus: 0)
let analyzerConnectionPoint = AVAudioConnectionPoint(node: analyzerNode, bus: 0)
let volumeConnectionPoint = AVAudioConnectionPoint(node: volumeNode, bus: 0)
engine.connect(inputNode, to: [analyzerConnectionPoint, volumeConnectionPoint], fromBus: 0, format: inputFormat)
let mainMixerNode = engine.mainMixerNode
let mixerFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: inputFormat.sampleRate, channels: 1, interleaved: false)
engine.connect(analyzerNode, to: mainMixerNode, fromBus: 0, toBus: 0, format: mixerFormat)
engine.connect(volumeNode, to: mainMixerNode, fromBus: 0, toBus: 1, format: mixerFormat)
}
我遇到了这个崩溃:
AURemoteIO.cpp:1128 failed: -10851 (enable 1, outf< 2 ch, 0 Hz, Float32, deinterleaved> inf< 2 ch, 0 Hz, Float32, deinterleaved>)
2022-03-08 12:59:57.950612-0500 SnoreLabo[2914:456147] [avae] AVAEInternal.h:76 required condition is false: [AVAudioEngineGraph.mm:2401:ConnectMultipleOutputs: (IsFormatSampleRateAndChannelCountValid(format))]
2022-03-08 12:59:58.030789-0500 SnoreLabo[2914:456147] *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: IsFormatSampleRateAndChannelCountValid(format)'
*** First throw call stack:
(0x18273ed3c 0x199aa36a8 0x1828085bc 0x1ddf44eac 0x1ddf9b020 0x1de01bfa0 0x1de018328 0x104d4db1c 0x104d4e1f8 0x104ed4f6c 0x104bcdbe8 0x10dc00718 0x10dc01f94 0x10dc13edc 0x10dc146fc 0x1dcc4ae48 0x1dcc4a9f0)
libc++abi: terminating with uncaught exception of type NSException
dyld4 config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib
*** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: IsFormatSampleRateAndChannelCountValid(format)'
terminating with uncaught exception of type NSException
编辑
我最终使用了这个:
print("Current category: \(AVAudioSession.sharedInstance().category)")
engine.connect(inputNode, to: [analyzerConnectionPoint, volumeConnectionPoint], fromBus: 0, format: inputFormat)
但是我仍然时不时地遇到同样的崩溃...并且当崩溃时类别被正确设置为
.playAndRecord
,所以这不是问题...
文档指出连接可以是一对一、一对多,但绝不能是多对一。
如果要将输出连接到单个输入,则需要使用 AVAudioMixerNode。这就是混音器的用途 - 它将多个信号流混合(组合)为单个流。