我有一个应用程序可以处理多个midi乐器。除了演奏打击乐器外,一切都很棒。我明白为了在General MIDI中打打击乐,你必须将事件发送到第10频道。我尝试了很多不同的东西,我无法弄清楚如何让它发挥作用,这里是我的一个例子这是为旋律乐器和打击乐而做的。
// Melodic instrument
MusicDeviceMIDIEvent(self.samplerUnit, 0x90, (UInt8)pitch, 127, 0);
// Percussion Instruments
MusicDeviceMIDIEvent(self.samplerUnit, 0x99, (UInt8)pitch, 127, 0);
采样器单位是AudioUnit
,音高通过我的UI以int形式给出。
提前致谢!
答案 0 :(得分:1)
假设您加载了某种通用MIDI 声音字体或类似字体,则需要在发送音高/力度信息之前设置正确的状态字节。因此,对于标准MIDI鼓组(通道9),您可以在Swift中执行以下操作:
var status = OSStatus(noErr)
let drumCommand = UInt32( 0xC9 | 0 )
let noteOnCommand = UInt32(0x90 | channel)
status = MusicDeviceMIDIEvent(self._samplerUnit, drumCommand, 0, 0, 0) // set device
status = MusicDeviceMIDIEvent(self._samplerUnit, noteOnCommand, noteNum, velocity, 0) // sends note ON message
无需对MIDI 注意消息采取任何特殊措施。
答案 1 :(得分:0)
好的,所以我让它运转了。我想我加载声音字体的方式使得频道的东西没有做任何事情。相反,我必须将bankMSB
上的AUSamplerBankPresetData
属性设置为kAUSampler_DefaultPercussionBankMSB
而不是kAUSampler_DefaultMelodicBankMSB
我为打击乐器添加了另一种不同的字体加载方法:
- (OSStatus) loadPercussionWithSoundFont: (NSURL *)bankURL {
OSStatus result = noErr;
// fill out a bank preset data structure
AUSamplerBankPresetData bpdata;
bpdata.bankURL = (__bridge CFURLRef) bankURL;
bpdata.bankMSB = kAUSampler_DefaultPercussionBankMSB;
bpdata.bankLSB = kAUSampler_DefaultBankLSB;
bpdata.presetID = (UInt8) 32;
// set the kAUSamplerProperty_LoadPresetFromBank property
result = AudioUnitSetProperty(self.samplerUnit,
kAUSamplerProperty_LoadPresetFromBank,
kAudioUnitScope_Global,
0,
&bpdata,
sizeof(bpdata));
// check for errors
NSCAssert (result == noErr,
@"Unable to set the preset property on the Sampler. Error code:%d '%.4s'",
(int) result,
(const char *)&result);
return result;
}