发布 iOS 个音频单元
Publishing iOS Audio Unit
我正在尝试制作一个应用程序间音频 iOS 应用程序,看起来我在 AudioOutputUnitPublish
方法上遇到了问题。方法如下:
- (void)publishOutputAudioUnit {
AudioComponentDescription desc = {kAudioUnitType_RemoteInstrument,
'iasp','rfoo', 0, 1};
OSStatus result = AudioOutputUnitPublish(&desc, CFSTR("MyMusicApp"),
1, outputUnit);
if (result != noErr)
NSLog(@"AudioOutputUnitPublish instrument result: %d", (int)result);
desc = { kAudioUnitType_RemoteGenerator, 'iasp', 'rfoo', 0, 1 };
result = AudioOutputUnitPublish(&desc, CFSTR("MyMusicApp"), 1, outputUnit);
if (result != noErr)
NSLog(@"AudioOutputUnitPublish generator result: %d", (int)result);
}
这是我的 plist 信息:
<key>AudioComponents</key>
<array>
<dict>
<key>manufacturer</key>
<string>rfoo</string>
<key>name</key>
<string>MyMusicApp</string>
<key>subtype</key>
<string>iasp</string>
<key>type</key>
<string>aurg</string>
<key>version</key>
<integer>1</integer>
</dict>
<dict>
<key>manufacturer</key>
<string>rfoo</string>
<key>name</key>
<string>MyMusicApp</string>
<key>subtype</key>
<string>iasp</string>
<key>type</key>
<string>auri</string>
<key>version</key>
<integer>1</integer>
</dict>
</array>
这是我得到的结果:
AudioOutputUnitPublish instrument result: -50
AudioOutputUnitPublish generator result: -50
我知道 OSStatus 代码 -50 表示参数无效...但我似乎无法弄清楚哪个参数无效。谁能帮我调试这里?谢谢!
编辑:
只是想 post 更多代码以便其他人可以帮助我:
我有两个音频单元,希望还有第三个 - MIDISynth(目前不活动)、MultiChannelMixer 和 RemoteIO 音频单元。我有一个连接到混音器音频单元的渲染回调。我猜我在我的 AUGraph 中连接有问题(none 我见过的示例已将音频渲染回调附加到音频单元,所以这可能是我做错的地方)。希望有人能指出我做错了什么!
代码如下:
- (AUGraph)createAUGraphWithSynth:(AudioUnit *)sUnit mixUnit:(AudioUnit *)mixUnit remoteUnit:(AudioUnit *)remUnit {
// Initializations
AUGraph graph = 0;
OSStatus result = noErr;
// Create graph nodes
AUNode mixerNode, ioNode;
// Create Component Descriptor
AudioComponentDescription cd;
cd.componentManufacturer = kAudioUnitManufacturer_Apple;
cd.componentFlags = 0;
cd.componentFlagsMask = 0;
// Init AUGraph
Check(result = NewAUGraph(&graph));
// Init Mixer unit
cd.componentType = kAudioUnitType_Mixer;
cd.componentSubType = kAudioUnitSubType_MultiChannelMixer;
Check(result = AUGraphAddNode(graph, &cd, &mixerNode));
// Init io Unit
cd.componentType = kAudioUnitType_Output;
cd.componentSubType = kAudioUnitSubType_RemoteIO;
Check(result = AUGraphAddNode(graph, &cd, &ioNode));
// Open AUGraph
Check(AUGraphOpen(graph));
// Get mixer unit
Check(AUGraphNodeInfo(graph, mixerNode, NULL, mixUnit));
// Get io unit
Check(AUGraphNodeInfo(graph, ioNode, NULL, remUnit));
// Set number of input busses
UInt32 numBuses = 1;
UInt32 size = sizeof(numBuses);
Check(AudioUnitSetProperty(*mixUnit,
kAudioUnitProperty_ElementCount,
kAudioUnitScope_Input,
0, &numBuses, size));
AudioStreamBasicDescription desc;
const int four_bytes_per_float = 4;
const int eight_bits_per_byte = 8;
for (int i = 0; i < numBuses; ++i) {
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = outputCallback;
callbackStruct.inputProcRefCon = (__bridge void *)self;
Check(AUGraphSetNodeInputCallback(graph, mixerNode, i, &callbackStruct));
UInt32 size = sizeof(desc);
Check(AudioUnitGetProperty(*mixUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0, &desc, &size));
memset(&desc, 0, sizeof(desc));
desc.mSampleRate = SAMPLE_RATE;
desc.mFormatID = kAudioFormatLinearPCM;
desc.mFormatFlags = kAudioFormatFlagsNativeFloatPacked
| kAudioFormatFlagIsNonInterleaved;
desc.mBytesPerPacket = four_bytes_per_float;
desc.mFramesPerPacket = 1;
desc.mBytesPerFrame = four_bytes_per_float;
desc.mBitsPerChannel = four_bytes_per_float * eight_bits_per_byte;
desc.mChannelsPerFrame = 2;
Check(AudioUnitSetProperty(*remUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0, &desc, sizeof(desc)));
}
Check(AudioUnitSetProperty(*mixUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0, &desc, sizeof(desc)));
Check(AudioUnitGetProperty(*mixUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0, &desc, &size));
memset(&desc, 0, sizeof(desc));
desc.mSampleRate = SAMPLE_RATE;
desc.mFormatID = kAudioFormatLinearPCM;
desc.mFormatFlags = kAudioFormatFlagsNativeFloatPacked
| kAudioFormatFlagIsNonInterleaved;
desc.mBytesPerPacket = four_bytes_per_float;
desc.mFramesPerPacket = 1;
desc.mBytesPerFrame = four_bytes_per_float;
desc.mBitsPerChannel = four_bytes_per_float * eight_bits_per_byte;
desc.mChannelsPerFrame = 2;
Check(AudioUnitSetProperty(*mixUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0, &desc, sizeof(desc)));
// Must configure remote io unit:
Check(AudioUnitSetProperty(*remUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
1, &desc, sizeof(desc)));
// Connect nodes (synth->output)
Check(AUGraphConnectNodeInput(graph, mixerNode, 0, ioNode, 0));
return graph;
}
AudioComponentDescription 中的最后一个字段 componentFlagsMask
应为 0,而不是 1。(请参阅 documentation. It looks like at least one tutorial 将此字段错误识别为组件版本。)
我不确定这是否是问题的唯一原因。其余代码看起来没问题,但我想项目的其他地方可能存在问题,例如。具有能力。
我正在尝试制作一个应用程序间音频 iOS 应用程序,看起来我在 AudioOutputUnitPublish
方法上遇到了问题。方法如下:
- (void)publishOutputAudioUnit {
AudioComponentDescription desc = {kAudioUnitType_RemoteInstrument,
'iasp','rfoo', 0, 1};
OSStatus result = AudioOutputUnitPublish(&desc, CFSTR("MyMusicApp"),
1, outputUnit);
if (result != noErr)
NSLog(@"AudioOutputUnitPublish instrument result: %d", (int)result);
desc = { kAudioUnitType_RemoteGenerator, 'iasp', 'rfoo', 0, 1 };
result = AudioOutputUnitPublish(&desc, CFSTR("MyMusicApp"), 1, outputUnit);
if (result != noErr)
NSLog(@"AudioOutputUnitPublish generator result: %d", (int)result);
}
这是我的 plist 信息:
<key>AudioComponents</key>
<array>
<dict>
<key>manufacturer</key>
<string>rfoo</string>
<key>name</key>
<string>MyMusicApp</string>
<key>subtype</key>
<string>iasp</string>
<key>type</key>
<string>aurg</string>
<key>version</key>
<integer>1</integer>
</dict>
<dict>
<key>manufacturer</key>
<string>rfoo</string>
<key>name</key>
<string>MyMusicApp</string>
<key>subtype</key>
<string>iasp</string>
<key>type</key>
<string>auri</string>
<key>version</key>
<integer>1</integer>
</dict>
</array>
这是我得到的结果:
AudioOutputUnitPublish instrument result: -50
AudioOutputUnitPublish generator result: -50
我知道 OSStatus 代码 -50 表示参数无效...但我似乎无法弄清楚哪个参数无效。谁能帮我调试这里?谢谢!
编辑:
只是想 post 更多代码以便其他人可以帮助我:
我有两个音频单元,希望还有第三个 - MIDISynth(目前不活动)、MultiChannelMixer 和 RemoteIO 音频单元。我有一个连接到混音器音频单元的渲染回调。我猜我在我的 AUGraph 中连接有问题(none 我见过的示例已将音频渲染回调附加到音频单元,所以这可能是我做错的地方)。希望有人能指出我做错了什么!
代码如下:
- (AUGraph)createAUGraphWithSynth:(AudioUnit *)sUnit mixUnit:(AudioUnit *)mixUnit remoteUnit:(AudioUnit *)remUnit {
// Initializations
AUGraph graph = 0;
OSStatus result = noErr;
// Create graph nodes
AUNode mixerNode, ioNode;
// Create Component Descriptor
AudioComponentDescription cd;
cd.componentManufacturer = kAudioUnitManufacturer_Apple;
cd.componentFlags = 0;
cd.componentFlagsMask = 0;
// Init AUGraph
Check(result = NewAUGraph(&graph));
// Init Mixer unit
cd.componentType = kAudioUnitType_Mixer;
cd.componentSubType = kAudioUnitSubType_MultiChannelMixer;
Check(result = AUGraphAddNode(graph, &cd, &mixerNode));
// Init io Unit
cd.componentType = kAudioUnitType_Output;
cd.componentSubType = kAudioUnitSubType_RemoteIO;
Check(result = AUGraphAddNode(graph, &cd, &ioNode));
// Open AUGraph
Check(AUGraphOpen(graph));
// Get mixer unit
Check(AUGraphNodeInfo(graph, mixerNode, NULL, mixUnit));
// Get io unit
Check(AUGraphNodeInfo(graph, ioNode, NULL, remUnit));
// Set number of input busses
UInt32 numBuses = 1;
UInt32 size = sizeof(numBuses);
Check(AudioUnitSetProperty(*mixUnit,
kAudioUnitProperty_ElementCount,
kAudioUnitScope_Input,
0, &numBuses, size));
AudioStreamBasicDescription desc;
const int four_bytes_per_float = 4;
const int eight_bits_per_byte = 8;
for (int i = 0; i < numBuses; ++i) {
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = outputCallback;
callbackStruct.inputProcRefCon = (__bridge void *)self;
Check(AUGraphSetNodeInputCallback(graph, mixerNode, i, &callbackStruct));
UInt32 size = sizeof(desc);
Check(AudioUnitGetProperty(*mixUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0, &desc, &size));
memset(&desc, 0, sizeof(desc));
desc.mSampleRate = SAMPLE_RATE;
desc.mFormatID = kAudioFormatLinearPCM;
desc.mFormatFlags = kAudioFormatFlagsNativeFloatPacked
| kAudioFormatFlagIsNonInterleaved;
desc.mBytesPerPacket = four_bytes_per_float;
desc.mFramesPerPacket = 1;
desc.mBytesPerFrame = four_bytes_per_float;
desc.mBitsPerChannel = four_bytes_per_float * eight_bits_per_byte;
desc.mChannelsPerFrame = 2;
Check(AudioUnitSetProperty(*remUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0, &desc, sizeof(desc)));
}
Check(AudioUnitSetProperty(*mixUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0, &desc, sizeof(desc)));
Check(AudioUnitGetProperty(*mixUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0, &desc, &size));
memset(&desc, 0, sizeof(desc));
desc.mSampleRate = SAMPLE_RATE;
desc.mFormatID = kAudioFormatLinearPCM;
desc.mFormatFlags = kAudioFormatFlagsNativeFloatPacked
| kAudioFormatFlagIsNonInterleaved;
desc.mBytesPerPacket = four_bytes_per_float;
desc.mFramesPerPacket = 1;
desc.mBytesPerFrame = four_bytes_per_float;
desc.mBitsPerChannel = four_bytes_per_float * eight_bits_per_byte;
desc.mChannelsPerFrame = 2;
Check(AudioUnitSetProperty(*mixUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0, &desc, sizeof(desc)));
// Must configure remote io unit:
Check(AudioUnitSetProperty(*remUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
1, &desc, sizeof(desc)));
// Connect nodes (synth->output)
Check(AUGraphConnectNodeInput(graph, mixerNode, 0, ioNode, 0));
return graph;
}
AudioComponentDescription 中的最后一个字段 componentFlagsMask
应为 0,而不是 1。(请参阅 documentation. It looks like at least one tutorial 将此字段错误识别为组件版本。)
我不确定这是否是问题的唯一原因。其余代码看起来没问题,但我想项目的其他地方可能存在问题,例如。具有能力。