CoreMidi を使用して、コンピューターで実行されているホスト (単純な Ableton Live または Logic Pro) から MIDI テンポ (bpm) を受信する方法を知りたいですか?
MIDI 規格はこの機能をサポートしていますか? はいの場合、Objective C コードの例を教えてください。MIDI の送信には petegoodliffe-PGMidi を使用しています。しかし、この場合、ホストからテンポを受け取りたいです。
ありがとう。
信じられないかもしれませんが、「現在のテンポは 120BPM です」という MIDI メッセージはありません。とにかく、この種のメッセージはあまり役に立ちません。ほとんどの場合、現在のテンポを知る理由はデバイスを同期させるためです。あなたがしなければならないことは、MIDI クロック メッセージのタイミングに基づいて現在のテンポを計算することです。
MIDI クロック同期メッセージは、1 バイト(またはバイナリ) で構成されるシステム リアルタイムメッセージです。これらは、MIDI クロック ソースから 4 分音符あたり 24 回送信されます。0xFA
1111 1000
BPM が 120 の場合、これらのメッセージが 1 分あたり 2,880 件、つまり 1 秒あたり 48 件表示されます。つまり、各クロック メッセージは 20.8333 ミリ秒間隔になります。
1000 / ((BPM * 24) / 60) = MS_BETWEEN_MESSAGES
MIDI クロックから BPM を計算するには、各クロック メッセージ間の時間を知る必要があります。それがわかれば、この式は逆方向にも機能します。メッセージが約 17.86 ミリ秒離れていることがわかっているとします。
(1000 / 17.86 / 24) * 60 = 139.978 BPM
ここで大きな落とし穴があります。現実的には、これらのメッセージ間の正確な時間を知ることはできません。オフになる量は、システムやプログラムによって異なりますが、オフになります。完璧な世界でも、その 1 バイトがネットワーク上に送信される時間があります。私が過去に行ったことは、最後のいくつかのメッセージの平均時間をとることです。これにより、BPM 測定がより安定しますが、影響がないわけではありません。BPM が急速に変化すると、BPM の測定が遅れます。これをどのように処理するかは、ニーズによって異なります。
あとは、MIDI クロック メッセージを送信するように Ableton Live を設定するだけです。これを行うには、[設定]、[MIDI] に移動し、目的の MIDI インターフェイスの [同期] をオンにします。
BPMとQuantize計算を備えたPGMidiのフォークがあります。そのここ:https ://github.com/yderidde/PGMidi/blob/master/Sources/PGMidi/PGMidiSession.mm#L186
そうは言っても、より良い、より正確な結果を得るために最適化できると確信しています。実際、誰かがこれをさらに良くするための提案があれば、私に知らせてください!
コアミディアプリを作成するときに誰もが必要とするこれらすべての基本機能のためのオープンソースソリューションを用意する時が来ました。
- (void) midiRead:(const MIDIPacketList *)pktlist{
MIDIPacket *packet = MIDIPacketListInit((MIDIPacketList*)pktlist);
int statusByte = packet->data[0];
int status = statusByte >= 0xf0 ? statusByte : statusByte >> 4 << 4;
switch (status) {
case 0xb0: //cc
NSLog(@"CC working!");
break;
case 0x90: // Note on, etc...
NSLog(@"Note on/off working!");
break;
case 0xf8: // Clock tick
NSLog(@"clock working!");
break;
}