SVN レポジトリを調べたところ、ラッパー コードでこれに遭遇しました。「なぜ 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 メッセージは (通常) 2 バイト (16 ビット) であるため、MIDI は 31250 ボー (毎秒 31250 ビット) と非常に遅く、毎秒最大 1953 メッセージを意味します。(ここで間違っているかもしれませんが、正しくない場合はかなり近いです)
ただし、希望はあります。簡単な修正方法は、ほとんどのオペレーティング システムで、混乱することなく 2 ミリ秒までスリープできることです。
time.sleep(.002) # 2 millisecond sleep
ただし、write_short() を使用しているため、1 秒あたり 500 メッセージしか得られません。したがって、送信メッセージに対して .002 秒ごとにポーリングされるキューを作成し、スタックから 16 をポップし、それらを書き込んでからスリープするようなことをしたい場合があります。そうすれば、MIDI スタック全体がその速度をサポートしている場合、1 秒あたり 8000 メッセージを取得できます。
次のコードで、スリープ時間を .002 よりも低くすると、プログラムを終了するまでMIDI がまったく送信されず、すべてのイベントが MIDI バスに吐き出されることに気付きました。そのため、portmidi のレート制限または OSX に問題がある可能性があります。
もう 1 つ心に留めておくべきことは、本当に MIDI を吹き飛ばしている場合、つまりコントロール チェンジの値である可能性が高く、ハイパス フィルターなどを変更している場合、値「1」は「2」のように聞こえます。メッセージの粒度を下げる (2 または 4 ずつ増やす、または減らす) と、音声に顕著な違いを生じることなく、メッセージの数を減らすことができます。これは最適ではない解決策であり、おそらくあなたの MIDI スタックはおそらく 31250 ボーよりもはるかに速い速度をサポートしています。
考慮すべきもう 1 つの点は、portmidi アプリケーションを MIDI クロックにスレーブ化すると、MIDI ホストから信頼できるティックのストリームを取得できることです。これをトリガーとして使用して、MIDI データを書き戻すことができます (スリープは必要ありません)。
幸運を!
-n
PPQN クロック
MIDI 1.0