Как запазвате уникалността на виртуалния MIDI източник от MIDISourceCreate()?

Работя върху малък хак, изпращащ MIDI съобщения от приложение, използващо RtMidi като обвивка за CoreMIDI на OS X. Използвам RtMidiOut::openVirtualPort("MyAwesomePort"), за да мога да избера приложението си като входен източник в DAW.

Ако обаче програмата ми се затвори и я отворя отново, моята DAW не разпознава входното устройство като същия порт, въпреки че му е дадено същото име.

Първоначално използвах pyrtmidi, така че отидох и проверих поведението при писане на C++ директно с RtMidi. „Моята DAW“ в този случай е Reaper 4, но съм дублирал поведението в Pro Tools, Logic и MuLab.

Знам, че е възможно да се запази известна уникалност на виртуален midi порт, тъй като MidiKeys се държи точно както Бих искал приложението ми да се държи правилно: моите DAW го запомнят дори ако MidiKeys се затвори и отвори отново, докато моят DAW все още работи.

Така че се зарових в източника на RtMidi и обвивката на CoreMIDI изглеждаше достатъчно ясна. Всичко, което MIDISourceCreate изисква, е низ. Параметърът на клиента е (това, което предполагам след разглеждане на документите) идентификатор за моето приложение, което е клиент на услугите на 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 и прочетох това:

След като създадете виртуален източник, добра идея е да му присвоите същия уникален идентификатор, който имаше последния път, когато вашето приложение го създаде. (Въпреки че трябва да сте подготвени това да се провали в малко вероятния случай на сблъсък.) Това ще позволи на други клиенти да запазят по-лесно постоянни препратки към вашия виртуален източник.

Това изглежда като точно това, което търся. Освен че нямам представа как да присвоя на източника уникален идентификатор. Изходящият параметър за MIDISourceCreate е MIDIEndpointRef, който според документите е просто дефиниран до UInt32 надолу по реда. Така че предположих, че може би трябва да следя този UInt32, но това изглежда като лоша идея.

След като прерових всичко това, имам чувството, че се удрям в тухлена стена. Как да запазя уникалността на моя MIDI порт между стартиранията на моето приложение?


person michael.bartnett    schedule 04.10.2011    source източник


Отговори (1)


Според документи,

kMIDIPropertyUniqueID

Системата присвоява уникални идентификатори на всички обекти. Създателите на виртуални крайни точки могат да зададат това свойство на своите крайни точки, въпреки че това може да се провали, ако избраният идентификатор не е уникален.

Така че може би нещо подобно:

// 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?
}

Уникалният идентификатор е типизиран на SInt32. Направих предположението, че 0 е невалиден уникален идентификатор, което е вярно поне за връзките (документите за kMIDIPropertyConnectionUniqueID казват, че не съществува или 0, ако няма връзка).

Не съм сигурен как поддържате дългосрочна уникалност само с 32 бита, но се надяваме, че ще бъде достатъчно за повторно стартиране на вашето приложение.

person tc.    schedule 04.10.2011
comment
А, значи там беше. Ще го направя тест този уикенд. Благодаря ти! - person michael.bartnett; 05.10.2011