     // MARK: - Virtual MIDI
 
     /// Create set of virtual MIDI ports
-    open func createVirtualPorts(_ uniqueID: Int32 = 2_000_000) {
+    open func createVirtualPorts(_ uniqueID: Int32 = 2_000_000, name:String? = nil) {
         destroyVirtualPorts()
-
-        var result = MIDIDestinationCreateWithBlock(client, clientName, &virtualInput) { packetList, _ in
+        createVirtualInputPort(uniqueID, name: name)
+        createVirtualOutputPort(uniqueID, name: name)
+    }
+    open func createVirtualInputPort(_ uniqueID: Int32 = 2_000_000, name:String? = nil) {destroyVirtualPorts()
+        let virtualPortname = ((name != nil) ? name! : String(clientName))
+        
+        let result = MIDIDestinationCreateWithBlock(client, virtualPortname as CFString, &virtualInput) { packetList, _ in
             for packet in packetList.pointee {
                 // a coremidi packet may contain multiple midi events
                 for event in packet {

                }
            }
        }

        if result == noErr {
            MIDIObjectSetIntegerProperty(virtualInput, kMIDIPropertyUniqueID, uniqueID)
        } else {
            AKLog("Error creatervirt dest: \(clientName) -- \(virtualInput)")
        }

        result = MIDISourceCreate(client, clientName, &virtualOutput)
        if result == noErr {
            MIDIObjectSetIntegerProperty(virtualInput, kMIDIPropertyUniqueID, uniqueID + 1)
        } else {
            AKLog("Error creating virtual source: \(clientName) -- \(virtualOutput)")
        }
    }

    /// Discard all virtual ports
    open func destroyVirtualPorts() {

    internal var outputPort = MIDIPortRef()

    /// Virtual MIDI output
    open var virtualOutput = MIDIPortRef()

    /// Array of MIDI Endpoints
    open var endpoints = [String: MIDIEndpointRef]()

    /// MIDI Out Port Name
    internal var outputPortName: CFString = "MIDI Out Port" as CFString
