2011-10-04 28 views
5

Tôi đang thực hiện một chút hack khi gửi tin nhắn MIDI từ một ứng dụng bằng RtMidi như một trình bao bọc cho CoreMIDI trên OS X. Tôi sử dụng RtMidiOut::openVirtualPort("MyAwesomePort") để tôi có thể chọn ứng dụng của mình làm nguồn đầu vào trong DAW.Làm cách nào để giữ lại tính duy nhất của nguồn MIDI ảo từ MIDISourceCreate()?

Tuy nhiên, nếu chương trình của tôi đóng và tôi mở lại, DAW của tôi không nhận dạng thiết bị đầu vào là cùng một cổng, mặc dù có cùng tên.

Ban đầu tôi sử dụng pyrtmidi, vì vậy đã đi và xác minh hành vi viết bằng C++ trực tiếp với RtMidi. "DAW của tôi" trong trường hợp này là Reaper 4, nhưng tôi đã sao chép hành vi trong Pro Tools, Logic và MuLab.

Tôi biết có thể giữ một số tính duy nhất của cổng midi ảo, vì MidiKeys hoạt động giống như ứng dụng của tôi hoạt động: DAW của tôi nhớ nó ngay cả khi MidiKey đóng và mở lại trong khi DAW của tôi vẫn đang chạy .

Vì vậy, tôi đã đào sâu vào nguồn RtMidi và trình bao bọc CoreMIDI có vẻ khá đơn giản. Tất cả những gì mà MIDISourceCreate yêu cầu là một chuỗi. Tham số khách hàng là (những gì tôi đoán sau khi duyệt các tài liệu) một định danh cho ứng dụng của tôi, nó là một khách hàng của các dịch vụ 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; 
} 

Vì vậy, tôi đã xem xét các tài liệu MIDISourceCreate, và đọc:

Sau khi tạo một nguồn ảo, đó là một ý tưởng tốt để gán nó cùng một ID duy nhất nó có thời gian qua ứng dụng của bạn tạo ra nó. (Mặc dù bạn nên chuẩn bị cho điều này để thất bại trong trường hợp không chắc chắn của một vụ va chạm.) Điều này sẽ cho phép các khách hàng khác để giữ lại tài liệu tham khảo liên tục đến nguồn ảo của bạn dễ dàng hơn.

Điều này có vẻ giống như những gì tôi đang tìm kiếm. Ngoại trừ tôi không có ý tưởng làm thế nào để gán cho nguồn một ID duy nhất. Tham số ngoài cho MIDISourceCreateMIDIEndpointRef, theo tài liệu chỉ được nhập vào một số UInt32 xuống dòng. Vì vậy, tôi đưa ra giả thuyết rằng có lẽ tôi nên theo dõi UInt32 này, nhưng điều đó có vẻ như là một ý tưởng tồi.

Sau khi đào qua tất cả những điều này tôi cảm thấy như tôi đang đánh một chút của một bức tường gạch. Làm cách nào để giữ lại tính duy nhất của cổng MIDI của tôi ở giữa các lần chạy ứng dụng của tôi? hệ thống

Trả lời

5

Theo docs,

kMIDIPropertyUniqueID

Các gán độc đáo ID cho tất cả các đối tượng. Người sáng tạo các điểm cuối ảo có thể đặt thuộc tính này trên thiết bị đầu cuối của họ, mặc dù làm như vậy có thể bị lỗi nếu ID đã chọn không phải là duy nhất.

Vì vậy, có lẽ một cái gì đó như thế này:

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

ID duy nhất được typedefed đến một SInt32. Tôi đã giả định rằng 0 là một ID duy nhất không hợp lệ, ít nhất là đúng đối với các kết nối (các tài liệu cho kMIDIPropertyConnectionUniqueID nói rằng nó "không tồn tại hoặc 0 nếu không có kết nối").

Tôi không chắc chắn cách bạn duy trì tính duy nhất lâu dài chỉ với 32 bit, nhưng hy vọng sẽ đủ để khởi chạy lại ứng dụng của bạn.

+0

Ah, vậy là xong rồi. Tôi sẽ cho một bài kiểm tra vào cuối tuần này. Cảm ơn bạn! –

Các vấn đề liên quan