IOS,设置AUGraphConnectNodeInput时无输出
IOS, No output when AUGraphConnectNodeInput is set
我现在被 AUGraph 困扰了一段时间,如果我的问题得到解决,我将不胜感激。
我现在要做的是播放来自 UDP 的数据(字节)。我已经成功实现了如何使用 AUGraph 播放数据,但我不知道如何更改其播放速度。
我目前的方案是从 UDP 获取数据,将其传递给转换器 -> newTimePitch -> 转换器 -> ioUnit。
转换器:转换器,将 48000 的 ASBD 转换为 timePitch 所需的格式,然后再次将其转换回 48000 以从 ioUnit 播放。
IOUnit 目前为了演示,我已经删除了 UDP 并使用 2 个不同的 ioUnit(一个用于录制,另一个用于播放)播放恢复。
CircularBuffer 在记录回调中,我将数据推送到我的循环缓冲区中,在回放回调中,我从中弹出数据,memcpy 到我的 ioData
不要被您看到的代码所淹没。这很简单。
正在启动 AUGraph 并录制 AudioUnit。
private func startRecordingUnit()
{
check(error: AUGraphStart(graph!), description: "Failed to start AUGraph")
check(error: AudioOutputUnitStart(audioUnit!), description: "Failed to start recording
audio unit.")
}
设置 AUGraph
private func setupRecordingUnit(){
var description = AudioComponentDescription(
componentType: OSType(kAudioUnitType_Output),
componentSubType: OSType(kAudioUnitSubType_VoiceProcessingIO),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0,
componentFlagsMask: 0
)
let inputComponent = AudioComponentFindNext(nil, &description)
check(error: AudioComponentInstanceNew(inputComponent!, &audioUnit), description:
"Failed to init recording audio unit.")
check(error: AudioUnitSetProperty(
audioUnit!,
AudioUnitPropertyID(kAudioOutputUnitProperty_EnableIO),
AudioUnitScope(kAudioUnitScope_Input),
kInputBus,
&flag,
MemoryLayoutStride.SizeOf32(flag)
),
description: "Failed to set enable IO for recording."
)
check(error: AudioUnitSetProperty(
audioUnit!,
AudioUnitPropertyID(kAudioUnitProperty_StreamFormat),
AudioUnitScope(kAudioUnitScope_Output),
kInputBus,
&ioFormat!,
MemoryLayoutStride.SizeOf32(ioFormat)
),
description: "Failed to set stream format on output unit with scope input."
)
check(error: NewAUGraph(&graph), description: "Failed to create AU Graph")
check(error: AUGraphOpen(graph!), description: "Failed to open AUGraph")
var outputDesc = AudioComponentDescription(
componentType: OSType(kAudioUnitType_Output),
componentSubType: OSType(kAudioUnitSubType_VoiceProcessingIO),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0,
componentFlagsMask: 0
)
var firstConverterDesc = AudioComponentDescription(
componentType: OSType(kAudioUnitType_FormatConverter),
componentSubType: OSType(kAudioUnitSubType_AUConverter),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0,
componentFlagsMask: 0
)
var pitchConverterDesc = AudioComponentDescription(
componentType: OSType(kAudioUnitType_FormatConverter),
componentSubType: OSType(kAudioUnitSubType_NewTimePitch),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0,
componentFlagsMask: 0
)
var secondConverterDesc = AudioComponentDescription(
componentType: OSType(kAudioUnitType_FormatConverter),
componentSubType: OSType(kAudioUnitSubType_AUConverter),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0,
componentFlagsMask: 0
)
check(error: AUGraphAddNode(graph!, &firstConverterDesc, &firstConverterNode),
description: "Failed to Add Node of First desc")
check(error: AUGraphAddNode(graph!, &pitchConverterDesc, &newTimePitchNode),
description: "Failed to Add Node of new Time Desc")
check(error: AUGraphAddNode(graph!, &secondConverterDesc, &secondConverterNode),
description: "Failed to Add Node of Second desc")
check(error: AUGraphAddNode(graph!, &outputDesc, &outputNode), description: "Failed to
add node of output desc")
check(error: AUGraphNodeInfo(graph!, firstConverterNode, nil, &firstConverterUnit),
description: "Failed to get Node Info of FIRST Unit")
check(error: AUGraphNodeInfo(graph!, newTimePitchNode, nil, &newTimePitchUnit),
description: "Failed to get Node Info of new Time Unit")
check(error: AUGraphNodeInfo(graph!, secondConverterNode, nil, &secondConverterUnit),
description: "Failed to get Node Info of SECOND Unit")
check(error: AUGraphNodeInfo(graph!, outputNode, nil, &outputUnit), description: "Failed
to get Node Info of output Unit");
var sizeASBD = MemoryLayoutStride.SizeOf32(AudioStreamBasicDescription())
var ioASBDin = AudioStreamBasicDescription()
var ioASBDout = AudioStreamBasicDescription()
AudioUnitGetProperty(newTimePitchUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kOutputBus, &ioASBDin, &sizeASBD);
AudioUnitGetProperty(newTimePitchUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, kOutputBus, &ioASBDout, &sizeASBD);
check(error: AudioUnitSetProperty(firstConverterUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kOutputBus, &ioFormat, MemoryLayoutStride.SizeOf32(ioFormat)),
description: "Failed to set property of FIRST Unit")
check(error: AudioUnitSetProperty(firstConverterUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, kOutputBus, &ioASBDin, MemoryLayoutStride.SizeOf32(ioASBDin)),
description: "Failed to set property first unit to temp format")
check(error: AudioUnitSetProperty(newTimePitchUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kOutputBus, &ioASBDin, MemoryLayoutStride.SizeOf32(ioASBDin)),
description: "Failed to set property of new Time Pitch")
check(error: AudioUnitSetProperty(newTimePitchUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, kOutputBus, &ioASBDout, MemoryLayoutStride.SizeOf32(ioASBDout)),
description: "Failed to set property of new Time Pitch OUTOUT")
check(error: AudioUnitSetProperty(secondConverterUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kOutputBus, &ioASBDout, MemoryLayoutStride.SizeOf32(ioASBDout)),
description: "Failed to set property of Second Converter Unit")
check(error: AudioUnitSetProperty(secondConverterUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, kOutputBus, &ioFormat, MemoryLayoutStride.SizeOf32(ioFormat)),
description: "Failed to set property of Second Converter Unit to io Format")
check(error: AudioUnitSetProperty(outputUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kOutputBus, &ioFormat, MemoryLayoutStride.SizeOf32(ioFormat)),
description: "Failed to set property of OUTPUT Unit")
// ************************************* RECORDING
****************************************************
var recordingCallback = AURenderCallbackStruct(
inputProc: AudioController_RecordingCallback,
inputProcRefCon: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())
)
check(error: AudioUnitSetProperty(
audioUnit!,
AudioUnitPropertyID(kAudioOutputUnitProperty_SetInputCallback),
AudioUnitScope(kAudioUnitScope_Global),
kInputBus,
&recordingCallback,
MemoryLayout<AURenderCallbackStruct>.size.ui
),
description: "Failed to set property on recording callback."
)
// *************************************** RECORDING END
****************************************************
var playbackCallback = AURenderCallbackStruct(
inputProc: AudioController_PlaybackCallback,
inputProcRefCon: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())
)
check(error: AUGraphConnectNodeInput(graph!, firstConverterNode, 0, newTimePitchNode,
0), description: "Failed to connect FIRST AND timePitch Nodes")
check(error: AUGraphConnectNodeInput(graph!, newTimePitchNode, 0, secondConverterNode,
0), description: "Failed to connect timePitch AND Second Nodes")
check(error: AUGraphConnectNodeInput(graph!, secondConverterNode, 0, outputNode, 0),
description: "Failed to connect Second AND OUTPUT Nodes")
check(error: AudioUnitSetProperty(outputUnit!, kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Output, kOutputBus, &playbackCallback,
MemoryLayout<AURenderCallbackStruct>.size.ui), description: "Failed to set Property for
varispeed Unit 1")
check(error: AUGraphInitialize(graph!), description: "Unable to initialize AUGraph")
}
录音工作正常,但在我将它与 AUConvertor
连接后,playbackCalback 没有 运行。
出于测试目的,我删除了连接 AUGraphConnectNodeInput
并开始播放。我认为连接有问题,如果我能理解导致问题的原因,我将不胜感激。
- https://whosebug.com/users/1313967/dave234
- Connection of varispeed with RemoteIO in iOS
我进行了几次搜索,但找不到任何有用的帮助。
问题可能是您正在为 IO 节点设置两个输入(远程或语音处理),而没有为音频图设置任何输入。
我现在被 AUGraph 困扰了一段时间,如果我的问题得到解决,我将不胜感激。 我现在要做的是播放来自 UDP 的数据(字节)。我已经成功实现了如何使用 AUGraph 播放数据,但我不知道如何更改其播放速度。
我目前的方案是从 UDP 获取数据,将其传递给转换器 -> newTimePitch -> 转换器 -> ioUnit。
转换器:转换器,将 48000 的 ASBD 转换为 timePitch 所需的格式,然后再次将其转换回 48000 以从 ioUnit 播放。
IOUnit 目前为了演示,我已经删除了 UDP 并使用 2 个不同的 ioUnit(一个用于录制,另一个用于播放)播放恢复。
CircularBuffer 在记录回调中,我将数据推送到我的循环缓冲区中,在回放回调中,我从中弹出数据,memcpy 到我的 ioData
不要被您看到的代码所淹没。这很简单。
正在启动 AUGraph 并录制 AudioUnit。
private func startRecordingUnit()
{
check(error: AUGraphStart(graph!), description: "Failed to start AUGraph")
check(error: AudioOutputUnitStart(audioUnit!), description: "Failed to start recording
audio unit.")
}
设置 AUGraph
private func setupRecordingUnit(){
var description = AudioComponentDescription(
componentType: OSType(kAudioUnitType_Output),
componentSubType: OSType(kAudioUnitSubType_VoiceProcessingIO),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0,
componentFlagsMask: 0
)
let inputComponent = AudioComponentFindNext(nil, &description)
check(error: AudioComponentInstanceNew(inputComponent!, &audioUnit), description:
"Failed to init recording audio unit.")
check(error: AudioUnitSetProperty(
audioUnit!,
AudioUnitPropertyID(kAudioOutputUnitProperty_EnableIO),
AudioUnitScope(kAudioUnitScope_Input),
kInputBus,
&flag,
MemoryLayoutStride.SizeOf32(flag)
),
description: "Failed to set enable IO for recording."
)
check(error: AudioUnitSetProperty(
audioUnit!,
AudioUnitPropertyID(kAudioUnitProperty_StreamFormat),
AudioUnitScope(kAudioUnitScope_Output),
kInputBus,
&ioFormat!,
MemoryLayoutStride.SizeOf32(ioFormat)
),
description: "Failed to set stream format on output unit with scope input."
)
check(error: NewAUGraph(&graph), description: "Failed to create AU Graph")
check(error: AUGraphOpen(graph!), description: "Failed to open AUGraph")
var outputDesc = AudioComponentDescription(
componentType: OSType(kAudioUnitType_Output),
componentSubType: OSType(kAudioUnitSubType_VoiceProcessingIO),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0,
componentFlagsMask: 0
)
var firstConverterDesc = AudioComponentDescription(
componentType: OSType(kAudioUnitType_FormatConverter),
componentSubType: OSType(kAudioUnitSubType_AUConverter),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0,
componentFlagsMask: 0
)
var pitchConverterDesc = AudioComponentDescription(
componentType: OSType(kAudioUnitType_FormatConverter),
componentSubType: OSType(kAudioUnitSubType_NewTimePitch),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0,
componentFlagsMask: 0
)
var secondConverterDesc = AudioComponentDescription(
componentType: OSType(kAudioUnitType_FormatConverter),
componentSubType: OSType(kAudioUnitSubType_AUConverter),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0,
componentFlagsMask: 0
)
check(error: AUGraphAddNode(graph!, &firstConverterDesc, &firstConverterNode),
description: "Failed to Add Node of First desc")
check(error: AUGraphAddNode(graph!, &pitchConverterDesc, &newTimePitchNode),
description: "Failed to Add Node of new Time Desc")
check(error: AUGraphAddNode(graph!, &secondConverterDesc, &secondConverterNode),
description: "Failed to Add Node of Second desc")
check(error: AUGraphAddNode(graph!, &outputDesc, &outputNode), description: "Failed to
add node of output desc")
check(error: AUGraphNodeInfo(graph!, firstConverterNode, nil, &firstConverterUnit),
description: "Failed to get Node Info of FIRST Unit")
check(error: AUGraphNodeInfo(graph!, newTimePitchNode, nil, &newTimePitchUnit),
description: "Failed to get Node Info of new Time Unit")
check(error: AUGraphNodeInfo(graph!, secondConverterNode, nil, &secondConverterUnit),
description: "Failed to get Node Info of SECOND Unit")
check(error: AUGraphNodeInfo(graph!, outputNode, nil, &outputUnit), description: "Failed
to get Node Info of output Unit");
var sizeASBD = MemoryLayoutStride.SizeOf32(AudioStreamBasicDescription())
var ioASBDin = AudioStreamBasicDescription()
var ioASBDout = AudioStreamBasicDescription()
AudioUnitGetProperty(newTimePitchUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kOutputBus, &ioASBDin, &sizeASBD);
AudioUnitGetProperty(newTimePitchUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, kOutputBus, &ioASBDout, &sizeASBD);
check(error: AudioUnitSetProperty(firstConverterUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kOutputBus, &ioFormat, MemoryLayoutStride.SizeOf32(ioFormat)),
description: "Failed to set property of FIRST Unit")
check(error: AudioUnitSetProperty(firstConverterUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, kOutputBus, &ioASBDin, MemoryLayoutStride.SizeOf32(ioASBDin)),
description: "Failed to set property first unit to temp format")
check(error: AudioUnitSetProperty(newTimePitchUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kOutputBus, &ioASBDin, MemoryLayoutStride.SizeOf32(ioASBDin)),
description: "Failed to set property of new Time Pitch")
check(error: AudioUnitSetProperty(newTimePitchUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, kOutputBus, &ioASBDout, MemoryLayoutStride.SizeOf32(ioASBDout)),
description: "Failed to set property of new Time Pitch OUTOUT")
check(error: AudioUnitSetProperty(secondConverterUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kOutputBus, &ioASBDout, MemoryLayoutStride.SizeOf32(ioASBDout)),
description: "Failed to set property of Second Converter Unit")
check(error: AudioUnitSetProperty(secondConverterUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, kOutputBus, &ioFormat, MemoryLayoutStride.SizeOf32(ioFormat)),
description: "Failed to set property of Second Converter Unit to io Format")
check(error: AudioUnitSetProperty(outputUnit!, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kOutputBus, &ioFormat, MemoryLayoutStride.SizeOf32(ioFormat)),
description: "Failed to set property of OUTPUT Unit")
// ************************************* RECORDING
****************************************************
var recordingCallback = AURenderCallbackStruct(
inputProc: AudioController_RecordingCallback,
inputProcRefCon: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())
)
check(error: AudioUnitSetProperty(
audioUnit!,
AudioUnitPropertyID(kAudioOutputUnitProperty_SetInputCallback),
AudioUnitScope(kAudioUnitScope_Global),
kInputBus,
&recordingCallback,
MemoryLayout<AURenderCallbackStruct>.size.ui
),
description: "Failed to set property on recording callback."
)
// *************************************** RECORDING END
****************************************************
var playbackCallback = AURenderCallbackStruct(
inputProc: AudioController_PlaybackCallback,
inputProcRefCon: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())
)
check(error: AUGraphConnectNodeInput(graph!, firstConverterNode, 0, newTimePitchNode,
0), description: "Failed to connect FIRST AND timePitch Nodes")
check(error: AUGraphConnectNodeInput(graph!, newTimePitchNode, 0, secondConverterNode,
0), description: "Failed to connect timePitch AND Second Nodes")
check(error: AUGraphConnectNodeInput(graph!, secondConverterNode, 0, outputNode, 0),
description: "Failed to connect Second AND OUTPUT Nodes")
check(error: AudioUnitSetProperty(outputUnit!, kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Output, kOutputBus, &playbackCallback,
MemoryLayout<AURenderCallbackStruct>.size.ui), description: "Failed to set Property for
varispeed Unit 1")
check(error: AUGraphInitialize(graph!), description: "Unable to initialize AUGraph")
}
录音工作正常,但在我将它与 AUConvertor
连接后,playbackCalback 没有 运行。
出于测试目的,我删除了连接 AUGraphConnectNodeInput
并开始播放。我认为连接有问题,如果我能理解导致问题的原因,我将不胜感激。
- https://whosebug.com/users/1313967/dave234
- Connection of varispeed with RemoteIO in iOS
我进行了几次搜索,但找不到任何有用的帮助。
问题可能是您正在为 IO 节点设置两个输入(远程或语音处理),而没有为音频图设置任何输入。