OSX Core MIDI-从NSTimer调用MIDIPacketListAdd

时间:2011-10-05 22:14:47

标签: macos nstimer core-audio midi coremidi

我正在使用MIDIPacketListAdd发送一串MIDI数据包。我想在播放过程中动态更改数据包,因此我使用NSTimer在数据包发出的预定时间之前添加每个数据包。

代码工作正常,当前数据包的地址正确更新,我已经验证所有数据都是正确的。但是,从计时器调用MIDIPacketListAdd时,不会发送MIDI数据。我在启动计时器之前添加前两个数据包,以确保在需要播放之前将数据包发送到MIDIPacketListAdd。

我很困惑。有什么建议吗?

谢谢,Tom Jeffries

1 个答案:

答案 0 :(得分:3)

您的描述正是我发送MIDI数据的方式,它运行正常。也许你可以发布你的源代码,但没有它有点难以猜出是什么问题。

此外,为了测试,尝试将时间戳设置为零,只是为了确保您能够发送MIDI,之后您可以将时间戳重新放入以单独调试它们。

代替源代码,这是一个发送MIDI的简单方法,我从NSTimer调用它,它基于一些Apple示例而且有效。注意'outputPort'是你应该在尝试发送MIDI和你的客户端参考之前在某处创建的东西(我假设你已经这样做了)

OSStatus s;
MIDIClientRef client;
MIDIPortRef outputPort;
s = MIDIClientCreate((CFStringRef)@"My Test MIDI Client", MyMIDINotifyProc, self, &client);
s = MIDIOutputPortCreate(client, (CFStringRef)@"My Test MIDI Output Port", &outputPort);

一旦你有了这些,就可以发送MIDI

- (void) MySendMidi:(const UInt8*)data size:(UInt32)bsize
{
    NSLog(@"%s(%u bytes to core MIDI)", __func__, unsigned(bsize));
    assert(bsize < 65536);

    Byte packetBuffer[bsize+100];
    MIDIPacketList *packetList = (MIDIPacketList*)packetBuffer;
    MIDIPacket     *packet     = MIDIPacketListInit(packetList);

    packet = MIDIPacketListAdd(packetList, sizeof(packetBuffer), packet, 0, bsize, data);

    // Send it to every destination in the system...
    for (ItemCount index = 0; index < MIDIGetNumberOfDestinations(); ++index)
    {
        MIDIEndpointRef outputEndpoint = MIDIGetDestination(index);
        if (outputEndpoint)
        {
            // Send it
            OSStatus s = MIDISend(outputPort, outputEndpoint, packetList);
        }
    }
}