当我看看SVN repo时,我在包装代码中遇到了这个问题,注意'为什么bufferSize是0?'评论..
def __init__(self, OutputDevice, latency=0):
...stuff...
# Why is bufferSize 0 here?
err = Pm_OpenOutput(&(self.midi), self.i, NULL, 0, PmPtr, NULL, latency)
API文档显示具有以下签名Pm_OpenOutput
PmError Pm_OpenOutput (
PortMidiStream **stream,
PmDeviceID outputDevice,
void *outputDriverInfo,
long bufferSize,
PmTimeProcPtr time_proc,
void *time_info,
long latency
)
似乎没有要找出当前缓冲区堆栈长度的任何明显的方法,更重要的是,它看起来Python包装完全忽略缓冲区设置。
portmidi.c讲述了一个稍微不同的故事:
if (bufferSize <= 0) bufferSize = 256; /* default buffer size */
midi->queue = Pm_QueueCreate(bufferSize, sizeof(PmEvent));
if (!midi->queue) {
/* free portMidi data */
*stream = NULL;
pm_free(midi);
err = pmInsufficientMemory;
goto error_return;
}
那么,256是默认的。这将解释为什么你遇到大约100左右的问题。
然而,有些东西要记住 - MIDI极其缓慢,31250个波特(31250个比特每秒), 由于MIDI信息是(通常)2个字节(16位),这意味着最大的每 1953条的消息第二。 (我在这里可能是错的,但是如果我不对,我会非常接近)
但是,有一个简单的解决方法,你可以在大多数 操作系统上睡2ms,而不会搞砸。
time.sleep(.002) # 2 millisecond sleep
但是,由于您使用的是write_short(),每秒只能发送500条消息。 所以你可能想要做一些事情,比如让一个队列每隔0.002秒轮询一次,传出消息,弹出16个堆栈,写入然后休眠。这样,如果整个MIDI堆栈支持的速率可以达到每秒8000条消息的速度。
我注意到,在下面的代码中,如果我将睡眠时间降低到0.002以下,则根本不会发送任何MIDI 直到我退出程序,然后所有事件喷到MIDI总线上。所以Portmidi速率限制或OSX上可能存在问题。
要记住,如果你真的爆破MIDI另一件事 - 最有可能的控制变化值,如果你修改类似的高通滤波器,“1”的值听起来很像“ 2',所以如果你的消息不那么精细(递增或递减2或4),你可以减少消息的数量 而不会有明显的音频差异。这是一个不太理想的解决方案,很可能你的MIDI堆栈支持的速度可能比31250波特快得多。
要考虑的另一件事是,如果你将你的portmidi应用程序从属于MIDI时钟,你可以从MIDI主机获得可靠的刻度流,你可以用它作为触发器来写回MIDI数据(no睡觉必要)。
祝你好运!
-n
PPQN Clock MIDI 1.0
意想不到的答案,谢谢! – tomcat23