Macos 正确使用MIDIPacketListAdd(CoreMIDI)
我正在尝试使用CoreAudio的MIDIPacketListAdd(在mac上): MIDIPacketListAdd(打包列表、打包列表大小、当前数据包、马赫绝对时间、长度、数据) 我想在发送之前多次调用这个方法,这样我的packetList中就有>1个包了。 然而,当我这样做的时候,numPackets永远不会增加,我得到的是packetList->packet[0],其中的packet[0]数据包不断增加 1) 使用这种方法的正确方法是什么?我看了几个例子,包括“Learning Core Audio”中的一个——它们似乎都只发送一个数据包 2) 如果我在一个数据包列表中打包多个数据包,而不是多次发送一个数据包列表中的一个数据包,那么性能是否会有所提高 谢谢,谢谢你在这方面的帮助 编辑以便后续:下面是我初始化数据包列表的方式Macos 正确使用MIDIPacketListAdd(CoreMIDI),macos,core-audio,coremidi,Macos,Core Audio,Coremidi,我正在尝试使用CoreAudio的MIDIPacketListAdd(在mac上): MIDIPacketListAdd(打包列表、打包列表大小、当前数据包、马赫绝对时间、长度、数据) 我想在发送之前多次调用这个方法,这样我的packetList中就有>1个包了。 然而,当我这样做的时候,numPackets永远不会增加,我得到的是packetList->packet[0],其中的packet[0]数据包不断增加 1) 使用这种方法的正确方法是什么?我看了几个例子,包括“Learning Cor
#define PACKETLIST_SIZE 512
- (void) initPacketList {
if (packetList) {
free(packetList);
packetList = NULL;
}
packetList = (MIDIPacketList *)malloc(PACKETLIST_SIZE * sizeof(char));
currentPacket = MIDIPacketListInit(packetList);
}
- (void) clearPacketList {
packetList->numPackets = 0;
currentPacket = MIDIPacketListInit(packetList);
}
- (void) addPacketToPacketList:(Byte*) data ofLength:(int) len {
NSLog(@"length %d", len);
//NSLog(@"%lld", mach_absolute_time());
currentPacket = MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time, len, data);
//if (!currentPacket) exit(1);
}
返回值
如果数据包中没有空间容纳事件,则返回null;否则,返回一个数据包指针,该指针应在随后调用此函数时作为curPacket传递
因此,您可能需要以下内容:
currentPacket = MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time, len, data);
确保每次之后检查currentPacket
是否为空
如果将多个数据包放在一个数据包列表中,性能应该会更好,因为向MIDI服务器发出的跨进程请求会更少,但老实说,在现代Mac上不太可能注意到这一点
编辑:以下是你做错的地方
packetList = (MIDIPacketList *)malloc(PACKETLIST_SIZE * sizeof(char));
根据定义,C语言中的sizeof(char)始终为1malloc(PACKETLIST\u SIZE)
是您所需要的全部
currentPacket = MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time, len, data);
这给了我一个编译器警告,因为您正在传递mach\u absolute\u time
函数的地址,而不是调用该函数。你的意思是:
currentPacket = MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time(), len, data);
一旦我这样做了,我看到packetList->numPackets
如预期的那样增加
但是,请注意两件事:
- 如果要立即发送MIDI数据,只需提供时间戳
0
- 如果您使用与上一次调用相同的时间戳调用
,那么它只会将您的数据连接到上一个数据包。您将看到MIDIPacketListAdd
和packetList->numPackets
保持不变,但currentPacket
将增加currentPacket->length
packetList->numPackets
增加的原因:mach\u absolute\u time
的地址是一个常量,所以您的“时间戳”每次都是相同的。
返回值
如果数据包中没有空间容纳事件,则返回null;否则,返回一个数据包指针,该指针应在随后调用此函数时作为curPacket传递
因此,您可能需要以下内容:
currentPacket = MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time, len, data);
确保每次之后检查currentPacket
是否为空
如果将多个数据包放在一个数据包列表中,性能应该会更好,因为向MIDI服务器发出的跨进程请求会更少,但老实说,在现代Mac上不太可能注意到这一点
编辑:以下是你做错的地方
packetList = (MIDIPacketList *)malloc(PACKETLIST_SIZE * sizeof(char));
根据定义,C语言中的sizeof(char)始终为1malloc(PACKETLIST\u SIZE)
是您所需要的全部
currentPacket = MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time, len, data);
这给了我一个编译器警告,因为您正在传递mach\u absolute\u time
函数的地址,而不是调用该函数。你的意思是:
currentPacket = MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time(), len, data);
一旦我这样做了,我看到packetList->numPackets
如预期的那样增加
但是,请注意两件事:
- 如果要立即发送MIDI数据,只需提供时间戳
0
- 如果您使用与上一次调用相同的时间戳调用
,那么它只会将您的数据连接到上一个数据包。您将看到MIDIPacketListAdd
和packetList->numPackets
保持不变,但currentPacket
将增加currentPacket->length
这就是为什么你没有看到
packetList->numPackets
增加的原因:mach\u absolute\u time
的地址是一个常数,所以你的“时间戳”每次都是一样的。嗨,库尔特,我正是这么做的,但是当我使用调试器检查数据包时,我的数据仍然被塞进了一个包中。packetList->packet[0]->当下一条数据应该在下一个数据包[1]中时,数据会变长。另一个问题是,如果我的packetList->packet[0]->数据是9个字节,我发送给的synth/虚拟仪器会忽略最后6个字节吗?调试器会误导您。MIDIPacket
是一种可变长度的结构——它有6个字节的头(4个字节时间戳
,2个字节长度
),然后是1到65535个字节的数据。MIDIPacketList
只是连续存储在内存中的一个或多个midipacket
。问题是:你不能用C来表示变长结构。因此,你不能说packet[1]
来获取第二个数据包——编译器和调试器都不会做正确的事情。使用MIDIPacketListNext
,或直接查看原始内存。此外,数据包的长度应为要发送的数据的确切长度。如果希望它发送3个字节,则长度应为3
。我不知道你为什么要将它设置为9
,然后再添加6个额外的垃圾字节。CoreMIDI(可能)会按原样发送,但如果它不是有效的MIDI,接收器可以做任何事情。啊,I c。。还有一件事我觉得很奇怪。即使我在发送packetList之前调用currentPacket=MIDIPacketListAdd(packetList,packetList\u SIZE,currentPacket,mach\u absolute\u time,len,data)3次,packetList->numPackets仍然是1,每次我打印它。这是我自己更新的吗?嗨,库尔特,我正在做上面的事情,但我的数据仍然在被保存