我正在使用 Apple 的 MixerHost 示例项目,该项目设置了一个音频单元处理图,该图由连接到远程 I/O 音频单元的多通道混音器音频单元组成。我正在尝试在两者之间放置一个格式转换器音频单元,以便我可以转换混音器输出的格式。
复制两个现有音频单元的设置似乎很简单,当我输出图形设置时,它看起来是正确的:
Member Nodes:
node 1: 'auou' 'rioc' 'appl', instance 0x1cdf10 O
node 2: 'aufc' 'conv' 'appl', instance 0x1ce890 O
node 3: 'aumx' 'mcmx' 'appl', instance 0x1ceba0 O
Connections:
node 3 bus 0 => node 2 bus 1
node 2 bus 0 => node 1 bus 0 [ 2 ch, 0 Hz, 'lpcm' (0x0000000C) 16-bit little-endian signed integer]
但是,当我初始化图表时,我收到错误 -10877,无效元素,并且图表没有启动。任何人都可以看到有什么问题吗?这是完整的设置代码:
NSLog (@"Configuring and then initializing audio processing graph");
OSStatus result = noErr;
//............................................................................
// Create a new audio processing graph.
result = NewAUGraph (&processingGraph);
if (noErr != result) {[self printErrorMessage: @"NewAUGraph" withStatus: result]; return;}
//............................................................................
// Specify the audio unit component descriptions for the audio units to be
// added to the graph.
// I/O unit
AudioComponentDescription ioUnitDescription;
ioUnitDescription.componentType = kAudioUnitType_Output;
ioUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO;
ioUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
ioUnitDescription.componentFlags = 0;
ioUnitDescription.componentFlagsMask = 0;
// Converter unit
AudioComponentDescription ConverterUnitDescription;
ConverterUnitDescription.componentType = kAudioUnitType_FormatConverter;
ConverterUnitDescription.componentSubType = kAudioUnitSubType_AUConverter;
ConverterUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
ConverterUnitDescription.componentFlags = 0;
ConverterUnitDescription.componentFlagsMask = 0;
// Multichannel mixer unit
AudioComponentDescription MixerUnitDescription;
MixerUnitDescription.componentType = kAudioUnitType_Mixer;
MixerUnitDescription.componentSubType = kAudioUnitSubType_MultiChannelMixer;
MixerUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
MixerUnitDescription.componentFlags = 0;
MixerUnitDescription.componentFlagsMask = 0;
//............................................................................
// Add nodes to the audio processing graph.
NSLog (@"Adding nodes to audio processing graph");
AUNode mixerNode; // node for Multichannel Mixer unit
AUNode converterNode; // node for AU Converter unit
AUNode ioNode; // node for I/O unit
// Add the nodes to the audio processing graph
result = AUGraphAddNode (
processingGraph,
&ioUnitDescription,
&ioNode);
if (noErr != result) {[self printErrorMessage: @"AUGraphNewNode failed for I/O unit" withStatus: result]; return;}
result = AUGraphAddNode (
processingGraph,
&ConverterUnitDescription,
&converterNode
);
if (noErr != result) {[self printErrorMessage: @"AUGraphNewNode failed for Converter unit" withStatus: result]; return;}
result = AUGraphAddNode (
processingGraph,
&MixerUnitDescription,
&mixerNode
);
if (noErr != result) {[self printErrorMessage: @"AUGraphNewNode failed for Mixer unit" withStatus: result]; return;}
//............................................................................
// Open the audio processing graph
// Following this call, the audio units are instantiated but not initialized
// (no resource allocation occurs and the audio units are not in a state to
// process audio).
result = AUGraphOpen (processingGraph);
if (noErr != result) {[self printErrorMessage: @"AUGraphOpen" withStatus: result]; return;}
//............................................................................
// Obtain the audio unit instances from their corresponding nodes.
AudioUnit mixerUnit;
AudioUnit converterUnit;
AudioUnit ioUnit;
result = AUGraphNodeInfo (
processingGraph,
ioNode,
NULL,
&ioUnit
);
if (noErr != result) {[self printErrorMessage: @"AUGraphNodeInfo" withStatus: result]; return;}
result = AUGraphNodeInfo (
processingGraph,
converterNode,
NULL,
&converterUnit
);
if (noErr != result) {[self printErrorMessage: @"AUGraphNodeInfo" withStatus: result]; return;}
result = AUGraphNodeInfo (
processingGraph,
mixerNode,
NULL,
&mixerUnit
);
if (noErr != result) {[self printErrorMessage: @"AUGraphNodeInfo" withStatus: result]; return;}
//............................................................................
// Audio Unit Setup
// Set the mixer unit's output sample rate format. This is the only aspect of the output stream
// format that must be explicitly set.
NSLog (@"Setting sample rate for mixer unit output scope");
result = AudioUnitSetProperty (
mixerUnit,
kAudioUnitProperty_SampleRate,
kAudioUnitScope_Output,
0,
&graphSampleRate,
sizeof (graphSampleRate)
);
if (noErr != result) {[self printErrorMessage: @"AudioUnitSetProperty (set mixer unit output stream format)" withStatus: result]; return;}
//............................................................................
// Connect the nodes of the audio processing graph
NSLog (@"Connecting the mixer output to the input of the converter unit input element");
result = AUGraphConnectNodeInput (
processingGraph,
mixerNode, // source node
0, // source node output bus number
converterNode, // destination node
1 // destination node input bus number
);
if (noErr != result) {[self printErrorMessage: @"AUGraphConnectNodeInput" withStatus: result]; return;}
NSLog (@"Connecting the converter output to the input of the I/O unit output element");
result = AUGraphConnectNodeInput (
processingGraph,
converterNode, // source node
0, // source node output bus number
ioNode, // destination node
0 // destination node input bus number
);
if (noErr != result) {[self printErrorMessage: @"AUGraphConnectNodeInput" withStatus: result]; return;}
//............................................................................
// Initialize audio processing graph
// Diagnostic code
// Call CAShow if you want to look at the state of the audio processing
// graph.
NSLog (@"Audio processing graph state immediately before initializing it:");
CAShow (processingGraph);
NSLog (@"Initializing the audio processing graph");
// Initialize the audio processing graph, configure audio data stream formats for
// each input and output, and validate the connections between audio units.
result = AUGraphInitialize (processingGraph);
if (noErr != result) {[self printErrorMessage: @"AUGraphInitialize" withStatus: result]; return;}