首页 > 解决方案 > 如何创建 Inter App MIDI In 端口

问题描述

我将在我的编曲应用程序中编写一个应用程序间 MIDI 输入端口,其他 MIDI 应用程序可以访问该端口。我非常感谢获得一些示例代码。我像这样构建了一个虚拟 MIDI In 端口,但是如何使它对其他应用程序可见:

MIDIClientRef virtualMidi;
result = MIDIClientCreate(CFSTR("Virtual Client"), MyMIDINotifyProc, NULL, &virtualMidi);

标签: objective-cxcodemidicoremidi

解决方案


您需要使用MIDIDestinationCreate,它对其他 MIDI 客户端可见。您需要提供一个MIDIReadProc回调,当 MIDI 事件到达您的 MIDI 目的地时,该回调将得到通知。您也可以使用相同的回调创建另一个MIDI 输入端口,您可以自己从自己的程序中连接到外部 MIDI 源。

这是一个示例(在 C++ 中):

void internalCreate(CFStringRef name)
{
    OSStatus result = noErr;
    result = MIDIClientCreate( name , nullptr, nullptr, &m_client );
    if (result != noErr) {
        qDebug() << "MIDIClientCreate() err:" << result;
        return;
    }
    result = MIDIDestinationCreate ( m_client, name, MacMIDIReadProc, (void*) this, &m_endpoint );
    if (result != noErr) {
        qDebug() << "MIDIDestinationCreate() err:" << result;
        return;
    }
    result = MIDIInputPortCreate( m_client, name, MacMIDIReadProc, (void *) this,  &m_port );
    if (result != noErr) {
        qDebug() << "MIDIInputPortCreate() error:" << result;
        return;
    }
}

另一个例子,在来自symplesynth的 ObjectiveC

- (id)initWithName:(NSString*)newName
{
    PYMIDIManager*  manager = [PYMIDIManager sharedInstance];
    MIDIEndpointRef newEndpoint;
    OSStatus        error;
    SInt32          newUniqueID;

    // This makes sure that we don't get notified about this endpoint until after
    // we're done creating it.
    [manager disableNotifications];

    MIDIDestinationCreate ([manager midiClientRef], (CFStringRef)newName, midiReadProc, self, &newEndpoint);

    // This code works around a bug in OS X 10.1 that causes
    // new sources/destinations to be created without unique IDs.
    error = MIDIObjectGetIntegerProperty (newEndpoint, kMIDIPropertyUniqueID, &newUniqueID);
    if (error == kMIDIUnknownProperty) {
        newUniqueID = PYMIDIAllocateUniqueID();
        MIDIObjectSetIntegerProperty (newEndpoint, kMIDIPropertyUniqueID, newUniqueID);
    }

    MIDIObjectSetIntegerProperty (newEndpoint, CFSTR("PYMIDIOwnerPID"), [[NSProcessInfo processInfo] processIdentifier]);

    [manager enableNotifications];

    self = [super initWithMIDIEndpointRef:newEndpoint];

    ioIsRunning = NO;

    return self;
}

推荐阅读