我正在尝试编写一个程序来接收来自不同乐器的 MIDI 信号。目前,MIDI 信号被发送到采样器单元 (kAudioUnitSubType_Sampler),每个采样器单元都有一个相关的音效 - 由声音字体提供。单独我可以让乐器正确演奏,但是我需要能够混合多种乐器。
起初我想为每个音轨创建一个单独的 AUGraph,但我想这会占用大量内存并且不是最好的解决方案。
从那时起,我一直试图让混音器工作(kAudioUnitSubType_AU3DMixerEmbedded)。在设置了其他音频单元(我已经测试过)之后,我使用以下代码设置了混音器:
cd.componentType = kAudioUnitType_Mixer;
cd.componentSubType = kAudioUnitSubType_AU3DMixerEmbedded;
result = AUGraphAddNode (_processingGraph, &cd, &mixerNode);
NSCAssert (result == noErr, @"Unable to add the Output unit to the audio processing graph. Error code: %d '%.4s'", (int) result, (const char *)&result);
然后我打开图表:
result = AUGraphOpen (_processingGraph);
NSCAssert (result == noErr, @"Unable to open the audio processing graph. Error code: %d '%.4s'", (int) result, (const char *)&result);
接下来我设置流描述:
AudioStreamBasicDescription desc;
desc.mSampleRate = 44100; // set sample rate
desc.mFormatID = kAudioFormatLinearPCM;
desc.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
desc.mBitsPerChannel = sizeof(AudioSampleType) * 8; // AudioSampleType == 16 bit signed ints
desc.mChannelsPerFrame = 1;
desc.mFramesPerPacket = 1;
desc.mBytesPerFrame = ( desc.mBitsPerChannel / 8 ) * desc.mChannelsPerFrame;
desc.mBytesPerPacket = desc.mBytesPerFrame * desc.mFramesPerPacket;
最后,我将所有节点连接在一起:
result = AUGraphConnectNodeInput (_processingGraph, mixerNode, 0, ioNode, 0);
NSCAssert (result == noErr, @"Unable to interconnect the nodes in the audio processing graph. Error code: %d '%.4s'", (int) result, (const char *)&result);
result = AUGraphConnectNodeInput(_processingGraph, samplerNode, 0, mixerNode, 0);
NSCAssert (result == noErr, @"Couldn't connect mixer output(0) to outputNode (0). Error code: %d '%.4s'", (int) result, (const char *)&result);
result = AUGraphConnectNodeInput(_processingGraph, drumSamplerNode, 0, mixerNode, 1);
NSCAssert (result == noErr, @"Couldn't connect speech synth unit output (0) to mixer input (1). Error code: %d '%.4s'", (int) result, (const char *)&result);
我将混音器连接到 io-unit。第一个采样器连接到混音器上的总线 0,第二个采样器连接到采样器上的第二个输入总线。这是 CAShow 的副本:
Member Nodes:
node 1: 'aumu' 'samp' 'appl', instance 0x8882210 O
node 2: 'aumu' 'samp' 'appl', instance 0x88819d0 O
node 3: 'auou' 'rioc' 'appl', instance 0x8883510 O
node 4: 'aumx' '3dem' 'appl', instance 0x8a5d5d0 O
Connections:
node 4 bus 0 => node 3 bus 0 [ 1 ch, 44100 Hz, 'lpcm' (0x0000000C) 16-bit little-endian signed integer]
node 1 bus 0 => node 4 bus 0 [ 1 ch, 44100 Hz, 'lpcm' (0x0000000C) 16-bit little-endian signed integer]
node 2 bus 0 => node 4 bus 1 [ 1 ch, 44100 Hz, 'lpcm' (0x0000000C) 16-bit little-endian signed integer]
CurrentState:
mLastUpdateError=0, eventsToProcess=F, isRunning=F
当我初始化图表时,我得到一个 OSStatus -10868。我见过使用环形缓冲区和渲染回调的例子。在使用 MIDI 时或仅在从麦克风等现场设备获取输入时是否需要这样做?我真的很想知道我的一般方法是否可行(即它应该可以正常工作,但我在某处犯了一些小错误),或者我是否需要花几个小时阅读有关环形缓冲区的信息。
任何帮助将不胜感激!