2011-10-04 11 views
5

Estoy trabajando en un pequeño hack enviando mensajes MIDI desde una aplicación utilizando RtMidi como un contenedor para CoreMIDI en OS X. Utilizo RtMidiOut::openVirtualPort("MyAwesomePort") para poder seleccionar mi aplicación como fuente de entrada en un DAW.¿Cómo se conserva la originalidad de la fuente MIDI virtual desde MIDISourceCreate()?

Sin embargo, si mi programa se cierra y lo vuelvo a abrir, mi DAW no reconoce el dispositivo de entrada como el mismo puerto, a pesar de recibir el mismo nombre.

Originalmente estaba usando pyrtmidi, así que fui y verifiqué el comportamiento escribiendo en C++ directamente con RtMidi. "Mi DAW" en este caso es Reaper 4, pero he duplicado el comportamiento en Pro Tools, Logic y MuLab.

Sé que es posible conservar algo de originalidad de un puerto midi virtual, ya que MidiKeys se comporta como me gustaría que se comporte mi aplicación: mis DAW lo recuerdan incluso si MidiKeys se cierra y vuelve a abrir mientras mi DAW todavía está ejecutándose .

Así que busqué en la fuente RtMidi, y la envoltura CoreMIDI parecía lo suficientemente directa. Todo lo que pide el MIDISourceCreate es una cadena. El parámetro del cliente es (lo que supongo después de examinar los documentos) un identificador para mi aplicación, ya que es un cliente de los servicios de 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; 
} 

Así que miré a la documentación MIDISourceCreate, y leyeron:

Después de crear una fuente virtual, que es una buena idea para asignar el mismo identificador único que tenía la última vez que su aplicación lo creó. (Aunque debe estar preparado para que esto falle en el improbable caso de una colisión). Esto permitirá que otros clientes retengan referencias persistentes a su fuente virtual más fácilmente.

Esto parece exactamente lo que estoy buscando. Excepto que no tengo idea de cómo asignarle a la fuente una identificación única. El parámetro out para MIDISourceCreate es MIDIEndpointRef, que de acuerdo con los documentos es simplemente typedef'd a UInt32 en la línea. Así que formulé la hipótesis de que tal vez debería hacer un seguimiento de este UInt32, pero parece una mala idea.

Después de excavar a través de todo esto, siento que estoy golpeando un poco de una pared de ladrillos. ¿Cómo retengo la singularidad de mi puerto MIDI entre las ejecuciones de mi aplicación?

Respuesta

5

De acuerdo con la docs,

kMIDIPropertyUniqueID

El sistema asigna una ID única de que todos los objetos. Los creadores de puntos finales virtuales pueden establecer esta propiedad en sus puntos finales, aunque al hacerlo pueden fallar si la ID elegida no es única.

Así que tal vez algo como esto:

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

El ID único se typedefed a un Sint32. He asumido que 0 es una ID única no válida, que al menos es cierta para las conexiones (los documentos para kMIDIPropertyConnectionUniqueID dicen que es "inexistente o 0 si no hay conexión").

No estoy seguro de cómo mantener la exclusividad a largo plazo con solo 32 bits, pero con suerte será suficiente para relanzar su aplicación.

+0

Ah, eso es lo que era. Le daré una prueba este fin de semana. ¡Gracias! –

Cuestiones relacionadas