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

Я работаю над небольшой хакерской отправкой 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 запрашивает, это строка.Параметр 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 и прочитал это:

После создания виртуального источника рекомендуется назначить ему тот же уникальный идентификатор, который был у него при последнем создании приложения.(Хотя вы должны быть готовы к тому, что это приведет к сбою в маловероятном случае столкновения.) Это позволит другим клиентам легче сохранять постоянные ссылки на ваш виртуальный источник.

Похоже, именно это я и ищуза.За исключением того, что я понятия не имею, как назначить источнику уникальный идентификатор.Параметр out для MIDISourceCreate - это MIDIEndpointRef, который, согласно документам, просто typedef'd до UInt32 вниз по линии.Поэтому я предположил, что, может быть, мне следует следить за этим UInt32, но это кажется плохой идеей.

Перебирая все это, я чувствую, что ударился о кирпичную стену.Как сохранить уникальность моего MIDI-порта между запусками моего приложения?

1 Ответ

5 голосов
/ 04 октября 2011

По документам ,

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

...