为什么这个简单的CoreMIDI程序不能产生MIDI输出?

six*_*six 20 macos midi core-foundation coremidi

这是一个发送MIDI数据的极其简单的CoreMIDI OS X应用程序.问题是它不起作用.编译好,并运行.它报告没有错误,并且不会崩溃.创建的源在MIDI监视器中可见.但是,没有MIDI数据出来.

有人能告诉我这里我做错了什么吗?

#include <CoreMIDI/CoreMIDI.h>

int main(int argc, char *args[])
{
    MIDIClientRef   theMidiClient;
    MIDIEndpointRef midiOut;
    MIDIPortRef     outPort;
    char pktBuffer[1024];
    MIDIPacketList* pktList = (MIDIPacketList*) pktBuffer;
    MIDIPacket     *pkt;
    Byte            midiDataToSend[] = {0x91, 0x3c, 0x40};
    int             i;

    MIDIClientCreate(CFSTR("Magical MIDI"), NULL, NULL,
                     &theMidiClient);
    MIDISourceCreate(theMidiClient, CFSTR("Magical MIDI Source"),
                     &midiOut);
    MIDIOutputPortCreate(theMidiClient, CFSTR("Magical MIDI Out Port"),
                         &outPort);

    pkt = MIDIPacketListInit(pktList);
    pkt = MIDIPacketListAdd(pktList, 1024, pkt, 0, 3, midiDataToSend);

    for (i = 0; i < 100; i++) {
        if (pkt == NULL || MIDISend(outPort, midiOut, pktList)) {
            printf("failed to send the midi.\n");
        } else {
            printf("sent!\n");
        }
        sleep(1);
    }

return 0;
}
Run Code Online (Sandbox Code Playgroud)

Kur*_*vis 26

您正在调用MIDISourceCreate创建虚拟MIDI源.

这意味着您的源将出现在其他应用程序的MIDI设置UI中,并且这些应用程序可以选择是否收听您的来源.您的MIDI不会被发送到任何物理MIDI端口,除非其他应用程序碰巧将其传送到那里.这也意味着您的应用程序无法选择发送的MIDI的位置.我假设那就是你想要的.

MIDISourceCreate的文档说:

创建虚拟源后,使用MIDIReceived将虚拟源中的MIDI消息传输到连接到虚拟源的任何客户端.

那么,做两件事:

  • 删除创建输出端口的代码.你不需要它.
  • 更改MIDISend(outPort, midiOut, pktList)到:MIDIReceived(midiOut, pktlist).

那应该可以解决你的问题.

那么输出端口有什么用呢?如果您想将MIDI数据导向特定目的地(可能是物理MIDI端口),则不会创建虚拟MIDI源.代替:

  1. 调用MIDIOutputPortCreate()输出端口
  2. 使用MIDIGetNumberOfDestinations()MIDIGetDestination()获取目的地列表并找到您感兴趣的目的地.
  3. 要将MIDI发送到一个目的地,请致电MIDISend(outputPort, destination, packetList).

  • 从来没有一千年我会想用MIDIReceived发送MIDI.谢谢你的出色解释. (6认同)
  • 如果您在MIDI设备驱动程序的上下文中考虑MIDI源,则会更有意义:在这种情况下,驱动程序接收了一些MIDI(通过线路),并告诉CoreMIDI.稍后添加了虚拟MIDI源. (5认同)
  • #rant `MIDIReceived` **收到**。让它陷入困境。即使它在虚拟源之前转发 MIDI 也是糟糕的命名。幸运的是,我们现在有 Swift 来解决所有这些文档/命名问题。/秒 (2认同)