Как вы сохраняете уникальность виртуального MIDI-источника из MIDISourceCreate()?

Я работаю над небольшим хаком, отправляя MIDI-сообщения из приложения, используя RtMidi в качестве оболочки для CoreMIDI в OS X. Я использую RtMidiOut::openVirtualPort("MyAwesomePort"), поэтому я могу выбрать свое приложение в качестве источника ввода в DAW.

Однако, если моя программа закрывается, а я открываю ее снова, моя DAW не распознает устройство ввода как тот же порт, несмотря на то, что ему присвоено то же имя.

Первоначально я использовал pyrtmidi, поэтому пошел и проверил поведение, написанное на C++, непосредственно с помощью RtMidi. «Моей DAW» в данном случае является Reaper 4, но я продублировал поведение в Pro Tools, Logic и MuLab.

Я знаю, что можно сохранить некоторую уникальность виртуального миди-порта, поскольку 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