3

pyportmidi を使用して Novation Launchpad と通信しようとしています。指示を送信し続けるmidiOut.WriteShort()と、最初の 100 程度が処理され、残りが失われることに気付きました。

どこかにいっぱいになりつつあるバッファがあり、いっぱいになると命令が失われると思います。各メッセージの後に time.sleep(.1) を追加することで問題を回避できますが、これにより明らかに動作が非常に遅くなります。バッファがいっぱいかどうかをテストし、必要な場合にのみスリープする方法はありますか? または、さらにデータを送信する前にバッファが空になるのを待つ方法はありますか?

4

1 に答える 1

4

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

于 2011-11-21T09:14:48.570 に答える