### Initialize and Start MIDI Manager Source: https://context7.com/orchetect/swift-midi/llms.txt Create a single instance of `MIDI.IO.Manager` per application and call `start()` before performing any I/O operations. The manager handles CoreMIDI lifecycle and automatic reconnection. ```swift import SwiftMIDI class AppDelegate: NSObject, NSApplicationDelegate { let midiManager = MIDI.IO.Manager( clientName: "MyAppMIDIManager", // internal CoreMIDI identifier model: "MyApp", // user-visible model name on virtual ports manufacturer: "MyCompany" // user-visible manufacturer name ) func applicationDidFinishLaunching(_ notification: Notification) { // Optional: receive CoreMIDI system notifications midiManager.notificationHandler = { notification, manager in print("Core MIDI system notification:", notification) } do { try midiManager.start() print("MIDI Manager started successfully.") } catch { print("Error starting MIDI Manager:", error) } } // Manager disposes itself (and all owned ports/connections) on deinit. // No manual cleanup is required before app termination. } ``` -------------------------------- ### Start the MIDI Manager Source: https://github.com/orchetect/swift-midi/wiki/Setting-up-the-Manager Call the start() method on the MIDI manager instance to enable MIDI functionality. This should be done once, typically at app launch. Subsequent calls have no effect. Error handling is included for the start operation. ```swift do { try midiManager.start() } catch { print("Error while starting MIDI manager: \(error)") } ``` -------------------------------- ### MIDI Listener Class Setup and Event Handling Source: https://github.com/orchetect/swift-midi/wiki/Simple-MIDI-Listener-Class-Example This Swift class sets up a MIDI manager, creates a virtual input port, and defines a handler for receiving and processing MIDI events. It prints received Note On, Note Off, CC, and Program Change events to the console. Ensure the MIDIKit framework is imported. ```swift import Foundation import MIDIKit public class MIDIModule { private let midiManager = MIDI.IO.Manager( clientName: "MIDIEventLogger", model: "LoggerApp", manufacturer: "MyCompany") public init() { do { midiManager.notificationHandler = { notification, manager in print("Core MIDI notification:", notification) } print("Starting MIDI manager.") try midiManager.start() print("Creating virtual input MIDI port.") let inputTag = "Virtual_MIDI_In" try midiManager.addInput( name: "LoggerApp MIDI In", tag: inputTag, uniqueID: .userDefaultsManaged(key: inputTag), receiveHandler: .events { [weak self] events in // Note: this handler will be called on a background thread // so call the next line on main if it may result in UI updates DispatchQueue.main.async { events.forEach { self?.receivedMIDIEvent($0) } } } ) } catch { print("MIDI Setup Error:", error) } } private func receivedMIDIEvent(_ event: MIDI.Event) { switch event { case .noteOn(let payload): print("NoteOn:", payload.note, payload.velocity, payload.channel) case .noteOff(let payload): print("NoteOff:", payload.note, payload.velocity, payload.channel) case .cc(let payload): print("CC:", payload.controller, payload.value, payload.channel) case .programChange(let payload): print("PrgCh:", payload.program, payload.channel) // etc... default: break } } } ``` -------------------------------- ### Complete MIDI Listener Class in Swift Source: https://context7.com/orchetect/swift-midi/llms.txt This class sets up a MIDI manager, creates a virtual input port, and handles incoming MIDI events. It's designed as a starting point for applications needing to log or process MIDI data. Ensure SwiftMIDI is imported and configured correctly. ```swift import Foundation import SwiftMIDI public class MIDIModule { private let midiManager = MIDI.IO.Manager( clientName: "MIDIEventLogger", model: "LoggerApp", manufacturer: "MyCompany" ) public init() { do { midiManager.notificationHandler = { notification, _ in print("Core MIDI notification:", notification) } try midiManager.start() let inputTag = "Virtual_MIDI_In" try midiManager.addInput( name: "LoggerApp MIDI In", tag: inputTag, uniqueID: .userDefaultsManaged(key: inputTag), receiveHandler: .events { [weak self] events in DispatchQueue.main.async { events.forEach { self?.receivedMIDIEvent($0) } } } ) } catch { print("MIDI Setup Error:", error) } } private func receivedMIDIEvent(_ event: MIDI.Event) { switch event { case .noteOn(let payload): print("NoteOn:", payload.note, payload.velocity.midi1Value, "ch:", payload.channel) case .noteOff(let payload): print("NoteOff:", payload.note, payload.velocity.midi1Value, "ch:", payload.channel) case .cc(let payload): print("CC:", payload.controller, payload.value.midi1Value, "ch:", payload.channel) case .programChange(let payload): print("ProgramChange:", payload.program, "ch:", payload.channel) case .pitchBend(let payload): print("PitchBend:", payload.value.midi1Value, "ch:", payload.channel) case .sysEx7(let payload): print("SysEx7:", payload.data.map { String(format: "%02X", $0) }.joined(separator: " ")) default: break } } } ``` -------------------------------- ### Import SwiftMIDI Library Source: https://github.com/orchetect/swift-midi/blob/main/Sources/SwiftMIDI/SwiftMIDI.docc/SwiftMIDI.md Import the entire SwiftMIDI library to make all extensions available. Consider importing specific packages if only a subset of features is needed. ```swift import SwiftMIDI ``` -------------------------------- ### Create MIDI Manager Instance Source: https://github.com/orchetect/swift-midi/wiki/Setting-up-the-Manager Instantiate MIDI.IO.Manager with your application's client name, model, and manufacturer. This manager is typically scoped at an app-level and can be stored globally. ```swift let midiManager = MIDI.IO.Manager( clientName: "MyAppMIDIManager", model: "MyApp", manufacturer: "MyCompany" ) ``` -------------------------------- ### Enable Network MIDI Sessions with SwiftMIDI Source: https://context7.com/orchetect/swift-midi/llms.txt Configure the global Network MIDI policy using `MIDI.IO.setNetworkSession`. After enabling, network endpoints are available in the standard endpoint lists. ```swift import SwiftMIDI // Allow connections from anyone on the local network MIDI.IO.setNetworkSession(policy: .anyone) // Once enabled, network MIDI endpoints appear in the normal endpoint list: let availableInputs = midiManager.endpoints.inputs let availableOutputs = midiManager.endpoints.outputs ``` -------------------------------- ### Add SwiftMIDI Product to Target Source: https://github.com/orchetect/swift-midi/blob/main/README.md After adding the SwiftMIDI umbrella repository as a dependency, include the 'SwiftMIDI' product in your target's build settings. ```swift .product(name: "SwiftMIDI", package: "swift-midi") ``` -------------------------------- ### UInt32 Initialization with Bipolar Unit Interval Source: https://github.com/orchetect/swift-midi/wiki/Value-Types Initializes a `UInt32` value by scaling a bipolar unit interval (-1.0 to 1.0) to the full range of `UInt32` (0x0 to 0xFFFFFFFF), maintaining consistent midpoints. ```swift let uint32Value = UInt32(bipolarUnitInterval: 0.75) ``` -------------------------------- ### Create Virtual MIDI Output Port Source: https://context7.com/orchetect/swift-midi/llms.txt Registers an app as a MIDI source. Events can be sent by referencing the port via its tag. Ensure the output port is added before attempting to send events. ```swift import SwiftMIDI let outputTag = "Virtual_MIDI_Out" do { try midiManager.addOutput( name: "MyApp MIDI Out", tag: outputTag, uniqueID: .userDefaultsManaged(key: outputTag) ) } catch { print("Failed to create virtual output:", error) } // Send events via the managed output let output = midiManager.managedOutputs[outputTag] do { try output?.send(event: .noteOn(60, velocity: .midi1(127), channel: 0x0)) try output?.send(event: .noteOn(64, velocity: .unitInterval(0.8), channel: 0x0)) try output?.send(event: .cc(11, value: .midi1(64), channel: 0x0)) // Expression try output?.send(event: .pitchBend(.midi1(8192), channel: 0x0)) // center try output?.send(event: .noteOff(60, velocity: .midi1(0), channel: 0x0)) } catch { print("Failed to send MIDI event:", error) } ``` -------------------------------- ### Create Virtual MIDI Input Port Source: https://context7.com/orchetect/swift-midi/llms.txt Registers an app as a MIDI destination. Events are received asynchronously on a background thread. Ensure to dispatch UI updates to the main thread. ```swift import SwiftMIDI let inputTag = "Virtual_MIDI_In" do { try midiManager.addInput( name: "MyApp MIDI In", // user-visible name in the system tag: inputTag, // internal identifier for this Manager uniqueID: .userDefaultsManaged(key: inputTag), // persists CoreMIDI identity across launches receiveHandler: .events { [weak self] events in // Called on a background thread — dispatch to main for UI updates DispatchQueue.main.async { events.forEach { self?.handleMIDIEvent($0) } } } ) } catch { print("Failed to create virtual input:", error) } func handleMIDIEvent(_ event: MIDI.Event) { switch event { case .noteOn(let payload): print("Note On — note: \(payload.note), vel: \(payload.velocity.midi1Value), ch: \(payload.channel)") case .noteOff(let payload): print("Note Off — note: \(payload.note), vel: \(payload.velocity.midi1Value), ch: \(payload.channel)") case .cc(let payload): print("CC — controller: \(payload.controller), value: \(payload.value.midi1Value), ch: \(payload.channel)") case .programChange(let payload): print("Program Change — program: \(payload.program), ch: \(payload.channel)") default: break } } ``` -------------------------------- ### Import MIDIKit Library Source: https://github.com/orchetect/swift-midi/wiki/Home Import the MIDIKit library into your Swift project. All MIDIKit types are accessed through the global `MIDI` namespace. ```swift import MIDIKit ``` -------------------------------- ### Enable Network MIDI Session Source: https://github.com/orchetect/swift-midi/wiki/Enable-Network-MIDI-Sessions Set the global policy for network MIDI connections to allow anyone to connect. This is a static setting for the entire application. ```swift MIDI.IO.setNetworkSession(policy: .anyone) ``` -------------------------------- ### Double Initialization with Bipolar Unit Interval Source: https://github.com/orchetect/swift-midi/wiki/Value-Types Initializes a `Double` value by scaling a bipolar unit interval (ranging from -1.0 to 1.0) to a standard unit interval (0.0 to 1.0), ensuring consistent midpoints. ```swift let doubleValue = Double(bipolarUnitInterval: -0.5) ``` -------------------------------- ### Add Virtual MIDI Input Port Source: https://context7.com/orchetect/swift-midi/llms.txt Registers your app as a MIDI destination visible to other system software. Events are received asynchronously on a background thread. ```APIDOC ## Virtual MIDI Input Port A virtual input port registers your app as a MIDI destination visible to other software in the system. Events are received asynchronously on a background thread. ```swift import SwiftMIDI let inputTag = "Virtual_MIDI_In" do { try midiManager.addInput( name: "MyApp MIDI In", // user-visible name in the system tag: inputTag, // internal identifier for this Manager uniqueID: .userDefaultsManaged(key: inputTag), // persists CoreMIDI identity across launches receiveHandler: .events { [weak self] events in // Called on a background thread — dispatch to main for UI updates DispatchQueue.main.async { events.forEach { self?.handleMIDIEvent($0) } } } ) } catch { print("Failed to create virtual input:", error) } func handleMIDIEvent(_ event: MIDI.Event) { switch event { case .noteOn(let payload): print("Note On — note: \(payload.note), vel: \(payload.velocity.midi1Value), ch: \(payload.channel)") case .noteOff(let payload): print("Note Off — note: \(payload.note), vel: \(payload.velocity.midi1Value), ch: \(payload.channel)") case .cc(let payload): print("CC — controller: \(payload.controller), value: \(payload.value.midi1Value), ch: \(payload.channel)") case .programChange(let payload): print("Program Change — program: \(payload.program), ch: \(payload.channel)") default: break } } ``` ``` -------------------------------- ### Optional MIDIKit Extensions Source: https://github.com/orchetect/swift-midi/wiki/Home Import optional MIDIKit extensions to access additional functionality for specific purposes like Standard MIDI Files, MIDI Timecode, or HUI protocol. ```swift MIDI.File // from MIDIKitSMF, Standard MIDI File related MIDI.MTC // from MIDIKitSync, MIDI Timecode related MIDI.HUI // from MIDIKitControlSurfaces, HUI protocol related ``` -------------------------------- ### Add Virtual MIDI Input Port Source: https://github.com/orchetect/swift-midi/wiki/Virtual-MIDI-Ports Creates a virtual MIDI input port. MIDI events are received on a background thread, so UI updates must be dispatched to the main queue. Use `.userDefaultsManaged` for persistent endpoint identification. ```swift let inputTag = "Virtual_MIDI_In" try midiManager.addInput( name: "MyApp MIDI In", tag: inputTag, uniqueID: .userDefaultsManaged(key: inputTag), receiveHandler: .events { [weak self] events in // Note: this handler will be called on a background thread // so call the next line on main if it may result in UI updates DispatchQueue.main.async { events.forEach { self?.receivedMIDIEvent($0) } } } ) ``` ```swift private func receivedMIDIEvent(_ event: MIDI.Event) { switch event { case .noteOn(let payload): print("NoteOn:", payload.note, payload.velocity, payload.channel) case .noteOff(let payload): print("NoteOff:", payload.note, payload.velocity, payload.channel) case .cc(let payload): print("CC:", payload.controller, payload.value, payload.channel) case .programChange(let payload): print("PrgCh:", payload.program, payload.channel) // etc... default: break } } ``` -------------------------------- ### Add Virtual MIDI Output Port Source: https://github.com/orchetect/swift-midi/wiki/Virtual-MIDI-Ports Creates a virtual MIDI output port. Use `.userDefaultsManaged` for persistent endpoint identification. This allows other applications to reliably reconnect to your virtual output. ```swift let outputTag = "Virtual_MIDI_Out" try midiManager.addOutput( name: "MyApp MIDI Out", tag: outputTag, uniqueID: .userDefaultsManaged(key: outputTag) ) ``` -------------------------------- ### Add Virtual MIDI Output Port Source: https://context7.com/orchetect/swift-midi/llms.txt Registers your app as a MIDI source visible to other software. Events are sent by referencing the port via its tag in `managedOutputs`. ```APIDOC ## Virtual MIDI Output Port A virtual output port registers your app as a MIDI source visible to other software. Send events by referencing the port via its tag in `managedOutputs`. ```swift import SwiftMIDI let outputTag = "Virtual_MIDI_Out" do { try midiManager.addOutput( name: "MyApp MIDI Out", tag: outputTag, uniqueID: .userDefaultsManaged(key: outputTag) ) } catch { print("Failed to create virtual output:", error) } // Send events via the managed output let output = midiManager.managedOutputs[outputTag] do { try output?.send(event: .noteOn(60, velocity: .midi1(127), channel: 0x0)) try output?.send(event: .noteOn(64, velocity: .unitInterval(0.8), channel: 0x0)) try output?.send(event: .cc(11, value: .midi1(64), channel: 0x0)) // Expression try output?.send(event: .pitchBend(.midi1(8192), channel: 0x0)) // center try output?.send(event: .noteOff(60, velocity: .midi1(0), channel: 0x0)) } catch { print("Failed to send MIDI event:", error) } ``` ``` -------------------------------- ### MIDIKit Namespace Structure Source: https://github.com/orchetect/swift-midi/wiki/Home Understand the hierarchical structure of the MIDIKit namespace for accessing different modules like I/O, Events, and optional extensions. ```swift MIDI // Base namespace, containing common types MIDI.IO // I/O related MIDI.Event // MIDI events related ``` -------------------------------- ### Add Managed Input Connection to All Endpoints Source: https://github.com/orchetect/swift-midi/wiki/Managed-Connections Creates a managed input connection that automatically subscribes to all current and future MIDI outputs. It filters out endpoints owned by the Manager itself. Configure a receive handler to process incoming events. ```swift try midiManager.addInputConnection( toOutputs: [], tag: "InputConnection1", mode: .allEndpoints, // continually auto-add new outputs that appear filter: .owned(), // filter out Manager-owned virtual outputs receiveHandler: // add your handler here... ) ``` -------------------------------- ### Add Managed Output Connection Source: https://github.com/orchetect/swift-midi/wiki/Managed-Connections Creates a managed output connection to specified input endpoints. The connection will automatically re-establish if target endpoints disappear and reappear. ```swift try midiManager.addOutputConnection( toInputs: [], tag: "OutputConnection1" ) ``` -------------------------------- ### MIDI Event Note On Value Types Source: https://github.com/orchetect/swift-midi/wiki/Value-Types Demonstrates how to create MIDI Note On events using different velocity value types: MIDI 1.0 (7-bit), MIDI 2.0 (16-bit), and Unit Interval (Double). MIDIKit ensures seamless conversion and midpoint consistency across these types. ```swift MIDI.Event.noteOn(60, velocity: .midi1(64), // 7-bit, 0 ... 127 channel: 0) // MIDI 2.0 value type MIDI.Event.noteOn(60, velocity: .midi2(32768), // 16-bit, 0 ... 65535 channel: 0) // Unit Interval value type (MIDI protocol agnostic) MIDI.Event.noteOn(60, velocity: .unitInterval(0.5), // Double, 0.0 ... 1.0 channel: 0) ``` -------------------------------- ### Manage Target Endpoints for Output Connection Source: https://github.com/orchetect/swift-midi/wiki/Managed-Connections Allows adding or removing specific MIDI input endpoints from an existing managed output connection. Targets can be specified directly or by unique ID. ```swift let conn = midiManager.managedOutputConnections["OutputConnection1"] // add/remove endpoints conn?.add(inputs: [endpoint]) conn?.remove(inputs: [endpoint]) // add/remove endpoints based on criteria such as unique ID conn?.add(inputs: [.uniqueID(uID)]) conn?.remove(inputs: [.uniqueID(uID)]) ``` -------------------------------- ### Add SwiftMIDI Dependency to Package.swift Source: https://context7.com/orchetect/swift-midi/llms.txt Add the SwiftMIDI umbrella package as a dependency in your Package.swift file to include all extensions. ```swift // Package.swift dependencies: [ .package(url: "https://github.com/orchetect/swift-midi", from: "1.0.0") ], targets: [ .target( name: "MyApp", dependencies: [ .product(name: "SwiftMIDI", package: "swift-midi") ] ) ] ``` ```swift // In your source files import SwiftMIDI // All extensions are now available: SwiftMIDICore, SwiftMIDIIO, // SwiftMIDIFile, SwiftMIDISync, SwiftMIDIControlSurfaces, SwiftMIDIUI ``` -------------------------------- ### Add SwiftMIDI Umbrella Repo as Dependency Source: https://github.com/orchetect/swift-midi/blob/main/README.md To use all extensions of SwiftMIDI, add the umbrella repository as a dependency in your Swift Package Manager configuration. ```swift .package(url: "https://github.com/orchetect/swift-midi", from: "1.0.0") ``` -------------------------------- ### Filter MIDI Events with SwiftMIDI Source: https://context7.com/orchetect/swift-midi/llms.txt Utilize category methods on `[MIDI.Event]` arrays for filtering. Strategies include `only`, `keep`, and `drop`. Filters are chainable and support various event types and ranges. ```swift import SwiftMIDI let events: [MIDI.Event] = receivedEvents // array from a receive handler // --- Channel Voice filters --- // Retain ONLY note on/off events on channel 0 let noteEvents = events .filter(chanVoice: .onlyTypes([.noteOn, .noteOff])) .filter(chanVoice: .onlyChannel(0x0)) // Keep CC 1 (mod wheel), 11 (expression), 64 (sustain) on ch 0; // drop Active Sensing; retain all other non-channel-voice events let filteredEvents = events .filter(sysRealTime: .dropTypes([.activeSensing])) .filter(chanVoice: .keepChannel(0x0)) .filter(chanVoice: .keepCCs([1, 11, 64])) // Keep only notes in the piano range let pianoRange = events .filter(chanVoice: .keepNotesInRanges([21...108])) // Drop all pitch bend events let noPitchBend = events .filter(chanVoice: .dropType(.pitchBend)) // --- System Exclusive filters --- let sysExOnly = events.filter(sysEx: .only) let noSysEx = events.filter(sysEx: .drop) // --- System Real Time filters --- let clockOnly = events.filter(sysRealTime: .onlyType(.timingClock)) let noClocks = events.filter(sysRealTime: .dropTypes([.timingClock, .activeSensing])) // --- MIDI 2.0 UMP Group filters --- let group0Events = events.filter(group: 0) let multiGroup = events.filter(groups: [0, 1]) ``` -------------------------------- ### Manage Target Endpoints for Input Connection Source: https://github.com/orchetect/swift-midi/wiki/Managed-Connections Allows adding or removing specific MIDI output endpoints from an existing managed input connection. Targets can be specified directly or by unique ID. ```swift let conn = midiManager.managedInputConnections["InputConnection1"] // add/remove endpoints conn?.add(outputs: [endpoint]) conn?.remove(outputs: [endpoint]) // add/remove endpoints based on criteria such as unique ID conn?.add(outputs: [.uniqueID(uID)]) conn?.remove(outputs: [.uniqueID(uID)]) ``` -------------------------------- ### Add Managed Input Connection Source: https://github.com/orchetect/swift-midi/wiki/Managed-Connections Creates a managed input connection to specified output endpoints. The connection will automatically re-establish if target endpoints disappear and reappear. A receive handler processes incoming MIDI events on a background thread. ```swift try midiManager.addInputConnection( toOutputs: [], tag: "InputConnection1", receiveHandler: .events { [weak self] events in // Note: this handler will be called on a background thread // so call the next line on main if it may result in UI updates DispatchQueue.main.async { events.forEach { self?.receivedMIDIEvent($0) } } } ) ``` -------------------------------- ### Send MIDI Events via Virtual Output Source: https://github.com/orchetect/swift-midi/wiki/Virtual-MIDI-Ports Sends MIDI events through a previously created virtual output port. Events are sent using the `.send(event:)` method on the managed output. ```swift let output = midiManager.managedOutputs[outputTag] try output?.send(event: .noteOn(60, velocity: .midi1(127), channel: 0x2)) try output?.send(event: .cc(11, value: .midi1(64), channel: 0x2)) ``` -------------------------------- ### Send MIDI Events via Managed Output Connection Source: https://github.com/orchetect/swift-midi/wiki/Managed-Connections Sends a MIDI event through a specified managed output connection. Supports various MIDI message types like note on and control change. ```swift let conn = midiManager.managedOutputConnections["OutputConnection1"] try conn?.send(event: .noteOn(60, velocity: .midi1(127), channel: 0x2)) try conn?.send(event: .cc(11, value: .midi1(64), channel: 0x2)) ``` -------------------------------- ### Remove All Virtual Ports or Connections of a Type Source: https://github.com/orchetect/swift-midi/wiki/Remove-a-Virtual-Port-or-Connection Use the .all option with the remove method to clear all virtual ports or connections of a specific type. This is useful for resetting all inputs, outputs, input connections, or output connections. ```swift midiManager.remove(.input, .all) midiManager.remove(.output, .all) midiManager.remove(.inputConnection, .all) midiManager.remove(.outputConnection, .all) ``` -------------------------------- ### Accessing MIDI Velocity Values Source: https://github.com/orchetect/swift-midi/wiki/Value-Types Shows how to access the different representations (MIDI 1.0, MIDI 2.0, Unit Interval) of a MIDI Note On event's velocity payload. This allows for easy conversion and use of velocity data across various MIDI contexts. ```swift func receivedMIDI(event: MIDI.Event) { switch event { case .noteOn(payload): print(payload.velocity.midi1Value) // "64" print(payload.velocity.midi2Value) // "32768" print(payload.velocity.unitIntervalValue) // "0.5" default: break } } ``` -------------------------------- ### Add Managed Output Connection Source: https://context7.com/orchetect/swift-midi/llms.txt Sends events to one or more system input endpoints, with automatic reconnection on endpoint disappearance/reappearance. ```APIDOC ## Managed Output Connection A managed output connection sends events to one or more system input endpoints, with automatic reconnection on endpoint disappearance/reappearance. ```swift import SwiftMIDI do { try midiManager.addOutputConnection( toInputs: [], // add target inputs later, or specify here tag: "OutputConnection1" ) } catch { print("Failed to create output connection:", error) } // Dynamically add a target endpoint by unique ID let conn = midiManager.managedOutputConnections["OutputConnection1"] conn?.add(inputs: [.uniqueID(someEndpointUniqueID)]) // Send MIDI events do { try conn?.send(event: .noteOn(60, velocity: .midi1(100), channel: 0x0)) try conn?.send(event: .cc(7, value: .midi1(100), channel: 0x0)) // Channel Volume try conn?.send(event: .noteOff(60, velocity: .midi1(0), channel: 0x0)) } catch { print("Send error:", error) } ``` ``` -------------------------------- ### Remove All Owned Virtual Ports and Connections Source: https://github.com/orchetect/swift-midi/wiki/Remove-a-Virtual-Port-or-Connection Call midiManager.removeAll() to dispose of all virtual ports and connections currently owned by the Manager at once. This provides a quick way to clean up all created virtual MIDI endpoints. ```swift midiManager.removeAll() ``` -------------------------------- ### Remove All Source: https://github.com/orchetect/swift-midi/wiki/Remove-a-Virtual-Port-or-Connection Removes all virtual ports and connections owned by the Manager. ```APIDOC ## Remove All Or remove all ports and connections that are owned by the `Manager` at once: ```swift midiManager.removeAll() ``` ``` -------------------------------- ### Filter System Common Events Source: https://github.com/orchetect/swift-midi/wiki/Event-Filters Provides methods to filter System Common MIDI events. You can choose to retain only specific types, keep specific types while retaining all others, or drop specific types. ```swift .filter(sysCommon: .only) ``` ```swift .filter(sysCommon: .onlyType(.songSelect)) ``` ```swift .filter(sysCommon: .onlyTypes([.songSelect, .tuneRequest])) ``` ```swift .filter(sysCommon: .keepType(.songSelect)) ``` ```swift .filter(sysCommon: .keepTypes([.songSelect, .tuneRequest])) ``` ```swift .filter(sysCommon: .drop) ``` ```swift .filter(sysCommon: .dropType(.songSelect)) ``` ```swift .filter(sysCommon: .dropTypes([.songSelect, .tuneRequest])) ``` -------------------------------- ### Add Managed Output Connection Source: https://context7.com/orchetect/swift-midi/llms.txt Sends events to system input endpoints with automatic reconnection. Target endpoints can be added dynamically by their unique ID. Ensure the connection is established before sending events. ```swift import SwiftMIDI do { try midiManager.addOutputConnection( toInputs: [], // add target inputs later, or specify here tag: "OutputConnection1" ) } catch { print("Failed to create output connection:", error) } // Dynamically add a target endpoint by unique ID let conn = midiManager.managedOutputConnections["OutputConnection1"] conn?.add(inputs: [.uniqueID(someEndpointUniqueID)]) // Send MIDI events do { try conn?.send(event: .noteOn(60, velocity: .midi1(100), channel: 0x0)) try conn?.send(event: .cc(7, value: .midi1(100), channel: 0x0)) // Channel Volume try conn?.send(event: .noteOff(60, velocity: .midi1(0), channel: 0x0)) } catch { print("Send error:", error) } ``` -------------------------------- ### Access Bluetooth MIDI Endpoints on iOS with SwiftMIDI Source: https://context7.com/orchetect/swift-midi/llms.txt Bluetooth MIDI devices are automatically integrated into the endpoint lists once the CoreBluetooth/CoreMIDI pairing UI is presented. Connect to them like any other endpoint. ```swift import SwiftMIDI // Bluetooth MIDI devices appear automatically in the endpoint lists // once the CoreBluetooth/CoreMIDI pairing UI is presented (see example projects). let bluetoothInputs = midiManager.endpoints.inputs // includes BT devices let bluetoothOutputs = midiManager.endpoints.outputs // includes BT devices // Connect to a Bluetooth output just like any other endpoint let conn = midiManager.managedInputConnections["InputConnection1"] if let btOutput = bluetoothOutputs.first(where: { $0.displayName == "My BT Device" }) { conn?.add(outputs: [btOutput]) } ``` -------------------------------- ### Add Managed Input Connection Source: https://context7.com/orchetect/swift-midi/llms.txt Receives events from system output endpoints. The Manager automatically reconnects if endpoints disappear and reappear. Use `.allEndpoints` to auto-connect to every system output. ```swift import SwiftMIDI // Connect to all system outputs (auto-subscribes to new ones as they appear) do { try midiManager.addInputConnection( toOutputs: [], // start with no specific targets tag: "InputConnection1", mode: .allEndpoints, // auto-connect to every system output filter: .owned(), // exclude virtual outputs owned by this Manager receiveHandler: .events { [weak self] events in DispatchQueue.main.async { events.forEach { self?.handleMIDIEvent($0) } } } ) } catch { print("Failed to create input connection:", error) } // Add or remove specific endpoints dynamically let conn = midiManager.managedInputConnections["InputConnection1"] conn?.add(outputs: [.uniqueID(someEndpointUniqueID)]) conn?.remove(outputs: [.uniqueID(someEndpointUniqueID)]) ``` -------------------------------- ### Remove Ports and Connections with SwiftMIDI Source: https://context7.com/orchetect/swift-midi/llms.txt Use the `remove` method to delete individual or all ports and connections owned by the `midiManager`. Call `removeAll()` to clear all managed resources. ```swift import SwiftMIDI // Remove individual ports or connections by tag midiManager.remove(.input, .withTag("Virtual_MIDI_In")) midiManager.remove(.output, .withTag("Virtual_MIDI_Out")) midiManager.remove(.inputConnection, .withTag("InputConnection1")) midiManager.remove(.outputConnection, .withTag("OutputConnection1")) // Remove all of a specific type midiManager.remove(.input, .all) midiManager.remove(.output, .all) midiManager.remove(.inputConnection, .all) midiManager.remove(.outputConnection, .all) // Remove everything the Manager owns at once midiManager.removeAll() ``` -------------------------------- ### Add Managed Input Connection Source: https://context7.com/orchetect/swift-midi/llms.txt Receives events from one or more system output endpoints. The Manager automatically reconnects if endpoints disappear and reappear. ```APIDOC ## Managed Input Connection A managed input connection receives events from one or more system output endpoints. The Manager automatically reconnects if endpoints disappear and reappear. ```swift import SwiftMIDI // Connect to all system outputs (auto-subscribes to new ones as they appear) do { try midiManager.addInputConnection( toOutputs: [], // start with no specific targets tag: "InputConnection1", mode: .allEndpoints, // auto-connect to every system output filter: .owned(), // exclude virtual outputs owned by this Manager receiveHandler: .events { [weak self] events in DispatchQueue.main.async { events.forEach { self?.handleMIDIEvent($0) } } } ) } catch { print("Failed to create input connection:", error) } // Add or remove specific endpoints dynamically let conn = midiManager.managedInputConnections["InputConnection1"] conn?.add(outputs: [.uniqueID(someEndpointUniqueID)]) conn?.remove(outputs: [.uniqueID(someEndpointUniqueID)]) ``` ``` -------------------------------- ### MIDI Event Value Types and Conversions Source: https://context7.com/orchetect/swift-midi/llms.txt MIDI events utilize a hybrid value system supporting MIDI 1.0 (7-bit), MIDI 2.0 (16/32-bit), and unit interval (0.0-1.0) representations, with automatic midpoint-preserving scaling. Special integer types enforce valid MIDI value ranges. ```swift import SwiftMIDI // These three Note On events are semantically identical: let event1 = MIDI.Event.noteOn(60, velocity: .midi1(64), channel: 0) let event2 = MIDI.Event.noteOn(60, velocity: .midi2(32768), channel: 0) let event3 = MIDI.Event.noteOn(60, velocity: .unitInterval(0.5), channel: 0) // Reading values back from a received event: func receivedMIDI(event: MIDI.Event) { switch event { case .noteOn(let payload): print(payload.velocity.midi1Value) // 64 print(payload.velocity.midi2Value) // 32768 print(payload.velocity.unitIntervalValue) // 0.5 case .cc(let payload): print(payload.controller) // e.g. MIDI.Event.CC.Controller.modWheel print(payload.value.midi1Value) // 0...127 default: break } } // Special integer types enforce valid MIDI value ranges at compile time: let nibble: MIDI.UInt4 = 0xF // 4-bit, 0...15 let sevenBit: MIDI.UInt7 = 127 // 7-bit, 0...127 let fourteenBit: MIDI.UInt14 = 8192 // 14-bit, 0...16383 // Bipolar unit interval helpers (e.g. for pitch bend, pan): let pitchBendValue = Double(bipolarUnitInterval: -0.5) // scales -1.0...1.0 → 0.0...1.0 let bipolar = someUInt32.bipolarUnitIntervalValue // scales 0x0...0xFFFFFFFF → -1.0...1.0 ``` -------------------------------- ### Remove All of a Type Source: https://github.com/orchetect/swift-midi/wiki/Remove-a-Virtual-Port-or-Connection Removes all virtual ports or connections of a specified type. ```APIDOC ## Remove All of a Type Additionally, you can remove all of a certain type: ```swift midiManager.remove(.input, .all) midiManager.remove(.output, .all) midiManager.remove(.inputConnection, .all) midiManager.remove(.outputConnection, .all) ``` ``` -------------------------------- ### Remove Individual Virtual Port or Connection Source: https://github.com/orchetect/swift-midi/wiki/Remove-a-Virtual-Port-or-Connection Call the relevant remove method on the midiManager to dispose of an individual virtual port or connection by its tag. Ensure the correct type (input, output, inputConnection, outputConnection) and tag are provided. ```swift midiManager.remove(.input, .withTag("VirtualInputTagHere")) midiManager.remove(.output, .withTag("VirtualOutputTagHere")) midiManager.remove(.inputConnection, .withTag("InConnTagHere")) midiManager.remove(.outputConnection, .withTag("OutConnTagHere")) ``` -------------------------------- ### UInt32 Bipolar Unit Interval Property Source: https://github.com/orchetect/swift-midi/wiki/Value-Types Scales a `UInt32` value (from 0x0 to 0xFFFFFFFF) to a bipolar unit interval (-1.0 to 1.0). This allows for the representation of a wide range of integer values within a bipolar scale. ```swift let bipolarUInt32 = someUInt32.bipolarUnitIntervalValue ``` -------------------------------- ### Filter System Exclusive Events Source: https://github.com/orchetect/swift-midi/wiki/Event-Filters Offers filtering capabilities for System Exclusive MIDI events. Options include retaining only specific types, keeping specific types while preserving others, or dropping specific types. ```swift .filter(sysEx: .only) ``` ```swift .filter(sysEx: .onlyType(.sysEx)) ``` ```swift .filter(sysEx: .onlyTypes([.sysEx, .universalSysEx])) ``` ```swift .filter(sysEx: .keepType(.sysEx)) ``` ```swift .filter(sysEx: .keepTypes([.sysEx, .universalSysEx])) ``` -------------------------------- ### Filter MIDI Events by Channel Voice Source: https://github.com/orchetect/swift-midi/wiki/Event-Filters Filters a collection of MIDI events to include only those matching specific channel voice criteria. This is useful for isolating specific types of performance or control data. ```swift let events: [MIDI.Event] = [ ... ] let onlyChannel0Events = events.filter(chanVoice: .onlyChannel(0)) ``` ```swift let filteredEvents = events .filter(sysRealTime: .dropTypes([.activeSensing])) .filter(chanVoice: .keepChannel(0x0)) .filter(chanVoice: .keepCCs([1, 11, 64])) ``` -------------------------------- ### Filter System Real Time Events Source: https://github.com/orchetect/swift-midi/wiki/Event-Filters Selectively keep or drop System Real Time messages based on their type. This allows fine-grained control over which real-time signals are processed. ```swift .filter(sysRealTime: .only) .filter(sysRealTime: .onlyType(.timingClock)) .filter(sysRealTime: .onlyTypes([.start, .stop, .continue])) ``` ```swift .filter(sysRealTime: .keepType(.timingClock)) .filter(sysRealTime: .keepTypes([.start, .stop, .continue])) ``` ```swift .filter(sysRealTime: .drop) .filter(sysRealTime: .dropType(.activeSensing)) .filter(sysRealTime: .dropTypes([.activeSensing, .timingClock])) ``` -------------------------------- ### Remove Individual Virtual Port or Connection Source: https://github.com/orchetect/swift-midi/wiki/Remove-a-Virtual-Port-or-Connection Removes a specific virtual port or connection by its type and tag. ```APIDOC ## Remove Individual Virtual Port or Connection To remove an individual virtual port or connection owned by the `Manager` and dispose of it in the system, call the relevant remove method: ```swift midiManager.remove(.input, .withTag("VirtualInputTagHere")) midiManager.remove(.output, .withTag("VirtualOutputTagHere")) midiManager.remove(.inputConnection, .withTag("InConnTagHere")) midiManager.remove(.outputConnection, .withTag("OutConnTagHere")) ``` ``` -------------------------------- ### Double Bipolar Unit Interval Property Source: https://github.com/orchetect/swift-midi/wiki/Value-Types Scales a `Double` value representing a unit interval (0.0 to 1.0) to a bipolar unit interval (-1.0 to 1.0). This is useful for representing values that can be positive, negative, or zero. ```swift let bipolarValue = someDouble.bipolarUnitIntervalValue ``` -------------------------------- ### Filter UMP Group Events Source: https://github.com/orchetect/swift-midi/wiki/Event-Filters Retain or drop MIDI events based on their Universal MIDI Packet (UMP) group. This is useful for isolating specific data streams within a UMP context. ```swift // retains only events in the given UMP group(s) .filter(group: 0) .filter(groups: [0, 1]) ``` ```swift // drops events in the given UMP group(s) .drop(group: 0) .drop(groups: [0, 1]) ``` -------------------------------- ### Filter Channel Voice Events: Keep Source: https://github.com/orchetect/swift-midi/wiki/Event-Filters Retains Channel Voice events that match the specified criteria, while also keeping all non-Channel Voice events. This is useful for selectively filtering specific Channel Voice messages without affecting other MIDI message types. ```swift .filter(chanVoice: .keepType(.noteOn)) ``` ```swift .filter(chanVoice: .keepTypes([.noteOn, .noteOff])) ``` ```swift .filter(chanVoice: .keepChannel(0x0)) ``` ```swift .filter(chanVoice: .keepChannels([0x0, 0x1, 0x2])) ``` ```swift .filter(chanVoice: .keepCC(1)) ``` ```swift .filter(chanVoice: .keepCCs([1, 11, 64])) ``` ```swift .filter(chanVoice: .keepNotesInRange(40...80)) ``` ```swift .filter(chanVoice: .keepNotesInRanges([20...40, 60...80])) ``` -------------------------------- ### Drop SysEx Events Source: https://github.com/orchetect/swift-midi/wiki/Event-Filters Use these filters to drop specific types of System Exclusive messages. Specify individual types or a list of types to exclude. ```swift .filter(sysEx: .drop) .filter(sysEx: .dropType(.sysEx)) .filter(sysEx: .dropTypes([.sysEx, .universalSysEx])) ``` -------------------------------- ### Filter Channel Voice Events: Only Source: https://github.com/orchetect/swift-midi/wiki/Event-Filters Retains only Channel Voice events that strictly match the specified criteria. Non-Channel Voice events are discarded. ```swift .filter(chanVoice: .only) ``` ```swift .filter(chanVoice: .onlyType(.noteOn)) ``` ```swift .filter(chanVoice: .onlyTypes([.noteOn, .noteOff])) ``` ```swift .filter(chanVoice: .onlyChannel(0x0)) ``` ```swift .filter(chanVoice: .onlyChannels([0x0, 0x1, 0x2])) ``` ```swift .filter(chanVoice: .onlyCC(1)) ``` ```swift .filter(chanVoice: .onlyCCs([1, 11, 64])) ``` ```swift .filter(chanVoice: .onlyNotesInRange(40...80)) ``` ```swift .filter(chanVoice: .onlyNotesInRanges([20...40, 60...80])) ``` -------------------------------- ### Filter Channel Voice Events: Drop Source: https://github.com/orchetect/swift-midi/wiki/Event-Filters Removes Channel Voice events that match the specified criteria, while leaving all non-Channel Voice events unaffected. This is useful for excluding specific Channel Voice messages from a stream. ```swift .filter(chanVoice: .drop) ``` ```swift .filter(chanVoice: .dropType(.noteOn)) ``` ```swift .filter(chanVoice: .dropTypes([.noteOn, .noteOff])) ``` ```swift .filter(chanVoice: .dropChannel(0x0)) ``` ```swift .filter(chanVoice: .dropChannels([0x0, 0x1, 0x2])) ``` ```swift .filter(chanVoice: .dropCC(1)) ``` ```swift .filter(chanVoice: .dropCCs([1, 11, 64])) ``` ```swift .filter(chanVoice: .dropNotesInRange(40...80)) ``` ```swift .filter(chanVoice: .dropNotesInRanges([20...40, 60...80])) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.