在iOS上使用midi演奏打击乐器

时间:2016-03-08 22:15:13

标签: ios objective-c swift midi

我有一个应用程序可以处理多个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形式给出。

提前致谢!

2 个答案:

答案 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;
}