2011-10-04 8 views
5

OS XでCoreMIDIのラッパーとしてRtMidiを使用しているアプリケーションからMIDIメッセージを送信するのにちょっとしたハッキン​​グに取り組んでいます。私はRtMidiOut::openVirtualPort("MyAwesomePort")を使用していますので、私のアプリケーションをDAWの入力ソースとして選択できます。MIDISourceCreate()から仮想MIDIソースの一意性をどのように保持しますか?

しかし、私のプログラムが閉じてもう一度開くと、私のDAWは、同じ名前が与えられているにもかかわらず、入力デバイスを同じポートとして認識しません。

私はもともとpyrtmidiを使用していましたので、RtMidiを使用してC++での動作を直接検証しました。この場合の「My DAW」はReaper 4ですが、Pro Tools、Logic、およびMuLabで動作を再現しました。

MidiKeysは、私のアプリケーションが動作するように動作するので、仮想MIDIポートのいくつかの一意性を保持することができます。私のDAWは、DAWが動作している間にMidiKeysを閉じて再起動しても覚えています。 。

私はRtMidiソースを掘り出したので、CoreMIDIラッパーは簡単に思えました。 MIDISourceCreateが要求するものはすべて文字列です。 clientパラメータは、アプリケーションを識別する識別子(CoreMIDIサービスのクライアント)です。

void RtMidiOut :: openVirtualPort(std::string portName) 
{ 
    CoreMidiData *data = static_cast<CoreMidiData *> (apiData_); 

    if (data->endpoint) { 
    errorString_ = "RtMidiOut::openVirtualPort: a virtual output port already exists!"; 
    error(RtError::WARNING); 
    return; 
    } 

    // Create a virtual MIDI output source. 
    MIDIEndpointRef endpoint; 
    OSStatus result = MIDISourceCreate(data->client, 
             CFStringCreateWithCString(NULL, portName.c_str(), kCFStringEncodingASCII), 
             &endpoint); 
    if (result != noErr) { 
    errorString_ = "RtMidiOut::initialize: error creating OS-X virtual MIDI source."; 
    error(RtError::DRIVER_ERROR); 
    } 

    // Save our api-specific connection information. 
    data->endpoint = endpoint; 
} 

は、だから私はMIDISourceCreateのドキュメントを見て、これを読んで:

仮想ソースを作成したら、それはそれはあなたのアプリケーションがそれを作成した最後の時間を持っていた同じ一意のIDを割り当てるには、お勧めします。 (万が一衝突が発生した場合にこれが失敗する可能性はありますが)他のクライアントが仮想ソースへの永続的な参照をより簡単に保持できるようになります。

これはまさに私が探しているようです。私はどのようにソースに一意のIDを割り当てるか分かりません。 MIDISourceCreateのoutパラメータはMIDIEndpointRefであり、ドキュメントによれば、その行の下のUInt32にtypedefされているだけです。だから、私はこのUInt32を追跡しなければならないかもしれないと仮説を立てましたが、それは悪い考えです。

このすべてを掘り下げた後、私は少しのレンガの壁に当たっているように感じる。アプリケーションの実行の間にMIDIポートの一意性を保持するにはどうすればよいですか?

答えて

5

docsによると、

kMIDIPropertyUniqueID

システムは、すべてのオブジェクトにユニークなIDを割り当てます。選択したIDが一意でない場合、仮想エンドポイントの作成者はエンドポイントでこのプロパティを設定できます。

そのため、おそらくこのような何か:ユニークなIDがSInt32にtypedefedさ

// Try to set the ID if it's saved. 
if (savedUniqueId) { 
    OSStatus result = MIDIObjectSetIntegerProperty(endpoint, kMIDIPropertyUniqueID, myUniqueId); 
    if (result == kMIDIIDNotUnique) { 
    savedUniqueId = 0; 
    } 
} 
// If not saved, record the system-assigned ID 
if (!savedUniqueId) { 
    OSStatus result = MIDIObjectGetIntegerProperty(endpoint, kMIDIPropertyUniqueID, &savedUniqueId); 
    // Handle the error? 
} 

。私は、0が無効な一意のIDであると仮定しました。これは少なくとも接続には当てはまります(kMIDIPropertyConnectionUniqueIDのドキュメントでは、 "存在しないか、接続がない場合は0"と言います)。

長期的な一意性をどのようにわずか32ビットで維持しているかわかりませんが、アプリのリニューアルには十分なはずです。

+0

ああ、そうだった。私は今週末にそのテストを行います。ありがとうございました! –

関連する問題