连接节点错误 kAudioUnitErr_PropertyNotWriteable 时 AudioToolbox AUGraph 失败

Posted

技术标签:

【中文标题】连接节点错误 kAudioUnitErr_PropertyNotWriteable 时 AudioToolbox AUGraph 失败【英文标题】:AudioToolbox AUGraph failure when connecting nodes error kAudioUnitErr_PropertyNotWriteable 【发布时间】:2014-08-04 22:10:36 【问题描述】:

我正在尝试使用混音器和 io 单元创建音频图。 io 单元将从麦克风接收音频并将其发送到混音器,混音器会将其与外部声音混合,然后通过扬声器播放。我已经创建了如下所示的音频图,并尝试尽可能地遵循指南。但是,当我尝试将混音器节点连接到输出节点时,我不断收到错误 -10865 (kAudioUnitErr_PropertyNotWriteable)。有人可以为我澄清一下出了什么问题吗?如果需要,我将包含更多代码,例如我的回调和私有变量。

NSLog(@"Creating audio graph");
sampleRate = 44100.0;

// Will check results
OSStatus result;

// Create the graph
result = NewAUGraph(&graph);
if(result != noErr)
    NSLog(@"Failed creating graph");

result = AUGraphInitialize(graph);
if(result != noErr)
    NSLog(@"Failed to initialize audio graph Error code: %d '%.4s", (int) result, (const char *)&result);

// Create audio nodes
AudioComponentDescription ioDescription;
ioDescription.componentType = kAudioUnitType_Output;
ioDescription.componentSubType = kAudioUnitSubType_RemoteIO;
ioDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
ioDescription.componentFlagsMask = 0;
ioDescription.componentFlags = 0;

AudioComponentDescription mixerDescription;
mixerDescription.componentType = kAudioUnitType_Mixer;
mixerDescription.componentSubType = kAudioUnitSubType_MultiChannelMixer;
mixerDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
mixerDescription.componentFlagsMask = 0;
mixerDescription.componentFlags = 0;

// Add nodes to the graph
AUNode ioNode;
AUNode mixerNode;

result = AUGraphAddNode(graph, &ioDescription, &ioNode);
if(result != noErr)
    NSLog(@"Failed to add microphone node");
result = AUGraphAddNode(graph, &mixerDescription, &mixerNode);
if(result != noErr)
    NSLog(@"Failed to add mixer node");

// Open the graph
result = AUGraphOpen(graph);
if(result != noErr)
    NSLog(@"Failed to open graph");

// Get the IO node
result = AUGraphNodeInfo(graph, ioNode, NULL, &ioUnit);
if(result != noErr)
    NSLog(@"Failed to fetch info from io node");

// Enable IO on the io node
UInt32 flag = 1;
result = AudioUnitSetProperty(ioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &flag, sizeof(flag));
if(result != noErr)
    NSLog(@"Failed enabling IO on io unit");

// Get the mixer unit
result = AUGraphNodeInfo(graph, mixerNode, NULL, &mixerUnit);
if(result != noErr)
    NSLog(@"Failed to fetch info from mixer node");

// Set up the mixer unit bus count
UInt32 busCount = 2;
result = AudioUnitSetProperty(mixerUnit, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &busCount, sizeof(busCount));
if(result != noErr)
    NSLog(@"Failed to set property mixer input bus count");

// Attach render callback to sound effect bus
UInt32 soundEffectBus = 1;

AURenderCallbackStruct inputCallbackStruct;
inputCallbackStruct.inputProc = &inputRenderCallback;
inputCallbackStruct.inputProcRefCon = soundStruct;

result = AUGraphSetNodeInputCallback(graph, mixerNode, soundEffectBus, &inputCallbackStruct);
if(result != noErr)
    NSLog(@"Failed to set mixer node input callback for sound effect bus");

// Set stream format for sound effect bus
UInt32 bytesPerSample = sizeof (AudioUnitSampleType);

stereoDescription.mFormatID = kAudioFormatLinearPCM;
stereoDescription.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
stereoDescription.mBytesPerPacket = bytesPerSample;
stereoDescription.mFramesPerPacket = 1;
stereoDescription.mBytesPerFrame = bytesPerSample;
stereoDescription.mChannelsPerFrame = 2;
stereoDescription.mBitsPerChannel = 8 * bytesPerSample;
stereoDescription.mSampleRate = sampleRate;

result = AudioUnitSetProperty(mixerUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, soundEffectBus, &stereoDescription, sizeof(stereoDescription));
if(result != noErr)
    NSLog(@"Failed to set stream description");

// Set mixer output sample rate
result = AudioUnitSetProperty(mixerUnit, kAudioUnitProperty_SampleRate, kAudioUnitScope_Output, 0, &sampleRate, sizeof(sampleRate));
if(result != noErr)
    NSLog(@"Failed to set mixer output sample rate");

// Connect input to mixer
result = AUGraphConnectNodeInput(graph, ioNode, 1, mixerNode, 0);
if(result != noErr)
    NSLog(@"Failed to connect microphone node to mixer node");

这里发生错误

// Connect mixer to output
result = AUGraphConnectNodeInput(graph, mixerNode, 0, ioNode, 0);
if(result != noErr)
    NSLog(@"Failed to connect mixer to output node %d", result);

// Initialize the audio graph
CAShow(graph);

// Start the graph
result = AUGraphStart(graph);
if(result != noErr)
    NSLog(@"Failed to start audio graph");

NSLog(@"Graph started");

编辑

我能够理解为什么会出现此错误,我想我是在将混音器输出分配给 io 单元的输入通道(这是只读的,当然因为它来自麦克风)。但是,在切换之后,因为我更改了上面的代码,我有这个错误

ERROR:     [0x196f982a0] 308: input bus 0 sample rate is 0

谁能帮助我?有什么我忘记设置的吗?

【问题讨论】:

【参考方案1】:

根据错误信息,我建议您在混音器的每条总线(输入和输出)上显式设置流格式,以确保确定。就个人而言,我没有在混音器上设置 kAudioUnitProperty_SampleRate,我认为它在那里没有意义(恕我直言,这在硬件 IO 单元上选择 DAC 的采样率是有意义的,它可能也有格式的意义转换器单位)

【讨论】:

以上是关于连接节点错误 kAudioUnitErr_PropertyNotWriteable 时 AudioToolbox AUGraph 失败的主要内容,如果未能解决你的问题,请参考以下文章

多节点cassandra集群:连接错误:('无法连接到任何服务器')

节点 mongodb:错误:连接因 parseError 而关闭

节点 js 错误:Mongoose 与 MongoDB 连接字符串

尝试从节点应用程序连接时出现 PostgreSQL 错误

连接节点 v5.10.1 时握手不活动超时错误。到 aws mysql RDS

如何执行 30k 连续 API 调用(节点)[错误:连接 ECONNRESET]