diff --git a/.swiftformat b/.swiftformat index e778692250..139b3cc9ec 100644 --- a/.swiftformat +++ b/.swiftformat @@ -23,7 +23,7 @@ --funcattributes prev-line --groupedextension "MARK: %c" --guardelse auto ---header "\n {file}\n MIDIKit • https://github.com/orchetect/MIDIKit\n © {year} Steffan Andrews • Licensed under MIT License\n" +--header "\n {file}\n MIDIKit • https://github.com/orchetect/MIDIKit\n © 2021-{year} Steffan Andrews • Licensed under MIT License\n" --hexgrouping 4,8 --hexliteralcase uppercase --ifdef no-indent diff --git a/Examples/Advanced/HUITest/HUITest.xcodeproj/project.pbxproj b/Examples/Advanced/HUITest/HUITest.xcodeproj/project.pbxproj index fdd8bb1082..e079094d67 100644 --- a/Examples/Advanced/HUITest/HUITest.xcodeproj/project.pbxproj +++ b/Examples/Advanced/HUITest/HUITest.xcodeproj/project.pbxproj @@ -556,7 +556,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/Advanced/HUITest/HUITest/AppDelegate.swift b/Examples/Advanced/HUITest/HUITest/AppDelegate.swift index 929b10e6dd..72c87c4a89 100644 --- a/Examples/Advanced/HUITest/HUITest/AppDelegate.swift +++ b/Examples/Advanced/HUITest/HUITest/AppDelegate.swift @@ -1,7 +1,7 @@ // // AppDelegate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Cocoa @@ -92,7 +92,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { func orderAllWindowsFront() { DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) { - //NSApp.windows.forEach { $0.makeKeyAndOrderFront(self) } + // NSApp.windows.forEach { $0.makeKeyAndOrderFront(self) } self.huiSurfaceWindow.makeKeyAndOrderFront(self) self.huiHostWindow.makeKeyAndOrderFront(self) } diff --git a/Examples/Advanced/HUITest/HUITest/Control Views/Buttons.swift b/Examples/Advanced/HUITest/HUITest/Control Views/Buttons.swift index 44d310e103..a3d0211ce8 100644 --- a/Examples/Advanced/HUITest/HUITest/Control Views/Buttons.swift +++ b/Examples/Advanced/HUITest/HUITest/Control Views/Buttons.swift @@ -1,7 +1,7 @@ // // Buttons.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -104,8 +104,8 @@ struct HUIButton: View, MomentaryButtonProtocol { image: Image? = nil, title: String = "", param: HUISwitch, - width: CGFloat? = nil, //MomentaryButton.kDefaultWidth, - height: CGFloat? = nil, //MomentaryButton.kDefaultHeight, + width: CGFloat? = nil, // MomentaryButton.kDefaultWidth, + height: CGFloat? = nil, // MomentaryButton.kDefaultHeight, fontSize: CGFloat? = nil ) { self.image = image @@ -148,8 +148,8 @@ struct HUIStateButton: View, MomentaryButtonProtocol { title: String = "", param: HUISwitch, ledColor: HUISwitchColor, - width: CGFloat? = nil, //MomentaryButton.kDefaultWidth, - height: CGFloat? = nil, //MomentaryButton.kDefaultHeight, + width: CGFloat? = nil, // MomentaryButton.kDefaultWidth, + height: CGFloat? = nil, // MomentaryButton.kDefaultHeight, fontSize: CGFloat? = nil ) { self.image = image diff --git a/Examples/Advanced/HUITest/HUITest/Control Views/Fader.swift b/Examples/Advanced/HUITest/HUITest/Control Views/Fader.swift index fbeeb449fc..29fcc56056 100644 --- a/Examples/Advanced/HUITest/HUITest/Control Views/Fader.swift +++ b/Examples/Advanced/HUITest/HUITest/Control Views/Fader.swift @@ -1,7 +1,7 @@ // // Fader.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // // TODO: this struct could be moved to AudioKit/Controls repo diff --git a/Examples/Advanced/HUITest/HUITest/Control Views/FourCharLCD.swift b/Examples/Advanced/HUITest/HUITest/Control Views/FourCharLCD.swift index 70f2a65654..bf05bb517c 100644 --- a/Examples/Advanced/HUITest/HUITest/Control Views/FourCharLCD.swift +++ b/Examples/Advanced/HUITest/HUITest/Control Views/FourCharLCD.swift @@ -1,7 +1,7 @@ // // FourCharLCD.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/Control Views/Knobs.swift b/Examples/Advanced/HUITest/HUITest/Control Views/Knobs.swift index 60171d5cd1..d116724fda 100644 --- a/Examples/Advanced/HUITest/HUITest/Control Views/Knobs.swift +++ b/Examples/Advanced/HUITest/HUITest/Control Views/Knobs.swift @@ -1,7 +1,7 @@ // // Knobs.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -166,14 +166,14 @@ struct KnobShape: View { if size > 100 { VStack { HStack { // ◀︎ ▶︎ ← → - //Text("◀︎") - //Text("▶︎") + // Text("◀︎") + // Text("▶︎") Text("←").rotationEffect(.degrees(360 - 15)) Text("→").rotationEffect(.degrees(15)) } .font(.system(size: 24)) .foregroundColor(.black.opacity(0.7)) - .scaleEffect(CGSize.init(width: size/140, height: size/140)) + .scaleEffect(CGSize(width: size / 140, height: size / 140)) Spacer() } .padding(size / 5) diff --git a/Examples/Advanced/HUITest/HUITest/Control Views/Labels.swift b/Examples/Advanced/HUITest/HUITest/Control Views/Labels.swift index d908f15c22..ac8db4133c 100644 --- a/Examples/Advanced/HUITest/HUITest/Control Views/Labels.swift +++ b/Examples/Advanced/HUITest/HUITest/Control Views/Labels.swift @@ -1,7 +1,7 @@ // // Labels.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -33,5 +33,3 @@ struct HUISectionDivider: View { } } } - - diff --git a/Examples/Advanced/HUITest/HUITest/Control Views/MomentaryPressView.swift b/Examples/Advanced/HUITest/HUITest/Control Views/MomentaryPressView.swift index 19da859189..e7edc83108 100644 --- a/Examples/Advanced/HUITest/HUITest/Control Views/MomentaryPressView.swift +++ b/Examples/Advanced/HUITest/HUITest/Control Views/MomentaryPressView.swift @@ -1,7 +1,7 @@ // // MomentaryPressView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -31,7 +31,8 @@ struct MomentaryPressView: View { var body: some View { content .highPriorityGesture( - // this is a workaround to enable a button which triggers two different actions, one on mouse-down and one on mouse-up + // this is a workaround to enable a button which triggers two + // different actions: one on mouse-down and one on mouse-up DragGesture(minimumDistance: 0) .onChanged { _ in if !isPressed { diff --git a/Examples/Advanced/HUITest/HUITest/Control Views/SwiftUI Extensions.swift b/Examples/Advanced/HUITest/HUITest/Control Views/SwiftUI Extensions.swift index 7736762215..9b2b353f2d 100644 --- a/Examples/Advanced/HUITest/HUITest/Control Views/SwiftUI Extensions.swift +++ b/Examples/Advanced/HUITest/HUITest/Control Views/SwiftUI Extensions.swift @@ -1,7 +1,7 @@ // // SwiftUI Extensions.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUIHostView/HUIHostHelper.swift b/Examples/Advanced/HUITest/HUITest/HUIHostView/HUIHostHelper.swift index c6009eb5b4..5013abe516 100644 --- a/Examples/Advanced/HUITest/HUITest/HUIHostView/HUIHostHelper.swift +++ b/Examples/Advanced/HUITest/HUITest/HUIHostView/HUIHostHelper.swift @@ -1,7 +1,7 @@ // // HUIHostHelper.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -85,20 +85,20 @@ class HUIHostHelper: ObservableObject { switch event { case let .faderLevel(channelStrip: 0, level): let scaledValue = Float(level) / Float(UInt14.max) - self.model.bank0.channel0.faderLevel = scaledValue + model.bank0.channel0.faderLevel = scaledValue case let .switch(huiSwitch, state): switch huiSwitch { case let .channelStrip(0, channelItem): switch channelItem { case .solo: - if state { self.model.bank0.channel0.solo.toggle() } + if state { model.bank0.channel0.solo.toggle() } case .mute: - if state { self.model.bank0.channel0.mute.toggle() } + if state { model.bank0.channel0.mute.toggle() } case .select: - if state { self.model.bank0.channel0.selected.toggle() } + if state { model.bank0.channel0.selected.toggle() } case .faderTouched: - self.model.bank0.channel0.faderTouched = state + model.bank0.channel0.faderTouched = state default: break } @@ -109,8 +109,8 @@ class HUIHostHelper: ObservableObject { case let .vPot(vPot: vPot, delta: delta): switch vPot { case .channel(0): - self.model.bank0.channel0.pan = ( - self.model.bank0.channel0.pan + Float(delta.intValue) / 100 + model.bank0.channel0.pan = ( + model.bank0.channel0.pan + Float(delta.intValue) / 100 ).clamped(to: 0.0 ... 1.0) default: break @@ -122,7 +122,8 @@ class HUIHostHelper: ObservableObject { } } -/// Host model. Can contain one or more banks. Each bank corresponds to an entire HUI device (remote control surface). +/// Host model. Can contain one or more banks. +/// Each bank corresponds to an entire HUI device (remote control surface). struct HUIHostModel { public var bank0 = Bank() } diff --git a/Examples/Advanced/HUITest/HUITest/HUIHostView/HUIHostView.swift b/Examples/Advanced/HUITest/HUITest/HUIHostView/HUIHostView.swift index 6bc31cb0bc..a5dbe70c70 100644 --- a/Examples/Advanced/HUITest/HUITest/HUIHostView/HUIHostView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUIHostView/HUIHostView.swift @@ -1,7 +1,7 @@ // // HUIHostView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -61,12 +61,16 @@ struct HUIHostView: View { .backgroundColor(Color(nsColor: .controlBackgroundColor)) .indicatorWidth(15) .frame(height: 20) - .onChange(of: huiHostHelper.model.bank0.channel0.pan) { newValue in + .onChange( + of: huiHostHelper.model.bank0.channel0.pan + ) { newValue in transmitVPot(value: newValue) } } Toggle("Low", isOn: $huiHostHelper.model.bank0.channel0.vPotLowerLED) - .onChange(of: huiHostHelper.model.bank0.channel0.vPotLowerLED) { newValue in + .onChange( + of: huiHostHelper.model.bank0.channel0.vPotLowerLED + ) { newValue in transmitVPot(lowerLED: newValue) } } @@ -98,11 +102,17 @@ struct HUIHostView: View { } GroupBox(label: Text("Fader")) { Ribbon(position: $huiHostHelper.model.bank0.channel0.faderLevel) - .foregroundColor(huiHostHelper.model.bank0.channel0.faderTouched ? .green : .secondary) + .foregroundColor( + huiHostHelper.model.bank0.channel0.faderTouched + ? .green + : .secondary + ) .backgroundColor(Color(nsColor: .controlBackgroundColor)) .indicatorWidth(15) .frame(height: 20) - .onChange(of: huiHostHelper.model.bank0.channel0.faderLevel) { newValue in + .onChange( + of: huiHostHelper.model.bank0.channel0.faderLevel + ) { newValue in let scaledLevel = UInt14(newValue * Float(UInt14.max)) huiBank0?.transmitFader(level: scaledLevel, channel: 0) } diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/HUIClientView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/HUIClientView.swift index 649954b5f8..c42103410b 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/HUIClientView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/HUIClientView.swift @@ -1,7 +1,7 @@ // // HUIClientView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitIO @@ -53,10 +53,12 @@ struct HUIClientView: View { tag: Self.kHUIInputName, uniqueID: .userDefaultsManaged(key: Self.kHUIInputName), receiver: .events(translateMIDI1NoteOnZeroVelocityToNoteOff: false) - { [weak huiSurface] midiEvents in - // since handler callbacks from MIDI are on a CoreMIDI thread, parse the MIDI on the main thread because SwiftUI state in this app will be updated as a result + { [weak huiSurface] events in + // since handler callbacks from MIDI are on a CoreMIDI thread, + // parse the MIDI on the main thread because SwiftUI state in + // this app will be updated as a result DispatchQueue.main.async { - huiSurface?.midiIn(events: midiEvents) + huiSurface?.midiIn(events: events) } } ) diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/HUISurfaceView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/HUISurfaceView.swift index 6a212061f3..2f58117d5c 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/HUISurfaceView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/HUISurfaceView.swift @@ -1,7 +1,7 @@ // // HUISurfaceView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/LeftSideView/LeftSideView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/LeftSideView/LeftSideView.swift index 373b04c66c..70d28f28a6 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/LeftSideView/LeftSideView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/LeftSideView/LeftSideView.swift @@ -1,7 +1,7 @@ // // LeftSideView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/MixerView/ChannelStripView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/MixerView/ChannelStripView.swift index 58cd1c1b4e..6b337d683f 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/MixerView/ChannelStripView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/MixerView/ChannelStripView.swift @@ -1,7 +1,7 @@ // // ChannelStripView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/MixerView/FaderView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/MixerView/FaderView.swift index ae19c3c068..3bd448fcc6 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/MixerView/FaderView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/MixerView/FaderView.swift @@ -1,7 +1,7 @@ // // FaderView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/MixerView/MixerView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/MixerView/MixerView.swift index 14d9c369c9..8628124a57 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/MixerView/MixerView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/MixerView/MixerView.swift @@ -1,7 +1,7 @@ // // MixerView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/ControlRoomView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/ControlRoomView.swift index 4f99b871be..f773682ced 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/ControlRoomView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/ControlRoomView.swift @@ -1,7 +1,7 @@ // // ControlRoomView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/FKeysView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/FKeysView.swift index deb597647a..7c9279943b 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/FKeysView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/FKeysView.swift @@ -1,7 +1,7 @@ // // FKeysView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/MainTimeDisplayView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/MainTimeDisplayView.swift index e93ab20607..0bdd0c2c19 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/MainTimeDisplayView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/MainTimeDisplayView.swift @@ -1,7 +1,7 @@ // // MainTimeDisplayView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/NumPadView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/NumPadView.swift index 3e886079d0..0d881d571e 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/NumPadView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/NumPadView.swift @@ -1,7 +1,7 @@ // // NumPadView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/ParameterEditAssignView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/ParameterEditAssignView.swift index 7c6b621c9c..059bce9e7f 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/ParameterEditAssignView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/ParameterEditAssignView.swift @@ -1,7 +1,7 @@ // // ParameterEditAssignView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/RightSideView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/RightSideView.swift index c364812f65..7ea1a130cd 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/RightSideView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/RightSideView.swift @@ -1,7 +1,7 @@ // // RightSideView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/SwitchMatrixView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/SwitchMatrixView.swift index 795a415b33..ed5659d5c6 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/SwitchMatrixView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/SwitchMatrixView.swift @@ -1,7 +1,7 @@ // // SwitchMatrixView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/TransportView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/TransportView.swift index d810123fcf..9e4a218f38 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/TransportView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/RightSideView/TransportView.swift @@ -1,7 +1,7 @@ // // TransportView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -74,13 +74,13 @@ extension HUISurfaceView { Group { HUIStateButton( image: Image(systemName: "backward.end.fill"), - //title: "|◀︎ RTZ", + // title: "|◀︎ RTZ", param: .transport(.rtz), ledColor: .yellow ) HUIStateButton( image: Image(systemName: "forward.end.fill"), - //title: "END ▶︎|", + // title: "END ▶︎|", param: .transport(.end), ledColor: .yellow ) @@ -91,7 +91,7 @@ extension HUISurfaceView { ) HUIStateButton( image: Image(systemName: "repeat"), - //title: "LOOP", + // title: "LOOP", param: .transport(.loop), ledColor: .yellow ) @@ -129,7 +129,7 @@ extension HUISurfaceView { Group { HUIStateButton( image: Image(systemName: "backward.fill"), - //title: "REWIND", + // title: "REWIND", param: .transport(.rewind), ledColor: .red, width: 60, @@ -138,7 +138,7 @@ extension HUISurfaceView { HUIStateButton( image: Image(systemName: "forward.fill"), - //title: "FAST FWD", + // title: "FAST FWD", param: .transport(.fastFwd), ledColor: .red, width: 60, @@ -147,7 +147,7 @@ extension HUISurfaceView { HUIStateButton( image: Image(systemName: "stop.fill"), - //title: "STOP", + // title: "STOP", param: .transport(.stop), ledColor: .red, width: 60, @@ -156,7 +156,7 @@ extension HUISurfaceView { HUIStateButton( image: Image(systemName: "play.fill"), - //title: "PLAY", + // title: "PLAY", param: .transport(.play), ledColor: .red, width: 60, @@ -165,7 +165,7 @@ extension HUISurfaceView { HUIStateButton( image: Image(systemName: "record.circle.fill"), - //title: "RECORD", + // title: "RECORD", param: .transport(.record), ledColor: .red, width: 60, diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/TopView/LargeTextDisplayView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/TopView/LargeTextDisplayView.swift index 67c0af9676..9f7c89dc60 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/TopView/LargeTextDisplayView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/TopView/LargeTextDisplayView.swift @@ -1,7 +1,7 @@ // // LargeTextDisplayView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/TopView/MeterBridgeView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/TopView/MeterBridgeView.swift index 39c1b8feff..5032ce852b 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/TopView/MeterBridgeView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/TopView/MeterBridgeView.swift @@ -1,7 +1,7 @@ // // MeterBridgeView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/TopView/TopView.swift b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/TopView/TopView.swift index c5ad2d813c..8340ba6b82 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISurfaceView/TopView/TopView.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISurfaceView/TopView/TopView.swift @@ -1,7 +1,7 @@ // // TopView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/HUITest/HUITest/HUISwitch Wrapper.swift b/Examples/Advanced/HUITest/HUITest/HUISwitch Wrapper.swift index 12cc9da2d1..685a5fcdb1 100644 --- a/Examples/Advanced/HUITest/HUITest/HUISwitch Wrapper.swift +++ b/Examples/Advanced/HUITest/HUITest/HUISwitch Wrapper.swift @@ -1,7 +1,7 @@ // // HUISwitch Wrapper.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -10,10 +10,12 @@ import MIDIKitControlSurfaces extension HUISwitch { /// Because SwiftUI wants to crash constantly for no reason. - /// The workaround is to make a class wrapper for `HUISwitch` instance storage in a SwiftUI View. That prevents SwiftUI from attempting to compare the stored enum instance when recalculating the view during runtime and resulting in inexplicable crashes. + /// The workaround is a class wrapper for `HUISwitch` instance storage in a SwiftUI View. + /// That prevents SwiftUI from attempting to compare the stored enum instance when recalculating + /// the view during runtime and resulting in inexplicable crashes. /// /// References: - /// - [SwiftUI Crash in AG::LayoutDescriptor::compare](https://noahgilmore.com/blog/swiftui-equatable-crash/) + /// - [SwiftUI Crash](https://noahgilmore.com/blog/swiftui-equatable-crash/) /// - [Twitter Thread](https://twitter.com/orchetect/status/1416871188723224577) class Wrapper { let wrapped: HUISwitch diff --git a/Examples/Advanced/HUITest/HUITest/Logger.swift b/Examples/Advanced/HUITest/HUITest/Logger.swift index 6da6a36860..d70a629d9e 100644 --- a/Examples/Advanced/HUITest/HUITest/Logger.swift +++ b/Examples/Advanced/HUITest/HUITest/Logger.swift @@ -1,7 +1,7 @@ // // Logger.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import os.log diff --git a/Examples/Advanced/MIDIEventLogger/MIDIEventLogger.xcodeproj/project.pbxproj b/Examples/Advanced/MIDIEventLogger/MIDIEventLogger.xcodeproj/project.pbxproj index f3708175ec..b144ea343c 100644 --- a/Examples/Advanced/MIDIEventLogger/MIDIEventLogger.xcodeproj/project.pbxproj +++ b/Examples/Advanced/MIDIEventLogger/MIDIEventLogger.xcodeproj/project.pbxproj @@ -384,7 +384,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/AppDelegate.swift b/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/AppDelegate.swift index b32dce80de..6207140d05 100644 --- a/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/AppDelegate.swift +++ b/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/AppDelegate.swift @@ -1,7 +1,7 @@ // // AppDelegate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/ContentView SubViews.swift b/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/ContentView SubViews.swift index 6bae7e60b5..80cd38ccf9 100644 --- a/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/ContentView SubViews.swift +++ b/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/ContentView SubViews.swift @@ -1,7 +1,7 @@ // // ContentView SubViews.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/ContentView.swift b/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/ContentView.swift index 6d19a92885..6b16afe965 100644 --- a/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/ContentView.swift +++ b/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/ContentView.swift @@ -1,7 +1,7 @@ // // ContentView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/Log.swift b/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/Log.swift index 53de3e24cb..e59e0b64f0 100644 --- a/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/Log.swift +++ b/Examples/Advanced/MIDIEventLogger/MIDIEventLogger/Log.swift @@ -1,7 +1,7 @@ // // Log.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import OTCore diff --git a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo.xcodeproj/project.pbxproj b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo.xcodeproj/project.pbxproj index 89164ed758..eac8b0e6e0 100644 --- a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo.xcodeproj/project.pbxproj +++ b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo.xcodeproj/project.pbxproj @@ -390,7 +390,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/AppDelegate.swift b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/AppDelegate.swift index 5b042e1d9a..e1892dc0df 100644 --- a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/AppDelegate.swift +++ b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/AppDelegate.swift @@ -1,7 +1,7 @@ // // AppDelegate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/ContentView.swift b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/ContentView.swift index 9d0b024ed8..14d62a3b8c 100644 --- a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/ContentView.swift +++ b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/ContentView.swift @@ -1,7 +1,7 @@ // // ContentView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -9,8 +9,11 @@ import MIDIKit import OTCore struct ContentView: View { - // if you declare a view that creates its own @ObservedObject instance, that instance is replaced every time SwiftUI decides that it needs to discard and redraw that view. - // it should instead be used to retain a weak reference from the view's initializer, with the original instance of the object stored in a parent scope as either a var or @StateObject but not an @ObservedObject + // if you declare a view that creates its own @ObservedObject instance, that instance is + // replaced every time SwiftUI decides that it needs to discard and redraw that view. + // it should instead be used to retain a weak reference from the view's initializer, with the + // original instance of the object stored in a parent scope as either a var or @StateObject but + // not an @ObservedObject @ObservedObject var midiManager: MIDIManager diff --git a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/DetailsView.swift b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/DetailsView.swift index 7699294c41..9e7ff32b81 100644 --- a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/DetailsView.swift +++ b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/DetailsView.swift @@ -1,7 +1,7 @@ // // DetailsView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -9,7 +9,8 @@ import WebKit import MIDIKit struct EmptyDetailsView: View { - /// coaxes WebKit to start up when EmptyDetailsView first shows in the main view, making the next WebKitView view that loads to load faster + /// coaxes WebKit to start up when EmptyDetailsView first shows in the main view, + /// making the next WebKitView view that loads to load faster private let dummyWKView = WKWebView() var body: some View { @@ -25,7 +26,7 @@ struct DetailsView: View { @State private var webViewHeight: CGFloat = .zero - @State private var webview: WKWebView = .init() + @State private var webView: WKWebView = .init() @State private var showAll: Bool = false @@ -114,7 +115,7 @@ struct DetailsView: View { if let unwrappedObject = object { WebKitView( dynamicHeight: $webViewHeight, - webview: $webview, + webView: $webView, html: generateHTML(unwrappedObject) ) diff --git a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/HostingWindowKey.swift b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/HostingWindowKey.swift index dc0e94cc14..3624c3b6e6 100644 --- a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/HostingWindowKey.swift +++ b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/HostingWindowKey.swift @@ -1,12 +1,13 @@ // // HostingWindowKey.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI -/// Allows accessing the hosting window object (`NSWindow`/`UIWindow`) from any subview by way of environment keypath. +/// Allows accessing the hosting window object (`NSWindow`/`UIWindow`) +/// from any subview by way of environment keypath. /// /// Typical use: /// @@ -38,7 +39,8 @@ struct HostingWindowKey: EnvironmentKey { } extension EnvironmentValues { - /// Allows accessing the hosting window object (`NSWindow`/`UIWindow`) from any subview by way of environment keypath. + /// Allows accessing the hosting window object (`NSWindow`/`UIWindow`) + /// from any subview by way of environment keypath. /// /// Typical use: /// diff --git a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/Log.swift b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/Log.swift index a170642e30..4c9b4f2139 100644 --- a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/Log.swift +++ b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/Log.swift @@ -1,7 +1,7 @@ // // Log.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import OTCore diff --git a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/WebKitView.swift b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/WebKitView.swift index 483c9e9c17..bd5fa397f4 100644 --- a/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/WebKitView.swift +++ b/Examples/Advanced/MIDISystemInfo/MIDISystemInfo/WebKitView.swift @@ -1,7 +1,7 @@ // // WebKitView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -10,7 +10,7 @@ import WebKit struct WebKitView: NSViewRepresentable { @Binding var dynamicHeight: CGFloat - @Binding var webview: WKWebView + @Binding var webView: WKWebView var html: String = "" @@ -40,14 +40,14 @@ struct WebKitView: NSViewRepresentable { } func setHTML(_ html: String) { - webview.loadHTMLString(html, baseURL: nil) + webView.loadHTMLString(html, baseURL: nil) } func makeNSView(context: Context) -> WKWebView { - // webview.enclosingScrollView.bounces = false - webview.navigationDelegate = context.coordinator - webview.loadHTMLString("", baseURL: nil) - return webview + // webView.enclosingScrollView.bounces = false + webView.navigationDelegate = context.coordinator + webView.loadHTMLString("", baseURL: nil) + return webView } func updateNSView(_ nsView: NSViewType, context: Context) { diff --git a/Examples/Advanced/MTCExample/MTCExample.xcodeproj/project.pbxproj b/Examples/Advanced/MTCExample/MTCExample.xcodeproj/project.pbxproj index 2571ef10c7..dfab1dca5f 100644 --- a/Examples/Advanced/MTCExample/MTCExample.xcodeproj/project.pbxproj +++ b/Examples/Advanced/MTCExample/MTCExample.xcodeproj/project.pbxproj @@ -411,7 +411,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; E29EF02D267BF47F00282F94 /* XCRemoteSwiftPackageReference "SwiftRadix" */ = { diff --git a/Examples/Advanced/MTCExample/MTCExample/AppDelegate.swift b/Examples/Advanced/MTCExample/MTCExample/AppDelegate.swift index c3fe2f0cd2..fae3afb66a 100644 --- a/Examples/Advanced/MTCExample/MTCExample/AppDelegate.swift +++ b/Examples/Advanced/MTCExample/MTCExample/AppDelegate.swift @@ -1,7 +1,7 @@ // // AppDelegate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Cocoa diff --git a/Examples/Advanced/MTCExample/MTCExample/Audio.swift b/Examples/Advanced/MTCExample/MTCExample/Audio.swift index a091278e64..a070a5593c 100644 --- a/Examples/Advanced/MTCExample/MTCExample/Audio.swift +++ b/Examples/Advanced/MTCExample/MTCExample/Audio.swift @@ -1,7 +1,7 @@ // // Audio.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Examples/Advanced/MTCExample/MTCExample/Log.swift b/Examples/Advanced/MTCExample/MTCExample/Log.swift index a170642e30..4c9b4f2139 100644 --- a/Examples/Advanced/MTCExample/MTCExample/Log.swift +++ b/Examples/Advanced/MTCExample/MTCExample/Log.swift @@ -1,7 +1,7 @@ // // Log.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import OTCore diff --git a/Examples/Advanced/MTCExample/MTCExample/MIDI Endpoints.swift b/Examples/Advanced/MTCExample/MTCExample/MIDI Endpoints.swift index e4ef09a02f..a73a2569cb 100644 --- a/Examples/Advanced/MTCExample/MTCExample/MIDI Endpoints.swift +++ b/Examples/Advanced/MTCExample/MTCExample/MIDI Endpoints.swift @@ -1,7 +1,7 @@ // // MIDI Endpoints.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // enum kMIDISources { diff --git a/Examples/Advanced/MTCExample/MTCExample/MIDIKitSync Extensions.swift b/Examples/Advanced/MTCExample/MTCExample/MIDIKitSync Extensions.swift index ed3dc1fbbe..78b108c244 100644 --- a/Examples/Advanced/MTCExample/MTCExample/MIDIKitSync Extensions.swift +++ b/Examples/Advanced/MTCExample/MTCExample/MIDIKitSync Extensions.swift @@ -1,7 +1,7 @@ // // MIDIKitSync Extensions.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Examples/Advanced/MTCExample/MTCExample/MTCGenContentView.swift b/Examples/Advanced/MTCExample/MTCExample/MTCGenContentView.swift index 98bf7ed3fd..e8e120ee89 100644 --- a/Examples/Advanced/MTCExample/MTCExample/MTCGenContentView.swift +++ b/Examples/Advanced/MTCExample/MTCExample/MTCGenContentView.swift @@ -1,7 +1,7 @@ // // MTCGenContentView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Combine diff --git a/Examples/Advanced/MTCExample/MTCExample/MTCRecContentView.swift b/Examples/Advanced/MTCExample/MTCExample/MTCRecContentView.swift index 3f088bed81..3b1e8e9985 100644 --- a/Examples/Advanced/MTCExample/MTCExample/MTCRecContentView.swift +++ b/Examples/Advanced/MTCExample/MTCExample/MTCRecContentView.swift @@ -1,7 +1,7 @@ // // MTCRecContentView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Combine @@ -173,7 +173,6 @@ struct MTCRecContentView: View { dropOutFrames: 10 ) ) { timecode, _, _, displayNeedsUpdate in - receiverTC = timecode.stringValue receiverFR = mtcRec.mtcFrameRate @@ -231,9 +230,7 @@ struct MTCRecContentView: View { name: kMIDISources.MTCRec.name, tag: kMIDISources.MTCRec.tag, uniqueID: .userDefaultsManaged(key: udKey), - receiver: .events { [weak mtcRec] midiEvents in - mtcRec?.midiIn(events: midiEvents) - } + receiver: .object(mtcRec, held: .weakly) ) } catch { logger.error(error) diff --git a/Examples/Advanced/MTCExample/README.md b/Examples/Advanced/MTCExample/README.md new file mode 100644 index 0000000000..9dad9083b0 --- /dev/null +++ b/Examples/Advanced/MTCExample/README.md @@ -0,0 +1,11 @@ +# MTC Example + +This project demonstrates both MTC generation and chase (receive). + +### Usage + +This demo does not feed back into itself - it is meant to interact with a DAW that supports MTC (Logic Pro, Pro Tools, Cubase, Reaper, etc.) or MTC-compatible hardware. + +- Use the MTC Generator window to transmit MTC messages to a DAW and have the DAW chase it. + +- Use the MTC Receiver window to receive MTC messages from a DAW and display the timecode being received. diff --git a/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI.xcodeproj/project.pbxproj b/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI.xcodeproj/project.pbxproj index 2841c43ce0..c823175e13 100644 --- a/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI.xcodeproj/project.pbxproj +++ b/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI.xcodeproj/project.pbxproj @@ -360,7 +360,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/BluetoothMIDIApp.swift b/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/BluetoothMIDIApp.swift index 34c2c3778b..0594823cd6 100644 --- a/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/BluetoothMIDIApp.swift +++ b/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/BluetoothMIDIApp.swift @@ -1,7 +1,7 @@ // // BluetoothMIDIApp.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/BluetoothMIDIPeripheralView.swift b/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/BluetoothMIDIPeripheralView.swift index 1165c43b71..1f9cff8c1b 100644 --- a/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/BluetoothMIDIPeripheralView.swift +++ b/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/BluetoothMIDIPeripheralView.swift @@ -1,7 +1,7 @@ // // BluetoothMIDIPeripheralView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if os(iOS) diff --git a/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/BluetoothMIDIView.swift b/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/BluetoothMIDIView.swift index 470d24e983..f71b9a79a8 100644 --- a/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/BluetoothMIDIView.swift +++ b/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/BluetoothMIDIView.swift @@ -1,7 +1,7 @@ // // BluetoothMIDIView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if os(iOS) diff --git a/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/ContentView.swift b/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/ContentView.swift index c34a3d562a..76859c9eca 100644 --- a/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/ContentView.swift +++ b/Examples/iOS SwiftUI/BluetoothMIDI/BluetoothMIDI/ContentView.swift @@ -1,7 +1,7 @@ // // ContentView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -48,7 +48,6 @@ struct ContentView: View { .navigationTitle("Bluetooth MIDI") InfoView() - } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .padding() diff --git a/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers.xcodeproj/project.pbxproj b/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers.xcodeproj/project.pbxproj index 4b01c3ab4b..41e2496d96 100644 --- a/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers.xcodeproj/project.pbxproj +++ b/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers.xcodeproj/project.pbxproj @@ -365,7 +365,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/ContentView.swift b/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/ContentView.swift index 483e563f2a..4d796e4f31 100644 --- a/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/ContentView.swift +++ b/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/ContentView.swift @@ -1,7 +1,7 @@ // // ContentView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/EndpointPickersApp.swift b/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/EndpointPickersApp.swift index bcdc98ee31..4747316b4a 100644 --- a/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/EndpointPickersApp.swift +++ b/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/EndpointPickersApp.swift @@ -1,7 +1,7 @@ // // EndpointPickersApp.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/MIDIEndpointSelectionView.swift b/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/MIDIEndpointSelectionView.swift index 8a4b0b9796..d9f6f4c75f 100644 --- a/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/MIDIEndpointSelectionView.swift +++ b/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/MIDIEndpointSelectionView.swift @@ -1,7 +1,7 @@ // // MIDIEndpointSelectionView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/MIDIHelper.swift b/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/MIDIHelper.swift index f4e2a67a5a..8efbd14cfb 100644 --- a/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/MIDIHelper.swift +++ b/Examples/iOS SwiftUI/EndpointPickers/EndpointPickers/MIDIHelper.swift @@ -1,7 +1,7 @@ // // MIDIHelper.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/iOS SwiftUI/EventParsing/EventParsing.xcodeproj/project.pbxproj b/Examples/iOS SwiftUI/EventParsing/EventParsing.xcodeproj/project.pbxproj index b0319e5256..0b3afe07a7 100644 --- a/Examples/iOS SwiftUI/EventParsing/EventParsing.xcodeproj/project.pbxproj +++ b/Examples/iOS SwiftUI/EventParsing/EventParsing.xcodeproj/project.pbxproj @@ -357,7 +357,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/iOS SwiftUI/EventParsing/EventParsing/ContentView.swift b/Examples/iOS SwiftUI/EventParsing/EventParsing/ContentView.swift index 2cd3b005f6..51fe3927c0 100644 --- a/Examples/iOS SwiftUI/EventParsing/EventParsing/ContentView.swift +++ b/Examples/iOS SwiftUI/EventParsing/EventParsing/ContentView.swift @@ -1,7 +1,7 @@ // // ContentView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/iOS SwiftUI/EventParsing/EventParsing/EventParsingApp.swift b/Examples/iOS SwiftUI/EventParsing/EventParsing/EventParsingApp.swift index 94c45d84b6..db4518f0be 100644 --- a/Examples/iOS SwiftUI/EventParsing/EventParsing/EventParsingApp.swift +++ b/Examples/iOS SwiftUI/EventParsing/EventParsing/EventParsingApp.swift @@ -1,7 +1,7 @@ // // EventParsingApp.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/iOS SwiftUI/EventParsing/EventParsing/MIDIHelper.swift b/Examples/iOS SwiftUI/EventParsing/EventParsing/MIDIHelper.swift index 17c61b86cf..160be60522 100644 --- a/Examples/iOS SwiftUI/EventParsing/EventParsing/MIDIHelper.swift +++ b/Examples/iOS SwiftUI/EventParsing/EventParsing/MIDIHelper.swift @@ -1,7 +1,7 @@ // // MIDIHelper.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/iOS SwiftUI/VirtualInput/VirtualInput.xcodeproj/project.pbxproj b/Examples/iOS SwiftUI/VirtualInput/VirtualInput.xcodeproj/project.pbxproj index f7fb732582..499ed2eea5 100644 --- a/Examples/iOS SwiftUI/VirtualInput/VirtualInput.xcodeproj/project.pbxproj +++ b/Examples/iOS SwiftUI/VirtualInput/VirtualInput.xcodeproj/project.pbxproj @@ -353,7 +353,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/iOS SwiftUI/VirtualInput/VirtualInput/ContentView.swift b/Examples/iOS SwiftUI/VirtualInput/VirtualInput/ContentView.swift index 90d55b78b9..ef1c393103 100644 --- a/Examples/iOS SwiftUI/VirtualInput/VirtualInput/ContentView.swift +++ b/Examples/iOS SwiftUI/VirtualInput/VirtualInput/ContentView.swift @@ -1,7 +1,7 @@ // // ContentView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/iOS SwiftUI/VirtualInput/VirtualInput/VirtualInputApp.swift b/Examples/iOS SwiftUI/VirtualInput/VirtualInput/VirtualInputApp.swift index 4404fecbb8..4f9591758c 100644 --- a/Examples/iOS SwiftUI/VirtualInput/VirtualInput/VirtualInputApp.swift +++ b/Examples/iOS SwiftUI/VirtualInput/VirtualInput/VirtualInputApp.swift @@ -1,7 +1,7 @@ // // VirtualInputApp.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/iOS SwiftUI/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj b/Examples/iOS SwiftUI/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj index 1b45249846..a5767d9225 100644 --- a/Examples/iOS SwiftUI/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj +++ b/Examples/iOS SwiftUI/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj @@ -353,7 +353,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/iOS SwiftUI/VirtualOutput/VirtualOutput/ContentView.swift b/Examples/iOS SwiftUI/VirtualOutput/VirtualOutput/ContentView.swift index 21d1ff6179..49694b5bf0 100644 --- a/Examples/iOS SwiftUI/VirtualOutput/VirtualOutput/ContentView.swift +++ b/Examples/iOS SwiftUI/VirtualOutput/VirtualOutput/ContentView.swift @@ -1,7 +1,7 @@ // // ContentView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -36,44 +36,32 @@ struct ContentView: View { } extension ContentView { - /// Convenience accessor for the created virtual MIDI Output. + /// Convenience accessor for created virtual MIDI Output. var virtualOutput: MIDIOutput? { midiManager.managedOutputs[virtualOutputName] } func sendNoteOn() { - guard let output = virtualOutput else { return } - - try? output.send( - event: .noteOn( - 60, - velocity: .midi1(127), - channel: 0 - ) - ) + try? virtualOutput?.send(event: .noteOn( + 60, + velocity: .midi1(127), + channel: 0 + )) } func sendNoteOff() { - guard let output = virtualOutput else { return } - - try? output.send( - event: .noteOff( - 60, - velocity: .midi1(0), - channel: 0 - ) - ) + try? virtualOutput?.send(event: .noteOff( + 60, + velocity: .midi1(0), + channel: 0 + )) } func sendCC1() { - guard let output = virtualOutput else { return } - - try? output.send( - event: .cc( - 1, - value: .midi1(64), - channel: 0 - ) - ) + try? virtualOutput?.send(event: .cc( + 1, + value: .midi1(64), + channel: 0 + )) } } diff --git a/Examples/iOS SwiftUI/VirtualOutput/VirtualOutput/VirtualOutputApp.swift b/Examples/iOS SwiftUI/VirtualOutput/VirtualOutput/VirtualOutputApp.swift index 2ba8a4494f..19fefbdbdd 100644 --- a/Examples/iOS SwiftUI/VirtualOutput/VirtualOutput/VirtualOutputApp.swift +++ b/Examples/iOS SwiftUI/VirtualOutput/VirtualOutput/VirtualOutputApp.swift @@ -1,7 +1,7 @@ // // VirtualOutputApp.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI.xcodeproj/project.pbxproj b/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI.xcodeproj/project.pbxproj index db201e024a..28871a01d1 100644 --- a/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI.xcodeproj/project.pbxproj +++ b/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI.xcodeproj/project.pbxproj @@ -385,7 +385,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/AppDelegate.swift b/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/AppDelegate.swift index d220cb9dae..58ab5e3123 100644 --- a/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/AppDelegate.swift +++ b/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/AppDelegate.swift @@ -1,7 +1,7 @@ // // AppDelegate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import UIKit diff --git a/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/BTMIDICentralViewController.swift b/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/BTMIDICentralViewController.swift index c69c612894..d927debd71 100644 --- a/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/BTMIDICentralViewController.swift +++ b/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/BTMIDICentralViewController.swift @@ -1,7 +1,7 @@ // // BTMIDICentralViewController.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if os(iOS) diff --git a/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/BTMIDIPeripheralViewController.swift b/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/BTMIDIPeripheralViewController.swift index 1989f2e738..d537a14aca 100644 --- a/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/BTMIDIPeripheralViewController.swift +++ b/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/BTMIDIPeripheralViewController.swift @@ -1,7 +1,7 @@ // // BTMIDIPeripheralViewController.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if os(iOS) diff --git a/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/ViewController.swift b/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/ViewController.swift index fd3b838727..947bb3de26 100644 --- a/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/ViewController.swift +++ b/Examples/iOS UIKit/BluetoothMIDI/BluetoothMIDI/ViewController.swift @@ -1,7 +1,7 @@ // // ViewController.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import UIKit diff --git a/Examples/iOS UIKit/EventParsing/EventParsing.xcodeproj/project.pbxproj b/Examples/iOS UIKit/EventParsing/EventParsing.xcodeproj/project.pbxproj index f7e2c51f2b..23a7370806 100644 --- a/Examples/iOS UIKit/EventParsing/EventParsing.xcodeproj/project.pbxproj +++ b/Examples/iOS UIKit/EventParsing/EventParsing.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ E27D0E1E284F2A8900F43247 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27D0E1D284F2A8900F43247 /* AppDelegate.swift */; }; - E27D0E22284F2A8900F43247 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27D0E21284F2A8900F43247 /* ViewController.swift */; }; E27D0E25284F2A8900F43247 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E27D0E23284F2A8900F43247 /* Main.storyboard */; }; E27D0E2A284F2A8900F43247 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E27D0E28284F2A8900F43247 /* LaunchScreen.storyboard */; }; E27D0E35284F2E0A00F43247 /* MIDIKit in Frameworks */ = {isa = PBXBuildFile; productRef = E27D0E34284F2E0A00F43247 /* MIDIKit */; }; @@ -19,7 +18,6 @@ /* Begin PBXFileReference section */ E27D0E1A284F2A8900F43247 /* EventParsing.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EventParsing.app; sourceTree = BUILT_PRODUCTS_DIR; }; E27D0E1D284F2A8900F43247 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - E27D0E21284F2A8900F43247 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; E27D0E24284F2A8900F43247 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; E27D0E29284F2A8900F43247 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; E27D0E2B284F2A8900F43247 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -61,7 +59,6 @@ isa = PBXGroup; children = ( E27D0E1D284F2A8900F43247 /* AppDelegate.swift */, - E27D0E21284F2A8900F43247 /* ViewController.swift */, E27D0E23284F2A8900F43247 /* Main.storyboard */, E27D0E28284F2A8900F43247 /* LaunchScreen.storyboard */, E29FF2982880BC60005E2BC2 /* Images.xcassets */, @@ -148,7 +145,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E27D0E22284F2A8900F43247 /* ViewController.swift in Sources */, E27D0E1E284F2A8900F43247 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -376,7 +372,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/iOS UIKit/EventParsing/EventParsing/AppDelegate.swift b/Examples/iOS UIKit/EventParsing/EventParsing/AppDelegate.swift index 022b7875ed..e3e5ad74cf 100644 --- a/Examples/iOS UIKit/EventParsing/EventParsing/AppDelegate.swift +++ b/Examples/iOS UIKit/EventParsing/EventParsing/AppDelegate.swift @@ -1,7 +1,7 @@ // // AppDelegate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import UIKit diff --git a/Examples/iOS UIKit/EventParsing/EventParsing/Base.lproj/Main.storyboard b/Examples/iOS UIKit/EventParsing/EventParsing/Base.lproj/Main.storyboard index 1ef224f918..1aa5d33994 100644 --- a/Examples/iOS UIKit/EventParsing/EventParsing/Base.lproj/Main.storyboard +++ b/Examples/iOS UIKit/EventParsing/EventParsing/Base.lproj/Main.storyboard @@ -12,7 +12,7 @@ - + diff --git a/Examples/iOS UIKit/EventParsing/EventParsing/ViewController.swift b/Examples/iOS UIKit/EventParsing/EventParsing/ViewController.swift deleted file mode 100644 index 38c58e6f7d..0000000000 --- a/Examples/iOS UIKit/EventParsing/EventParsing/ViewController.swift +++ /dev/null @@ -1,9 +0,0 @@ -// -// ViewController.swift -// MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License -// - -import UIKit - -class ViewController: UIViewController { } diff --git a/Examples/iOS UIKit/VirtualInput/VirtualInput.xcodeproj/project.pbxproj b/Examples/iOS UIKit/VirtualInput/VirtualInput.xcodeproj/project.pbxproj index d4ceb460c0..d487e20397 100644 --- a/Examples/iOS UIKit/VirtualInput/VirtualInput.xcodeproj/project.pbxproj +++ b/Examples/iOS UIKit/VirtualInput/VirtualInput.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ E27D0E1E284F2A8900F43247 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27D0E1D284F2A8900F43247 /* AppDelegate.swift */; }; - E27D0E22284F2A8900F43247 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27D0E21284F2A8900F43247 /* ViewController.swift */; }; E27D0E25284F2A8900F43247 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E27D0E23284F2A8900F43247 /* Main.storyboard */; }; E27D0E2A284F2A8900F43247 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E27D0E28284F2A8900F43247 /* LaunchScreen.storyboard */; }; E27D0E35284F2E0A00F43247 /* MIDIKit in Frameworks */ = {isa = PBXBuildFile; productRef = E27D0E34284F2E0A00F43247 /* MIDIKit */; }; @@ -19,7 +18,6 @@ /* Begin PBXFileReference section */ E27D0E1A284F2A8900F43247 /* VirtualInput.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VirtualInput.app; sourceTree = BUILT_PRODUCTS_DIR; }; E27D0E1D284F2A8900F43247 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - E27D0E21284F2A8900F43247 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; E27D0E24284F2A8900F43247 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; E27D0E29284F2A8900F43247 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; E27D0E2B284F2A8900F43247 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -61,7 +59,6 @@ isa = PBXGroup; children = ( E27D0E1D284F2A8900F43247 /* AppDelegate.swift */, - E27D0E21284F2A8900F43247 /* ViewController.swift */, E27D0E23284F2A8900F43247 /* Main.storyboard */, E27D0E28284F2A8900F43247 /* LaunchScreen.storyboard */, E29FF29A2880BC72005E2BC2 /* Images.xcassets */, @@ -148,7 +145,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E27D0E22284F2A8900F43247 /* ViewController.swift in Sources */, E27D0E1E284F2A8900F43247 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -378,7 +374,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/iOS UIKit/VirtualInput/VirtualInput/AppDelegate.swift b/Examples/iOS UIKit/VirtualInput/VirtualInput/AppDelegate.swift index 4aeeffa9e2..8c7a85441e 100644 --- a/Examples/iOS UIKit/VirtualInput/VirtualInput/AppDelegate.swift +++ b/Examples/iOS UIKit/VirtualInput/VirtualInput/AppDelegate.swift @@ -1,7 +1,7 @@ // // AppDelegate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import UIKit diff --git a/Examples/iOS UIKit/VirtualInput/VirtualInput/Base.lproj/Main.storyboard b/Examples/iOS UIKit/VirtualInput/VirtualInput/Base.lproj/Main.storyboard index fa8f04a13f..e2e2a32ba2 100644 --- a/Examples/iOS UIKit/VirtualInput/VirtualInput/Base.lproj/Main.storyboard +++ b/Examples/iOS UIKit/VirtualInput/VirtualInput/Base.lproj/Main.storyboard @@ -12,7 +12,7 @@ - + @@ -23,7 +23,7 @@ - Virtual Input Example + Virtual Input Example This example creates a virtual MIDI input port named "TestApp Input". @@ -35,7 +35,7 @@ On modern operating systems supporting MIDI 2.0, event values will be natively r Regardless, MIDI 1.0 ←→ MIDI 2.0 values are always seamlessly convertible. -For more details, review the Event Parsing example project. +For more details, review the Event Parsing example project. diff --git a/Examples/iOS UIKit/VirtualInput/VirtualInput/ViewController.swift b/Examples/iOS UIKit/VirtualInput/VirtualInput/ViewController.swift deleted file mode 100644 index 38c58e6f7d..0000000000 --- a/Examples/iOS UIKit/VirtualInput/VirtualInput/ViewController.swift +++ /dev/null @@ -1,9 +0,0 @@ -// -// ViewController.swift -// MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License -// - -import UIKit - -class ViewController: UIViewController { } diff --git a/Examples/iOS UIKit/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj b/Examples/iOS UIKit/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj index bd5033f2d1..d03050d020 100644 --- a/Examples/iOS UIKit/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj +++ b/Examples/iOS UIKit/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ E27D0E1E284F2A8900F43247 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27D0E1D284F2A8900F43247 /* AppDelegate.swift */; }; - E27D0E22284F2A8900F43247 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27D0E21284F2A8900F43247 /* ViewController.swift */; }; E27D0E25284F2A8900F43247 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E27D0E23284F2A8900F43247 /* Main.storyboard */; }; E27D0E2A284F2A8900F43247 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E27D0E28284F2A8900F43247 /* LaunchScreen.storyboard */; }; E27D0E35284F2E0A00F43247 /* MIDIKit in Frameworks */ = {isa = PBXBuildFile; productRef = E27D0E34284F2E0A00F43247 /* MIDIKit */; }; @@ -19,7 +18,6 @@ /* Begin PBXFileReference section */ E27D0E1A284F2A8900F43247 /* VirtualOutput.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VirtualOutput.app; sourceTree = BUILT_PRODUCTS_DIR; }; E27D0E1D284F2A8900F43247 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - E27D0E21284F2A8900F43247 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; E27D0E24284F2A8900F43247 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; E27D0E29284F2A8900F43247 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; E27D0E2B284F2A8900F43247 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -61,7 +59,6 @@ isa = PBXGroup; children = ( E27D0E1D284F2A8900F43247 /* AppDelegate.swift */, - E27D0E21284F2A8900F43247 /* ViewController.swift */, E27D0E23284F2A8900F43247 /* Main.storyboard */, E27D0E28284F2A8900F43247 /* LaunchScreen.storyboard */, E29FF29C2880BC84005E2BC2 /* Images.xcassets */, @@ -148,7 +145,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E27D0E22284F2A8900F43247 /* ViewController.swift in Sources */, E27D0E1E284F2A8900F43247 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -376,7 +372,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/iOS UIKit/VirtualOutput/VirtualOutput/AppDelegate.swift b/Examples/iOS UIKit/VirtualOutput/VirtualOutput/AppDelegate.swift index 7fa700b6c6..edcda218ed 100644 --- a/Examples/iOS UIKit/VirtualOutput/VirtualOutput/AppDelegate.swift +++ b/Examples/iOS UIKit/VirtualOutput/VirtualOutput/AppDelegate.swift @@ -1,7 +1,7 @@ // // AppDelegate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import UIKit @@ -44,42 +44,35 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return true } + /// Convenience accessor for created virtual MIDI Output. + var virtualOutput: MIDIOutput? { + midiManager.managedOutputs[virtualOutputName] + } + @IBAction func sendNoteOn(_ sender: Any) { - guard let output = midiManager.managedOutputs[virtualOutputName] else { return } - - try? output.send( - event: .noteOn( - 60, - velocity: .midi1(127), - channel: 0 - ) - ) + try? virtualOutput?.send(event: .noteOn( + 60, + velocity: .midi1(127), + channel: 0 + )) } @IBAction func sendNoteOff(_ sender: Any) { - guard let output = midiManager.managedOutputs[virtualOutputName] else { return } - - try? output.send( - event: .noteOff( - 60, - velocity: .midi1(0), - channel: 0 - ) - ) + try? virtualOutput?.send(event: .noteOff( + 60, + velocity: .midi1(0), + channel: 0 + )) } @IBAction func sendCC1(_ sender: Any) { - guard let output = midiManager.managedOutputs[virtualOutputName] else { return } - - try? output.send( - event: .cc( - 1, - value: .midi1(64), - channel: 0 - ) - ) + try? virtualOutput?.send(event: .cc( + 1, + value: .midi1(64), + channel: 0 + )) } } diff --git a/Examples/iOS UIKit/VirtualOutput/VirtualOutput/Base.lproj/Main.storyboard b/Examples/iOS UIKit/VirtualOutput/VirtualOutput/Base.lproj/Main.storyboard index 4f4fddc527..9742d527fa 100644 --- a/Examples/iOS UIKit/VirtualOutput/VirtualOutput/Base.lproj/Main.storyboard +++ b/Examples/iOS UIKit/VirtualOutput/VirtualOutput/Base.lproj/Main.storyboard @@ -12,7 +12,7 @@ - + diff --git a/Examples/iOS UIKit/VirtualOutput/VirtualOutput/ViewController.swift b/Examples/iOS UIKit/VirtualOutput/VirtualOutput/ViewController.swift deleted file mode 100644 index 38c58e6f7d..0000000000 --- a/Examples/iOS UIKit/VirtualOutput/VirtualOutput/ViewController.swift +++ /dev/null @@ -1,9 +0,0 @@ -// -// ViewController.swift -// MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License -// - -import UIKit - -class ViewController: UIViewController { } diff --git a/Examples/macOS AppKit/EndpointMenus/EndpointMenus.xcodeproj/project.pbxproj b/Examples/macOS AppKit/EndpointMenus/EndpointMenus.xcodeproj/project.pbxproj index 109fc935b0..560288adc6 100644 --- a/Examples/macOS AppKit/EndpointMenus/EndpointMenus.xcodeproj/project.pbxproj +++ b/Examples/macOS AppKit/EndpointMenus/EndpointMenus.xcodeproj/project.pbxproj @@ -363,7 +363,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/macOS AppKit/EndpointMenus/EndpointMenus/AppDelegate.swift b/Examples/macOS AppKit/EndpointMenus/EndpointMenus/AppDelegate.swift index 994ac79c7a..74c630374c 100644 --- a/Examples/macOS AppKit/EndpointMenus/EndpointMenus/AppDelegate.swift +++ b/Examples/macOS AppKit/EndpointMenus/EndpointMenus/AppDelegate.swift @@ -1,7 +1,7 @@ // // AppDelegate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Cocoa @@ -173,8 +173,10 @@ extension AppDelegate { // --------------- midiInMenu.addItem(.separator()) - // If selected endpoint doesn't exist in the system, show it in the menu as missing but still selected. - // The MIDIManager will auto-reconnect to it if it reappears in the system in this condition. + // If selected endpoint doesn't exist in the system, + // show it in the menu as missing but still selected. + // The MIDIManager will auto-reconnect to it if it reappears + // in the system in this condition. if midiInMenuSelectedID != .invalidMIDIIdentifier, !sortedEndpoints.contains(whereUniqueID: midiInMenuSelectedID) { @@ -271,8 +273,10 @@ extension AppDelegate { // --------------- midiOutMenu.addItem(.separator()) - // If selected endpoint doesn't exist in the system, show it in the menu as missing but still selected. - // The MIDIManager will auto-reconnect to it if it reappears in the system in this condition. + // If selected endpoint doesn't exist in the system, + // show it in the menu as missing but still selected. + // The MIDIManager will auto-reconnect to it if it reappears + // in the system in this condition. if midiOutMenuSelectedID != .invalidMIDIIdentifier, !sortedEndpoints.contains(whereUniqueID: midiOutMenuSelectedID) { diff --git a/Examples/macOS AppKit/EventParsing/EventParsing.xcodeproj/project.pbxproj b/Examples/macOS AppKit/EventParsing/EventParsing.xcodeproj/project.pbxproj index e89b5ac636..6b98f3eb78 100644 --- a/Examples/macOS AppKit/EventParsing/EventParsing.xcodeproj/project.pbxproj +++ b/Examples/macOS AppKit/EventParsing/EventParsing.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ E24BA23E284F1A3300AA6767 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24BA23D284F1A3300AA6767 /* AppDelegate.swift */; }; - E24BA240284F1A3300AA6767 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24BA23F284F1A3300AA6767 /* ViewController.swift */; }; E24BA245284F1A3400AA6767 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E24BA243284F1A3400AA6767 /* Main.storyboard */; }; E24BA251284F1C5B00AA6767 /* MIDIKit in Frameworks */ = {isa = PBXBuildFile; productRef = E24BA250284F1C5B00AA6767 /* MIDIKit */; }; E29AC927285BF2A6009D1C2C /* MIDIKit in Frameworks */ = {isa = PBXBuildFile; productRef = E29AC926285BF2A6009D1C2C /* MIDIKit */; }; @@ -18,7 +17,6 @@ /* Begin PBXFileReference section */ E24BA23A284F1A3300AA6767 /* EventParsing.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EventParsing.app; sourceTree = BUILT_PRODUCTS_DIR; }; E24BA23D284F1A3300AA6767 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - E24BA23F284F1A3300AA6767 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; E24BA244284F1A3400AA6767 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; E24BA246284F1A3400AA6767 /* EventParsing.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = EventParsing.entitlements; sourceTree = ""; }; E29A5E972852A29F00E87812 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; @@ -59,7 +57,6 @@ isa = PBXGroup; children = ( E24BA23D284F1A3300AA6767 /* AppDelegate.swift */, - E24BA23F284F1A3300AA6767 /* ViewController.swift */, E24BA243284F1A3400AA6767 /* Main.storyboard */, E24BA246284F1A3400AA6767 /* EventParsing.entitlements */, E29FF2A02880BCC5005E2BC2 /* Images.xcassets */, @@ -144,7 +141,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E24BA240284F1A3300AA6767 /* ViewController.swift in Sources */, E24BA23E284F1A3300AA6767 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -367,7 +363,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/macOS AppKit/EventParsing/EventParsing/AppDelegate.swift b/Examples/macOS AppKit/EventParsing/EventParsing/AppDelegate.swift index 19ee75f458..7c0bd61d49 100644 --- a/Examples/macOS AppKit/EventParsing/EventParsing/AppDelegate.swift +++ b/Examples/macOS AppKit/EventParsing/EventParsing/AppDelegate.swift @@ -1,7 +1,7 @@ // // AppDelegate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Cocoa diff --git a/Examples/macOS AppKit/EventParsing/EventParsing/Base.lproj/Main.storyboard b/Examples/macOS AppKit/EventParsing/EventParsing/Base.lproj/Main.storyboard index d6cc68533e..96ed34cd38 100644 --- a/Examples/macOS AppKit/EventParsing/EventParsing/Base.lproj/Main.storyboard +++ b/Examples/macOS AppKit/EventParsing/EventParsing/Base.lproj/Main.storyboard @@ -704,7 +704,7 @@ - + diff --git a/Examples/macOS AppKit/EventParsing/EventParsing/ViewController.swift b/Examples/macOS AppKit/EventParsing/EventParsing/ViewController.swift deleted file mode 100644 index 4144b20920..0000000000 --- a/Examples/macOS AppKit/EventParsing/EventParsing/ViewController.swift +++ /dev/null @@ -1,9 +0,0 @@ -// -// ViewController.swift -// MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License -// - -import Cocoa - -class ViewController: NSViewController { } diff --git a/Examples/macOS AppKit/VirtualInput/VirtualInput.xcodeproj/project.pbxproj b/Examples/macOS AppKit/VirtualInput/VirtualInput.xcodeproj/project.pbxproj index 8e8f93f346..609e8dc25d 100644 --- a/Examples/macOS AppKit/VirtualInput/VirtualInput.xcodeproj/project.pbxproj +++ b/Examples/macOS AppKit/VirtualInput/VirtualInput.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ E24BA23E284F1A3300AA6767 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24BA23D284F1A3300AA6767 /* AppDelegate.swift */; }; - E24BA240284F1A3300AA6767 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24BA23F284F1A3300AA6767 /* ViewController.swift */; }; E24BA245284F1A3400AA6767 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E24BA243284F1A3400AA6767 /* Main.storyboard */; }; E24BA251284F1C5B00AA6767 /* MIDIKit in Frameworks */ = {isa = PBXBuildFile; productRef = E24BA250284F1C5B00AA6767 /* MIDIKit */; }; E29AC92A285BF2E6009D1C2C /* MIDIKit in Frameworks */ = {isa = PBXBuildFile; productRef = E29AC929285BF2E6009D1C2C /* MIDIKit */; }; @@ -18,7 +17,6 @@ /* Begin PBXFileReference section */ E24BA23A284F1A3300AA6767 /* VirtualInput.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VirtualInput.app; sourceTree = BUILT_PRODUCTS_DIR; }; E24BA23D284F1A3300AA6767 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - E24BA23F284F1A3300AA6767 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; E24BA244284F1A3400AA6767 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; E24BA246284F1A3400AA6767 /* VirtualInput.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = VirtualInput.entitlements; sourceTree = ""; }; E29A5E972852A29F00E87812 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; @@ -59,7 +57,6 @@ isa = PBXGroup; children = ( E24BA23D284F1A3300AA6767 /* AppDelegate.swift */, - E24BA23F284F1A3300AA6767 /* ViewController.swift */, E24BA243284F1A3400AA6767 /* Main.storyboard */, E24BA246284F1A3400AA6767 /* VirtualInput.entitlements */, E29FF2A22880BCD5005E2BC2 /* Images.xcassets */, @@ -144,7 +141,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E24BA240284F1A3300AA6767 /* ViewController.swift in Sources */, E24BA23E284F1A3300AA6767 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -367,7 +363,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/macOS AppKit/VirtualInput/VirtualInput/AppDelegate.swift b/Examples/macOS AppKit/VirtualInput/VirtualInput/AppDelegate.swift index 5ab2800276..2777fc6be6 100644 --- a/Examples/macOS AppKit/VirtualInput/VirtualInput/AppDelegate.swift +++ b/Examples/macOS AppKit/VirtualInput/VirtualInput/AppDelegate.swift @@ -1,7 +1,7 @@ // // AppDelegate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Cocoa diff --git a/Examples/macOS AppKit/VirtualInput/VirtualInput/Base.lproj/Main.storyboard b/Examples/macOS AppKit/VirtualInput/VirtualInput/Base.lproj/Main.storyboard index d52e9daf55..0d5ef6ea04 100644 --- a/Examples/macOS AppKit/VirtualInput/VirtualInput/Base.lproj/Main.storyboard +++ b/Examples/macOS AppKit/VirtualInput/VirtualInput/Base.lproj/Main.storyboard @@ -704,7 +704,7 @@ - + diff --git a/Examples/macOS AppKit/VirtualInput/VirtualInput/ViewController.swift b/Examples/macOS AppKit/VirtualInput/VirtualInput/ViewController.swift deleted file mode 100644 index 4144b20920..0000000000 --- a/Examples/macOS AppKit/VirtualInput/VirtualInput/ViewController.swift +++ /dev/null @@ -1,9 +0,0 @@ -// -// ViewController.swift -// MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License -// - -import Cocoa - -class ViewController: NSViewController { } diff --git a/Examples/macOS AppKit/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj b/Examples/macOS AppKit/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj index 5c08e47c03..e88f213957 100644 --- a/Examples/macOS AppKit/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj +++ b/Examples/macOS AppKit/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ E24BA23E284F1A3300AA6767 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24BA23D284F1A3300AA6767 /* AppDelegate.swift */; }; - E24BA240284F1A3300AA6767 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24BA23F284F1A3300AA6767 /* ViewController.swift */; }; E24BA245284F1A3400AA6767 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E24BA243284F1A3400AA6767 /* Main.storyboard */; }; E24BA251284F1C5B00AA6767 /* MIDIKit in Frameworks */ = {isa = PBXBuildFile; productRef = E24BA250284F1C5B00AA6767 /* MIDIKit */; }; E29AC92D285BF31F009D1C2C /* MIDIKit in Frameworks */ = {isa = PBXBuildFile; productRef = E29AC92C285BF31F009D1C2C /* MIDIKit */; }; @@ -18,7 +17,6 @@ /* Begin PBXFileReference section */ E24BA23A284F1A3300AA6767 /* VirtualOutput.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VirtualOutput.app; sourceTree = BUILT_PRODUCTS_DIR; }; E24BA23D284F1A3300AA6767 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - E24BA23F284F1A3300AA6767 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; E24BA244284F1A3400AA6767 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; E24BA246284F1A3400AA6767 /* VirtualOutput.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = VirtualOutput.entitlements; sourceTree = ""; }; E29A5E982852A2AA00E87812 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; @@ -59,7 +57,6 @@ isa = PBXGroup; children = ( E24BA23D284F1A3300AA6767 /* AppDelegate.swift */, - E24BA23F284F1A3300AA6767 /* ViewController.swift */, E24BA243284F1A3400AA6767 /* Main.storyboard */, E24BA246284F1A3400AA6767 /* VirtualOutput.entitlements */, E29FF2A42880BCE6005E2BC2 /* Images.xcassets */, @@ -144,7 +141,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E24BA240284F1A3300AA6767 /* ViewController.swift in Sources */, E24BA23E284F1A3300AA6767 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -363,7 +359,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/macOS AppKit/VirtualOutput/VirtualOutput/AppDelegate.swift b/Examples/macOS AppKit/VirtualOutput/VirtualOutput/AppDelegate.swift index a4c5a27042..e248c7eb3e 100644 --- a/Examples/macOS AppKit/VirtualOutput/VirtualOutput/AppDelegate.swift +++ b/Examples/macOS AppKit/VirtualOutput/VirtualOutput/AppDelegate.swift @@ -1,7 +1,7 @@ // // AppDelegate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Cocoa @@ -41,42 +41,35 @@ class AppDelegate: NSObject, NSApplicationDelegate { } } + /// Convenience accessor for created virtual MIDI Output. + var virtualOutput: MIDIOutput? { + midiManager.managedOutputs[virtualOutputName] + } + @IBAction func sendNoteOn(_ sender: Any) { - guard let output = midiManager.managedOutputs[virtualOutputName] else { return } - - try? output.send( - event: .noteOn( - 60, - velocity: .midi1(127), - channel: 0 - ) - ) + try? virtualOutput?.send(event: .noteOn( + 60, + velocity: .midi1(127), + channel: 0 + )) } @IBAction func sendNoteOff(_ sender: Any) { - guard let output = midiManager.managedOutputs[virtualOutputName] else { return } - - try? output.send( - event: .noteOff( - 60, - velocity: .midi1(0), - channel: 0 - ) - ) + try? virtualOutput?.send(event: .noteOff( + 60, + velocity: .midi1(0), + channel: 0 + )) } @IBAction func sendCC1(_ sender: Any) { - guard let output = midiManager.managedOutputs[virtualOutputName] else { return } - - try? output.send( - event: .cc( - 1, - value: .midi1(64), - channel: 0 - ) - ) + try? virtualOutput?.send(event: .cc( + 1, + value: .midi1(64), + channel: 0 + )) } } diff --git a/Examples/macOS AppKit/VirtualOutput/VirtualOutput/Base.lproj/Main.storyboard b/Examples/macOS AppKit/VirtualOutput/VirtualOutput/Base.lproj/Main.storyboard index ae89279db1..e6b214730d 100644 --- a/Examples/macOS AppKit/VirtualOutput/VirtualOutput/Base.lproj/Main.storyboard +++ b/Examples/macOS AppKit/VirtualOutput/VirtualOutput/Base.lproj/Main.storyboard @@ -704,7 +704,7 @@ - + diff --git a/Examples/macOS AppKit/VirtualOutput/VirtualOutput/ViewController.swift b/Examples/macOS AppKit/VirtualOutput/VirtualOutput/ViewController.swift deleted file mode 100644 index 203a507a91..0000000000 --- a/Examples/macOS AppKit/VirtualOutput/VirtualOutput/ViewController.swift +++ /dev/null @@ -1,10 +0,0 @@ -// -// ViewController.swift -// MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License -// - -import Cocoa -import MIDIKit - -class ViewController: NSViewController { } diff --git a/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers.xcodeproj/project.pbxproj b/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers.xcodeproj/project.pbxproj index 0f91b111e8..89d63d9e17 100644 --- a/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers.xcodeproj/project.pbxproj +++ b/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers.xcodeproj/project.pbxproj @@ -9,10 +9,9 @@ /* Begin PBXBuildFile section */ E2055B7A285A733B00DC1138 /* MIDIHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2055B79285A733B00DC1138 /* MIDIHelper.swift */; }; E24CB06F285199E400649B50 /* MIDIEndpointSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24CB06E285199E400649B50 /* MIDIEndpointSelectionView.swift */; }; + E26CCDB028F95BD50045256C /* MIDIKitIO in Frameworks */ = {isa = PBXBuildFile; productRef = E26CCDAF28F95BD50045256C /* MIDIKitIO */; }; E27D0E43284F378100F43247 /* EndpointPickersApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27D0E42284F378100F43247 /* EndpointPickersApp.swift */; }; E27D0E45284F378100F43247 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27D0E44284F378100F43247 /* ContentView.swift */; }; - E27D0E55284F386A00F43247 /* MIDIKit in Frameworks */ = {isa = PBXBuildFile; productRef = E27D0E54284F386A00F43247 /* MIDIKit */; }; - E29AC930285BF355009D1C2C /* MIDIKit in Frameworks */ = {isa = PBXBuildFile; productRef = E29AC92F285BF355009D1C2C /* MIDIKit */; }; E29FF2A72880BCF7005E2BC2 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E29FF2A62880BCF7005E2BC2 /* Images.xcassets */; }; /* End PBXBuildFile section */ @@ -32,8 +31,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E29AC930285BF355009D1C2C /* MIDIKit in Frameworks */, - E27D0E55284F386A00F43247 /* MIDIKit in Frameworks */, + E26CCDB028F95BD50045256C /* MIDIKitIO in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -87,8 +85,7 @@ ); name = EndpointPickers; packageProductDependencies = ( - E27D0E54284F386A00F43247 /* MIDIKit */, - E29AC92F285BF355009D1C2C /* MIDIKit */, + E26CCDAF28F95BD50045256C /* MIDIKitIO */, ); productName = EndpointPickers; productReference = E27D0E3F284F378100F43247 /* EndpointPickers.app */; @@ -119,7 +116,7 @@ ); mainGroup = E27D0E36284F378100F43247; packageReferences = ( - E29AC92E285BF355009D1C2C /* XCRemoteSwiftPackageReference "MIDIKit" */, + E26CCDAE28F95BD40045256C /* XCRemoteSwiftPackageReference "MIDIKit" */, ); productRefGroup = E27D0E40284F378100F43247 /* Products */; projectDirPath = ""; @@ -353,25 +350,21 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - E29AC92E285BF355009D1C2C /* XCRemoteSwiftPackageReference "MIDIKit" */ = { + E26CCDAE28F95BD40045256C /* XCRemoteSwiftPackageReference "MIDIKit" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - E27D0E54284F386A00F43247 /* MIDIKit */ = { + E26CCDAF28F95BD50045256C /* MIDIKitIO */ = { isa = XCSwiftPackageProductDependency; - productName = MIDIKit; - }; - E29AC92F285BF355009D1C2C /* MIDIKit */ = { - isa = XCSwiftPackageProductDependency; - package = E29AC92E285BF355009D1C2C /* XCRemoteSwiftPackageReference "MIDIKit" */; - productName = MIDIKit; + package = E26CCDAE28F95BD40045256C /* XCRemoteSwiftPackageReference "MIDIKit" */; + productName = MIDIKitIO; }; /* End XCSwiftPackageProductDependency section */ }; diff --git a/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/ContentView.swift b/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/ContentView.swift index 8f930c8401..b371b361ae 100644 --- a/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/ContentView.swift +++ b/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/ContentView.swift @@ -1,11 +1,11 @@ // // ContentView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI -import MIDIKit +import MIDIKitIO struct ContentView: View { @EnvironmentObject var midiManager: MIDIManager diff --git a/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/EndpointPickersApp.swift b/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/EndpointPickersApp.swift index 75a958cd1a..8b6c486235 100644 --- a/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/EndpointPickersApp.swift +++ b/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/EndpointPickersApp.swift @@ -1,11 +1,11 @@ // // EndpointPickersApp.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI -import MIDIKit +import MIDIKitIO @main struct EndpointPickersApp: App { diff --git a/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/MIDIEndpointSelectionView.swift b/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/MIDIEndpointSelectionView.swift index 654b13c2f8..40da02842f 100644 --- a/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/MIDIEndpointSelectionView.swift +++ b/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/MIDIEndpointSelectionView.swift @@ -1,11 +1,11 @@ // // MIDIEndpointSelectionView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI -import MIDIKit +import MIDIKitIO struct MIDIInSelectionView: View { @EnvironmentObject var midiManager: MIDIManager diff --git a/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/MIDIHelper.swift b/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/MIDIHelper.swift index f4e2a67a5a..7fc8cc72ac 100644 --- a/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/MIDIHelper.swift +++ b/Examples/macOS SwiftUI/EndpointPickers/EndpointPickers/MIDIHelper.swift @@ -1,11 +1,11 @@ // // MIDIHelper.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI -import MIDIKit +import MIDIKitIO class MIDIHelper: ObservableObject { public weak var midiManager: MIDIManager? diff --git a/Examples/macOS SwiftUI/EventParsing/EventParsing.xcodeproj/project.pbxproj b/Examples/macOS SwiftUI/EventParsing/EventParsing.xcodeproj/project.pbxproj index de4cf74574..53ba1f4f20 100644 --- a/Examples/macOS SwiftUI/EventParsing/EventParsing.xcodeproj/project.pbxproj +++ b/Examples/macOS SwiftUI/EventParsing/EventParsing.xcodeproj/project.pbxproj @@ -350,7 +350,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/macOS SwiftUI/EventParsing/EventParsing/ContentView.swift b/Examples/macOS SwiftUI/EventParsing/EventParsing/ContentView.swift index fc944e20e7..d4198218d3 100644 --- a/Examples/macOS SwiftUI/EventParsing/EventParsing/ContentView.swift +++ b/Examples/macOS SwiftUI/EventParsing/EventParsing/ContentView.swift @@ -1,7 +1,7 @@ // // ContentView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/macOS SwiftUI/EventParsing/EventParsing/EventParsingApp.swift b/Examples/macOS SwiftUI/EventParsing/EventParsing/EventParsingApp.swift index 6f8da5c286..a7b4c17e3a 100644 --- a/Examples/macOS SwiftUI/EventParsing/EventParsing/EventParsingApp.swift +++ b/Examples/macOS SwiftUI/EventParsing/EventParsing/EventParsingApp.swift @@ -1,7 +1,7 @@ // // EventParsingApp.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/macOS SwiftUI/EventParsing/EventParsing/MIDIHelper.swift b/Examples/macOS SwiftUI/EventParsing/EventParsing/MIDIHelper.swift index 17c61b86cf..160be60522 100644 --- a/Examples/macOS SwiftUI/EventParsing/EventParsing/MIDIHelper.swift +++ b/Examples/macOS SwiftUI/EventParsing/EventParsing/MIDIHelper.swift @@ -1,7 +1,7 @@ // // MIDIHelper.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/macOS SwiftUI/VirtualInput/VirtualInput.xcodeproj/project.pbxproj b/Examples/macOS SwiftUI/VirtualInput/VirtualInput.xcodeproj/project.pbxproj index b2ce0cb9fb..ca16cb8ad4 100644 --- a/Examples/macOS SwiftUI/VirtualInput/VirtualInput.xcodeproj/project.pbxproj +++ b/Examples/macOS SwiftUI/VirtualInput/VirtualInput.xcodeproj/project.pbxproj @@ -346,7 +346,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/macOS SwiftUI/VirtualInput/VirtualInput/ContentView.swift b/Examples/macOS SwiftUI/VirtualInput/VirtualInput/ContentView.swift index 857831f45d..f18b9654e6 100644 --- a/Examples/macOS SwiftUI/VirtualInput/VirtualInput/ContentView.swift +++ b/Examples/macOS SwiftUI/VirtualInput/VirtualInput/ContentView.swift @@ -1,7 +1,7 @@ // // ContentView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Examples/macOS SwiftUI/VirtualInput/VirtualInput/VirtualInputApp.swift b/Examples/macOS SwiftUI/VirtualInput/VirtualInput/VirtualInputApp.swift index 061b529a57..6d103734ec 100644 --- a/Examples/macOS SwiftUI/VirtualInput/VirtualInput/VirtualInputApp.swift +++ b/Examples/macOS SwiftUI/VirtualInput/VirtualInput/VirtualInputApp.swift @@ -1,7 +1,7 @@ // // VirtualInputApp.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -24,7 +24,7 @@ struct VirtualInputApp: App { } catch { print("Error starting MIDI services:", error.localizedDescription) } - + do { print("Creating virtual MIDI input.") try midiManager.addInput( diff --git a/Examples/macOS SwiftUI/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj b/Examples/macOS SwiftUI/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj index cabfc0e87c..7aeaca0178 100644 --- a/Examples/macOS SwiftUI/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj +++ b/Examples/macOS SwiftUI/VirtualOutput/VirtualOutput.xcodeproj/project.pbxproj @@ -346,7 +346,7 @@ repositoryURL = "https://github.com/orchetect/MIDIKit"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Examples/macOS SwiftUI/VirtualOutput/VirtualOutput/ContentView.swift b/Examples/macOS SwiftUI/VirtualOutput/VirtualOutput/ContentView.swift index ab0f0fe0f6..571961427e 100644 --- a/Examples/macOS SwiftUI/VirtualOutput/VirtualOutput/ContentView.swift +++ b/Examples/macOS SwiftUI/VirtualOutput/VirtualOutput/ContentView.swift @@ -1,7 +1,7 @@ // // ContentView.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI @@ -36,45 +36,33 @@ struct ContentView: View { } } -extension ContentView{ +extension ContentView { /// Convenience accessor for created virtual MIDI Output. var virtualOutput: MIDIOutput? { midiManager.managedOutputs[virtualOutputName] } func sendNoteOn() { - guard let output = virtualOutput else { return } - - try? output.send( - event: .noteOn( - 60, - velocity: .midi1(127), - channel: 0 - ) - ) + try? virtualOutput?.send(event: .noteOn( + 60, + velocity: .midi1(127), + channel: 0 + )) } func sendNoteOff() { - guard let output = virtualOutput else { return } - - try? output.send( - event: .noteOff( - 60, - velocity: .midi1(0), - channel: 0 - ) - ) + try? virtualOutput?.send(event: .noteOff( + 60, + velocity: .midi1(0), + channel: 0 + )) } func sendCC1() { - guard let output = virtualOutput else { return } - - try? output.send( - event: .cc( - 1, - value: .midi1(64), - channel: 0 - ) - ) + try? virtualOutput?.send(event: .cc( + 1, + value: .midi1(64), + channel: 0 + )) } } diff --git a/Examples/macOS SwiftUI/VirtualOutput/VirtualOutput/VirtualOutputApp.swift b/Examples/macOS SwiftUI/VirtualOutput/VirtualOutput/VirtualOutputApp.swift index 4e50b3993c..b783ee9a93 100644 --- a/Examples/macOS SwiftUI/VirtualOutput/VirtualOutput/VirtualOutputApp.swift +++ b/Examples/macOS SwiftUI/VirtualOutput/VirtualOutput/VirtualOutputApp.swift @@ -1,7 +1,7 @@ // // VirtualOutputApp.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import SwiftUI diff --git a/Sources/MIDIKit/MIDIKit.swift b/Sources/MIDIKit/MIDIKit.swift index b4b997b4ef..fcc717281e 100644 --- a/Sources/MIDIKit/MIDIKit.swift +++ b/Sources/MIDIKit/MIDIKit.swift @@ -1,7 +1,7 @@ // // MIDIKit.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // // Welcome to MIDIKit :) diff --git a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUICharacterProtocol.swift b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUICharacterProtocol.swift index 061cafa3f6..226491ea8e 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUICharacterProtocol.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUICharacterProtocol.swift @@ -1,7 +1,7 @@ // // HUICharacterProtocol.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUILargeDisplayCharacter.swift b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUILargeDisplayCharacter.swift index effeb311c7..9395472ed2 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUILargeDisplayCharacter.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUILargeDisplayCharacter.swift @@ -1,7 +1,7 @@ // // HUILargeDisplayCharacter.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUILargeDisplayString.swift b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUILargeDisplayString.swift index 760efc87f0..5b2956523a 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUILargeDisplayString.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUILargeDisplayString.swift @@ -1,7 +1,7 @@ // // HUILargeDisplayString.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUISmallDisplay.swift b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUISmallDisplay.swift index 5a55228106..d384bac618 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUISmallDisplay.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUISmallDisplay.swift @@ -1,7 +1,7 @@ // // HUISmallDisplay.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUISmallDisplayCharacter.swift b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUISmallDisplayCharacter.swift index 3770d1a1d3..6772fbb6d2 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUISmallDisplayCharacter.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUISmallDisplayCharacter.swift @@ -1,7 +1,7 @@ // // HUISmallDisplayCharacter.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUISmallDisplayString.swift b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUISmallDisplayString.swift index 01a22920e5..ae1d083395 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUISmallDisplayString.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUISmallDisplayString.swift @@ -1,7 +1,7 @@ // // HUISmallDisplayString.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIStringProtocol.swift b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIStringProtocol.swift index 2e84ba9e11..b2944f61b0 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIStringProtocol.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIStringProtocol.swift @@ -1,14 +1,14 @@ // // HUIStringProtocol.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation public protocol HUIStringProtocol: CustomStringConvertible -where Self: Equatable & Hashable, - Element: Equatable & Hashable + where Self: Equatable & Hashable, + Element: Equatable & Hashable { associatedtype Element: HUICharacterProtocol static var defaultChars: [Element] { get } @@ -27,7 +27,8 @@ where Self: Equatable & Hashable, init(chars: [Element]) /// Initialize from a string. - /// Characters will be converted or substituted if they are not contained in ``Element``'s character set. + /// Characters will be converted or substituted if they + /// are not contained in ``Element``'s character set. /// String will be padded and truncated to the appropriate static length. init(lossy source: S) diff --git a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUITimeDisplayCharacter.swift b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUITimeDisplayCharacter.swift index 60b82d01bb..d7468ac353 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUITimeDisplayCharacter.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUITimeDisplayCharacter.swift @@ -1,7 +1,7 @@ // // HUITimeDisplayCharacter.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUITimeDisplayString.swift b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUITimeDisplayString.swift index 097ab53a26..18c1b6a1c1 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUITimeDisplayString.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUITimeDisplayString.swift @@ -1,14 +1,16 @@ // // HUITimeDisplayString.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation /// HUI time display string, comprised of 8 digits. /// -/// The time display consists of eight 7-segment displays (called digits). Every digit except the last (rightmost) has the ability to show a trailing decimal point (dot). +/// The time display consists of eight 7-segment displays (called digits). +/// Every digit except the last (rightmost) has the ability +/// to show a trailing decimal point (dot). public struct HUITimeDisplayString: HUIStringProtocol, Equatable, Hashable { public typealias Element = HUITimeDisplayCharacter @@ -54,7 +56,8 @@ public struct HUITimeDisplayString: HUIStringProtocol, Equatable, Hashable { } /// Internal: - /// Updates the string from a partial or whole character sequence, in sequence order from right to left. + /// Updates the string from a partial or whole character sequence, + /// in sequence order from right to left. /// /// - Parameters: /// - charsRightToLeft: Between 1 and 8 characters, in sequence order from right to left. diff --git a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPot.swift b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPot.swift index 96424bed91..9558b1560e 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPot.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPot.swift @@ -1,7 +1,7 @@ // // HUIVPot.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -84,11 +84,13 @@ public enum HUIVPot: Equatable, Hashable { /// Specialized HUI V-Pot value. enum HUIVPotValue: Equatable, Hashable { /// V-Pot display LED ring. (11 LED ring with a lower LED) - /// Only applies to HUI messages sent from the host in order to update a client surface's V-Pot LEDs. + /// Only applies to HUI messages sent from the host in order to update + /// a client surface's V-Pot LEDs. case display(HUIVPotDisplay) /// V-Pot rotary knob delta change -/+. - /// Only applies to HUI messages sent from a client surface in order to transmit rotary knob input from the user to the host. + /// Only applies to HUI messages sent from a client surface in order to transmit + /// rotary knob input from the user to the host. case delta(Int7) /// Internal: diff --git a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPotDisplay/HUIVPotDisplay.swift b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPotDisplay/HUIVPotDisplay.swift index de20e3caa6..39c9d873e7 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPotDisplay/HUIVPotDisplay.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPotDisplay/HUIVPotDisplay.swift @@ -1,14 +1,15 @@ // // HUIVPotDisplay.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation /// HUI V-Pot LED Ring Display. /// -/// Around each V-Pot are 11 LEDs in a ring (semi-circle), as well as a single LED centered underneath. +/// Around each V-Pot are 11 LEDs in a ring (semi-circle), +/// as well as a single LED centered underneath. public struct HUIVPotDisplay: Equatable, Hashable { // MARK: State diff --git a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPotDisplay/LEDState LED.swift b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPotDisplay/LEDState LED.swift index 73368e9f23..5409cc1e42 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPotDisplay/LEDState LED.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPotDisplay/LEDState LED.swift @@ -1,7 +1,7 @@ // // LEDState LED.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -80,7 +80,8 @@ extension HUIVPotDisplay.LEDState.LED { } } - /// Initialize from the LED count from center as an absolute (positive) unit interval (`0.0 ... 1.0`). + /// Initialize from the LED count from center as + /// an absolute (positive) unit interval (`0.0 ... 1.0`). public init?(radiusUnitInterval: Double) { switch radiusUnitInterval { case 0.0 ..< 0.2: self = .C @@ -102,7 +103,9 @@ extension HUIVPotDisplay.LEDState.LED { // MARK: - Unit Interval extension HUIVPotDisplay.LEDState.LED { - /// Initialize from a unit interval (`0.0 ... 1.0`) corresponding to the nearest LED position from left-to-right. Value will be clamped. + /// Initialize from a unit interval (`0.0 ... 1.0`) corresponding + /// to the nearest LED position from left-to-right. + /// Value will be clamped. public init(position unitInterval: Double) { let raw = UInt8((unitInterval * 0xA).clamped(to: 0x0 ... 0xA)) self = Self(rawValue: raw) ?? .L5 @@ -118,13 +121,15 @@ extension HUIVPotDisplay.LEDState.LED { extension HUIVPotDisplay.LEDState.LED { /// Internal: - /// The lower bound of the LED's position as a fraction of the overall distance of the unit interval scale. + /// The lower bound of the LED's position as a fraction of + /// the overall distance of the unit interval scale. var unitIntervalLowerBound: Double { Double(rawValue) / 0xB } /// Internal: - /// The upper bound of the LED's position as a fraction of the overall distance of the unit interval scale. + /// The upper bound of the LED's position as a fraction of + /// the overall distance of the unit interval scale. var unitIntervalUpperBound: Double { Double(rawValue + 1) / 0xB } diff --git a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPotDisplay/LEDState.swift b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPotDisplay/LEDState.swift index 04f6254cfa..c623e01261 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPotDisplay/LEDState.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/Character and LED Tables/HUIVPotDisplay/LEDState.swift @@ -1,7 +1,7 @@ // // LEDState.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -289,12 +289,12 @@ extension HUIVPotDisplay.LEDState { .single(LED(position: unitInterval)) } - /// Initialize by returning a ``left(to:)-swift.enum.case`` case constructed from a unit interval corresponding to the terminating LED position. + /// Initialize by returning a ``left(to:)`` case constructed from a unit interval corresponding to the terminating LED position. public static func left(toUnitInterval unitInterval: Double) -> Self { .left(to: LED(position: unitInterval)) } - /// Initialize by returning a ``center(to:)-swift.enum.case`` case constructed from a unit interval corresponding to the terminating LED position. + /// Initialize by returning a ``center(to:)`` case constructed from a unit interval corresponding to the terminating LED position. public static func center(toUnitInterval unitInterval: Double) -> Self { .center(to: LED(position: unitInterval)) } diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUI Encode Utilities.swift b/Sources/MIDIKitControlSurfaces/HUI/HUI Encode Utilities.swift index 4c543833c8..af4b3a6b83 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUI Encode Utilities.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUI Encode Utilities.swift @@ -1,7 +1,7 @@ // // HUI Encode Utilities.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore @@ -162,7 +162,8 @@ func encodeHUIFader( /// - Parameters: /// - channel: Channel strip number (`0 ... 7`). /// - side: Left or right side of the stereo meter. -/// - level: Level amount (`0x0 ... 0xC`). Where `0x0` is off, `0x1 ... 0xB` is signal level, and `0xC` is clipping (red LED). +/// - level: Level amount (`0x0 ... 0xC`). +/// Where `0x0` is off, `0x1 ... 0xB` is signal level, and `0xC` is clipping (red LED). /// - Returns: MIDI event. func encodeHUILevelMeter( channel: UInt4, @@ -185,7 +186,10 @@ func encodeHUILevelMeter( /// /// - Parameters: /// - vPot: V-Pot identity. -/// - rawValue: Encoded value. When encoding host → surface, this is the LED preset index. When encoding surface → host, this is the delta rotary knob change value -/+ when the user turns the knob. +/// - rawValue: Encoded value. +/// When encoding host → surface, this is the LED preset index. +/// When encoding surface → host, this is the delta rotary knob change +/// value -/+ when the user turns the knob. /// - role: Transmission direction (to host or to remote client surface). /// - Returns: MIDI event. func encodeHUIVPot( @@ -205,7 +209,10 @@ func encodeHUIVPot( /// /// - Parameters: /// - vPot: V-Pot identity. -/// - rawValue: Encoded value. When encoding host → surface, this is the LED preset index. When encoding surface → host, this is the delta rotary knob change value -/+ when the user turns the knob. +/// - rawValue: Encoded value. +/// When encoding host → surface, this is the LED preset index. +/// When encoding surface → host, this is the delta rotary knob change +/// value -/+ when the user turns the knob. /// - role: Transmission direction (to host or to remote client surface). /// - Returns: MIDI event. func encodeHUIVPot( @@ -218,7 +225,8 @@ func encodeHUIVPot( /// Utility: /// Encodes HUI V-Pot value message as a MIDI event. (To host) /// -/// > Note: Input value is clamped to `-63 ... 63` due to bit truncation meaning an input delta value of -64 is not possible and will be truncated to -63. +/// > Note: Input value is clamped to `-63 ... 63` due to bit truncation meaning an input delta +/// value of -64 is not possible and will be truncated to -63. /// /// - Parameters: /// - vPot: V-Pot identity. @@ -254,7 +262,8 @@ func encodeJogWheel( /// Utility: /// Encode HUI large text display as MIDI events. (To surface) -/// Encodes the entire large text display (40 x 2 characters) sourced as 8 text slices of 10 characters each, which matches the HUI encoding. +/// Encodes the entire large text display (40 x 2 characters) sourced as 8 text slices of 10 +/// characters each, which matches the HUI encoding. /// /// - Parameters: /// - display: Top and bottom text line text, each 40 characters in length. @@ -267,7 +276,8 @@ func encodeHUILargeDisplay( /// Utility: /// Encode HUI large text display as MIDI events. (To surface) -/// Encodes the entire large text display (40 x 2 characters) sourced as 8 text slices of 10 characters each, which matches the HUI encoding. +/// Encodes the entire large text display (40 x 2 characters) sourced as +/// 8 text slices of 10 characters each, which matches the HUI encoding. /// /// - Parameters: /// - top: Top text line text of 40 characters in length. @@ -282,9 +292,14 @@ func encodeHUILargeDisplay( /// Utility: /// Encode HUI large text display as MIDI events. (To surface) -/// Encodes the entire large text display (40 x 2 characters) sourced as 8 text slices of 10 characters each, which matches the HUI encoding. +/// Encodes the entire large text display (40 x 2 characters) sourced as +/// 8 text slices of 10 characters each, which matches the HUI encoding. /// -/// This text display is split into 8 slices of 10 characters each, with slices indexed `0 ... 3` for the top 40-character row, and `4 ... 7` for the bottom 40-character row. (This mirrors its raw HUI MIDI message encoding format.) Any of these slices may be sent at any time in any order. +/// This text display is split into 8 slices of 10 characters each, +/// with slices indexed `0 ... 3` for the top 40-character row, +/// and `4 ... 7` for the bottom 40-character row. +/// (This mirrors its raw HUI MIDI message encoding format.) +/// Any of these slices may be sent at any time in any order. /// /// - Parameters: /// - slices: Between 1 and 8 text slices of 10 characters each. @@ -351,7 +366,8 @@ func encodeHUITimeDisplay( /// Encode time display message (timecode, mm:ss, bars/beats, frames). (To client surface) /// /// - Parameters: -/// - charsRightToLeft: Between 1 and 8 characters in reverse sequence order (first array element is rightmost digit). More than 8 characters will discarded and truncated to 8 characters. +/// - charsRightToLeft: Between 1 and 8 characters in reverse sequence order (first array element +/// is rightmost digit). More than 8 characters will discarded and truncated to 8 characters. /// - Returns: MIDI event. func encodeHUITimeDisplay( charsRightToLeft: [HUITimeDisplayCharacter] @@ -417,9 +433,11 @@ func encodeHUISystemReset() -> MIDIEvent { /// Utility: /// Encodes HUI delta value (V-Pot, jog wheel) into a raw byte. /// -/// > Note: Input value is clamped to `-63 ... 63` due to bit truncation meaning an input delta value of -64 is not possible and will be truncated to -63. +/// > Note: Input value is clamped to `-63 ... 63` due to bit truncation meaning an input delta +/// value of -64 is not possible and will be truncated to -63. /// -/// > Note: This is used for surface → host transmission of delta pot changes and not relevant for LED ring display encoding. +/// > Note: This is used for surface → host transmission of delta pot changes and not relevant for +/// LED ring display encoding. /// /// - Parameters: /// - delta: Delta -/+ value (will be clamped to `-63 ... 63`). @@ -438,7 +456,8 @@ func encodeHUIDelta(from delta: Int7) -> UInt7 { /// Utility: /// Decodes a raw byte into a HUI delta value (V-Pot, jog wheel). /// -/// > Note: This is used for surface → host transmission of delta pot changes and not relevant for LED ring display encoding. +/// > Note: This is used for surface → host transmission of delta pot changes and not relevant for +/// LED ring display encoding. /// /// - Parameters: /// - delta: Encoded `UInt7` byte from a HUI MIDI message. diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUI Types.swift b/Sources/MIDIKitControlSurfaces/HUI/HUI Types.swift index 21177ebaa1..218f9b622e 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUI Types.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUI Types.swift @@ -1,7 +1,7 @@ // // HUI Types.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// Raw HUI zone byte. @@ -20,7 +20,8 @@ public enum HUIRole: Equatable, Hashable, CaseIterable { case host /// HUI Surface - /// (ie: a physical HUI control surface device or a software emulation like an iPad HUI control surface app). + /// (ie: a physical HUI control surface device or + /// a software emulation like an iPad HUI control surface app). case surface /// Returns the inverted role. diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUIConstants.swift b/Sources/MIDIKitControlSurfaces/HUI/HUIConstants.swift index 217901f624..d75e8cc078 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUIConstants.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUIConstants.swift @@ -1,7 +1,7 @@ // // HUIConstants.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUICoreEvent.swift b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUICoreEvent.swift index c8c34359d2..fe87c8f927 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUICoreEvent.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUICoreEvent.swift @@ -1,20 +1,28 @@ // // HUICoreEvent.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore /// HUI Core Event. -/// Abstracts raw HUI messages into basic common-currency HUI message types carrying raw data as encoded. +/// Abstracts raw HUI messages into basic common-currency HUI message types carrying raw data as +/// encoded. /// -/// > This event can be used in either direction (to client surface or to host) but not all events are relevant. +/// > This event can be used in either direction (to client surface or to host) but not all events +/// are relevant. /// > /// > For example: /// > -/// > - Both a host and client surface can send channel strip Solo state to each other. The host sends the state to the client surface, and the client surface updates its state and UI to reflect it. Then the user can interact with the client surface at any time to toggle the Solo button which sends the same message back to the host, causing the host to toggle the corresponding track Solo. -/// > - A host can send a time display change to a client surface, but a client surface cannot send any time display changes back to the host. It is a read-only display on the client surface and there is no way to interact with it. +/// > - Both a host and client surface can send channel strip Solo state to each other. The host +/// sends the state to the client surface, and the client surface updates its state and UI to +/// reflect it. Then the user can interact with the client surface at any time to toggle the Solo +/// button which sends the same message back to the host, causing the host to toggle the +/// corresponding track Solo. +/// > - A host can send a time display change to a client surface, but a client surface cannot send +/// any time display changes back to the host. It is a read-only display on the client surface and +/// there is no way to interact with it. internal enum HUICoreEvent: Equatable, Hashable { /// HUI ping message. case ping @@ -34,7 +42,8 @@ internal enum HUICoreEvent: Equatable, Hashable { /// V-Pot encoding. /// When encoding host → surface, this is the LED preset index. - /// When encoding surface → host, this is the delta rotary knob change value -/+ when the user turns the knob. + /// When encoding surface → host, this is the delta rotary knob change value -/+ when the user + /// turns the knob. case vPot( vPot: HUIVPot, value: HUIVPotValue @@ -47,9 +56,12 @@ internal enum HUICoreEvent: Equatable, Hashable { /// Time Display digits. /// - /// Between one and 8 digits, indexed in the array from right-to-left of the actual display. (Index 0 is the rightmost character). + /// Between one and 8 digits, indexed in the array from right-to-left of the actual display. + /// (Index 0 is the rightmost character). /// - /// This is because HUI encodes time display digits in reverse order since the digits on the righthand side of a time display will update most frequently, which allows conservation of data bandwidth when transmitting frequent time display changes. + /// This is because HUI encodes time display digits in reverse order since the digits on the + /// righthand side of a time display will update most frequently, which allows conservation of + /// data bandwidth when transmitting frequent time display changes. case timeDisplay(charsRightToLeft: [HUITimeDisplayCharacter]) /// Select Assign 4-character text display. diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIDecoder.swift b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIDecoder.swift index 9466321646..defc56f55c 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIDecoder.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIDecoder.swift @@ -1,7 +1,7 @@ // // HUIDecoder.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore @@ -62,7 +62,9 @@ extension HUIDecoder: ReceivesMIDIEvents { /// Decodes a MIDI event. /// - /// - Returns: One or more HUI core events if the MIDI event results in decoded HUI event(s). Not all MIDI events will generate HUI event(s); some merely update the decoder's internal state, in which case an empty array will be returned. This is not an error condition. + /// - Returns: One or more HUI core events if the MIDI event results in decoded HUI event(s). + /// Not all MIDI events will generate HUI event(s); some merely update the decoder's internal + /// state, in which case an empty array will be returned. This is not an error condition. /// /// - Throws: An error if the MIDI event was malformed or contained unexpected data. func decode(event: MIDIEvent) throws -> [HUICoreEvent] { @@ -80,8 +82,8 @@ extension HUIDecoder: ReceivesMIDIEvents { payload.note.number == 0 && [0, 0x8000].contains(payload.velocity.midi2Value): - // MIDI 2.0 translation from MIDI 1.0 at the Core MIDI subsystem level - // will force MIDI 1.0 Note On events with a velocity of 0 to be a MIDI 2.0 Note Off event. + // MIDI 2.0 translation from MIDI 1.0 at the Core MIDI subsystem level will + // force MIDI 1.0 Note On events with a velocity of 0 to be a MIDI 2.0 Note Off event. // Technically the MIDI 2.0 spec states that the velocity should be 0, // however it seems Core MIDI wants to send a 16-bit midpoint value of 0x8000 instead @@ -138,8 +140,8 @@ extension HUIDecoder { else { throw HUIDecoderError.malformed( "SysEx sub-IDs (first two bytes) are not recognized. " - + "It is possible the IDs belong to hardware other than the Mackie HUI. " - + "Raw data: [\(data.hexString(padEachTo: 2, prefixes: false))]" + + "It is possible the IDs belong to hardware other than the Mackie HUI. " + + "Raw data: [\(data.hexString(padEachTo: 2, prefixes: false))]" ) } @@ -319,7 +321,8 @@ extension HUIDecoder { // V-Pots // When encoding host → surface, this is the LED preset index. - // When encoding surface → host, this is the delta rotary knob change value -/+ when the user turns the knob. + // When encoding surface → host, this is the delta rotary knob change value -/+ when the + // user turns the knob. let number = dataByte1 % 0x10 guard let vPot = HUIVPot(rawValue: number) @@ -370,7 +373,10 @@ extension HUIDecoder { state = false case 0x2: - // Not sure what this is used for. Any of the HUI docs available don't mention it being used. However, Pro Tools transmits switch messages that utilize this sate nibble. It's been observed being transmit when changing a track's automation mode to Read, and one message per track is sent when opening a Pro Tools session. + // Not sure what this is used for. Any of the HUI docs available don't mention it + // being used. However, Pro Tools transmits switch messages that utilize this sate + // nibble. It's been observed being transmit when changing a track's automation mode + // to Read, and one message per track is sent when opening a Pro Tools session. Logger.debug( "Received (switch cmd msg 2/2) with unhandled state nibble 0x2. Ignoring." ) diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIDecoderError.swift b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIDecoderError.swift index d0740abacd..c657ef9aaf 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIDecoderError.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIDecoderError.swift @@ -1,7 +1,7 @@ // // HUIDecoderError.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// Error type thrown by HUI decoders. diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIDecoderProtocol.swift b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIDecoderProtocol.swift index a27d20c0e7..309f4fff65 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIDecoderProtocol.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIDecoderProtocol.swift @@ -1,7 +1,7 @@ // // HUIDecoderProtocol.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIEventProtocol.swift b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIEventProtocol.swift index d38679cca2..9b14f4677f 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIEventProtocol.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIEventProtocol.swift @@ -1,7 +1,7 @@ // // HUIEventProtocol.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIHostEventDecoder.swift b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIHostEventDecoder.swift index ba3aa0ef33..f0946920ea 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIHostEventDecoder.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUIHostEventDecoder.swift @@ -1,7 +1,7 @@ // // HUIHostEventDecoder.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUISurfaceEventDecoder.swift b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUISurfaceEventDecoder.swift index 6975c51553..69dc8c3215 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUISurfaceEventDecoder.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUIDecoder/HUISurfaceEventDecoder.swift @@ -1,7 +1,7 @@ // // HUISurfaceEventDecoder.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUIHost/HUIHost.swift b/Sources/MIDIKitControlSurfaces/HUI/HUIHost/HUIHost.swift index a8dfaf05b0..fafbfd6f28 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUIHost/HUIHost.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUIHost/HUIHost.swift @@ -1,7 +1,7 @@ // // HUIHost.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -11,9 +11,13 @@ import MIDIKitInternals /// Object representing a HUI host which can provide one or more HUI banks. /// Each bank can service a single HUI device and requires a MIDI input and output for each bank. /// -/// This object would typically be used by a desktop application such as a DAW (Digital Audio Workstation) which is the host. Remote HUI devices (physical HUI hardware or iPad apps that emulate HUI, for example) can then connect to the host through bidirectional MIDI (input and output). +/// This object would typically be used by a desktop application such as a DAW (Digital Audio +/// Workstation) which is the host. Remote HUI devices (physical HUI hardware or iPad apps that +/// emulate HUI, for example) can then connect to the host through bidirectional MIDI (input and +/// output). /// -/// > HUI (_Human User Interface for Digital Audio Workstations_) is a DAW control surface protocol developed by Mackie that uses MIDI events as its underlying encoding. +/// > HUI (_Human User Interface for Digital Audio Workstations_) is a DAW control surface protocol +/// developed by Mackie that uses MIDI events as its underlying encoding. /// > /// > References: /// > - [HUI Hardware Reference Guide](https://loudaudio.netx.net/portals/loud-public/#asset/9795) @@ -21,7 +25,10 @@ public final class HUIHost { /// HUI banks that are configured for this HUI host instance. public internal(set) var banks: [HUIHostBank] = [] - /// A HUI host transmits a ping message every 1 second to each of the remote surfaces that are configured to connect to it. So each bank will receive pings individually. HUI surfaces should respond with a ping-reply after each ping so that the host can maintain connection presence. + /// A HUI host transmits a ping message every 1 second to each of the remote surfaces that are + /// configured to connect to it. So each bank will receive pings individually. HUI surfaces + /// should respond with a ping-reply after each ping so that the host can maintain connection + /// presence. internal var pingTimer: SafeDispatchTimer? // MARK: - Init diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUIHost/HUIHostBank Transmit.swift b/Sources/MIDIKitControlSurfaces/HUI/HUIHost/HUIHostBank Transmit.swift index 97729077ca..d5f7adc64c 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUIHost/HUIHostBank Transmit.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUIHost/HUIHostBank Transmit.swift @@ -1,7 +1,7 @@ // // HUIHostBank Transmit.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore @@ -10,7 +10,8 @@ extension HUIHostBank { // MARK: - Ping /// Transmit a HUI ping message to the client surface. - /// It is not necessary to call this manually. The ``HUIHost`` object will handle ping transmission on an internal timer automatically. + /// It is not necessary to call this manually. The ``HUIHost`` object will handle ping + /// transmission on an internal timer automatically. internal func transmitPing() { let event = encodeHUIPing(to: .surface) midiOut(event) @@ -60,7 +61,8 @@ extension HUIHostBank { /// - Parameters: /// - channel: Channel strip number (`0 ... 7`). /// - side: Left or right side of the stereo meter. - /// - level: Level amount (`0x0 ... 0xC`). Where `0x0` is off, `0x1 ... 0xB` is signal level, and `0xC` is clipping (red LED). + /// - level: Level amount (`0x0 ... 0xC`). + /// Where `0x0` is off, `0x1 ... 0xB` is signal level, and `0xC` is clipping (red LED). public func transmitLevelMeter( channel: UInt4, side: HUISurfaceModel.StereoLevelMeter.Side, @@ -80,7 +82,10 @@ extension HUIHostBank { /// /// - Parameters: /// - vPot: V-Pot identity. - /// - value: Encoded value. When encoding host → surface, this is the LED preset index. When encoding surface → host, this is the delta rotary knob change value -/+ when the user turns the knob. + /// - value: Encoded value. + /// When encoding host → surface, this is the LED preset index. + /// When encoding surface → host, this is the delta rotary knob change + /// value -/+ when the user turns the knob. public func transmitVPot( _ vPot: HUIVPot, display: HUIVPotDisplay @@ -107,7 +112,11 @@ extension HUIHostBank { /// Transmit portion(s) of large display text (40 x 2 characters) to the client surface. /// - /// This text display is split into 8 slices of 10 characters each, with slices indexed `0 ... 3` for the top 40-character row, and `4 ... 7` for the bottom 40-character row. (This mirrors its raw HUI MIDI message encoding format.) Any of these slices may be sent at any time in any order. + /// This text display is split into 8 slices of 10 characters each, with slices + /// indexed `0 ... 3` for the top 40-character row, + /// and `4 ... 7` for the bottom 40-character row. + /// (This mirrors its raw HUI MIDI message encoding format.) + /// Any of these slices may be sent at any time in any order. /// /// - Parameters: /// - slices: Between 1 and 8 text slices of 10 characters each. @@ -134,7 +143,9 @@ extension HUIHostBank { /// Transmit some or all of the time display digits to the client surface. /// /// - Parameters: - /// - charsRightToLeft: Between 1 and 8 characters in reverse sequence order (first array element is rightmost digit). More than 8 characters will discarded and truncated to 8 characters. + /// - charsRightToLeft: Between 1 and 8 characters in reverse sequence order (first array + /// element is rightmost digit). More than 8 characters will discarded and truncated to 8 + /// characters. public func transmitTimeDisplay( charsRightToLeft: [HUITimeDisplayCharacter] ) { diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUIHost/HUIHostBank.swift b/Sources/MIDIKitControlSurfaces/HUI/HUIHost/HUIHostBank.swift index 1517d7761a..536c3b9e13 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUIHost/HUIHostBank.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUIHost/HUIHostBank.swift @@ -1,7 +1,7 @@ // // HUIHostBank.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -10,7 +10,9 @@ import MIDIKitInternals /// Object representing a ``HUIHost`` bank (connectable to one HUI surface over bidirectional MIDI). /// -/// This object is created and managed by ``HUIHost``. Do not instantiate this object directly. Instead, call ``HUIHost/addBank(huiEventHandler:midiOutHandler:remotePresenceChangedHandler:)`` to add banks to your ``HUIHost`` instance. +/// This object is created and managed by ``HUIHost``. Do not instantiate this object directly. +/// Instead, call ``HUIHost/addBank(huiEventHandler:midiOutHandler:remotePresenceChangedHandler:)`` +/// to add banks to your ``HUIHost`` instance. public final class HUIHostBank { // MARK: - Decoder @@ -34,9 +36,11 @@ public final class HUIHostBank { // MARK: - Presence - /// Time duration to wait since the last ping received before transitioning ``isRemotePresent`` to `false`. + /// Time duration to wait since the last ping received before transitioning ``isRemotePresent`` + /// to `false`. /// - /// HUI pings are sent from the host to surface(s) every 1 second. A timeout duration between 2 ... 5 seconds is reasonable depending on desired leeway. + /// HUI pings are sent from the host to surface(s) every 1 second. + /// A timeout duration between `2 ... 5` seconds is reasonable depending on desired leeway. public var remotePresenceTimeout: TimeInterval = 2.0 { didSet { // validate diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUIHostEvent/HUIHostEvent Encode.swift b/Sources/MIDIKitControlSurfaces/HUI/HUIHostEvent/HUIHostEvent Encode.swift index fd7ca9a2f6..57f7667849 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUIHostEvent/HUIHostEvent Encode.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUIHostEvent/HUIHostEvent Encode.swift @@ -1,7 +1,7 @@ // // HUIHostEvent Encode.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUIHostEvent/HUIHostEvent.swift b/Sources/MIDIKitControlSurfaces/HUI/HUIHostEvent/HUIHostEvent.swift index 8b94182f64..be3e392530 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUIHostEvent/HUIHostEvent.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUIHostEvent/HUIHostEvent.swift @@ -1,13 +1,14 @@ // // HUIHostEvent.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore /// HUI Host Event: basic HUI host message definition. -/// These events are sent from the host to the client surface to update state of the surface: fader levels, text displays, LEDs, and even triggering beep sounds. +/// These events are sent from the host to the client surface to update state of the surface: fader +/// levels, text displays, LEDs, and even triggering beep sounds. public enum HUIHostEvent: Equatable, Hashable { /// HUI ping message. case ping @@ -44,9 +45,12 @@ public enum HUIHostEvent: Equatable, Hashable { /// Time Display digits. /// - /// Between one and 8 digits, indexed in the array from right-to-left of the actual display. (Index 0 is the rightmost character). + /// Between one and 8 digits, indexed in the array from right-to-left of the actual display. + /// (Index 0 is the rightmost character). /// - /// This is because HUI encodes time display digits in reverse order since the digits on the righthand side of a time display will update most frequently, which allows conservation of data bandwidth when transmitting frequent time display changes. + /// This is because HUI encodes time display digits in reverse order since the digits on the + /// righthand side of a time display will update most frequently, which allows conservation of + /// data bandwidth when transmitting frequent time display changes. case timeDisplay(charsRightToLeft: [HUITimeDisplayCharacter]) /// Select Assign 4-character text display. diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurface/HUISurface Transmit.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurface/HUISurface Transmit.swift index 48451bd79d..864367289b 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurface/HUISurface Transmit.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurface/HUISurface Transmit.swift @@ -1,14 +1,15 @@ // // HUISurface Transmit.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore extension HUISurface { /// Transmit a HUI ping message to the host. - /// It is not necessary to call this manually. The ``HUISurface`` object will handle ping replies automatically. + /// It is not necessary to call this manually. The ``HUISurface`` object will handle ping + /// replies automatically. internal func transmitPing() { let event = encodeHUIPing(to: .host) midiOut(event) diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurface/HUISurface.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurface/HUISurface.swift index 655c1ccb94..12a9f280f7 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurface/HUISurface.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurface/HUISurface.swift @@ -1,18 +1,22 @@ // // HUISurface.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation import MIDIKitCore import MIDIKitInternals -/// Object representing a single HUI control surface device, holding a model of its state and providing granular update notifications. +/// Object representing a single HUI control surface device, holding a model of its state and +/// providing granular update notifications. /// -/// This object would typically be used by a client application (ie: a control surface application on an iPad) in order to manage state of a HUI surface. It interfaces with HUI host software/hardware through bidirectional MIDI (input and output). +/// This object would typically be used by a client application (ie: a control surface application +/// on an iPad) in order to manage state of a HUI surface. It interfaces with HUI host +/// software/hardware through bidirectional MIDI (input and output). /// -/// > HUI (_Human User Interface for Digital Audio Workstations_) is a DAW control surface protocol developed by Mackie that uses MIDI events as its underlying encoding. +/// > HUI (_Human User Interface for Digital Audio Workstations_) is a DAW control surface protocol +/// developed by Mackie that uses MIDI events as its underlying encoding. /// > /// > References: /// > - [HUI Hardware Reference Guide](https://loudaudio.netx.net/portals/loud-public/#asset/9795) @@ -22,7 +26,8 @@ public final class HUISurface { /// HUI control surface state model. /// Represents state of an entire HUI control surface (all controls, display elements, etc.). /// - /// This property is observable with Combine/SwiftUI and can trigger UI updates upon changes when ``HUISurface`` is instanced as a `@ObservedObject var`. + /// This property is observable with Combine/SwiftUI and can trigger UI updates upon changes + /// when ``HUISurface`` is instanced as a `@ObservedObject var`. public internal(set) var model: HUISurfaceModel { willSet { if #available(macOS 10.15, macCatalyst 13, iOS 13, tvOS 13.0, watchOS 6.0, *) { @@ -42,10 +47,12 @@ public final class HUISurface { (_ notification: HUISurfaceModelNotification) -> Void ) - /// Notification handler that is called as a result of the ``model`` being updated from received HUI events. + /// Notification handler that is called as a result of the ``model`` being updated from received + /// HUI events. public var modelNotificationHandler: ModelNotificationHandler? - /// Notification handler will always be called even when a received HUI MIDI event from host does not result in a change to the HUI surface state model. + /// Notification handler will always be called even when a received HUI MIDI event from host + /// does not result in a change to the HUI surface state model. public var alwaysNotify: Bool = false /// Remote presence state change handler (when pings resume or cease after timeout). @@ -58,9 +65,11 @@ public final class HUISurface { // MARK: - Presence - /// Time duration to wait since the last ping received before transitioning ``isRemotePresent`` to `false`. + /// Time duration to wait since the last ping received before transitioning ``isRemotePresent`` + /// to `false`. /// - /// HUI pings are sent from the host to surface(s) every 1 second. A timeout duration between 2 ... 5 seconds is reasonable depending on desired leeway. + /// HUI pings are sent from the host to surface(s) every 1 second. A timeout duration between 2 + /// ... 5 seconds is reasonable depending on desired leeway. public var remotePresenceTimeout: TimeInterval = 2.0 { didSet { // validate @@ -180,14 +189,14 @@ extension HUISurface: ReceivesMIDIEvents { public func midiIn(event: MIDIEvent) { // capture MIDI Device Inquiry first switch event { - case .deviceInquiryRequest(deviceID: 0x00), - .deviceInquiryRequest(deviceID: 0x7F): + case .deviceInquiryRequest(deviceID: 0x00), + .deviceInquiryRequest(deviceID: 0x7F): let diResponse = MIDIEvent.deviceInquiryResponse( deviceID: 0x00, manufacturer: HUIConstants.kMIDI.kSysEx.kManufacturer, deviceFamilyCode: 0x05, // TODO: needs correct value deviceFamilyMemberCode: 0x00, // TODO: needs correct value - softwareRevision: (1,0,0,0) // TODO: needs correct value + softwareRevision: (1, 0, 0, 0) // TODO: needs correct value ) midiOut(diResponse) default: diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurface/HUISurfaceStateProtocol.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurface/HUISurfaceStateProtocol.swift index 6dd9a5b5bf..cc2875812a 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurface/HUISurfaceStateProtocol.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurface/HUISurfaceStateProtocol.swift @@ -1,7 +1,7 @@ // // HUISurfaceStateProtocol.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceEvent/HUISurfaceEvent Encode.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceEvent/HUISurfaceEvent Encode.swift index 7382ea3a73..71846d8855 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceEvent/HUISurfaceEvent Encode.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceEvent/HUISurfaceEvent Encode.swift @@ -1,7 +1,7 @@ // // HUISurfaceEvent Encode.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceEvent/HUISurfaceEvent.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceEvent/HUISurfaceEvent.swift index 903d2eb9ff..7b95b99c58 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceEvent/HUISurfaceEvent.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceEvent/HUISurfaceEvent.swift @@ -1,13 +1,15 @@ // // HUISurfaceEvent.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore /// HUI Surface Event: basic HUI surface message definition. -/// These events are sent from the client surface to the host as a result of user interaction with the surface: when the user moves a fader, turns a V-Pot knob, presses a button, or otherwise interacts with any aspect of the surface. +/// These events are sent from the client surface to the host as a result of user interaction with +/// the surface: when the user moves a fader, turns a V-Pot knob, presses a button, or otherwise +/// interacts with any aspect of the surface. public enum HUISurfaceEvent: Equatable, Hashable { /// HUI ping message. case ping diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModel Accessors.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModel Accessors.swift index 039a835b27..3ad714bd92 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModel Accessors.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModel Accessors.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel Accessors.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -11,7 +11,8 @@ extension HUISurfaceModel: HUISurfaceStateProtocol { /// Returns the current state in the model of the given HUI switch parameter. /// - /// > Reading state of ``HUISwitch/undefined(zone:port:)`` will always return `false` as state is not stored for undefined switches. + /// > Reading state of ``HUISwitch/undefined(zone:port:)`` will always return `false` as state + /// is not stored for undefined switches. public func state(of huiSwitch: Switch) -> Bool { switch huiSwitch { case let .channelStrip(channel, subParam): @@ -73,7 +74,8 @@ extension HUISurfaceModel: HUISurfaceStateProtocol { /// Sets the state in the model of the given HUI switch parameter. /// - /// > Setting state for ``HUISwitch/undefined(zone:port:)`` has no effect and will not be stored. + /// > Setting state for ``HUISwitch/undefined(zone:port:)`` has no effect and will not be + /// stored. public mutating func setState(of huiSwitch: Switch, to state: Bool) { switch huiSwitch { case let .channelStrip(channel, subParam): @@ -135,7 +137,8 @@ extension HUISurfaceModel: HUISurfaceStateProtocol { /// Returns the current LED display state in the model of the given HUI V-Pot. /// - /// > The rotary scroll knob in the DSP Edit/Assign section does not have an LED ring display, so default will always be returned. + /// > The rotary scroll knob in the DSP Edit/Assign section does not have an LED ring display, + /// so default will always be returned. public func state(of vPot: HUIVPot) -> HUIVPotDisplay { switch vPot { case let .channel(channel): diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModel Update.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModel Update.swift index d369c488f5..42a1c986cf 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModel Update.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModel Update.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel Update.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -10,15 +10,21 @@ import MIDIKitCore // MARK: - Main Update Method extension HUISurfaceModel { - /// Updates HUI state from a received ``HUIHostEvent`` (returned from ``HUIHostEventDecoder`` after parsing incoming HUI MIDI). - /// The corresponding granular ``HUISurfaceModelNotification`` is then returned containing the result of the model change. + /// Updates HUI state from a received ``HUIHostEvent`` (returned from ``HUIHostEventDecoder`` + /// after parsing incoming HUI MIDI). + /// The corresponding granular ``HUISurfaceModelNotification`` is then returned containing the + /// result of the model change. /// - /// > This is a utility method provided for custom implementations. When using ``HUIHost``/``HUIHostBank`` it is not necessary to call this method as it will be handled automatically. + /// > This is a utility method provided for custom implementations. When using + /// ``HUIHost``/``HUIHostBank`` it is not necessary to call this method as it will be handled + /// automatically. /// /// - Parameters: /// - receivedEvent: The incoming ``HUIHostEvent``. - /// - alwaysNotify: Always generate a ``HUISurfaceModelUpdateResult/changed(_:)`` notification even if the state update results in no change to the model. - /// - Returns: The strongly-typed ``HUISurfaceModelNotification`` containing the result of the state change. + /// - alwaysNotify: Always generate a ``HUISurfaceModelUpdateResult/changed(_:)`` notification + /// even if the state update results in no change to the model. + /// - Returns: The strongly-typed ``HUISurfaceModelNotification`` containing the result of the + /// state change. @discardableResult public mutating func updateState( from receivedEvent: HUIHostEvent, diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModel.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModel.swift index ac289ff038..9e91f9096e 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModel.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModel.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// HUI State Model. @@ -10,7 +10,8 @@ /// /// The same model is used for: /// - The main control surface unit (including extra functions and control room section) -/// - Any additional 8-fader bank extension units (except that the extra functions that don't exist on these hardware units simply don't apply and are ignored) +/// - Any additional 8-fader bank extension units (except that the extra functions that don't exist +/// on these hardware units simply don't apply and are ignored) public struct HUISurfaceModel: Equatable, Hashable { // MARK: - State Storage diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModelUpdateResult.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModelUpdateResult.swift index 04a4d2ae66..b900090adb 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModelUpdateResult.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/HUISurfaceModelUpdateResult.swift @@ -1,12 +1,12 @@ // // HUISurfaceModelUpdateResult.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation -/// Result returned from ``HUISurfaceModel/updateState(from:)``. +/// Result returned from ``HUISurfaceModel/updateState(from:alwaysNotify:)``. public enum HUISurfaceModelUpdateResult { /// The received HUI host event resulted in a change to the HUI surface model. case changed(HUISurfaceModelNotification) diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Assign.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Assign.swift index d75b2ad54b..a362900577 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Assign.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Assign.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel Assign.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel AutoEnable.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel AutoEnable.swift index 3242953d18..aac94e66c4 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel AutoEnable.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel AutoEnable.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel AutoEnable.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel AutoMode.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel AutoMode.swift index d9ae8a588c..70d67ae392 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel AutoMode.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel AutoMode.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel AutoMode.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel BankMove.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel BankMove.swift index d1e6c0cb46..4a36218435 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel BankMove.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel BankMove.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel BankMove.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ChannelStrip Fader.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ChannelStrip Fader.swift index 861fbeaee2..643593c670 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ChannelStrip Fader.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ChannelStrip Fader.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel ChannelStrip Fader.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -36,4 +36,5 @@ extension HUISurfaceModel.ChannelStrip { } } -// HUISurfaceStateProtocol conformance is on HUISurfaceModel.ChannelStrip and it handles the `.touched` switch property there, so we don't need a setter/getter here +// HUISurfaceStateProtocol conformance is on HUISurfaceModel.ChannelStrip and it handles the +// `.touched` switch property there, so we don't need a setter/getter here diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ChannelStrip.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ChannelStrip.swift index 9ec8b47498..970ce85302 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ChannelStrip.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ChannelStrip.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel ChannelStrip.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ControlRoom.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ControlRoom.swift index 70f6cb1143..33bfee50a9 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ControlRoom.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ControlRoom.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel ControlRoom.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Cursor.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Cursor.swift index 7380f5d4af..45ae4dd01f 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Cursor.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Cursor.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel Cursor.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Edit.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Edit.swift index db06dd4253..3ee40c8f42 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Edit.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Edit.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel Edit.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel FootswitchesAndSounds.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel FootswitchesAndSounds.swift index d105ecfc7e..8e0e7ca302 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel FootswitchesAndSounds.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel FootswitchesAndSounds.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel FootswitchesAndSounds.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel FunctionKey.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel FunctionKey.swift index cdfae3aa91..477b66f0a7 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel FunctionKey.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel FunctionKey.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel FunctionKey.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel HotKeys.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel HotKeys.swift index 7578f90967..c013168c5a 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel HotKeys.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel HotKeys.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel HotKeys.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel LargeDisplay.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel LargeDisplay.swift index bba0aedefe..91b3287370 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel LargeDisplay.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel LargeDisplay.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel LargeDisplay.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -27,7 +27,8 @@ extension HUISurfaceModel { // MARK: - Internal Methods /// Internal: - /// Get or set the 8 individual 10-character string slices that make up the large display contents. + /// Get or set the 8 individual 10-character string slices that make up + /// the large display contents. /// When encoded in a HUI message, these are indexed 0 through 7. var slices: HUILargeDisplaySlices { get { diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel NumPad.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel NumPad.swift index d08a7694a2..1883c1cfc0 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel NumPad.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel NumPad.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel NumPad.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ParameterEdit.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ParameterEdit.swift index 793c3c8c4b..2ec38c00da 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ParameterEdit.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel ParameterEdit.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel ParameterEdit.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel StatusAndGroup.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel StatusAndGroup.swift index 8b014e58ee..4e1c491e71 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel StatusAndGroup.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel StatusAndGroup.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel StatusAndGroup.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel StereoLevelMeter.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel StereoLevelMeter.swift index 01a6ab4b51..6885ac4e9c 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel StereoLevelMeter.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel StereoLevelMeter.swift @@ -1,15 +1,17 @@ // // HUISurfaceModel StereoLevelMeter.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation extension HUISurfaceModel { - /// State storage representing the state of a channel strip's stereo level meter on the meter bridge. + /// State storage representing the state of a channel strip's stereo level meter on the meter + /// bridge. /// - /// As value increases, all LEDs up to and including that value will illuminate, representing an audio level meter with 12 LED segments. A value of `0x0` indicates no LEDs are illuminated. + /// As value increases, all LEDs up to and including that value will illuminate, representing an + /// audio level meter with 12 LED segments. A value of `0x0` indicates no LEDs are illuminated. /// /// Value Level LED Segment /// ----- ---------- ----------------- @@ -30,7 +32,9 @@ extension HUISurfaceModel { public struct StereoLevelMeter: Equatable, Hashable { /// Left Meter Channel. /// - /// As value increases, all LEDs up to and including that value will illuminate, representing an audio level meter with 12 LED segments. A value of `0x0` indicates no LEDs are illuminated. + /// As value increases, all LEDs up to and including that value will illuminate, + /// representing an audio level meter with 12 LED segments. A value of `0x0` indicates no + /// LEDs are illuminated. /// /// Value Level LED Segment /// ----- ---------- ----------------- @@ -58,7 +62,9 @@ extension HUISurfaceModel { /// Right Meter Channel. /// - /// As value increases, all LEDs up to and including that value will illuminate, representing an audio level meter with 12 LED segments. A value of `0x0` indicates no LEDs are illuminated. + /// As value increases, all LEDs up to and including that value will illuminate, + /// representing an audio level meter with 12 LED segments. A value of `0x0` indicates no + /// LEDs are illuminated. /// /// Value Level LED Segment /// ----- ---------- ----------------- diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel TimeDisplay.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel TimeDisplay.swift index 78e3e94e15..6c30936bd6 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel TimeDisplay.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel TimeDisplay.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel TimeDisplay.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -11,7 +11,8 @@ extension HUISurfaceModel { public struct TimeDisplay: Equatable, Hashable { /// HUI time display string, comprised of 8 digits. /// - /// The time display consists of eight 7-segment displays (called digits). Every digit except the last (rightmost) has the ability to show a trailing decimal point (dot). + /// The time display consists of eight 7-segment displays (called digits). Every digit + /// except the last (rightmost) has the ability to show a trailing decimal point (dot). public var timeString: HUITimeDisplayString = .init() // LEDs diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Transport.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Transport.swift index ce64db4caf..87e7005444 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Transport.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel Transport.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel Transport.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel WindowFunctions.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel WindowFunctions.swift index aac63c9bf7..3fdcf89328 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel WindowFunctions.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModel/Storage/HUISurfaceModel WindowFunctions.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel WindowFunctions.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModelNotification/HUISurfaceModelNotification ChannelStripComponent.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModelNotification/HUISurfaceModelNotification ChannelStripComponent.swift index a06ecadfa7..90a4b756a7 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModelNotification/HUISurfaceModelNotification ChannelStripComponent.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModelNotification/HUISurfaceModelNotification ChannelStripComponent.swift @@ -1,7 +1,7 @@ // // HUISurfaceModelNotification ChannelStripComponent.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModelNotification/HUISurfaceModelNotification ParamEditComponent.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModelNotification/HUISurfaceModelNotification ParamEditComponent.swift index 5108490681..a27bec3e54 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModelNotification/HUISurfaceModelNotification ParamEditComponent.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModelNotification/HUISurfaceModelNotification ParamEditComponent.swift @@ -1,7 +1,7 @@ // // HUISurfaceModelNotification ParamEditComponent.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModelNotification/HUISurfaceModelNotification.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModelNotification/HUISurfaceModelNotification.swift index a75c8a4abe..ac7ebcd624 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModelNotification/HUISurfaceModelNotification.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISurfaceModelNotification/HUISurfaceModelNotification.swift @@ -1,12 +1,14 @@ // // HUISurfaceModelNotification.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore -/// Notification returned as a result of updating ``HUISurfaceModel`` state. Strongly-typed event abstractions representing each control and display element of a HUI control surface along with its new state value. +/// Notification returned as a result of updating ``HUISurfaceModel`` state. Strongly-typed event +/// abstractions representing each control and display element of a HUI control surface along with +/// its new state value. public enum HUISurfaceModelNotification: Hashable { // MARK: Ping diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Assign.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Assign.swift index bf427a9e6c..ee88851403 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Assign.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Assign.swift @@ -1,7 +1,7 @@ // // HUISwitch Assign.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch AutoEnable.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch AutoEnable.swift index 1ca86c8cc6..d424837d42 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch AutoEnable.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch AutoEnable.swift @@ -1,7 +1,7 @@ // // HUISwitch AutoEnable.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch AutoMode.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch AutoMode.swift index d8c99d7c31..6fd1285ac8 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch AutoMode.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch AutoMode.swift @@ -1,7 +1,7 @@ // // HUISwitch AutoMode.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch BankMove.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch BankMove.swift index 5953b13cd2..3a00678fec 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch BankMove.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch BankMove.swift @@ -1,7 +1,7 @@ // // HUISwitch BankMove.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch ChannelStrip.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch ChannelStrip.swift index 8974490369..ec928a7251 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch ChannelStrip.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch ChannelStrip.swift @@ -1,7 +1,7 @@ // // HUISwitch ChannelStrip.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -40,8 +40,10 @@ extension HUISwitch.ChannelStrip: HUISwitchProtocol { public var zoneAndPort: HUIZoneAndPort { // note: zone (channel number) will be provided when accessed from `HUISwitch.zoneAndPort` - // this method is only here to fulfill the HUISwitchProtocol protocol requirement, it's not actually used (and should not actually be used) - // if it is ever used, the channel (0x00) provided here should be replaced with the channel strip number (0x00 ... 0x07) after calling this method + // this method is only here to fulfill the HUISwitchProtocol protocol requirement, it's not + // actually used (and should not actually be used) + // if it is ever used, the channel (0x00) provided here should be replaced with the channel + // strip number (0x00 ... 0x07) after calling this method (0x00, port) } diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch ControlRoom.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch ControlRoom.swift index b9c05cdd40..13668861ec 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch ControlRoom.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch ControlRoom.swift @@ -1,7 +1,7 @@ // // HUISwitch ControlRoom.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Cursor.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Cursor.swift index 1cc032310b..9fc36b321f 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Cursor.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Cursor.swift @@ -1,7 +1,7 @@ // // HUISwitch Cursor.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Edit.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Edit.swift index d9aaac450b..9fff2fd556 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Edit.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Edit.swift @@ -1,7 +1,7 @@ // // HUISwitch Edit.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch FootswitchesAndSounds.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch FootswitchesAndSounds.swift index 5316dc5e93..cf505864bc 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch FootswitchesAndSounds.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch FootswitchesAndSounds.swift @@ -1,7 +1,7 @@ // // HUISwitch FootswitchesAndSounds.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch FunctionKey.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch FunctionKey.swift index 4def64b6c4..cf6d7b3ff7 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch FunctionKey.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch FunctionKey.swift @@ -1,7 +1,7 @@ // // HUISwitch FunctionKey.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch HotKey.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch HotKey.swift index 003d9fb426..0a2cd18551 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch HotKey.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch HotKey.swift @@ -1,7 +1,7 @@ // // HUISwitch HotKey.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch NumPad.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch NumPad.swift index dd7dafac50..82e2f0b0bf 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch NumPad.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch NumPad.swift @@ -1,7 +1,7 @@ // // HUISwitch NumPad.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch ParameterEdit.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch ParameterEdit.swift index 411527eeb7..5006d71615 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch ParameterEdit.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch ParameterEdit.swift @@ -1,7 +1,7 @@ // // HUISwitch ParameterEdit.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch StatusAndGroup.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch StatusAndGroup.swift index c125b7c311..1a344f0991 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch StatusAndGroup.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch StatusAndGroup.swift @@ -1,7 +1,7 @@ // // HUISwitch StatusAndGroup.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch TimeDisplayStatus.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch TimeDisplayStatus.swift index 490a48bc5e..46ae8c9449 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch TimeDisplayStatus.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch TimeDisplayStatus.swift @@ -1,7 +1,7 @@ // // HUISwitch TimeDisplayStatus.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -10,15 +10,18 @@ extension HUISwitch { /// Time Display LEDs. public enum TimeDisplayStatus: Equatable, Hashable { /// "TIME CODE" - /// Time format LEDs that are to the left of the main time display above the control room section (no button, LED only). + /// Time format LEDs that are to the left of the main time display above the control room + /// section (no button, LED only). case timecode /// "FEET" - /// Time format LEDs that are to the left of the main time display above the control room section (no button, LED only). + /// Time format LEDs that are to the left of the main time display above the control room + /// section (no button, LED only). case feet /// "BEATS" - /// Time format LEDs that are to the left of the main time display above the control room section (no button, LED only). + /// Time format LEDs that are to the left of the main time display above the control room + /// section (no button, LED only). case beats /// "RUDE SOLO LIGHT" diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Transport.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Transport.swift index 8dbea24d86..bd34e7d5c6 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Transport.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Transport.swift @@ -1,7 +1,7 @@ // // HUISwitch Transport.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Window.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Window.swift index c36b014620..cc77c15a6c 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Window.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch Window.swift @@ -1,7 +1,7 @@ // // HUISwitch Window.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch.swift index 3c05fb31a6..3cef58bf3e 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitch/HUISwitch.swift @@ -1,19 +1,27 @@ // // HUISwitch.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation import MIDIKitCore /// HUI Switch. -/// Identifiers for all possible HUI toggle/boolean controls: Buttons, LEDs, and auxiliary capabilities like external footswitch toggles and beep sounds. These are all collectively referred to as HUI switches. +/// Identifiers for all possible HUI toggle/boolean controls: Buttons, LEDs, and auxiliary +/// capabilities like external footswitch toggles and beep sounds. These are all collectively +/// referred to as HUI switches. /// -/// > Note: Not all switches are relevant for both host and surface. Some only apply to one or the other. But most apply to both. +/// > Note: Not all switches are relevant for both host and surface. Some only apply to one or the +/// other. But most apply to both. /// > /// > - An LED has a state of on (`true`) and off (`false`). -/// > - When a user engages a switch on a HUI control surface (ie: presses a button or touches a fader cap) it has a state of pressed/touched (`true`) and unpressed/untouched (`false`). Which means if a user momentarily pushes and releases a button it will result in two immediately successive `true` then `false` state messages. If a user presses and holds a button, it will result in a `true` state message upon press and then the `false` state message only upon button release. +/// > - When a user engages a switch on a HUI control surface (ie: presses a button or touches a +/// fader cap) it has a state of pressed/touched (`true`) and unpressed/untouched (`false`). Which +/// means if a user momentarily pushes and releases a button it will result in two immediately +/// successive `true` then `false` state messages. If a user presses and holds a button, it will +/// result in a `true` state message upon press and then the `false` state message only upon button +/// release. public enum HUISwitch: Equatable, Hashable { /// Channel strip component. case channelStrip(UInt4, ChannelStrip) diff --git a/Sources/MIDIKitControlSurfaces/HUI/HUISwitchProtocol.swift b/Sources/MIDIKitControlSurfaces/HUI/HUISwitchProtocol.swift index c8fbb1ac4a..008d59e413 100644 --- a/Sources/MIDIKitControlSurfaces/HUI/HUISwitchProtocol.swift +++ b/Sources/MIDIKitControlSurfaces/HUI/HUISwitchProtocol.swift @@ -1,7 +1,7 @@ // // HUISwitchProtocol.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitControlSurfaces/MIDIKitControlSurfaces.swift b/Sources/MIDIKitControlSurfaces/MIDIKitControlSurfaces.swift index 81b25312c4..ccda257963 100644 --- a/Sources/MIDIKitControlSurfaces/MIDIKitControlSurfaces.swift +++ b/Sources/MIDIKitControlSurfaces/MIDIKitControlSurfaces.swift @@ -1,7 +1,7 @@ // // MIDIKitControlSurfaces.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // @_exported import MIDIKitCore diff --git a/Sources/MIDIKitControlSurfaces/Utilities/Logger.swift b/Sources/MIDIKitControlSurfaces/Utilities/Logger.swift index fd09a239f2..af6f02537d 100644 --- a/Sources/MIDIKitControlSurfaces/Utilities/Logger.swift +++ b/Sources/MIDIKitControlSurfaces/Utilities/Logger.swift @@ -1,7 +1,7 @@ // // Logger.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import os.log diff --git a/Sources/MIDIKitCore/API Evolution/MIDIKit-0.6.0.swift b/Sources/MIDIKitCore/API Evolution/MIDIKit-0.6.0.swift index 2d28b13c17..e95969c76f 100644 --- a/Sources/MIDIKitCore/API Evolution/MIDIKit-0.6.0.swift +++ b/Sources/MIDIKitCore/API Evolution/MIDIKit-0.6.0.swift @@ -1,224 +1,13 @@ // // MIDIKit-0.6.0.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation // Symbols that were renamed or removed. -// NOTE: This is not by any means exhaustive, as nearly every symbol had namespace changes from 0.5.x -> 0.6.0 but the most common symbols are covered here to help guide code migration. - -@available( - *, deprecated, - message: "💡 The MIDI namespace has been removed as of MIDIKit 0.6.0. First-generation nested symbols have adopted a MIDI prefix instead. For example: MIDI.Event has become MIDIEvent, MIDI.IO.Manager has become MIDIManager." -) -public enum MIDI { - // MARK: Types - - public typealias UInt4 = MIDIKitCore.UInt4 - public typealias UInt7 = MIDIKitCore.UInt7 - public typealias UInt9 = MIDIKitCore.UInt9 - public typealias UInt14 = MIDIKitCore.UInt14 - public typealias UInt25 = MIDIKitCore.UInt25 - - @available(*, unavailable, renamed: "UInt8") - public typealias Byte = UInt8 - - @available(*, unavailable, renamed: "UInt4") - public typealias Nibble = UInt4 - - public typealias UMPWord = MIDIKitCore.UMPWord - - // MARK: Event - @available( - *, unavailable, - message: "The `MIDI.Event` namespace has been removed and first-generation nested types have been renamed `MIDIEvent.NoteOn`, `MIDIEvent.NoteOff`, etc." - ) - public enum Event { - case noteOn(Note.On) - case noteOff(Note.Off) - case noteCC(Note.CC) - case notePitchBend(Note.PitchBend) - case notePressure(Note.Pressure) - case noteManagement(Note.Management) - case cc(CC) - case programChange(ProgramChange) - case pitchBend(PitchBend) - case pressure(Pressure) - case sysEx7(SysEx7) - case universalSysEx7(UniversalSysEx7) - case sysEx8(SysEx8) - case universalSysEx8(UniversalSysEx8) - case timecodeQuarterFrame(TimecodeQuarterFrame) - case songPositionPointer(SongPositionPointer) - case songSelect(SongSelect) - case unofficialBusSelect(UnofficialBusSelect) - case tuneRequest(TuneRequest) - case timingClock(TimingClock) - case start(Start) - case `continue`(Continue) - case stop(Stop) - case activeSensing(ActiveSensing) - case systemReset(SystemReset) - case noOp(NoOp) - case jrClock(JRClock) - case jrTimestamp(JRTimestamp) - - // MARK: Static constructors - - public static func noteOn( - _ note: UInt7, - velocity: MIDIEvent.NoteVelocity, - attribute: MIDIEvent.NoteAttribute = .none, - channel: UInt4, - group: UInt4 = 0x0, - midi1ZeroVelocityAsNoteOff: Bool = true - ) -> Self { fatalError() } - - public static func noteOn( - _ note: MIDINote, - velocity: MIDIEvent.NoteVelocity, - attribute: MIDIEvent.NoteAttribute = .none, - channel: UInt4, - group: UInt4 = 0x0, - midi1ZeroVelocityAsNoteOff: Bool = true - ) -> Self { fatalError() } - - // MARK: Note - - @available( - *, unavailable, - message: "The `MIDI.Event.Note` namespace has been removed and first-generation nested types have been renamed `MIDIEvent.NoteOn`, `MIDIEvent.NoteOff`, etc." - ) - public enum Note { - @available(*, unavailable, message: "Renamed to MIDIEvent.NoteOn") - public struct On { - public init( - note: UInt7, - velocity: MIDIEvent.NoteVelocity, - attribute: MIDIEvent.NoteAttribute = .none, - channel: UInt4, - group: UInt4 = 0x0, - midi1ZeroVelocityAsNoteOff: Bool = true - ) { fatalError() } - - public init( - note: MIDINote, - velocity: MIDIEvent.NoteVelocity, - attribute: MIDIEvent.NoteAttribute = .none, - channel: UInt4, - group: UInt4 = 0x0, - midi1ZeroVelocityAsNoteOff: Bool = true - ) { fatalError() } - } - - @available(*, unavailable, message: "Renamed to MIDIEvent.NoteOff") - public struct Off { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.NoteCC") - public struct CC { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.PitchBend") - public struct PitchBend { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.Pressure") - public struct Pressure { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.Management") - public struct Management { } - } - - @available(*, unavailable, message: "Renamed to MIDIEvent.CC") - public enum CC { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.ProgramChange") - public enum ProgramChange { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.PitchBend") - public enum PitchBend { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.Pressure") - public enum Pressure { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.SysEx7") - public enum SysEx7 { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.UniversalSysEx7") - public enum UniversalSysEx7 { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.SysEx8") - public enum SysEx8 { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.UniversalSysEx8") - public enum UniversalSysEx8 { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.TimecodeQuarterFrame") - public enum TimecodeQuarterFrame { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.SongPositionPointer") - public enum SongPositionPointer { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.SongSelect") - public enum SongSelect { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.UnofficialBusSelect") - public enum UnofficialBusSelect { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.TuneRequest") - public enum TuneRequest { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.TimingClock") - public enum TimingClock { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.Start") - public enum Start { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.Continue") - public enum Continue { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.Stop") - public enum Stop { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.ActiveSensing") - public enum ActiveSensing { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.SystemReset") - public enum SystemReset { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.NoOp") - public enum NoOp { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.JRClock") - public enum JRClock { } - - @available(*, unavailable, message: "Renamed to MIDIEvent.JRTimestamp") - public enum JRTimestamp { } - } - - // MARK: Note - - @available(*, unavailable, message: "Renamed to MIDINote") - public struct Note { - public var number: UInt7 = 0 - public var style: MIDINote.Style = .yamaha - } - - // MARK: Utilities - Atomic - - @available( - *, - unavailable, - message: "Renamed to top-level @ThreadSafeAccess in MIDIKitInternals target" - ) - @propertyWrapper - public final class Atomic { - public init(wrappedValue value: T) { fatalError() } - public var wrappedValue: T { fatalError() } - } -} - // MARK: Category Extensions for Type conversion extension BinaryInteger { diff --git a/Sources/MIDIKitCore/API/MIDIProtocolVersion.swift b/Sources/MIDIKitCore/API/MIDIProtocolVersion.swift index e10ff63a62..f330e5aef3 100644 --- a/Sources/MIDIKitCore/API/MIDIProtocolVersion.swift +++ b/Sources/MIDIKitCore/API/MIDIProtocolVersion.swift @@ -1,21 +1,26 @@ // // MIDIProtocolVersion.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// MIDI protocol version. public enum MIDIProtocolVersion: Equatable, Hashable { /// MIDI 1.0 /// - /// MIDI 1.0 defines the original MIDI specification as ratified in the mid-1980s with minor revisions through 1996. + /// MIDI 1.0 defines the original MIDI specification as ratified in the mid-1980s with minor + /// revisions through 1996. case _1_0 /// MIDI 2.0 /// - /// MIDI 2.0 defines new packet formats and events over top of the MIDI 1.0 specification and underlying transport. + /// MIDI 2.0 defines new packet formats and events over top of the MIDI 1.0 specification and + /// underlying transport. /// - /// > TMA (The MIDI Association) states: "MIDI 2.0 is an extension of MIDI 1.0. It does not replace MIDI 1.0 but builds on the core principles, architecture, and semantics of MIDI 1.0. MIDI 2.0 is not a stand-alone specification. Manufacturers and developers must have a thorough understanding of MIDI 1.0 in order to implement MIDI 2.0. + /// > TMA (The MIDI Association) states: "MIDI 2.0 is an extension of MIDI 1.0. It does not + /// replace MIDI 1.0 but builds on the core principles, architecture, and semantics of MIDI 1.0. + /// MIDI 2.0 is not a stand-alone specification. Manufacturers and developers must have a + /// thorough understanding of MIDI 1.0 in order to implement MIDI 2.0. case _2_0 } diff --git a/Sources/MIDIKitCore/Events/API Evolution/MIDIKit-0.4.12.swift b/Sources/MIDIKitCore/Events/API Evolution/MIDIKit-0.4.12.swift index 82bb334880..ea3d844331 100644 --- a/Sources/MIDIKitCore/Events/API Evolution/MIDIKit-0.4.12.swift +++ b/Sources/MIDIKitCore/Events/API Evolution/MIDIKit-0.4.12.swift @@ -1,7 +1,7 @@ // // MIDIKit-0.4.12.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -34,7 +34,9 @@ extension MIDIEvent { ) } - /// Parse a complete raw MIDI 1.0 System Exclusive 7 message and return a ``sysEx7(manufacturer:data:group:)`` or ``universalSysEx7(universalType:deviceID:subID1:subID2:data:group:)`` case if successful. + /// Parse a complete raw MIDI 1.0 System Exclusive 7 message and return a + /// ``sysEx7(manufacturer:data:group:)`` or + /// ``universalSysEx7(universalType:deviceID:subID1:subID2:data:group:)`` case if successful. /// Message must begin with `0xF0` but terminating `0xF7` byte is optional. /// /// - Throws: ``ParseError`` if message is malformed. @@ -51,9 +53,12 @@ extension MIDIEvent { self = sysEx } - /// Parse a complete MIDI 2.0 System Exclusive 8 message (starting with the Stream ID byte until the end of the packet) and return a ``sysEx8(manufacturer:data:group:)`` or ``universalSysEx8(universalType:deviceID:subID1:subID2:data:group:)`` case if successful. + /// Parse a complete MIDI 2.0 System Exclusive 8 message (starting with the Stream ID byte until + /// the end of the packet) and return a ``sysEx8(manufacturer:data:group:)`` or + /// ``universalSysEx8(universalType:deviceID:subID1:subID2:data:group:)`` case if successful. /// - /// Valid rawBytes count is `1 ... 14`. (Must always contain a Stream ID, even if there are zero data bytes to follow) + /// Valid rawBytes count is `1 ... 14`. (Must always contain a Stream ID, even if there are zero + /// data bytes to follow) /// /// - Throws: ``ParseError`` if message is malformed. @available(*, unavailable, renamed: "Event.sysEx8(rawBytes:group:)") diff --git a/Sources/MIDIKitCore/Events/API Evolution/MIDIKit-0.5.0.swift b/Sources/MIDIKitCore/Events/API Evolution/MIDIKit-0.5.0.swift index d0b0488953..dbed0ab5da 100644 --- a/Sources/MIDIKitCore/Events/API Evolution/MIDIKit-0.5.0.swift +++ b/Sources/MIDIKitCore/Events/API Evolution/MIDIKit-0.5.0.swift @@ -1,7 +1,7 @@ // // MIDIKit-0.5.0.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller Operators.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller Operators.swift index e94f1a7675..d2f3530139 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller Operators.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller Operators.swift @@ -1,7 +1,7 @@ // // CC Controller Operators.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.CC.Controller { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller Properties.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller Properties.swift index ce2bf7d2cd..0c79a4eb39 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller Properties.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller Properties.swift @@ -1,7 +1,7 @@ // // CC Controller Properties.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.CC.Controller { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller allCases.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller allCases.swift index 0741dae014..cc4baa5fdd 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller allCases.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller allCases.swift @@ -1,7 +1,7 @@ // // CC Controller allCases.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.CC.Controller: CaseIterable { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller init.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller init.swift index 07074d662e..24791f3489 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller init.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller init.swift @@ -1,7 +1,7 @@ // // CC Controller init.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.CC.Controller { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller name.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller name.swift index 7508acc79f..d0f35e4cf0 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller name.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller name.swift @@ -1,7 +1,7 @@ // // CC Controller name.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.CC.Controller { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller.swift index c4eb46e129..55af7d7872 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/CC Controller.swift @@ -1,7 +1,7 @@ // // CC Controller.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.CC { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller LSB Undefined.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller LSB Undefined.swift index 675f2fd358..dd4ba7676f 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller LSB Undefined.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller LSB Undefined.swift @@ -1,7 +1,7 @@ // // Controller LSB Undefined.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.CC.Controller.LSB { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller LSB.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller LSB.swift index a1b47b9ea3..9fd16c5d3a 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller LSB.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller LSB.swift @@ -1,7 +1,7 @@ // // Controller LSB.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.CC.Controller { @@ -81,7 +81,8 @@ extension MIDIEvent.CC.Controller { // CC 52 ... 63 undefined /// LSBs for Undefined controller numbers - /// (Includes undefined controllers `20 ... 31`, corresponding to undefined LSBs of `52 ... 63`) + /// (Includes undefined controllers `20 ... 31`, + /// corresponding to undefined LSBs of `52 ... 63`) case undefined(LSB.Undefined) } } diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller Mode.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller Mode.swift index 0ac187cfd3..b08b18154c 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller Mode.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller Mode.swift @@ -1,7 +1,7 @@ // // Controller Mode.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.CC.Controller { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller NRPN.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller NRPN.swift index 8a7589175f..dfa822f288 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller NRPN.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller NRPN.swift @@ -1,7 +1,7 @@ // // Controller NRPN.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.CC.Controller { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller RPN.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller RPN.swift index ce80acbbd5..780b0825d3 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller RPN.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller RPN.swift @@ -1,7 +1,7 @@ // // Controller RPN.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.CC.Controller { @@ -11,17 +11,23 @@ extension MIDIEvent.CC.Controller { /// > /// > To set or change the value of a Registered Parameter: /// > - /// > 1. Send two Control Change messages using Control Numbers 101 (0x65) and 100 (0x64) to select the desired Registered Parameter Number. + /// > 1. Send two Control Change messages using Control Numbers 101 (0x65) and 100 (0x64) to + /// > select the desired Registered Parameter Number. /// > - /// > 2. To set the selected Registered Parameter to a specific value, send a Control Change messages to the Data Entry MSB controller (Control Number 6). If the selected Registered Parameter requires the LSB to be set, send another Control Change message to the Data Entry LSB controller (Control Number 38). + /// > 2. To set the selected Registered Parameter to a specific value, send a Control Change + /// > messages to the Data Entry MSB controller (Control Number 6). If the selected Registered + /// > Parameter requires the LSB to be set, send another Control Change message to the Data Entry + /// > LSB controller (Control Number 38). /// > - /// > 3. To make a relative adjustment to the selected Registered Parameter's current value, use the Data Increment or Data Decrement controllers (Control Numbers 96 and 97). + /// > 3. To make a relative adjustment to the selected Registered Parameter's current value, use + /// > the Data Increment or Data Decrement controllers (Control Numbers 96 and 97). /// > /// > Currently undefined RPN parameter numbers are all RESERVED for future MMA Definition. /// > /// > For custom Parameter Number use, see NRPN (non-Registered Parameter Numbers). /// - /// - Note: See Recommended Practise [RP-018](https://www.midi.org/specifications/midi1-specifications/midi-1-addenda/response-to-data-increment-decrement-controllers) of the MIDI 1.0 Spec Addenda. + /// - Note: See Recommended Practise + /// [RP-018](https://www.midi.org/specifications/midi1-specifications/midi-1-addenda/response-to-data-increment-decrement-controllers) of the MIDI 1.0 Spec Addenda. public enum RPN: Equatable, Hashable { // MIDI Spec diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller Undefined.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller Undefined.swift index 6b74298138..56318c8b6b 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller Undefined.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Controller/Named Controllers/Controller Undefined.swift @@ -1,7 +1,7 @@ // // Controller Undefined.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.CC.Controller { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Value.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Value.swift index 3689b21875..3b58955b34 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Value.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC Value.swift @@ -1,7 +1,7 @@ // // CC Value.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.CC { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC.swift index 2d942a20ab..a4164c9c4a 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/CC/CC.swift @@ -1,7 +1,7 @@ // // CC.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -116,7 +116,8 @@ extension MIDIEvent { extension MIDIEvent.CC { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [ 0xB0 + channel.uInt8Value, @@ -139,7 +140,8 @@ extension MIDIEvent.CC { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords( protocol midiProtocol: MIDIProtocolVersion ) -> [UMPWord] { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/ChanVoiceType.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/ChanVoiceType.swift index 57743cd55b..24cde7a3b3 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/ChanVoiceType.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/ChanVoiceType.swift @@ -1,7 +1,7 @@ // // ChanVoiceType.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteAttribute Pitch7_9.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteAttribute Pitch7_9.swift index f59a9f8f9a..bf32d607eb 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteAttribute Pitch7_9.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteAttribute Pitch7_9.swift @@ -1,7 +1,7 @@ // // NoteAttribute Pitch7_9.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Darwin @@ -28,7 +28,8 @@ extension MIDIEvent.NoteAttribute { /// Range: `0+(0/512) ... 127+(511/512)` /// /// - Parameters: - /// - coarse: 7-Bit coarse pitch in semitones, based on default Note Number equal temperament scale. + /// - coarse: 7-Bit coarse pitch in semitones, based on default Note Number equal + /// temperament scale. /// - fine: 9-Bit fractional pitch above Note Number (i.e., fraction of one semitone). public init( coarse: UInt7, diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteAttribute.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteAttribute.swift index 58b8bf3bc0..47b025fb97 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteAttribute.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteAttribute.swift @@ -1,7 +1,7 @@ // // NoteAttribute.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -9,7 +9,8 @@ extension MIDIEvent { /// (MIDI 2.0) public enum NoteAttribute: Equatable, Hashable { /// None: - /// When sending, Attribute Value will be `0x0000` and receiver should ignore Attribute Value. + /// When sending, Attribute Value will be `0x0000` and receiver should ignore Attribute + /// Value. case none /// Manufacturer Specific: @@ -28,8 +29,15 @@ extension MIDIEvent { /// /// > MIDI 2.0 Spec: /// > - /// > A Profile might define another Attribute Type that is defined for more specific use by that one Profile only. - /// > The application of an Attribute Type value might be defined by MMA/AMEI in a MIDI-CI Profile specification. For example, a drum Profile might define an Attribute Type as “Strike Position” with the Attribute Data value declaring the position from center of drum/cymbal to outer edge. An orchestral string Profile might define Attribute values to be used as Articulation choice such as Arco, Pizzicato, Spiccato, Tremolo, etc. Such cases generally require assigning 1 of the 256 available Attribute Types for use by that Profile. Some Profiles might be able to share some common Attribute types. + /// > A Profile might define another Attribute Type that is defined for more specific use by + /// that one Profile only. + /// > The application of an Attribute Type value might be defined by MMA/AMEI in a MIDI-CI + /// Profile specification. For example, a drum Profile might define an Attribute Type as + /// “Strike Position” with the Attribute Data value declaring the position from center of + /// drum/cymbal to outer edge. An orchestral string Profile might define Attribute values to + /// be used as Articulation choice such as Arco, Pizzicato, Spiccato, Tremolo, etc. Such + /// cases generally require assigning 1 of the 256 available Attribute Types for use by that + /// Profile. Some Profiles might be able to share some common Attribute types. case undefined(attributeType: UInt8, data: UInt16) } } @@ -69,7 +77,8 @@ extension MIDIEvent.NoteAttribute { /// Range: `0+(0/512) ... 127+(511/512)` /// /// - Parameters: - /// - coarse: 7-Bit coarse pitch in semitones, based on default Note Number equal temperament scale. + /// - coarse: 7-Bit coarse pitch in semitones, based on default Note Number equal temperament + /// scale. /// - fine: 9-Bit fractional pitch above Note Number (i.e., fraction of one semitone). public static func pitch7_9( coarse: UInt7, diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/NoteCC Value.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/NoteCC Value.swift index 67ed5c2c46..51bc606c16 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/NoteCC Value.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/NoteCC Value.swift @@ -1,7 +1,7 @@ // // NoteCC Value.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.NoteCC { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/NoteCC.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/NoteCC.swift index d2a65d3d65..b9107e335e 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/NoteCC.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/NoteCC.swift @@ -1,7 +1,7 @@ // // NoteCC.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -133,7 +133,8 @@ extension MIDIEvent { extension MIDIEvent.NoteCC { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .midi2ChannelVoice diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Assignable/PerNoteController Assignable.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Assignable/PerNoteController Assignable.swift index 4d15854d9e..625a09beca 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Assignable/PerNoteController Assignable.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Assignable/PerNoteController Assignable.swift @@ -1,7 +1,7 @@ // // PerNoteController Assignable.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.NoteCC.PerNoteController { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/NoteCC PerNoteController.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/NoteCC PerNoteController.swift index 86f331162a..74a95dd31f 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/NoteCC PerNoteController.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/NoteCC PerNoteController.swift @@ -1,7 +1,7 @@ // // NoteCC PerNoteController.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.NoteCC { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/Named Controllers/NoteCC Registered Pitch7_25.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/Named Controllers/NoteCC Registered Pitch7_25.swift index 0d0c17ced8..e3077eda4d 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/Named Controllers/NoteCC Registered Pitch7_25.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/Named Controllers/NoteCC Registered Pitch7_25.swift @@ -1,7 +1,7 @@ // // NoteCC Registered Pitch7_25.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.NoteCC.PerNoteController.Registered { @@ -12,7 +12,8 @@ extension MIDIEvent.NoteCC.PerNoteController.Registered { /// /// > MIDI 2.0 Spec: /// > - /// > Registered Per-Note Controller #3 is defined as Pitch 7.25. The message’s 32-bit data field contains: + /// > Registered Per-Note Controller #3 is defined as Pitch 7.25. The message’s 32-bit data + /// field contains: /// > - 7 bits: Pitch in semitones, based on default Note Number equal temperament scale /// > - 25 bits: Fractional Pitch above Note Number (i.e., fraction of one semitone) public struct Pitch7_25 { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/Named Controllers/NoteCC Undefined.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/Named Controllers/NoteCC Undefined.swift index bc1452a560..b1b62f98b1 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/Named Controllers/NoteCC Undefined.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/Named Controllers/NoteCC Undefined.swift @@ -1,7 +1,7 @@ // // NoteCC Undefined.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.NoteCC.PerNoteController.Registered { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered Operators.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered Operators.swift index 9cf85a3019..215f03288c 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered Operators.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered Operators.swift @@ -1,7 +1,7 @@ // // NoteCC Registered Operators.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.NoteCC.PerNoteController.Registered { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered Properties.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered Properties.swift index 074a3ed4db..e81aaf7eab 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered Properties.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered Properties.swift @@ -1,7 +1,7 @@ // // NoteCC Registered Properties.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.NoteCC.PerNoteController.Registered { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered allCases.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered allCases.swift index 33b51255b1..b2081970d8 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered allCases.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered allCases.swift @@ -1,7 +1,7 @@ // // NoteCC Registered allCases.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.NoteCC.PerNoteController.Registered: CaseIterable { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered init.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered init.swift index afe750388d..51a0b484eb 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered init.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered init.swift @@ -1,7 +1,7 @@ // // NoteCC Registered init.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.NoteCC.PerNoteController.Registered { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered name.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered name.swift index 8498633d59..f910d07a15 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered name.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered name.swift @@ -1,7 +1,7 @@ // // NoteCC Registered name.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.NoteCC.PerNoteController.Registered { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered.swift index 552a0de23e..dd0ab5c351 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteCC/PerNoteController/Registered/NoteCC Registered.swift @@ -1,7 +1,7 @@ // // NoteCC Registered.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.NoteCC.PerNoteController { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteManagement/NoteManagement.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteManagement/NoteManagement.swift index 52cc50ca63..4975f48730 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteManagement/NoteManagement.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteManagement/NoteManagement.swift @@ -1,14 +1,15 @@ // // NoteManagement.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { /// Channel Voice Message: Per-Note Management /// (MIDI 2.0) /// - /// The MIDI 2.0 Protocol introduces a Per-Note Management message to enable independent control from Per-Note Controllers to multiple Notes on the same Note Number. + /// The MIDI 2.0 Protocol introduces a Per-Note Management message to enable independent control + /// from Per-Note Controllers to multiple Notes on the same Note Number. public struct NoteManagement: Equatable, Hashable { /// Note Number /// @@ -27,7 +28,8 @@ extension MIDIEvent { /// Channel Voice Message: Per-Note Management /// (MIDI 2.0) /// - /// The MIDI 2.0 Protocol introduces a Per-Note Management message to enable independent control from Per-Note Controllers to multiple Notes on the same Note Number. + /// The MIDI 2.0 Protocol introduces a Per-Note Management message to enable independent + /// control from Per-Note Controllers to multiple Notes on the same Note Number. /// /// - Parameters: /// - note: Note Number (or Note Index if using MIDI 2.0 Pitch 7.9) @@ -50,7 +52,8 @@ extension MIDIEvent { /// Channel Voice Message: Per-Note Management /// (MIDI 2.0) /// - /// The MIDI 2.0 Protocol introduces a Per-Note Management message to enable independent control from Per-Note Controllers to multiple Notes on the same Note Number. + /// The MIDI 2.0 Protocol introduces a Per-Note Management message to enable independent + /// control from Per-Note Controllers to multiple Notes on the same Note Number. /// /// - Parameters: /// - note: Note Number (or Note Index if using MIDI 2.0 Pitch 7.9) @@ -76,7 +79,8 @@ extension MIDIEvent { /// Channel Voice Message: Per-Note Management /// (MIDI 2.0) /// - /// The MIDI 2.0 Protocol introduces a Per-Note Management message to enable independent control from Per-Note Controllers to multiple Notes on the same Note Number. + /// The MIDI 2.0 Protocol introduces a Per-Note Management message to enable independent control + /// from Per-Note Controllers to multiple Notes on the same Note Number. /// /// - Parameters: /// - note: Note Number (or Note Index if using MIDI 2.0 Pitch 7.9) @@ -103,7 +107,8 @@ extension MIDIEvent { /// Channel Voice Message: Per-Note Management /// (MIDI 2.0) /// - /// The MIDI 2.0 Protocol introduces a Per-Note Management message to enable independent control from Per-Note Controllers to multiple Notes on the same Note Number. + /// The MIDI 2.0 Protocol introduces a Per-Note Management message to enable independent control + /// from Per-Note Controllers to multiple Notes on the same Note Number. /// /// - Parameters: /// - note: Note Number (or Note Index if using MIDI 2.0 Pitch 7.9) @@ -131,7 +136,8 @@ extension MIDIEvent { extension MIDIEvent.NoteManagement { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .midi2ChannelVoice @@ -162,14 +168,18 @@ extension MIDIEvent.NoteManagement { /// /// > MIDI 2.0 Spec: /// > - /// > When a device receives a Per-Note Management message with D = 1 (Detach), all currently playing notes and previous notes on the referenced Note Number shall no longer respond to any Per-Note controllers. Currently playing notes shall maintain the current values for all Per-Note controllers until the end of the note life cycle. + /// > When a device receives a Per-Note Management message with D = 1 (Detach), all + /// currently playing notes and previous notes on the referenced Note Number shall no longer + /// respond to any Per-Note controllers. Currently playing notes shall maintain the current + /// values for all Per-Note controllers until the end of the note life cycle. case detachPerNoteControllers /// [S] Reset/Set Per-Note Controllers to default values /// /// > MIDI 2.0 Spec: /// > - /// > When a device receives a Per-Note Management message with S = 1, all Per-Note controllers on the referenced Note Number should be reset to their default values. + /// > When a device receives a Per-Note Management message with S = 1, all Per-Note + /// controllers on the referenced Note Number should be reset to their default values. case resetPerNoteControllers } } diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteOff/NoteOff.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteOff/NoteOff.swift index 5aa4b9c3ee..b2c1eba672 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteOff/NoteOff.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteOff/NoteOff.swift @@ -1,7 +1,7 @@ // // NoteOff.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -133,7 +133,8 @@ extension MIDIEvent { extension MIDIEvent.NoteOff { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [ 0x80 + channel.uInt8Value, @@ -156,7 +157,8 @@ extension MIDIEvent.NoteOff { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords( protocol midiProtocol: MIDIProtocolVersion ) -> [UMPWord] { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteOn/NoteOn.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteOn/NoteOn.swift index 8e98fb4845..7c8ce53f21 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteOn/NoteOn.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteOn/NoteOn.swift @@ -1,7 +1,7 @@ // // NoteOn.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -38,7 +38,8 @@ extension MIDIEvent { /// - channel: Channel Number (`0x0 ... 0xF`) /// - attribute: MIDI 2.0 Channel Voice Attribute /// - group: UMP Group (`0x0 ... 0xF`) - /// - midi1ZeroVelocityAsNoteOff: For MIDI 1.0, transmit velocity of 0 as a Note Off event. + /// - midi1ZeroVelocityAsNoteOff: For MIDI 1.0, transmit velocity of 0 as a Note Off + /// event. public init( note: UInt7, velocity: MIDIEvent.NoteVelocity, @@ -64,7 +65,8 @@ extension MIDIEvent { /// - channel: Channel Number (`0x0 ... 0xF`) /// - attribute: MIDI 2.0 Channel Voice Attribute /// - group: UMP Group (`0x0 ... 0xF`) - /// - midi1ZeroVelocityAsNoteOff: For MIDI 1.0, transmit velocity of 0 as a Note Off event. + /// - midi1ZeroVelocityAsNoteOff: For MIDI 1.0, transmit velocity of 0 as a Note Off + /// event. public init( note: MIDINote, velocity: MIDIEvent.NoteVelocity, @@ -172,7 +174,8 @@ extension MIDIEvent { extension MIDIEvent.NoteOn { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { func process(midi1Value: UInt7) -> [UInt8] { if midi1Value == 0, midi1ZeroVelocityAsNoteOff { @@ -199,7 +202,9 @@ extension MIDIEvent.NoteOn { case .midi2: // MIDI 2.0 Spec: - // When translating a MIDI 2.0 Note On message to the MIDI 1.0 Protocol, if the translated MIDI 1.0 value of the Velocity is zero, then the Translator shall replace the zero with a value of 1. + // When translating a MIDI 2.0 Note On message to the MIDI 1.0 Protocol, if the + // translated MIDI 1.0 value of the Velocity is zero, then the Translator shall replace + // the zero with a value of 1. var midi1Velocity = velocity.midi1Value.uInt8Value if midi1Velocity == 0 { midi1Velocity = 1 } @@ -229,7 +234,8 @@ extension MIDIEvent.NoteOn { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords( protocol midiProtocol: MIDIProtocolVersion ) -> [UMPWord] { @@ -251,7 +257,9 @@ extension MIDIEvent.NoteOn { case ._2_0: // MIDI 2.0 Spec: - // The allowable Velocity range for a MIDI 2.0 Note On message is 0x0000-0xFFFF. Unlike the MIDI 1.0 Note On message, a velocity value of zero does not function as a Note Off. + // The allowable Velocity range for a MIDI 2.0 Note On message is 0x0000-0xFFFF. Unlike + // the MIDI 1.0 Note On message, a velocity value of zero does not function as a Note + // Off. let word1 = UMPWord( mtAndGroup, diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePitchBend/NotePitchBend Value.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePitchBend/NotePitchBend Value.swift index 95d898caf0..1654bf0b50 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePitchBend/NotePitchBend Value.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePitchBend/NotePitchBend Value.swift @@ -1,7 +1,7 @@ // // NotePitchBend Value.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.NotePitchBend { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePitchBend/NotePitchBend.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePitchBend/NotePitchBend.swift index 345ffaaa33..70a554a410 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePitchBend/NotePitchBend.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePitchBend/NotePitchBend.swift @@ -1,7 +1,7 @@ // // NotePitchBend.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -118,7 +118,8 @@ extension MIDIEvent { extension MIDIEvent.NotePitchBend { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .midi2ChannelVoice diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePressure/NotePressure Amount.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePressure/NotePressure Amount.swift index 5b1f24a583..14d6531263 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePressure/NotePressure Amount.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePressure/NotePressure Amount.swift @@ -1,7 +1,7 @@ // // NotePressure Amount.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePressure/NotePressure.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePressure/NotePressure.swift index eb577441cf..e12b9fe694 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePressure/NotePressure.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NotePressure/NotePressure.swift @@ -1,7 +1,7 @@ // // NotePressure.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -129,7 +129,8 @@ extension MIDIEvent { extension MIDIEvent.NotePressure { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [ 0xA0 + channel.uInt8Value, @@ -152,7 +153,8 @@ extension MIDIEvent.NotePressure { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords( protocol midiProtocol: MIDIProtocolVersion ) -> [UMPWord] { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteVelocity.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteVelocity.swift index 699917080b..1c363294c4 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteVelocity.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Note/NoteVelocity.swift @@ -1,7 +1,7 @@ // // NoteVelocity.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,12 +10,16 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > Note velocity is a 7-bit value when encoded for MIDI 1.0. A velocity of zero typically functions as a Note Off, although this behavior is able to be bypassed. + /// > Note velocity is a 7-bit value when encoded for MIDI 1.0. A velocity of zero typically + /// functions as a Note Off, although this behavior is able to be bypassed. /// /// > MIDI 2.0 Spec: /// > - /// > The allowable Velocity range for a MIDI 2.0 Note On message is 0x0000-0xFFFF. Unlike the MIDI 1.0 Note On message, a velocity value of zero does not function as a Note Off. - /// > When translating a MIDI 2.0 Note On message to the MIDI 1.0 Protocol, if the translated MIDI 1.0 value of the Velocity is zero, then the Translator shall replace the zero with a value of 1. + /// > The allowable Velocity range for a MIDI 2.0 Note On message is 0x0000-0xFFFF. Unlike the + /// MIDI 1.0 Note On message, a velocity value of zero does not function as a Note Off. + /// > When translating a MIDI 2.0 Note On message to the MIDI 1.0 Protocol, if the translated + /// MIDI 1.0 value of the Velocity is zero, then the Translator shall replace the zero with a + /// value of 1. public typealias NoteVelocity = MIDIEvent.ChanVoice7Bit16BitValue /// MIDI Note Velocity. @@ -23,11 +27,15 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > Note velocity is a 7-bit value when encoded for MIDI 1.0. A velocity of zero typically functions as a Note Off, although this behavior is able to be bypassed. + /// > Note velocity is a 7-bit value when encoded for MIDI 1.0. A velocity of zero typically + /// functions as a Note Off, although this behavior is able to be bypassed. /// /// > MIDI 2.0 Spec: /// > - /// > The allowable Velocity range for a MIDI 2.0 Note On message is 0x0000-0xFFFF. Unlike the MIDI 1.0 Note On message, a velocity value of zero does not function as a Note Off. - /// > When translating a MIDI 2.0 Note On message to the MIDI 1.0 Protocol, if the translated MIDI 1.0 value of the Velocity is zero, then the Translator shall replace the zero with a value of 1. + /// > The allowable Velocity range for a MIDI 2.0 Note On message is 0x0000-0xFFFF. Unlike the + /// MIDI 1.0 Note On message, a velocity value of zero does not function as a Note Off. + /// > When translating a MIDI 2.0 Note On message to the MIDI 1.0 Protocol, if the translated + /// MIDI 1.0 value of the Velocity is zero, then the Translator shall replace the zero with a + /// value of 1. public typealias NoteVelocityValidated = NoteVelocity.Validated } diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/PitchBend/PitchBend Value.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/PitchBend/PitchBend Value.swift index a2e052df69..8e35363051 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/PitchBend/PitchBend Value.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/PitchBend/PitchBend Value.swift @@ -1,7 +1,7 @@ // // PitchBend Value.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.PitchBend { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/PitchBend/PitchBend.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/PitchBend/PitchBend.swift index fd951af9bc..efe50bae64 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/PitchBend/PitchBend.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/PitchBend/PitchBend.swift @@ -1,7 +1,7 @@ // // PitchBend.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -52,7 +52,8 @@ extension MIDIEvent { extension MIDIEvent.PitchBend { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { let bytePair = value.midi1Value.bytePair @@ -77,7 +78,8 @@ extension MIDIEvent.PitchBend { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords( protocol midiProtocol: MIDIProtocolVersion ) -> [UMPWord] { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Pressure/Pressure Amount.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Pressure/Pressure Amount.swift index 58c50e73cd..66110f6922 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Pressure/Pressure Amount.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Pressure/Pressure Amount.swift @@ -1,7 +1,7 @@ // // Pressure Amount.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.Pressure { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Pressure/Pressure.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Pressure/Pressure.swift index d401470905..4f378ff42a 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Pressure/Pressure.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Pressure/Pressure.swift @@ -1,7 +1,7 @@ // // Pressure.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -64,7 +64,8 @@ extension MIDIEvent { extension MIDIEvent.Pressure { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [ 0xD0 + channel.uInt8Value, @@ -86,7 +87,8 @@ extension MIDIEvent.Pressure { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords( protocol midiProtocol: MIDIProtocolVersion ) -> [UMPWord] { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/ProgramChange/ProgramChange Bank.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/ProgramChange/ProgramChange Bank.swift index 1bcf5bb00d..10ac70a1af 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/ProgramChange/ProgramChange Bank.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/ProgramChange/ProgramChange Bank.swift @@ -1,14 +1,15 @@ // // ProgramChange Bank.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent.ProgramChange { /// Bank Select /// (MIDI 1.0 / MIDI 2.0) /// - /// When receiving a Program Change event, if a bank number is present then the Bank Select event should be processed prior to the Program Change event. + /// When receiving a Program Change event, if a bank number is present then the Bank Select + /// event should be processed prior to the Program Change event. /// /// **MIDI 1.0** /// @@ -19,13 +20,16 @@ extension MIDIEvent.ProgramChange { /// /// Bank numbers in MIDI 1.0 are expressed as two 7-bit bytes (MSB/"coarse" and LSB/"fine"). /// - /// In some implementations, manufacturers have chosen to only use the MSB/"coarse" adjust (CC 0) switch banks since many devices don't have more than 128 banks (of 128 programs each). + /// In some implementations, manufacturers have chosen to only use the MSB/"coarse" adjust (CC + /// 0) switch banks since many devices don't have more than 128 banks (of 128 programs each). /// /// **MIDI 2.0** /// - /// For MIDI 2.0, Program Change and Bank Select information is all contained within a single UMP (Universal MIDI Packet). + /// For MIDI 2.0, Program Change and Bank Select information is all contained within a single + /// UMP (Universal MIDI Packet). /// - /// Bank numbers in MIDI 2.0 are expressed by combining the two MIDI 1.0 7-bit bytes into a 14-bit number (`0 ... 16383`). They correlate exactly to MIDI 1.0 bank numbers. + /// Bank numbers in MIDI 2.0 are expressed by combining the two MIDI 1.0 7-bit bytes into a + /// 14-bit number (`0 ... 16383`). They correlate exactly to MIDI 1.0 bank numbers. public enum Bank: Equatable, Hashable { /// No Bank Select operation will occur; only a Program Change event will happen. /// (MIDI 1.0 / 2.0) @@ -43,13 +47,17 @@ extension MIDIEvent.ProgramChange { /// /// Bank numbers in MIDI 1.0 are expressed as two 7-bit bytes (MSB/"coarse" and LSB/"fine"). /// - /// In some implementations, manufacturers have chosen to only use the MSB/"coarse" adjust (CC 0) switch banks since many devices don't have more than 128 banks (of 128 programs each). + /// In some implementations, manufacturers have chosen to only use the MSB/"coarse" adjust + /// (CC 0) switch banks since many devices don't have more than 128 banks (of 128 programs + /// each). /// /// **MIDI 2.0** /// - /// For MIDI 2.0, Program Change and Bank Select information is all contained within a single UMP (Universal MIDI Packet). + /// For MIDI 2.0, Program Change and Bank Select information is all contained within a + /// single UMP (Universal MIDI Packet). /// - /// Bank numbers in MIDI 2.0 are expressed by combining the two MIDI 1.0 7-bit bytes into a 14-bit number (`0 ... 16383`). They correlate exactly to MIDI 1.0 bank numbers. + /// Bank numbers in MIDI 2.0 are expressed by combining the two MIDI 1.0 7-bit bytes into a + /// 14-bit number (`0 ... 16383`). They correlate exactly to MIDI 1.0 bank numbers. case bankSelect(UInt14) } } @@ -67,13 +75,16 @@ extension MIDIEvent.ProgramChange.Bank { /// /// Bank numbers in MIDI 1.0 are expressed as two 7-bit bytes (MSB/"coarse" and LSB/"fine"). /// - /// In some implementations, manufacturers have chosen to only use the MSB/"coarse" adjust (CC 0) switch banks since many devices don't have more than 128 banks (of 128 programs each). + /// In some implementations, manufacturers have chosen to only use the MSB/"coarse" adjust (CC + /// 0) switch banks since many devices don't have more than 128 banks (of 128 programs each). /// /// **MIDI 2.0** /// - /// For MIDI 2.0, Program Change and Bank Select information is all contained within a single UMP (Universal MIDI Packet). + /// For MIDI 2.0, Program Change and Bank Select information is all contained within a single + /// UMP (Universal MIDI Packet). /// - /// Bank numbers in MIDI 2.0 are expressed by combining the two MIDI 1.0 7-bit bytes into a 14-bit number (`0 ... 16383`). They correlate exactly to MIDI 1.0 bank numbers. + /// Bank numbers in MIDI 2.0 are expressed by combining the two MIDI 1.0 7-bit bytes into a + /// 14-bit number (`0 ... 16383`). They correlate exactly to MIDI 1.0 bank numbers. public static func bankSelect( msb: UInt7, lsb: UInt7 diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/ProgramChange/ProgramChange.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/ProgramChange/ProgramChange.swift index 936c0b96a5..8be0c85312 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/ProgramChange/ProgramChange.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/ProgramChange/ProgramChange.swift @@ -1,18 +1,24 @@ // // ProgramChange.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { /// Channel Voice Message: Program Change /// (MIDI 1.0 / 2.0) /// - /// This event can optionally contain a Bank Select message. In MIDI 1.0, these will be transmit as separate messages. In MIDI 2.0, this information is all contained within a single packet. See the ``bank-swift.property`` property for more info. + /// This event can optionally contain a Bank Select message. In MIDI 1.0, these will be transmit + /// as separate messages. In MIDI 2.0, this information is all contained within a single packet. + /// See the ``bank-swift.property`` property for more info. /// /// > MIDI 2.0 Spec: /// > - /// > In the MIDI 2.0 Protocol, this message combines the MIDI 1.0 Protocol's separate Program Change and Bank Select messages into a single, unified message; by contrast, the MIDI 1.0 Protocol mechanism for selecting Banks and Programs requires sending three MIDI separate 1.0 Messages. The MIDI 1.0 Protocol’s existing 16,384 Banks, each with 128 Programs, are preserved and translate directly to the MIDI 2.0 Protocol. + /// > In the MIDI 2.0 Protocol, this message combines the MIDI 1.0 Protocol's separate Program + /// Change and Bank Select messages into a single, unified message; by contrast, the MIDI 1.0 + /// Protocol mechanism for selecting Banks and Programs requires sending three MIDI separate 1.0 + /// Messages. The MIDI 1.0 Protocol’s existing 16,384 Banks, each with 128 Programs, are + /// preserved and translate directly to the MIDI 2.0 Protocol. public struct ProgramChange: Equatable, Hashable { /// Program Number public var program: UInt7 @@ -20,7 +26,8 @@ extension MIDIEvent { /// Bank Select /// (MIDI 1.0 / 2.0) /// - /// When receiving a Program Change event, if a bank number is present then the Bank Select event should be processed prior to the Program Change event. + /// When receiving a Program Change event, if a bank number is present then the Bank Select + /// event should be processed prior to the Program Change event. /// /// **MIDI 1.0** /// @@ -31,13 +38,17 @@ extension MIDIEvent { /// /// Bank numbers in MIDI 1.0 are expressed as two 7-bit bytes (MSB/"coarse" and LSB/"fine"). /// - /// In some implementations, manufacturers have chosen to only use the MSB/"coarse" adjust (CC 0) switch banks since many devices don't have more than 128 banks (of 128 programs each). + /// In some implementations, manufacturers have chosen to only use the MSB/"coarse" adjust + /// (CC 0) switch banks since many devices don't have more than 128 banks (of 128 programs + /// each). /// /// **MIDI 2.0** /// - /// For MIDI 2.0, Program Change and Bank Select information is all contained within a single UMP (Universal MIDI Packet). + /// For MIDI 2.0, Program Change and Bank Select information is all contained within a + /// single UMP (Universal MIDI Packet). /// - /// Bank numbers in MIDI 2.0 are expressed by combining the two MIDI 1.0 7-bit bytes into a 14-bit number (0...16383). They correlate exactly to MIDI 1.0 bank numbers. + /// Bank numbers in MIDI 2.0 are expressed by combining the two MIDI 1.0 7-bit bytes into a + /// 14-bit number (0...16383). They correlate exactly to MIDI 1.0 bank numbers. public var bank: Bank /// Channel Number (`0x0 ... 0xF`) @@ -95,7 +106,8 @@ extension MIDIEvent { extension MIDIEvent.ProgramChange { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { let programChangeMessage = [ 0xC0 + channel.uInt8Value, @@ -140,7 +152,8 @@ extension MIDIEvent.ProgramChange { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords( protocol midiProtocol: MIDIProtocolVersion ) -> [UMPWord] { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice Value Conversions.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice Value Conversions.swift index 4d4151a9a3..ee2172ecf8 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice Value Conversions.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice Value Conversions.swift @@ -1,7 +1,7 @@ // // ChanVoice Value Conversions.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice14Bit32BitValue.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice14Bit32BitValue.swift index 00da2086c3..88ff6714a6 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice14Bit32BitValue.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice14Bit32BitValue.swift @@ -1,7 +1,7 @@ // // ChanVoice14Bit32BitValue.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice32BitValue.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice32BitValue.swift index 075a5d8928..0954194f52 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice32BitValue.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice32BitValue.swift @@ -1,7 +1,7 @@ // // ChanVoice32BitValue.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit16BitValue.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit16BitValue.swift index 0ea065f465..154682bc72 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit16BitValue.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit16BitValue.swift @@ -1,7 +1,7 @@ // // ChanVoice7Bit16BitValue.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit32BitValue.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit32BitValue.swift index 1c5489d624..59e3ce6427 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit32BitValue.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit32BitValue.swift @@ -1,7 +1,7 @@ // // ChanVoice7Bit32BitValue.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent Errors.swift b/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent Errors.swift index 0dbeca5a03..5a8f998b42 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent Errors.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent Errors.swift @@ -1,7 +1,7 @@ // // MIDIEvent Errors.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent Properties.swift b/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent Properties.swift index 2238e72c69..986f7290b1 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent Properties.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent Properties.swift @@ -1,7 +1,7 @@ // // MIDIEvent Properties.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent description.swift b/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent description.swift index f857c4f843..3408489eee 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent description.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent description.swift @@ -1,7 +1,7 @@ // // MIDIEvent description.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent rawBytes.swift b/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent rawBytes.swift index 3e39699b1a..e745f3e976 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent rawBytes.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent rawBytes.swift @@ -1,13 +1,14 @@ // // MIDIEvent rawBytes.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { switch self { // ------------------- @@ -120,7 +121,8 @@ extension MIDIEvent { extension MIDIEvent { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords(protocol midiProtocol: MIDIProtocolVersion) -> [[UMPWord]] { switch self { // ------------------- diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent.swift b/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent.swift index 653362b84c..028bdda2a9 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/MIDIEvent.swift @@ -1,7 +1,7 @@ // // MIDIEvent.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// MIDI Event. @@ -38,7 +38,8 @@ public enum MIDIEvent: Equatable, Hashable { /// Channel Voice Message: Per-Note Management /// (MIDI 2.0) /// - /// The MIDI 2.0 Protocol introduces a Per-Note Management message to enable independent control from Per- Note Controllers to multiple Notes on the same Note Number. + /// The MIDI 2.0 Protocol introduces a Per-Note Management message to enable independent control + /// from Per- Note Controllers to multiple Notes on the same Note Number. case noteManagement(NoteManagement) /// Channel Voice Message: Channel Control Change (CC) @@ -71,15 +72,22 @@ public enum MIDIEvent: Equatable, Hashable { /// /// > MIDI 1.0 Spec: /// > - /// > Receivers should ignore non-universal Exclusive messages with ID numbers that do not correspond to their own ID. + /// > Receivers should ignore non-universal Exclusive messages with ID numbers that do not + /// correspond to their own ID. /// > - /// > Any manufacturer of MIDI hardware or software may use the system exclusive codes of any existing product without the permission of the original manufacturer. However, they may not modify or extend it in any way that conflicts with the original specification published by the designer. Once published, an Exclusive format is treated like any other part of the instruments MIDI implementation — so long as the new instrument remains within the definitions of the published specification. + /// > Any manufacturer of MIDI hardware or software may use the system exclusive codes of any + /// existing product without the permission of the original manufacturer. However, they may not + /// modify or extend it in any way that conflicts with the original specification published by + /// the designer. Once published, an Exclusive format is treated like any other part of the + /// instruments MIDI implementation — so long as the new instrument remains within the + /// definitions of the published specification. case sysEx7(SysEx7) /// Universal System Exclusive (7-bit) /// (MIDI 1.0 / 2.0) /// - /// Some standard Universal System Exclusive messages have been defined by the MIDI Spec. See the official MIDI 1.0 and 2.0 specs for details. + /// Some standard Universal System Exclusive messages have been defined by the MIDI Spec. See + /// the official MIDI 1.0 and 2.0 specs for details. /// /// - `deviceID` of `0x7F` indicates "All Devices". case universalSysEx7(UniversalSysEx7) @@ -89,7 +97,11 @@ public enum MIDIEvent: Equatable, Hashable { /// /// > MIDI 2.0 Spec: /// > - /// > System Exclusive 8 messages have many similarities to the MIDI 1.0 Protocol’s original System Exclusive messages, but with the added advantage of allowing all 8 bits of each data byte to be used. By contrast, MIDI 1.0 Protocol System Exclusive requires a 0 in the high bit of every data byte, leaving only 7 bits to carry actual data. A System Exclusive 8 Message is carried in one or more 128-bit UMPs. + /// > System Exclusive 8 messages have many similarities to the MIDI 1.0 Protocol’s original + /// System Exclusive messages, but with the added advantage of allowing all 8 bits of each data + /// byte to be used. By contrast, MIDI 1.0 Protocol System Exclusive requires a 0 in the high + /// bit of every data byte, leaving only 7 bits to carry actual data. A System Exclusive 8 + /// Message is carried in one or more 128-bit UMPs. case sysEx8(SysEx8) /// Universal System Exclusive (8-bit) @@ -107,7 +119,11 @@ public enum MIDIEvent: Equatable, Hashable { /// /// > MIDI 1.0 Spec: /// > - /// > For device synchronization, MIDI Time Code uses two basic types of messages, described as Quarter Frame and Full. There is also a third, optional message for encoding SMPTE user bits. The Quarter Frame message communicates the Frame, Seconds, Minutes and Hours Count in an 8-message sequence. There is also an MTC FULL FRAME message which is a MIDI System Exclusive Message. + /// > For device synchronization, MIDI Time Code uses two basic types of messages, described as + /// Quarter Frame and Full. There is also a third, optional message for encoding SMPTE user + /// bits. The Quarter Frame message communicates the Frame, Seconds, Minutes and Hours Count in + /// an 8-message sequence. There is also an MTC FULL FRAME message which is a MIDI System + /// Exclusive Message. case timecodeQuarterFrame(TimecodeQuarterFrame) /// System Common: Song Position Pointer @@ -115,7 +131,9 @@ public enum MIDIEvent: Equatable, Hashable { /// /// > MIDI 1.0 Spec: /// > - /// > A sequencer's Song Position (SP) is the number of MIDI beats (1 beat = 6 MIDI clocks) that have elapsed from the start of the song and is used to begin playback of a sequence from a position other than the beginning of the song. + /// > A sequencer's Song Position (SP) is the number of MIDI beats (1 beat = 6 MIDI clocks) that + /// have elapsed from the start of the song and is used to begin playback of a sequence from a + /// position other than the beginning of the song. case songPositionPointer(SongPositionPointer) /// System Common: Song Select @@ -123,16 +141,25 @@ public enum MIDIEvent: Equatable, Hashable { /// /// > MIDI 1.0 Spec: /// > - /// > Specifies which song or sequence is to be played upon receipt of a Start message in sequencers and drum machines capable of holding multiple songs or sequences. This message should be ignored if the receiver is not set to respond to incoming Real-Time messages (MIDI Sync). + /// > Specifies which song or sequence is to be played upon receipt of a Start message in + /// sequencers and drum machines capable of holding multiple songs or sequences. This message + /// should be ignored if the receiver is not set to respond to incoming Real-Time messages (MIDI + /// Sync). case songSelect(SongSelect) /// Unofficial Bus Select (Status `0xF5`) /// - /// > Warning: This command is not officially supported and some MIDI subsystems will ignore it entirely. It is provided purely for legacy support and its use is discouraged. It will likely be removed in a future release of MIDIKit. + /// > Warning: This command is not officially supported and some MIDI subsystems will ignore it + /// entirely. It is provided purely for legacy support and its use is discouraged. It will + /// likely be removed in a future release of MIDIKit. /// /// > Reference: /// > - /// > "Some vendors have produced boxes with a single MIDI input, and multiple MIDI outputs. The Bus Select message specifies which of the outputs further data should be sent to. This is not an official message; the vendors in question should have used a SysEx command." -- [David Van Brink's MIDI Spec](https://www.cs.cmu.edu/~music/cmsip/readings/davids-midi-spec.htm) + /// > "Some vendors have produced boxes with a single MIDI input, and multiple MIDI outputs. The + /// Bus Select message specifies which of the outputs further data should be sent to. This is + /// not an official message; the vendors in question should have used a SysEx command." -- + /// [David Van Brink's MIDI + /// Spec](https://www.cs.cmu.edu/~music/cmsip/readings/davids-midi-spec.htm) case unofficialBusSelect(UnofficialBusSelect) /// System Common: Tune Request @@ -152,7 +179,11 @@ public enum MIDIEvent: Equatable, Hashable { /// /// > MIDI 1.0 Spec: /// > - /// > Clock-based MIDI systems are synchronized with this message, which is sent at a rate of 24 per quarter note. If Timing Clocks (`0xF8`) are sent during idle time they should be sent at the current tempo setting of the transmitter even while it is not playing. Receivers which are synchronized to incoming Real-Time messages (MIDI Sync mode) can thus phase lock their internal clocks while waiting for a Start (`0xFA`) or Continue (`0xFB`) command. + /// > Clock-based MIDI systems are synchronized with this message, which is sent at a rate of 24 + /// per quarter note. If Timing Clocks (`0xF8`) are sent during idle time they should be sent at + /// the current tempo setting of the transmitter even while it is not playing. Receivers which + /// are synchronized to incoming Real-Time messages (MIDI Sync mode) can thus phase lock their + /// internal clocks while waiting for a Start (`0xFA`) or Continue (`0xFB`) command. case timingClock(TimingClock) /// System Real-Time: Start @@ -160,7 +191,9 @@ public enum MIDIEvent: Equatable, Hashable { /// /// > MIDI 1.0 Spec: /// > - /// Start (`0xFA`) is sent when a PLAY button on the master (sequencer or drum machine) is pressed. This message commands all receivers which are synchronized to incoming Real-Time messages (MIDI Sync mode) to start at the beginning of the song or sequence. + /// Start (`0xFA`) is sent when a PLAY button on the master (sequencer or drum machine) is + /// pressed. This message commands all receivers which are synchronized to incoming Real-Time + /// messages (MIDI Sync mode) to start at the beginning of the song or sequence. case start(Start) /// System Real-Time: Continue @@ -168,7 +201,8 @@ public enum MIDIEvent: Equatable, Hashable { /// /// > MIDI 1.0 Spec: /// > - /// > Continue (`0xFB`) is sent when a CONTINUE button is hit. A sequence will continue from its current location upon receipt of the next Timing Clock (`0xF8`). + /// > Continue (`0xFB`) is sent when a CONTINUE button is hit. A sequence will continue from its + /// current location upon receipt of the next Timing Clock (`0xF8`). case `continue`(Continue) /// System Real-Time: Stop @@ -176,7 +210,8 @@ public enum MIDIEvent: Equatable, Hashable { /// /// > MIDI 1.0 Spec: /// > - /// > Stop (`0xFC`) is sent when a STOP button is hit. Playback in a receiver should stop immediately. + /// > Stop (`0xFC`) is sent when a STOP button is hit. Playback in a receiver should stop + /// immediately. case stop(Stop) /// System Real-Time: Active Sensing @@ -184,9 +219,17 @@ public enum MIDIEvent: Equatable, Hashable { /// /// > MIDI 1.0 Spec: /// > - /// > Use of Active Sensing is optional for either receivers or transmitters. This byte (`0xFE`) is sent every 300 ms (maximum) whenever there is no other MIDI data being transmitted. If a device never receives Active Sensing it should operate normally. However, once the receiver recognizes Active Sensing (`0xFE`), it then will expect to get a message of some kind every 300 milliseconds. If no messages are received within this time period the receiver will assume the MIDI cable has been disconnected for some reason and should turn off all voices and return to normal operation. It is recommended that transmitters transmit Active Sensing within 270ms and receivers judge at over 330ms leaving a margin of roughly 10%. + /// > Use of Active Sensing is optional for either receivers or transmitters. This byte (`0xFE`) + /// is sent every 300 ms (maximum) whenever there is no other MIDI data being transmitted. If a + /// device never receives Active Sensing it should operate normally. However, once the receiver + /// recognizes Active Sensing (`0xFE`), it then will expect to get a message of some kind every + /// 300 milliseconds. If no messages are received within this time period the receiver will + /// assume the MIDI cable has been disconnected for some reason and should turn off all voices + /// and return to normal operation. It is recommended that transmitters transmit Active Sensing + /// within 270ms and receivers judge at over 330ms leaving a margin of roughly 10%. /// - /// - Note: Use of Active Sensing in modern MIDI devices is uncommon and the use of this standard has been deprecated as of MIDI 2.0. + /// - Note: Use of Active Sensing in modern MIDI devices is uncommon and the use of this + /// standard has been deprecated as of MIDI 2.0. case activeSensing(ActiveSensing) /// System Real-Time: System Reset @@ -194,7 +237,10 @@ public enum MIDIEvent: Equatable, Hashable { /// /// > MIDI 1.0 Spec: /// > - /// > System Reset commands all devices in a system to return to their initialized, power-up condition. This message should be used sparingly, and should typically be sent by manual control only. It should not be sent automatically upon power-up and under no condition should this message be echoed. + /// > System Reset commands all devices in a system to return to their initialized, power-up + /// condition. This message should be used sparingly, and should typically be sent by manual + /// control only. It should not be sent automatically upon power-up and under no condition + /// should this message be echoed. case systemReset(SystemReset) // ------------------------------- @@ -206,7 +252,9 @@ public enum MIDIEvent: Equatable, Hashable { /// /// > MIDI 2.0 Spec: /// > - /// > The UMP Format provides a set of Utility Messages. Utility Messages include but are not limited to NOOP and timestamps, and might in the future include UMP transport-related functions. + /// > The UMP Format provides a set of Utility Messages. Utility Messages include but are not + /// limited to NOOP and timestamps, and might in the future include UMP transport-related + /// functions. case noOp(NoOp) /// JR Clock (Jitter-Reduction Clock) @@ -216,11 +264,14 @@ public enum MIDIEvent: Equatable, Hashable { /// > /// > The JR Clock message defines the current time of the Sender. /// > - /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 MHz / 32). + /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 + /// MHz / 32). /// > /// > The time value is expected to wrap around every 2.09712 seconds. /// > - /// > To avoid ambiguity of the 2.09712 seconds wrap, and to provide sufficient JR Clock messages for the Receiver, the Sender shall send a JR Clock message at least once every 250 milliseconds. + /// > To avoid ambiguity of the 2.09712 seconds wrap, and to provide sufficient JR Clock + /// messages for the Receiver, the Sender shall send a JR Clock message at least once every 250 + /// milliseconds. case jrClock(JRClock) /// JR Timestamp (Jitter-Reduction Timestamp) @@ -228,8 +279,10 @@ public enum MIDIEvent: Equatable, Hashable { /// /// > MIDI 2.0 Spec: /// > - /// > The JR Timestamp message defines the time of the following message(s). It is a complete message. + /// > The JR Timestamp message defines the time of the following message(s). It is a complete + /// message. /// > - /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 MHz / 32). + /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 + /// MHz / 32). case jrTimestamp(JRTimestamp) } diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Common/SongPositionPointer/SongPositionPointer.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Common/SongPositionPointer/SongPositionPointer.swift index 076b80bab7..e2bd790028 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Common/SongPositionPointer/SongPositionPointer.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Common/SongPositionPointer/SongPositionPointer.swift @@ -1,7 +1,7 @@ // // SongPositionPointer.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,7 +10,9 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > A sequencer's Song Position (SP) is the number of MIDI beats (1 beat = 6 MIDI clocks) that have elapsed from the start and is used to begin playback of a sequence from a position other than the beginning of the song. + /// > A sequencer's Song Position (SP) is the number of MIDI beats (1 beat = 6 MIDI clocks) that + /// have elapsed from the start and is used to begin playback of a sequence from a position + /// other than the beginning of the song. public struct SongPositionPointer: Equatable, Hashable { /// The number of MIDI beats (1 beat = 6 MIDI clocks) that have elapsed from the start. public var midiBeat: UInt14 @@ -32,7 +34,9 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > A sequencer's Song Position (SP) is the number of MIDI beats (1 beat = 6 MIDI clocks) that have elapsed from the start of the song and is used to begin playback of a sequence from a position other than the beginning of the song. + /// > A sequencer's Song Position (SP) is the number of MIDI beats (1 beat = 6 MIDI clocks) that + /// have elapsed from the start of the song and is used to begin playback of a sequence from a + /// position other than the beginning of the song. /// /// - Parameters: /// - midiBeat: MIDI beat number elapsed from the start @@ -53,7 +57,8 @@ extension MIDIEvent { extension MIDIEvent.SongPositionPointer { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { let bytePair = midiBeat.bytePair return [0xF2, bytePair.lsb, bytePair.msb] @@ -61,7 +66,8 @@ extension MIDIEvent.SongPositionPointer { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .systemRealTimeAndCommon diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Common/SongSelect/SongSelect.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Common/SongSelect/SongSelect.swift index cdc9d233fa..d477c88032 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Common/SongSelect/SongSelect.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Common/SongSelect/SongSelect.swift @@ -1,7 +1,7 @@ // // SongSelect.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,7 +10,10 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > Specifies which song or sequence is to be played upon receipt of a Start message in sequencers and drum machines capable of holding multiple songs or sequences. This message should be ignored if the receiver is not set to respond to incoming Real-Time messages (MIDI Sync). + /// > Specifies which song or sequence is to be played upon receipt of a Start message in + /// sequencers and drum machines capable of holding multiple songs or sequences. This message + /// should be ignored if the receiver is not set to respond to incoming Real-Time messages (MIDI + /// Sync). public struct SongSelect: Equatable, Hashable { /// Song Number public var number: UInt7 @@ -32,7 +35,10 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > Specifies which song or sequence is to be played upon receipt of a Start message in sequencers and drum machines capable of holding multiple songs or sequences. This message should be ignored if the receiver is not set to respond to incoming Real-Time messages (MIDI Sync). + /// > Specifies which song or sequence is to be played upon receipt of a Start message in + /// sequencers and drum machines capable of holding multiple songs or sequences. This message + /// should be ignored if the receiver is not set to respond to incoming Real-Time messages (MIDI + /// Sync). /// /// - Parameters: /// - number: Song Number @@ -53,14 +59,16 @@ extension MIDIEvent { extension MIDIEvent.SongSelect { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [0xF3, number.uInt8Value] } /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .systemRealTimeAndCommon diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Common/SysCommonType.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Common/SysCommonType.swift index 421783d40c..9f0d23cc5f 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Common/SysCommonType.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Common/SysCommonType.swift @@ -1,7 +1,7 @@ // // SysCommonType.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Common/TimecodeQuarterFrame/TimecodeQuarterFrame.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Common/TimecodeQuarterFrame/TimecodeQuarterFrame.swift index a24db56836..35385dda6b 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Common/TimecodeQuarterFrame/TimecodeQuarterFrame.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Common/TimecodeQuarterFrame/TimecodeQuarterFrame.swift @@ -1,7 +1,7 @@ // // TimecodeQuarterFrame.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,7 +10,11 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > For device synchronization, MIDI Time Code uses two basic types of messages, described as Quarter Frame and Full. There is also a third, optional message for encoding SMPTE user bits. The Quarter Frame message communicates the Frame, Seconds, Minutes and Hours Count in an 8-message sequence. There is also an MTC FULL FRAME message which is a MIDI System Exclusive Message. + /// > For device synchronization, MIDI Time Code uses two basic types of messages, described as + /// Quarter Frame and Full. There is also a third, optional message for encoding SMPTE user + /// bits. The Quarter Frame message communicates the Frame, Seconds, Minutes and Hours Count in + /// an 8-message sequence. There is also an MTC FULL FRAME message which is a MIDI System + /// Exclusive Message. public struct TimecodeQuarterFrame: Equatable, Hashable { /// Data Byte containing quarter-frame bits public var dataByte: UInt7 @@ -32,7 +36,11 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > For device synchronization, MIDI Time Code uses two basic types of messages, described as Quarter Frame and Full. There is also a third, optional message for encoding SMPTE user bits. The Quarter Frame message communicates the Frame, Seconds, Minutes and Hours Count in an 8-message sequence. There is also an MTC FULL FRAME message which is a MIDI System Exclusive Message. + /// > For device synchronization, MIDI Time Code uses two basic types of messages, described as + /// Quarter Frame and Full. There is also a third, optional message for encoding SMPTE user + /// bits. The Quarter Frame message communicates the Frame, Seconds, Minutes and Hours Count in + /// an 8-message sequence. There is also an MTC FULL FRAME message which is a MIDI System + /// Exclusive Message. /// /// - Parameters: /// - dataByte: Data Byte containing quarter-frame bits @@ -53,14 +61,16 @@ extension MIDIEvent { extension MIDIEvent.TimecodeQuarterFrame { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [0xF1, dataByte.uInt8Value] } /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .systemRealTimeAndCommon diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Common/TuneRequest/TuneRequest.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Common/TuneRequest/TuneRequest.swift index 655b520963..9dd01b6dda 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Common/TuneRequest/TuneRequest.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Common/TuneRequest/TuneRequest.swift @@ -1,7 +1,7 @@ // // TuneRequest.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -39,14 +39,16 @@ extension MIDIEvent { extension MIDIEvent.TuneRequest { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [0xF6] } /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .systemRealTimeAndCommon diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Common/UnofficialBusSelect/UnofficialBusSelect.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Common/UnofficialBusSelect/UnofficialBusSelect.swift index 76c8588497..901d8c6433 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Common/UnofficialBusSelect/UnofficialBusSelect.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Common/UnofficialBusSelect/UnofficialBusSelect.swift @@ -1,17 +1,23 @@ // // UnofficialBusSelect.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { /// Unofficial Bus Select (Status `0xF5`) /// - /// > Warning: This command is not officially supported and some MIDI subsystems will ignore it entirely. It is provided purely for legacy support and its use is discouraged. It will likely be removed in a future release of MIDIKit. + /// > Warning: This command is not officially supported and some MIDI subsystems will ignore it + /// entirely. It is provided purely for legacy support and its use is discouraged. It will + /// likely be removed in a future release of MIDIKit. /// /// > Reference: /// > - /// > Some vendors have produced boxes with a single MIDI input, and multiple MIDI outputs. The Bus Select message specifies which of the outputs further data should be sent to. This is not an official message; the vendors in question should have used a SysEx command." -- [David Van Brink's MIDI Spec](https://www.cs.cmu.edu/~music/cmsip/readings/davids-midi-spec.htm) + /// > Some vendors have produced boxes with a single MIDI input, and multiple MIDI outputs. The + /// Bus Select message specifies which of the outputs further data should be sent to. This is + /// not an official message; the vendors in question should have used a SysEx command." -- + /// [David Van Brink's MIDI + /// Spec](https://www.cs.cmu.edu/~music/cmsip/readings/davids-midi-spec.htm) public struct UnofficialBusSelect: Equatable, Hashable { /// Bus Number public var bus: UInt7 = 0 @@ -30,11 +36,17 @@ extension MIDIEvent { /// Unofficial Bus Select (Status `0xF5`) /// - /// > Warning: This command is not officially supported and some MIDI subsystems will ignore it entirely. It is provided purely for legacy support and its use is discouraged. It will likely be removed in a future release of MIDIKit. + /// > Warning: This command is not officially supported and some MIDI subsystems will ignore it + /// entirely. It is provided purely for legacy support and its use is discouraged. It will + /// likely be removed in a future release of MIDIKit. /// /// > Reference: /// > - /// > Some vendors have produced boxes with a single MIDI input, and multiple MIDI outputs. The Bus Select message specifies which of the outputs further data should be sent to. This is not an official message; the vendors in question should have used a SysEx command." -- [David Van Brink's MIDI Spec](https://www.cs.cmu.edu/~music/cmsip/readings/davids-midi-spec.htm) + /// > Some vendors have produced boxes with a single MIDI input, and multiple MIDI outputs. The + /// Bus Select message specifies which of the outputs further data should be sent to. This is + /// not an official message; the vendors in question should have used a SysEx command." -- + /// [David Van Brink's MIDI + /// Spec](https://www.cs.cmu.edu/~music/cmsip/readings/davids-midi-spec.htm) /// /// - Parameters: /// - bus: Bus Number (0x00...0x7F) @@ -55,14 +67,16 @@ extension MIDIEvent { extension MIDIEvent.UnofficialBusSelect { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [0xF5, bus.uInt8Value] } /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .systemRealTimeAndCommon diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx7/SysEx7 Parser.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx7/SysEx7 Parser.swift index 4d95b58d2d..0ab1ec4b9a 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx7/SysEx7 Parser.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx7/SysEx7 Parser.swift @@ -1,13 +1,15 @@ // // SysEx7 Parser.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation extension MIDIEvent { - /// Parse a complete raw MIDI 1.0 System Exclusive 7 message and return a ``sysEx7(manufacturer:data:group:)`` or ``universalSysEx7(universalType:deviceID:subID1:subID2:data:group:)`` case if successful. + /// Parse a complete raw MIDI 1.0 System Exclusive 7 message and return a + /// ``sysEx7(manufacturer:data:group:)`` or + /// ``universalSysEx7(universalType:deviceID:subID1:subID2:data:group:)`` case if successful. /// Message must begin with `0xF0` but terminating `0xF7` byte is optional. /// /// - Throws: ``ParseError`` if message is malformed. @@ -153,10 +155,13 @@ extension MIDIEvent { } } - /// Parse a complete raw MIDI 1.0 System Exclusive 7 message in the form of a hex string and return a ``sysEx7(manufacturer:data:group:)`` or ``universalSysEx7(universalType:deviceID:subID1:subID2:data:group:)`` case if successful. + /// Parse a complete raw MIDI 1.0 System Exclusive 7 message in the form of a hex string and + /// return a ``sysEx7(manufacturer:data:group:)`` or + /// ``universalSysEx7(universalType:deviceID:subID1:subID2:data:group:)`` case if successful. /// Message must begin with `"F0"` but terminating `"F7"` byte is optional. /// - /// Hex string may be formatted with (`"F7 01 02 03 F0"`) or without spaces (`"F7010203F0"`). String is case-insensitive. + /// Hex string may be formatted with (`"F7 01 02 03 F0"`) or without spaces (`"F7010203F0"`). + /// String is case-insensitive. /// /// - Throws: ``ParseError`` if message is malformed. public static func sysEx7( diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx7/SysEx7.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx7/SysEx7.swift index 28b88cf96c..7527d76996 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx7/SysEx7.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx7/SysEx7.swift @@ -1,7 +1,7 @@ // // SysEx7.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,9 +10,15 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > - Receivers should ignore non-universal Exclusive messages with ID numbers that do not correspond to their own ID. + /// > - Receivers should ignore non-universal Exclusive messages with ID numbers that do not + /// correspond to their own ID. /// > - /// > - Any manufacturer of MIDI hardware or software may use the system exclusive codes of any existing product without the permission of the original manufacturer. However, they may not modify or extend it in any way that conflicts with the original specification published by the designer. Once published, an Exclusive format is treated like any other part of the instruments MIDI implementation — so long as the new instrument remains within the definitions of the published specification. + /// > - Any manufacturer of MIDI hardware or software may use the system exclusive codes of any + /// existing product without the permission of the original manufacturer. However, they may not + /// modify or extend it in any way that conflicts with the original specification published by + /// the designer. Once published, an Exclusive format is treated like any other part of the + /// instruments MIDI implementation — so long as the new instrument remains within the + /// definitions of the published specification. public struct SysEx7: Equatable, Hashable { /// SysEx Manufacturer ID public var manufacturer: SysExManufacturer @@ -39,9 +45,15 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > Receivers should ignore non-universal Exclusive messages with ID numbers that do not correspond to their own ID. + /// > Receivers should ignore non-universal Exclusive messages with ID numbers that do not + /// correspond to their own ID. /// > - /// > Any manufacturer of MIDI hardware or software may use the system exclusive codes of any existing product without the permission of the original manufacturer. However, they may not modify or extend it in any way that conflicts with the original specification published by the designer. Once published, an Exclusive format is treated like any other part of the instruments MIDI implementation — so long as the new instrument remains within the definitions of the published specification. + /// > Any manufacturer of MIDI hardware or software may use the system exclusive codes of any + /// existing product without the permission of the original manufacturer. However, they may not + /// modify or extend it in any way that conflicts with the original specification published by + /// the designer. Once published, an Exclusive format is treated like any other part of the + /// instruments MIDI implementation — so long as the new instrument remains within the + /// definitions of the published specification. /// /// - Parameters: /// - manufacturer: SysEx Manufacturer ID @@ -63,7 +75,8 @@ extension MIDIEvent { } extension MIDIEvent.SysEx7 { - /// Returns the raw MIDI 1.0 message bytes that comprise the event as a human-readable string of hex characters. + /// Returns the raw MIDI 1.0 message bytes that comprise the event as a human-readable string of + /// hex characters. /// /// By default the string is returned separated by spaces (ie: `"F7 01 02 03 F0"`). /// @@ -89,7 +102,8 @@ extension MIDIEvent.SysEx7 { extension MIDIEvent.SysEx7 { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes( leadingF0: Bool = true, trailingF7: Bool = true @@ -102,9 +116,11 @@ extension MIDIEvent.SysEx7 { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// Generates one or more 64-bit UMP packets depending on the system exclusive data length (each packet comprised of two UInt32 words). + /// Generates one or more 64-bit UMP packets depending on the system exclusive data length (each + /// packet comprised of two UInt32 words). /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [[UMPWord]] { let rawData = manufacturer.sysEx7RawBytes() + data @@ -117,7 +133,8 @@ extension MIDIEvent.SysEx7 { extension MIDIEvent.SysEx7 { /// Internal: - /// Helper method to build the raw UMP packet words. This is not meant to be accessed directly; use the public `umpRawWords()` method instead. + /// Helper method to build the raw UMP packet words. This is not meant to be accessed directly; + /// use the public `umpRawWords()` method instead. internal static func umpRawWords( fromSysEx7Data data: [UInt8], group: UInt4 diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx7/UniversalSysEx7.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx7/UniversalSysEx7.swift index a1104e1035..1149f9684e 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx7/UniversalSysEx7.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx7/UniversalSysEx7.swift @@ -1,14 +1,15 @@ // // UniversalSysEx7.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { /// Universal System Exclusive (7-bit) /// (MIDI 1.0 / 2.0) /// - /// Some standard Universal System Exclusive messages have been defined by the MIDI Spec. See the official MIDI 1.0 and 2.0 specs for details. + /// Some standard Universal System Exclusive messages have been defined by the MIDI Spec. See + /// the official MIDI 1.0 and 2.0 specs for details. /// /// - `deviceID` of `0x7F` indicates "All Devices". public struct UniversalSysEx7: Equatable, Hashable { @@ -52,7 +53,8 @@ extension MIDIEvent { /// System Exclusive: Universal SysEx (7-bit) /// (MIDI 1.0 / 2.0) /// - /// Some standard Universal System Exclusive messages have been defined by the MIDI Spec. See the official MIDI 1.0 and 2.0 specs for details. + /// Some standard Universal System Exclusive messages have been defined by the MIDI Spec. See + /// the official MIDI 1.0 and 2.0 specs for details. /// /// - Parameters: /// - universalType: Universal SysEx type: realtime or non-realtime @@ -85,7 +87,8 @@ extension MIDIEvent { extension MIDIEvent.UniversalSysEx7 { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes( leadingF0: Bool = true, trailingF7: Bool = true @@ -103,7 +106,8 @@ extension MIDIEvent.UniversalSysEx7 { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [[UMPWord]] { let rawData = [ diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx8/SysEx8 Parser.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx8/SysEx8 Parser.swift index fdd870556c..33ebf8da92 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx8/SysEx8 Parser.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx8/SysEx8 Parser.swift @@ -1,19 +1,23 @@ // // SysEx8 Parser.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation extension MIDIEvent { - /// Parse a complete MIDI 2.0 System Exclusive 8 message (starting with the Stream ID byte until the end of the packet) and return a ``sysEx8(manufacturer:data:group:)`` or ``universalSysEx8(universalType:deviceID:subID1:subID2:data:group:)`` case if successful. + /// Parse a complete MIDI 2.0 System Exclusive 8 message (starting with the Stream ID byte until + /// the end of the packet) and return a ``sysEx8(manufacturer:data:group:)`` or + /// ``universalSysEx8(universalType:deviceID:subID1:subID2:data:group:)`` case if successful. /// - /// Valid rawBytes count is `1 ... 14`. (Must always contain a Stream ID, even if there are zero data bytes to follow) + /// Valid rawBytes count is `1 ... 14`. (Must always contain a Stream ID, even if there are zero + /// data bytes to follow) /// /// > Note: This does not parse an entire SysEx8 UMP packet. /// > - /// > `rawBytes` must start with the Stream ID byte and supply all bytes until the end of the packet. + /// > `rawBytes` must start with the Stream ID byte and supply all bytes until the end of the + /// packet. /// /// - Throws: ``ParseError`` if message is malformed. public static func sysEx8( diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx8/SysEx8.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx8/SysEx8.swift index 2976b0f7a0..59bc316a71 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx8/SysEx8.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx8/SysEx8.swift @@ -1,7 +1,7 @@ // // SysEx8.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,7 +10,11 @@ extension MIDIEvent { /// /// > MIDI 2.0 Spec: /// > - /// > System Exclusive 8 messages have many similarities to the MIDI 1.0 Protocol’s original System Exclusive messages, but with the added advantage of allowing all 8 bits of each data byte to be used. By contrast, MIDI 1.0 Protocol System Exclusive requires a 0 in the high bit of every data byte, leaving only 7 bits to carry actual data. A System Exclusive 8 Message is carried in one or more 128-bit UMPs. + /// > System Exclusive 8 messages have many similarities to the MIDI 1.0 Protocol’s original + /// System Exclusive messages, but with the added advantage of allowing all 8 bits of each data + /// byte to be used. By contrast, MIDI 1.0 Protocol System Exclusive requires a 0 in the high + /// bit of every data byte, leaving only 7 bits to carry actual data. A System Exclusive 8 + /// Message is carried in one or more 128-bit UMPs. public struct SysEx8: Equatable, Hashable { /// SysEx Manufacturer ID public var manufacturer: SysExManufacturer @@ -19,10 +23,13 @@ extension MIDIEvent { /// /// > MIDI 2.0 Spec: /// > - /// > System Exclusive 8 initial data bytes are the same as those found in MIDI 1.0 Protocol System Exclusive messages. These bytes are Manufacturer ID (including Special ID `0x7D`, or Universal System Exclusive IDs), Device ID, and Sub-ID#1 & Sub-ID#2 (if applicable). + /// > System Exclusive 8 initial data bytes are the same as those found in MIDI 1.0 Protocol + /// System Exclusive messages. These bytes are Manufacturer ID (including Special ID `0x7D`, + /// or Universal System Exclusive IDs), Device ID, and Sub-ID#1 & Sub-ID#2 (if applicable). public var data: [UInt8] - /// Interleaving of multiple simultaneous System Exclusive 8 messages is enabled by use of an 8-bit Stream ID field. + /// Interleaving of multiple simultaneous System Exclusive 8 messages is enabled by use of + /// an 8-bit Stream ID field. internal var streamID: UInt8 = 0x00 /// UMP Group (`0x0 ... 0xF`) @@ -56,7 +63,11 @@ extension MIDIEvent { /// /// > MIDI 2.0 Spec: /// > - /// > System Exclusive 8 messages have many similarities to the MIDI 1.0 Protocol’s original System Exclusive messages, but with the added advantage of allowing all 8 bits of each data byte to be used. By contrast, MIDI 1.0 Protocol System Exclusive requires a 0 in the high bit of every data byte, leaving only 7 bits to carry actual data. A System Exclusive 8 Message is carried in one or more 128-bit UMPs. + /// > System Exclusive 8 messages have many similarities to the MIDI 1.0 Protocol’s original + /// System Exclusive messages, but with the added advantage of allowing all 8 bits of each data + /// byte to be used. By contrast, MIDI 1.0 Protocol System Exclusive requires a 0 in the high + /// bit of every data byte, leaving only 7 bits to carry actual data. A System Exclusive 8 + /// Message is carried in one or more 128-bit UMPs. /// /// - Parameters: /// - manufacturer: SysEx Manufacturer ID @@ -80,9 +91,11 @@ extension MIDIEvent { extension MIDIEvent.SysEx8 { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// Generates one or more 64-bit UMP packets depending on the system exclusive data length (each packet comprised of two UInt32 words). + /// Generates one or more 64-bit UMP packets depending on the system exclusive data length (each + /// packet comprised of two UInt32 words). /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [[UMPWord]] { let rawData = manufacturer.sysEx8RawBytes() + data @@ -96,7 +109,8 @@ extension MIDIEvent.SysEx8 { extension MIDIEvent.SysEx8 { /// Internal: - /// Helper method to build the raw UMP packet words. This is not meant to be accessed directly; use the public ``umpRawWords()`` method instead. + /// Helper method to build the raw UMP packet words. This is not meant to be accessed directly; + /// use the public ``umpRawWords()`` method instead. internal static func umpRawWords( fromSysEx8Data data: [UInt8], streamID: UInt8, diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx8/UniversalSysEx8.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx8/UniversalSysEx8.swift index 6e9c7755d6..1782b2df0e 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx8/UniversalSysEx8.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysEx8/UniversalSysEx8.swift @@ -1,7 +1,7 @@ // // UniversalSysEx8.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -27,7 +27,8 @@ extension MIDIEvent { /// Data bytes (8-bit) (excluding leading 0xF0, trailing 0xF7, universal type and ID bytes) public var data: [UInt8] - /// Interleaving of multiple simultaneous System Exclusive 8 messages is enabled by use of an 8-bit Stream ID field. + /// Interleaving of multiple simultaneous System Exclusive 8 messages is enabled by use of + /// an 8-bit Stream ID field. internal var streamID: UInt8 = 0x00 /// UMP Group (`0x0 ... 0xF`) @@ -102,7 +103,8 @@ extension MIDIEvent { extension MIDIEvent.UniversalSysEx8 { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [[UMPWord]] { let rawData = [ diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysExID/SysExID.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysExID/SysExID.swift index 759cdd1473..570f68824f 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysExID/SysExID.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysExID/SysExID.swift @@ -1,7 +1,7 @@ // // SysExID.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -61,7 +61,8 @@ extension MIDIEvent.SysExID { } extension MIDIEvent.SysExID { - /// Returns the Manufacturer byte(s) formatted for MIDI 1.0 SysEx7, as one byte (7-bit) or three bytes (21-bit). + /// Returns the Manufacturer byte(s) formatted for MIDI 1.0 SysEx7, as one byte (7-bit) or three + /// bytes (21-bit). public func sysEx7RawBytes() -> [UInt8] { switch self { case let .manufacturer(mfr): diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysExManufacturer/SysExManufacturer.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysExManufacturer/SysExManufacturer.swift index 48ee7244f4..1692eb9b78 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysExManufacturer/SysExManufacturer.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysExManufacturer/SysExManufacturer.swift @@ -1,7 +1,7 @@ // // SysExManufacturer.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -11,9 +11,13 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > - To avoid conflicts with non-compatible Exclusive messages, a specific ID number is granted to manufacturers of MIDI instruments by the MMA or JMSC. + /// > - To avoid conflicts with non-compatible Exclusive messages, a specific ID number is + /// granted to manufacturers of MIDI instruments by the MMA or JMSC. /// > - /// > - `[0x00]` and `[0x00 0x00 0x00]` are not to be used. Special ID `0x7D` is reserved for non-commercial use (e.g. schools, research, etc.) and is not to be used on any product released to the public. Since Non-Commercial codes would not be seen or used by an ordinary user, there is no standard format. + /// > - `[0x00]` and `[0x00 0x00 0x00]` are not to be used. Special ID `0x7D` is reserved for + /// non-commercial use (e.g. schools, research, etc.) and is not to be used on any product + /// released to the public. Since Non-Commercial codes would not be seen or used by an ordinary + /// user, there is no standard format. /// > /// > - Special IDs `0x7E` and `0x7F` are the Universal System Exclusive IDs. /// @@ -97,7 +101,8 @@ extension MIDIEvent.SysExManufacturer { } extension MIDIEvent.SysExManufacturer { - /// Returns the Manufacturer byte(s) formatted for MIDI 1.0 SysEx7, as one byte (7-bit) or three bytes (21-bit). + /// Returns the Manufacturer byte(s) formatted for MIDI 1.0 SysEx7, as one byte (7-bit) or three + /// bytes (21-bit). public func sysEx7RawBytes() -> [UInt8] { switch self { case let .oneByte(byte): @@ -126,9 +131,11 @@ extension MIDIEvent.SysExManufacturer { extension MIDIEvent.SysExManufacturer { /// Returns whether the byte(s) are valid SysEx Manufacturer IDs. /// - /// This does not test whether the ID belongs to a registered manufacturer. Rather, it simply reports if the bytes are legal. + /// This does not test whether the ID belongs to a registered manufacturer. Rather, it simply + /// reports if the bytes are legal. /// - /// Use the ``name`` property to return the manufacturer's name associated with the ID, or `nil` if the ID is not registered. + /// Use the ``name`` property to return the manufacturer's name associated with the ID, or `nil` + /// if the ID is not registered. public var isValid: Bool { switch self { case let .oneByte(byte): @@ -141,7 +148,8 @@ extension MIDIEvent.SysExManufacturer { } } - /// Returns the name of the manufacturer associated with the Manufacturer System Exclusive ID, as assigned by the MIDI Manufacturers Association. + /// Returns the name of the manufacturer associated with the Manufacturer System Exclusive ID, + /// as assigned by the MIDI Manufacturers Association. /// /// Returns `nil` if the ID is not recognized. public var name: String? { @@ -160,7 +168,8 @@ extension MIDIEvent.SysExManufacturer: CustomStringConvertible { extension MIDIEvent.SysExManufacturer { /// Returns a new instance containing the Educational Use ID. /// - /// - Note: Reserved for use only in educational institutions or for unit testing; not public release. + /// - Note: Reserved for use only in educational institutions or for unit testing; not public + /// release. public static func educational() -> Self { .oneByte(0x7D) } @@ -170,7 +179,8 @@ extension MIDIEvent.SysExManufacturer { // Data updated as of March 2021 // source: https://www.midi.org/specifications-old/item/manufacturer-id-numbers - /// Lookup table for Manufacturer MIDI SysEx (system exclusive) IDs assigned by the MIDI Manufacturers Association. + /// Lookup table for Manufacturer MIDI SysEx (system exclusive) IDs assigned by the MIDI + /// Manufacturers Association. /// /// (IDs can be either 1 or 3 bytes long.) static let kSysExIDs: [[UInt8]: String] = [ diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysExType.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysExType.swift index 671fdfe0f3..254396b460 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysExType.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/SysExType.swift @@ -1,7 +1,7 @@ // // SysExType.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/UniversalSysExType.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/UniversalSysExType.swift index 0347cee2b6..602c1ed6f8 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/UniversalSysExType.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Exclusive/UniversalSysExType.swift @@ -40,7 +40,7 @@ extension MIDIEvent.UniversalSysExType: CustomStringConvertible { extension MIDIEvent { /// SysEx: Device Inquiry request message. /// - /// When a device receives a Device Inquiry request message that matches its device ID or uses the device ID of `0x7F` (meaning "all devices"), it should respond with a Device Inquiry response message (``deviceInquiryResponse(deviceID:)``). + /// When a device receives a Device Inquiry request message that matches its device ID or uses the device ID of `0x7F` (meaning "all devices"), it should respond with a Device Inquiry response message (``deviceInquiryResponse(deviceID:manufacturer:deviceFamilyCode:deviceFamilyMemberCode:softwareRevision:)``). /// /// - Parameter deviceID: SysEx Device ID. An ID of 0x7F indicates "all devices". /// - Returns: SysEx7 Message. diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/ActiveSensing/ActiveSensing.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/ActiveSensing/ActiveSensing.swift index 6bf9453478..99aa1480f3 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/ActiveSensing/ActiveSensing.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/ActiveSensing/ActiveSensing.swift @@ -1,7 +1,7 @@ // // ActiveSensing.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,9 +10,17 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// Use of Active Sensing is optional for either receivers or transmitters. This byte (`0xFE`) is sent every 300 ms (maximum) whenever there is no other MIDI data being transmitted. If a device never receives Active Sensing it should operate normally. However, once the receiver recognizes Active Sensing (`0xFE`), it then will expect to get a message of some kind every 300 milliseconds. If no messages are received within this time period the receiver will assume the MIDI cable has been disconnected for some reason and should turn off all voices and return to normal operation. It is recommended that transmitters transmit Active Sensing within 270ms and receivers judge at over 330ms leaving a margin of roughly 10%. + /// Use of Active Sensing is optional for either receivers or transmitters. This byte (`0xFE`) + /// is sent every 300 ms (maximum) whenever there is no other MIDI data being transmitted. If a + /// device never receives Active Sensing it should operate normally. However, once the receiver + /// recognizes Active Sensing (`0xFE`), it then will expect to get a message of some kind every + /// 300 milliseconds. If no messages are received within this time period the receiver will + /// assume the MIDI cable has been disconnected for some reason and should turn off all voices + /// and return to normal operation. It is recommended that transmitters transmit Active Sensing + /// within 270ms and receivers judge at over 330ms leaving a margin of roughly 10%. /// - /// - Note: Use of Active Sensing in modern MIDI devices is uncommon and the use of this standard has been deprecated as of MIDI 2.0. + /// - Note: Use of Active Sensing in modern MIDI devices is uncommon and the use of this + /// standard has been deprecated as of MIDI 2.0. public struct ActiveSensing: Equatable, Hashable { /// UMP Group (`0x0 ... 0xF`) public var group: UInt4 = 0x0 @@ -27,9 +35,17 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > Use of Active Sensing is optional for either receivers or transmitters. This byte (`0xFE`) is sent every 300 ms (maximum) whenever there is no other MIDI data being transmitted. If a device never receives Active Sensing it should operate normally. However, once the receiver recognizes Active Sensing (`0xFE`), it then will expect to get a message of some kind every 300 milliseconds. If no messages are received within this time period the receiver will assume the MIDI cable has been disconnected for some reason and should turn off all voices and return to normal operation. It is recommended that transmitters transmit Active Sensing within 270ms and receivers judge at over 330ms leaving a margin of roughly 10%. + /// > Use of Active Sensing is optional for either receivers or transmitters. This byte (`0xFE`) + /// is sent every 300 ms (maximum) whenever there is no other MIDI data being transmitted. If a + /// device never receives Active Sensing it should operate normally. However, once the receiver + /// recognizes Active Sensing (`0xFE`), it then will expect to get a message of some kind every + /// 300 milliseconds. If no messages are received within this time period the receiver will + /// assume the MIDI cable has been disconnected for some reason and should turn off all voices + /// and return to normal operation. It is recommended that transmitters transmit Active Sensing + /// within 270ms and receivers judge at over 330ms leaving a margin of roughly 10%. /// - /// - Note: Use of Active Sensing in modern MIDI devices is uncommon and the use of this standard has been deprecated as of MIDI 2.0. + /// - Note: Use of Active Sensing in modern MIDI devices is uncommon and the use of this + /// standard has been deprecated as of MIDI 2.0. /// /// - Parameters: /// - group: UMP Group (`0x0 ... 0xF`) @@ -43,14 +59,16 @@ extension MIDIEvent { extension MIDIEvent.ActiveSensing { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [0xFE] } /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .systemRealTimeAndCommon diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/Continue/Continue.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/Continue/Continue.swift index d65a5fb180..38e78f4003 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/Continue/Continue.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/Continue/Continue.swift @@ -1,7 +1,7 @@ // // Continue.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,7 +10,8 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > Continue (`0xFB`) is sent when a CONTINUE button is hit. A sequence will continue from its current location upon receipt of the next Timing Clock (`0xF8`). + /// > Continue (`0xFB`) is sent when a CONTINUE button is hit. A sequence will continue from its + /// current location upon receipt of the next Timing Clock (`0xF8`). public struct Continue: Equatable, Hashable { /// UMP Group (`0x0 ... 0xF`) public var group: UInt4 = 0x0 @@ -25,7 +26,8 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > Continue (`0xFB`) is sent when a CONTINUE button is hit. A sequence will continue from its current location upon receipt of the next Timing Clock (`0xF8`). + /// > Continue (`0xFB`) is sent when a CONTINUE button is hit. A sequence will continue from its + /// current location upon receipt of the next Timing Clock (`0xF8`). /// /// - Parameters: /// - group: UMP Group (`0x0 ... 0xF`) @@ -39,14 +41,16 @@ extension MIDIEvent { extension MIDIEvent.Continue { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [0xFB] } /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .systemRealTimeAndCommon diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/Start/Start.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/Start/Start.swift index 27ec682998..84a47d605e 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/Start/Start.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/Start/Start.swift @@ -1,7 +1,7 @@ // // Start.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,7 +10,9 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// Start (`0xFA`) is sent when a PLAY button on the master (sequencer or drum machine) is pressed. This message commands all receivers which are synchronized to incoming Real-Time messages (MIDI Sync mode) to start at the beginning of the song or sequence. + /// Start (`0xFA`) is sent when a PLAY button on the master (sequencer or drum machine) is + /// pressed. This message commands all receivers which are synchronized to incoming Real-Time + /// messages (MIDI Sync mode) to start at the beginning of the song or sequence. public struct Start: Equatable, Hashable { /// UMP Group (`0x0 ... 0xF`) public var group: UInt4 = 0x0 @@ -25,7 +27,9 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > Start (`0xFA`) is sent when a PLAY button on the master (sequencer or drum machine) is pressed. This message commands all receivers which are synchronized to incoming Real-Time messages (MIDI Sync mode) to start at the beginning of the song or sequence. + /// > Start (`0xFA`) is sent when a PLAY button on the master (sequencer or drum machine) is + /// pressed. This message commands all receivers which are synchronized to incoming Real-Time + /// messages (MIDI Sync mode) to start at the beginning of the song or sequence. /// /// - Parameters: /// - group: UMP Group (`0x0 ... 0xF`) @@ -39,14 +43,16 @@ extension MIDIEvent { extension MIDIEvent.Start { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [0xFA] } /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .systemRealTimeAndCommon diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/Stop/Stop.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/Stop/Stop.swift index a0c102539c..80b6b1642e 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/Stop/Stop.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/Stop/Stop.swift @@ -1,7 +1,7 @@ // // Stop.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,7 +10,8 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > Stop (`0xFC`) is sent when a STOP button is hit. Playback in a receiver should stop immediately. + /// > Stop (`0xFC`) is sent when a STOP button is hit. Playback in a receiver should stop + /// immediately. public struct Stop: Equatable, Hashable { /// UMP Group (`0x0 ... 0xF`) public var group: UInt4 = 0x0 @@ -25,7 +26,8 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > Stop (`0xFC`) is sent when a STOP button is hit. Playback in a receiver should stop immediately. + /// > Stop (`0xFC`) is sent when a STOP button is hit. Playback in a receiver should stop + /// immediately. /// /// - Parameters: /// - group: UMP Group (`0x0 ... 0xF`) @@ -39,14 +41,16 @@ extension MIDIEvent { extension MIDIEvent.Stop { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [0xFC] } /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .systemRealTimeAndCommon diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/SysRealTimeType.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/SysRealTimeType.swift index 824970e8af..bcf183ec13 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/SysRealTimeType.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/SysRealTimeType.swift @@ -1,7 +1,7 @@ // // SysRealTimeType.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/SystemReset/SystemReset.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/SystemReset/SystemReset.swift index 143278783a..049a1eab86 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/SystemReset/SystemReset.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/SystemReset/SystemReset.swift @@ -1,7 +1,7 @@ // // SystemReset.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,7 +10,10 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > System Reset commands all devices in a system to return to their initialized, power-up condition. This message should be used sparingly, and should typically be sent by manual control only. It should not be sent automatically upon power-up and under no condition should this message be echoed. + /// > System Reset commands all devices in a system to return to their initialized, power-up + /// condition. This message should be used sparingly, and should typically be sent by manual + /// control only. It should not be sent automatically upon power-up and under no condition + /// should this message be echoed. public struct SystemReset: Equatable, Hashable { /// UMP Group (`0x0 ... 0xF`) public var group: UInt4 = 0x0 @@ -25,7 +28,10 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// System Reset commands all devices in a system to return to their initialized, power-up condition. This message should be used sparingly, and should typically be sent by manual control only. It should not be sent automatically upon power-up and under no condition should this message be echoed. + /// System Reset commands all devices in a system to return to their initialized, power-up + /// condition. This message should be used sparingly, and should typically be sent by manual + /// control only. It should not be sent automatically upon power-up and under no condition + /// should this message be echoed. /// /// - Parameters: /// - group: UMP Group (`0x0 ... 0xF`) @@ -39,14 +45,16 @@ extension MIDIEvent { extension MIDIEvent.SystemReset { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [0xFF] } /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .systemRealTimeAndCommon diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/TimingClock/TimingClock.swift b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/TimingClock/TimingClock.swift index ffb398db4c..adfd2b8e50 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/TimingClock/TimingClock.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/System Real-Time/TimingClock/TimingClock.swift @@ -1,7 +1,7 @@ // // TimingClock.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,7 +10,11 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > Clock-based MIDI systems are synchronized with this message, which is sent at a rate of 24 per quarter note. If Timing Clocks (`0xF8`) are sent during idle time they should be sent at the current tempo setting of the transmitter even while it is not playing. Receivers which are synchronized to incoming Real-Time messages (MIDI Sync mode) can thus phase lock their internal clocks while waiting for a Start (`0xFA`) or Continue (`0xFB`) command. + /// > Clock-based MIDI systems are synchronized with this message, which is sent at a rate of 24 + /// per quarter note. If Timing Clocks (`0xF8`) are sent during idle time they should be sent at + /// the current tempo setting of the transmitter even while it is not playing. Receivers which + /// are synchronized to incoming Real-Time messages (MIDI Sync mode) can thus phase lock their + /// internal clocks while waiting for a Start (`0xFA`) or Continue (`0xFB`) command. public struct TimingClock: Equatable, Hashable { /// UMP Group (`0x0 ... 0xF`) public var group: UInt4 = 0x0 @@ -25,7 +29,11 @@ extension MIDIEvent { /// /// > MIDI 1.0 Spec: /// > - /// > Clock-based MIDI systems are synchronized with this message, which is sent at a rate of 24 per quarter note. If Timing Clocks (`0xF8`) are sent during idle time they should be sent at the current tempo setting of the transmitter even while it is not playing. Receivers which are synchronized to incoming Real-Time messages (MIDI Sync mode) can thus phase lock their internal clocks while waiting for a Start (`0xFA`) or Continue (`0xFB`) command. + /// > Clock-based MIDI systems are synchronized with this message, which is sent at a rate of 24 + /// per quarter note. If Timing Clocks (`0xF8`) are sent during idle time they should be sent at + /// the current tempo setting of the transmitter even while it is not playing. Receivers which + /// are synchronized to incoming Real-Time messages (MIDI Sync mode) can thus phase lock their + /// internal clocks while waiting for a Start (`0xFA`) or Continue (`0xFB`) command. /// /// - Parameters: /// - group: UMP Group (`0x0 ... 0xF`) @@ -39,14 +47,16 @@ extension MIDIEvent { extension MIDIEvent.TimingClock { /// Returns the raw MIDI 1.0 message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func midi1RawBytes() -> [UInt8] { [0xF8] } /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .systemRealTimeAndCommon diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Utility/JRClock/JRClock.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Utility/JRClock/JRClock.swift index a75f8fb014..c86775e9cd 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Utility/JRClock/JRClock.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Utility/JRClock/JRClock.swift @@ -1,7 +1,7 @@ // // JRClock.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -12,21 +12,27 @@ extension MIDIEvent { /// > /// > The JR Clock message defines the current time of the Sender. /// > - /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 MHz / 32). + /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 + /// MHz / 32). /// > /// > The time value is expected to wrap around every 2.09712 seconds. /// > - /// > To avoid ambiguity of the 2.09712 seconds wrap, and to provide sufficient JR Clock messages for the Receiver, the Sender shall send a JR Clock message at least once every 250 milliseconds. + /// > To avoid ambiguity of the 2.09712 seconds wrap, and to provide sufficient JR Clock + /// messages for the Receiver, the Sender shall send a JR Clock message at least once every 250 + /// milliseconds. public struct JRClock: Equatable, Hashable { /// 16-Bit Time Value /// /// > MIDI 2.0 Spec: /// > - /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 MHz / 32). + /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency + /// of 1 MHz / 32). /// > /// > The time value is expected to wrap around every 2.09712 seconds. /// > - /// > To avoid ambiguity of the 2.09712 seconds wrap, and to provide sufficient JR Clock messages for the Receiver, the Sender shall send a JR Clock message at least once every 250 milliseconds. + /// > To avoid ambiguity of the 2.09712 seconds wrap, and to provide sufficient JR Clock + /// messages for the Receiver, the Sender shall send a JR Clock message at least once every + /// 250 milliseconds. public var time: UInt16 /// UMP Group (`0x0 ... 0xF`) @@ -39,11 +45,14 @@ extension MIDIEvent { /// > /// > The JR Clock message defines the current time of the Sender. /// > - /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 MHz / 32). + /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency + /// of 1 MHz / 32). /// > /// > The time value is expected to wrap around every 2.09712 seconds. /// > - /// > To avoid ambiguity of the 2.09712 seconds wrap, and to provide sufficient JR Clock messages for the Receiver, the Sender shall send a JR Clock message at least once every 250 milliseconds. + /// > To avoid ambiguity of the 2.09712 seconds wrap, and to provide sufficient JR Clock + /// messages for the Receiver, the Sender shall send a JR Clock message at least once every + /// 250 milliseconds. public init( time: UInt16, group: UInt4 = 0x0 @@ -60,11 +69,14 @@ extension MIDIEvent { /// > /// > The JR Clock message defines the current time of the Sender. /// > - /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 MHz / 32). + /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 + /// MHz / 32). /// > /// > The time value is expected to wrap around every 2.09712 seconds. /// > - /// > To avoid ambiguity of the 2.09712 seconds wrap, and to provide sufficient JR Clock messages for the Receiver, the Sender shall send a JR Clock message at least once every 250 milliseconds. + /// > To avoid ambiguity of the 2.09712 seconds wrap, and to provide sufficient JR Clock + /// messages for the Receiver, the Sender shall send a JR Clock message at least once every 250 + /// milliseconds. public static func jrClock( time: UInt16, group: UInt4 = 0x0 @@ -81,7 +93,8 @@ extension MIDIEvent { extension MIDIEvent.JRClock { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .utility diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Utility/JRTimestamp/JRTimestamp.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Utility/JRTimestamp/JRTimestamp.swift index 0cd6b7bdeb..35773febfa 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Utility/JRTimestamp/JRTimestamp.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Utility/JRTimestamp/JRTimestamp.swift @@ -1,7 +1,7 @@ // // JRTimestamp.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,17 +10,21 @@ extension MIDIEvent { /// /// > MIDI 2.0 Spec: /// > - /// > The JR Timestamp message defines the time of the following message(s). It is a complete message. + /// > The JR Timestamp message defines the time of the following message(s). It is a complete + /// message. /// > - /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 MHz / 32). + /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 + /// MHz / 32). public struct JRTimestamp: Equatable, Hashable { /// 16-Bit Time Value /// /// > MIDI 2.0 Spec: /// > - /// > The JR Timestamp message defines the time of the following message(s). It is a complete message. + /// > The JR Timestamp message defines the time of the following message(s). It is a + /// complete message. /// > - /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 MHz / 32). + /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency + /// of 1 MHz / 32). public var time: UInt16 /// UMP Group (`0x0 ... 0xF`) @@ -31,9 +35,11 @@ extension MIDIEvent { /// /// > MIDI 2.0 Spec: /// > - /// > The JR Timestamp message defines the time of the following message(s). It is a complete message. + /// > The JR Timestamp message defines the time of the following message(s). It is a + /// complete message. /// > - /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 MHz / 32). + /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency + /// of 1 MHz / 32). public init( time: UInt16, group: UInt4 = 0x0 @@ -48,9 +54,11 @@ extension MIDIEvent { /// /// > MIDI 2.0 Spec: /// > - /// > The JR Timestamp message defines the time of the following message(s). It is a complete message. + /// > The JR Timestamp message defines the time of the following message(s). It is a complete + /// message. /// > - /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 MHz / 32). + /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 + /// MHz / 32). public static func jrTimestamp( time: UInt16, group: UInt4 = 0x0 @@ -67,7 +75,8 @@ extension MIDIEvent { extension MIDIEvent.JRTimestamp { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .utility diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Utility/NoOp/NoOp.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Utility/NoOp/NoOp.swift index 38cb7b24d9..5d6be5cba1 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Utility/NoOp/NoOp.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Utility/NoOp/NoOp.swift @@ -1,7 +1,7 @@ // // NoOp.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDIEvent { @@ -10,7 +10,9 @@ extension MIDIEvent { /// /// > MIDI 2.0 Spec: /// > - /// > The UMP Format provides a set of Utility Messages. Utility Messages include but are not limited to NOOP and timestamps, and might in the future include UMP transport-related functions. + /// > The UMP Format provides a set of Utility Messages. Utility Messages include but are not + /// limited to NOOP and timestamps, and might in the future include UMP transport-related + /// functions. public struct NoOp: Equatable, Hashable { /// UMP Group (`0x0 ... 0xF`) public var group: UInt4 = 0x0 @@ -25,7 +27,9 @@ extension MIDIEvent { /// /// > MIDI 2.0 Spec: /// > - /// > The UMP Format provides a set of Utility Messages. Utility Messages include but are not limited to NOOP and timestamps, and might in the future include UMP transport-related functions. + /// > The UMP Format provides a set of Utility Messages. Utility Messages include but are not + /// limited to NOOP and timestamps, and might in the future include UMP transport-related + /// functions. /// /// - Parameters: /// - group: UMP Group (`0x0 ... 0xF`) @@ -39,7 +43,8 @@ extension MIDIEvent { extension MIDIEvent.NoOp { /// Returns the raw MIDI 2.0 UMP (Universal MIDI Packet) message bytes that comprise the event. /// - /// - Note: This is mainly for internal use and is not necessary to access during typical usage of MIDIKit, but is provided publicly for introspection and debugging purposes. + /// - Note: This is mainly for internal use and is not necessary to access during typical usage + /// of MIDIKit, but is provided publicly for introspection and debugging purposes. public func umpRawWords() -> [UMPWord] { let umpMessageType: MIDIUMPMessageType = .utility diff --git a/Sources/MIDIKitCore/Events/MIDIEvent/Utility/UtilityType.swift b/Sources/MIDIKitCore/Events/MIDIEvent/Utility/UtilityType.swift index 658b031cef..63769f47c9 100644 --- a/Sources/MIDIKitCore/Events/MIDIEvent/Utility/UtilityType.swift +++ b/Sources/MIDIKitCore/Events/MIDIEvent/Utility/UtilityType.swift @@ -1,7 +1,7 @@ // // UtilityType.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter Channel Voice.swift b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter Channel Voice.swift index bafc28ecb5..443bfaf3cc 100644 --- a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter Channel Voice.swift +++ b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter Channel Voice.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter Channel Voice.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // // MARK: - Metadata properties diff --git a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter Group.swift b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter Group.swift index b88f779b3f..dc72d191c8 100644 --- a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter Group.swift +++ b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter Group.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter Group.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // // MARK: - Filter diff --git a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter System Common.swift b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter System Common.swift index f962cd16e4..c6b8d3ce83 100644 --- a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter System Common.swift +++ b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter System Common.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter System Common.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // // MARK: - Metadata properties diff --git a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter System Exclusive.swift b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter System Exclusive.swift index 3f22fa611a..df5e98ccc6 100644 --- a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter System Exclusive.swift +++ b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter System Exclusive.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter System Exclusive.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // // MARK: - Metadata properties diff --git a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter System Real-Time.swift b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter System Real-Time.swift index f23b284241..6e74639c21 100644 --- a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter System Real-Time.swift +++ b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter System Real-Time.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter System Real-Time.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // // MARK: - Metadata properties diff --git a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter Utility.swift b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter Utility.swift index fe8708ddbf..a9f79063aa 100644 --- a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter Utility.swift +++ b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEvent Filter Utility.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter Utility.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // // MARK: - Metadata properties diff --git a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEventFilter.swift b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEventFilter.swift index 26a264ab63..7b5e99c678 100644 --- a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEventFilter.swift +++ b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEventFilter.swift @@ -1,7 +1,7 @@ // // MIDIEventFilter.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// MIDI event filter definition. diff --git a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEventFilterGroup.swift b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEventFilterGroup.swift index 03168d3591..8ebf1dfd38 100644 --- a/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEventFilterGroup.swift +++ b/Sources/MIDIKitCore/Events/MIDIEventFilter/MIDIEventFilterGroup.swift @@ -1,25 +1,29 @@ // // MIDIEventFilterGroup.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // -/// A group of filters containing zero or more MIDI event filters in series, with a method to filter MIDI events through the stored filters. +/// A group of filters containing zero or more MIDI event filters in series, with a method to filter +/// MIDI events through the stored filters. public struct MIDIEventFilterGroup { /// Filters to use, processed in series. public var filters: [MIDIEventFilter] - /// An object that stores zero or more MIDI event filters, with a method to filter MIDI events through the filters. + /// An object that stores zero or more MIDI event filters, with a method to filter MIDI events + /// through the filters. public init() { filters = [] } - /// An object that stores zero or more MIDI event filters, with a method to filter MIDI events through the filters. + /// An object that stores zero or more MIDI event filters, with a method to filter MIDI events + /// through the filters. public init(filter: MIDIEventFilter) { filters = [filter] } - /// An object that stores zero or more MIDI event filters, with a method to filter MIDI events through the filters. + /// An object that stores zero or more MIDI event filters, with a method to filter MIDI events + /// through the filters. public init(filters: [MIDIEventFilter]) { self.filters = filters } diff --git a/Sources/MIDIKitCore/Events/MIDINote/MIDINote Layout.swift b/Sources/MIDIKitCore/Events/MIDINote/MIDINote Layout.swift index 6f029a451e..5cd0bd75c2 100644 --- a/Sources/MIDIKitCore/Events/MIDINote/MIDINote Layout.swift +++ b/Sources/MIDIKitCore/Events/MIDINote/MIDINote Layout.swift @@ -1,7 +1,7 @@ // // MIDINote Layout.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -33,7 +33,8 @@ extension MIDINoteRange { } extension MIDINote { - /// Returns `true` if note is sharp (has a ♯ accidental). On a piano keyboard, this would be a black key. + /// Returns `true` if note is sharp (has a ♯ accidental). + /// On a piano keyboard, this would be a black key. public var isSharp: Bool { let octaveMod = number % 12 return [1, 3, 6, 8, 10].contains(octaveMod) diff --git a/Sources/MIDIKitCore/Events/MIDINote/MIDINote Name.swift b/Sources/MIDIKitCore/Events/MIDINote/MIDINote Name.swift index 854a1ceb7b..640557adea 100644 --- a/Sources/MIDIKitCore/Events/MIDINote/MIDINote Name.swift +++ b/Sources/MIDIKitCore/Events/MIDINote/MIDINote Name.swift @@ -1,7 +1,7 @@ // // MIDINote Name.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // extension MIDINote { @@ -171,7 +171,9 @@ extension MIDINote { /// Returns the note name as a string. /// /// - Parameters: - /// - respellSharpAsFlat: If note is sharp, respell enharmonically as a flat (ie: G♯ becomes A♭) Otherwise, sharp is always used, which is typical convention for MIDI note names. + /// - respellSharpAsFlat: If note is sharp, respell enharmonically as a flat (ie: G♯ + /// becomes A♭) Otherwise, sharp is always used, which is typical convention for MIDI note + /// names. /// - unicodeAccidental: Use stylized unicode character for sharp (♯) and flat (♭). public func stringValue( respellSharpAsFlat: Bool = false, @@ -221,7 +223,8 @@ extension MIDINote { // swiftformat:enable spacearoundoperators } - /// Returns `true` if note is sharp (has a ♯ accidental). On a piano keyboard, this would be a black key. + /// Returns `true` if note is sharp (has a ♯ accidental). + /// On a piano keyboard, this would be a black key. public var isSharp: Bool { switch self { case .A, diff --git a/Sources/MIDIKitCore/Events/MIDINote/MIDINote NoteError.swift b/Sources/MIDIKitCore/Events/MIDINote/MIDINote NoteError.swift index e1c139fc10..c0e52eeeab 100644 --- a/Sources/MIDIKitCore/Events/MIDINote/MIDINote NoteError.swift +++ b/Sources/MIDIKitCore/Events/MIDINote/MIDINote NoteError.swift @@ -1,7 +1,7 @@ // // MIDINote NoteError.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitCore/Events/MIDINote/MIDINote Style.swift b/Sources/MIDIKitCore/Events/MIDINote/MIDINote Style.swift index 122b96ada0..63b22fd94d 100644 --- a/Sources/MIDIKitCore/Events/MIDINote/MIDINote Style.swift +++ b/Sources/MIDIKitCore/Events/MIDINote/MIDINote Style.swift @@ -1,7 +1,7 @@ // // MIDINote Style.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -23,7 +23,9 @@ extension MIDINote { /// /// Cakewalk originally chose "C5" to represent MIDI note 60 (Middle C). /// - /// Cakewalk started life as a character-based DOS sequencer, and if they’d used "C4" or "C3" for note 60, they’d have needed additional characters on-screen for notating the lower octaves, e.g. "C-2". "C5" in effect sets the lowest octave to octave zero (C0). + /// Cakewalk started life as a character-based DOS sequencer, and if they’d used "C4" or + /// "C3" for note 60, they’d have needed additional characters on-screen for notating the + /// lower octaves, e.g. "C-2". "C5" in effect sets the lowest octave to octave zero (C0). case cakewalk } } diff --git a/Sources/MIDIKitCore/Events/MIDINote/MIDINote.swift b/Sources/MIDIKitCore/Events/MIDINote/MIDINote.swift index 11e5ae4895..61b769e28c 100644 --- a/Sources/MIDIKitCore/Events/MIDINote/MIDINote.swift +++ b/Sources/MIDIKitCore/Events/MIDINote/MIDINote.swift @@ -1,14 +1,15 @@ // // MIDINote.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation /// Value type describing a MIDI note number. /// -/// Constructors and properties allow getting and setting by raw value, note name & octave, or string representation. +/// Constructors and properties allow getting and setting by raw value, note name & octave, or +/// string representation. public struct MIDINote: Equatable, Hashable { // MARK: - Constants @@ -105,7 +106,8 @@ public struct MIDINote: Equatable, Hashable { /// /// - Parameters: /// - namingStandard: Note naming standard (octave offset). - /// - respellSharpAsFlat: If note is sharp, respell enharmonically as a flat (ie: G♯ becomes A♭). Otherwise, sharp is always used, which is typical convention for MIDI note names. + /// - respellSharpAsFlat: If note is sharp, respell enharmonically as a flat (ie: G♯ becomes + /// A♭). Otherwise, sharp is always used, which is typical convention for MIDI note names. /// - unicodeAccidental: Use stylized unicode character for sharp (♯) and flat (♭). /// /// - Returns: MIDI note name string. diff --git a/Sources/MIDIKitCore/Events/Protocols/ReceivesMIDIEvents.swift b/Sources/MIDIKitCore/Events/Protocols/ReceivesMIDIEvents.swift index cf5063d547..5ffd9c0320 100644 --- a/Sources/MIDIKitCore/Events/Protocols/ReceivesMIDIEvents.swift +++ b/Sources/MIDIKitCore/Events/Protocols/ReceivesMIDIEvents.swift @@ -1,7 +1,7 @@ // // ReceivesMIDIEvents.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// Protocol that objects can adopt so MIDIKit knows they are capable of receiving MIDI events. diff --git a/Sources/MIDIKitCore/Events/Protocols/SendsMIDIEvents.swift b/Sources/MIDIKitCore/Events/Protocols/SendsMIDIEvents.swift index e41fbab5de..1aa8477b38 100644 --- a/Sources/MIDIKitCore/Events/Protocols/SendsMIDIEvents.swift +++ b/Sources/MIDIKitCore/Events/Protocols/SendsMIDIEvents.swift @@ -1,7 +1,7 @@ // // SendsMIDIEvents.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitCore/Events/Type Extensions/Double Extensions.swift b/Sources/MIDIKitCore/Events/Type Extensions/Double Extensions.swift index 44e0672d22..5cb981cad3 100644 --- a/Sources/MIDIKitCore/Events/Type Extensions/Double Extensions.swift +++ b/Sources/MIDIKitCore/Events/Type Extensions/Double Extensions.swift @@ -1,7 +1,7 @@ // // Double Extensions.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -35,7 +35,8 @@ extension Double { self = (bipolarUnitInterval / 2.0) + 0.5 } - /// Converts from integer to a bipolar floating-point unit interval (having a 0.0 neutral midpoint). + /// Converts from integer to a bipolar floating-point unit interval (having a 0.0 neutral + /// midpoint). @_disfavoredOverload public var bipolarUnitIntervalValue: Double { 2 * (clamped(to: 0.0 ... 1.0) - 0.5) diff --git a/Sources/MIDIKitCore/Events/Type Extensions/UInt32 Extensions.swift b/Sources/MIDIKitCore/Events/Type Extensions/UInt32 Extensions.swift index 67849a2808..bef013d35b 100644 --- a/Sources/MIDIKitCore/Events/Type Extensions/UInt32 Extensions.swift +++ b/Sources/MIDIKitCore/Events/Type Extensions/UInt32 Extensions.swift @@ -1,7 +1,7 @@ // // UInt32 Extensions.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -53,7 +53,8 @@ extension UInt32 { } } - /// Converts from integer to a bipolar floating-point unit interval (having a 0.0 neutral midpoint at 0x80000000). + /// Converts from integer to a bipolar floating-point unit interval (having a 0.0 neutral + /// midpoint at 0x80000000). /// (`0 ... 0x80000000 ... 0xFFFFFFFF` == `-1.0 ... 0.0 ... 1.0`) @_disfavoredOverload public var bipolarUnitIntervalValue: Double { diff --git a/Sources/MIDIKitCore/MIDIKitCore.swift b/Sources/MIDIKitCore/MIDIKitCore.swift index 588056e25f..1af734021f 100644 --- a/Sources/MIDIKitCore/MIDIKitCore.swift +++ b/Sources/MIDIKitCore/MIDIKitCore.swift @@ -1,3 +1,9 @@ +// +// MIDIKitCore.swift +// MIDIKit • https://github.com/orchetect/MIDIKit +// © 2021-2022 Steffan Andrews • Licensed under MIT License +// + // // MIDIKitCore.swift // MIDIKit • https://github.com/orchetect/MIDIKit diff --git a/Sources/MIDIKitCore/Packet Metadata/UniversalPacketData MessageType.swift b/Sources/MIDIKitCore/Packet Metadata/UniversalPacketData MessageType.swift index 87258ed359..7df3443f87 100644 --- a/Sources/MIDIKitCore/Packet Metadata/UniversalPacketData MessageType.swift +++ b/Sources/MIDIKitCore/Packet Metadata/UniversalPacketData MessageType.swift @@ -1,7 +1,7 @@ // // UniversalPacketData MessageType.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// Universal MIDI Packet Message Type @@ -19,7 +19,11 @@ public enum MIDIUMPMessageType: UInt4, CaseIterable { extension MIDIUMPMessageType { /// Returns the number of words associated with the Universal MIDI Packet Message Type. /// - /// - Note: MIDI 2.0 Utility (``utility``) messages themselves are always 1 word, however they may be followed by additional words that comprise another UMP message since utility messages can be timestamps that prepend non-utility UMP messages. (For example, a 64-bit channel voice UMP may be prepended by a 32-bit timestamp UMP to form a 96-bit timestamped message.) See the MIDI 2.0 Spec for details. + /// - Note: MIDI 2.0 Utility (``utility``) messages themselves are always 1 word, however they + /// may be followed by additional words that comprise another UMP message since utility messages + /// can be timestamps that prepend non-utility UMP messages. (For example, a 64-bit channel + /// voice UMP may be prepended by a 32-bit timestamp UMP to form a 96-bit timestamped message.) + /// See the MIDI 2.0 Spec for details. public var wordLength: Int { switch self { case .utility: return 1 @@ -61,20 +65,25 @@ public enum MIDIUMPUtilityStatusField: UInt4, CaseIterable { /// > /// > The JR Clock message defines the current time of the Sender. /// > - /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 MHz / 32). + /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 + /// MHz / 32). /// > /// > The time value is expected to wrap around every 2.09712 seconds. /// > - /// > To avoid ambiguity of the 2.09712 seconds wrap, and to provide sufficient JR Clock messages for the Receiver, the Sender shall send a JR Clock message at least once every 250 milliseconds. + /// > To avoid ambiguity of the 2.09712 seconds wrap, and to provide sufficient JR Clock + /// messages for the Receiver, the Sender shall send a JR Clock message at least once every 250 + /// milliseconds. case jrClock = 0x1 /// JR Timestamp (Jitter-Reduction Timestamp) /// /// > MIDI 2.0 Spec: /// > - /// > The JR Timestamp message defines the time of the following message(s). It is a complete message. + /// > The JR Timestamp message defines the time of the following message(s). It is a complete + /// message. /// > - /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 MHz / 32). + /// > A 16-bit time value in clock ticks of 1/31250 of one second (32 μsec, clock frequency of 1 + /// MHz / 32). case jrTimestamp = 0x2 // 0x3... are unused/reserved diff --git a/Sources/MIDIKitCore/Types/BytePair.swift b/Sources/MIDIKitCore/Types/BytePair.swift index b126787bbd..a9b752b67e 100644 --- a/Sources/MIDIKitCore/Types/BytePair.swift +++ b/Sources/MIDIKitCore/Types/BytePair.swift @@ -1,7 +1,7 @@ // // BytePair.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// Type that holds a pair of `UInt8` bytes representing MSB and LSB. diff --git a/Sources/MIDIKitCore/Types/Int7.swift b/Sources/MIDIKitCore/Types/Int7.swift index 08e70073a0..963573f524 100644 --- a/Sources/MIDIKitCore/Types/Int7.swift +++ b/Sources/MIDIKitCore/Types/Int7.swift @@ -1,7 +1,7 @@ // // Int7.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -14,7 +14,8 @@ public struct Int7 { var sixBitStorage: UInt8 var isNegative: Bool - /// Initializes from an unsigned integer value, throwing an exception in the event of overflow or underflow. + /// Initializes from an unsigned integer value, throwing an exception in the event of overflow + /// or underflow. public init(_ source: I) { switch source { case 0 ... 63: @@ -30,7 +31,8 @@ public struct Int7 { } } - /// Initializes from a signed integer value, throwing an exception in the event of overflow or underflow. + /// Initializes from a signed integer value, throwing an exception in the event of overflow or + /// underflow. public init(_ source: I) { switch source { case ...(-65): @@ -55,13 +57,15 @@ public struct Int7 { } } - /// Initializes from an unsigned integer value, returning nil if the value cannot be preserved because it would otherwise overflow or underflow. + /// Initializes from an unsigned integer value, returning nil if the value cannot be preserved + /// because it would otherwise overflow or underflow. public init?(exactly source: I) { guard (-64 ... 63).contains(source) else { return nil } self.init(truncatingIfNecessary: source) } - /// Initializes from a signed integer value, returning nil if the value cannot be preserved because it would otherwise overflow or underflow. + /// Initializes from a signed integer value, returning nil if the value cannot be preserved + /// because it would otherwise overflow or underflow. public init?(exactly source: I) { guard (-64 ... 63).contains(source) else { return nil } self.init(truncatingIfNecessary: source) diff --git a/Sources/MIDIKitCore/Types/MIDIUnsignedInteger.swift b/Sources/MIDIKitCore/Types/MIDIUnsignedInteger.swift index 42d4303f3a..5d5a7f1fad 100644 --- a/Sources/MIDIKitCore/Types/MIDIUnsignedInteger.swift +++ b/Sources/MIDIKitCore/Types/MIDIUnsignedInteger.swift @@ -1,7 +1,7 @@ // // MIDIUnsignedInteger.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -20,13 +20,14 @@ import MIDIKitInternals // -> Strideable // -> Comparable -/// Protocol adopted by specialized unsigned integer types in `MIDIKit` representing novel bit widths. +/// Protocol adopted by specialized unsigned integer types in `MIDIKit` representing novel bit +/// widths. public protocol MIDIUnsignedInteger: UnsignedInteger, Codable -where Magnitude == Storage.Magnitude, - Words == Storage.Words, - IntegerLiteralType == Storage, - IntegerLiteralType: Codable, - Stride == Int + where Magnitude == Storage.Magnitude, + Words == Storage.Words, + IntegerLiteralType == Storage, + IntegerLiteralType: Codable, + Stride == Int { /// Backing storage type for the integer. associatedtype Storage: BinaryInteger diff --git a/Sources/MIDIKitCore/Types/UInt14.swift b/Sources/MIDIKitCore/Types/UInt14.swift index 7f9aa48c6d..f757c87995 100644 --- a/Sources/MIDIKitCore/Types/UInt14.swift +++ b/Sources/MIDIKitCore/Types/UInt14.swift @@ -1,7 +1,7 @@ // // UInt14.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -111,7 +111,8 @@ extension UInt14 { /// Returns the integer as a `UInt16` instance. public var uInt16Value: UInt16 { storage } - /// Converts from integer to a bipolar floating-point unit interval (having a 0.0 neutral midpoint at 8192). + /// Converts from integer to a bipolar floating-point unit interval (having a 0.0 neutral + /// midpoint at 8192). /// (`0 ... 8192 ... 16383` == `-1.0 ... 0.0 ... 1.0`) public var bipolarUnitIntervalValue: Double { // account for non-symmetry and round up. (This is how MIDI 1.0 Spec pitchbend works) diff --git a/Sources/MIDIKitCore/Types/UInt25.swift b/Sources/MIDIKitCore/Types/UInt25.swift index 15062b2594..dab028d9be 100644 --- a/Sources/MIDIKitCore/Types/UInt25.swift +++ b/Sources/MIDIKitCore/Types/UInt25.swift @@ -1,7 +1,7 @@ // // UInt25.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitCore/Types/UInt4.swift b/Sources/MIDIKitCore/Types/UInt4.swift index c78e587994..26de501ad2 100644 --- a/Sources/MIDIKitCore/Types/UInt4.swift +++ b/Sources/MIDIKitCore/Types/UInt4.swift @@ -1,7 +1,7 @@ // // UInt4.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitCore/Types/UInt7 Pair.swift b/Sources/MIDIKitCore/Types/UInt7 Pair.swift index 1868d283d6..8613966091 100644 --- a/Sources/MIDIKitCore/Types/UInt7 Pair.swift +++ b/Sources/MIDIKitCore/Types/UInt7 Pair.swift @@ -1,7 +1,7 @@ // // UInt7 Pair.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// Type that holds a pair of `UInt7`s - one MSB `UInt7`, one LSB `UInt7`. diff --git a/Sources/MIDIKitCore/Types/UInt7.swift b/Sources/MIDIKitCore/Types/UInt7.swift index 1d9bc0d540..6d37674ebd 100644 --- a/Sources/MIDIKitCore/Types/UInt7.swift +++ b/Sources/MIDIKitCore/Types/UInt7.swift @@ -1,7 +1,7 @@ // // UInt7.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitCore/Types/UInt8.swift b/Sources/MIDIKitCore/Types/UInt8.swift index a83784a8d4..4b37ff7c1b 100644 --- a/Sources/MIDIKitCore/Types/UInt8.swift +++ b/Sources/MIDIKitCore/Types/UInt8.swift @@ -1,7 +1,7 @@ // // UInt8.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// a.k.a. 8-bit MIDI byte. diff --git a/Sources/MIDIKitCore/Types/UInt9.swift b/Sources/MIDIKitCore/Types/UInt9.swift index c03e9b27da..1a9ccd92c5 100644 --- a/Sources/MIDIKitCore/Types/UInt9.swift +++ b/Sources/MIDIKitCore/Types/UInt9.swift @@ -1,7 +1,7 @@ // // UInt9.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitCore/Types/UMPWord.swift b/Sources/MIDIKitCore/Types/UMPWord.swift index 03942721f1..5aa5797507 100644 --- a/Sources/MIDIKitCore/Types/UMPWord.swift +++ b/Sources/MIDIKitCore/Types/UMPWord.swift @@ -1,7 +1,7 @@ // // UMPWord.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// Universal MIDI Packet Word: Type representing four 8-bit bytes. diff --git a/Sources/MIDIKitIO/API Evolution/MIDIKit-0.6.0.swift b/Sources/MIDIKitIO/API Evolution/MIDIKit-0.6.0.swift index 840641f613..80fdb1aca4 100644 --- a/Sources/MIDIKitIO/API Evolution/MIDIKit-0.6.0.swift +++ b/Sources/MIDIKitIO/API Evolution/MIDIKit-0.6.0.swift @@ -1,7 +1,7 @@ // // MIDIKit-0.6.0.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -11,148 +11,6 @@ import MIDIKitCore // Symbols that were renamed or removed. -// NOTE: This is not by any means exhaustive, as nearly every symbol had namespace changes from 0.5.x -> 0.6.0 but the most common symbols are covered here to help guide code migration. - -extension MIDI { - @available( - *, unavailable, - message: "The `MIDI.IO` namespace has been removed and first-generation nested types have been renamed `MIDIManager`, `MIDIInputEndpoint`, etc." - ) - public enum IO { - // MARK: Core MIDI Aliased Types - - public typealias UniqueID = MIDIIdentifier - public typealias ObjectRef = UInt32 - public typealias ClientRef = CoreMIDIObjectRef - public typealias DeviceRef = CoreMIDIObjectRef - public typealias EntityRef = CoreMIDIObjectRef - public typealias PortRef = CoreMIDIObjectRef - public typealias EndpointRef = CoreMIDIObjectRef - public typealias ThruConnectionRef = CoreMIDIObjectRef - public typealias TimeStamp = UInt64 - public typealias CoreMIDIOSStatus = Int32 - - // MARK: Manager - - public class Manager { - @available(*, unavailable) - public init( - clientName: String, - model: String, - manufacturer: String, - notificationHandler: (( - _ notification: MIDIIONotification, - _ manager: MIDIManager - ) -> Void)? = nil - ) { fatalError() } - - public func addInput( - name: String, - tag: String, - uniqueID: MIDIIdentifierPersistence, - receiver: MIDIReceiver - ) throws { fatalError() } - - // MARK: - Add Methods - - public func addInputConnection( - toOutputs: Set, - tag: String, - mode: MIDIConnectionMode = .definedEndpoints, - filter: MIDIEndpointFilter = .default(), - receiver: MIDIReceiver - ) throws { fatalError() } - - public func addInputConnection( - toOutputs: [MIDIEndpointIdentity], - tag: String, - mode: MIDIConnectionMode = .definedEndpoints, - filter: MIDIEndpointFilter = .default(), - receiver: MIDIReceiver - ) throws { fatalError() } - - @_disfavoredOverload - public func addInputConnection( - toOutputs: [MIDIOutputEndpoint], - tag: String, - mode: MIDIConnectionMode = .definedEndpoints, - filter: MIDIEndpointFilter = .default(), - receiver: MIDIReceiver - ) throws { fatalError() } - - public func addOutput( - name: String, - tag: String, - uniqueID: MIDIIdentifierPersistence - ) throws { fatalError() } - - public func addOutputConnection( - toInputs: Set, - tag: String, - mode: MIDIConnectionMode = .definedEndpoints, - filter: MIDIEndpointFilter = .default() - ) throws { fatalError() } - - public func addOutputConnection( - toInputs: [MIDIEndpointIdentity], - tag: String, - mode: MIDIConnectionMode = .definedEndpoints, - filter: MIDIEndpointFilter = .default() - ) throws { fatalError() } - - @_disfavoredOverload - public func addOutputConnection( - toInputs: [MIDIInputEndpoint], - tag: String, - mode: MIDIConnectionMode = .definedEndpoints, - filter: MIDIEndpointFilter = .default() - ) throws { fatalError() } - - public func addThruConnection( - outputs: [MIDIOutputEndpoint], - inputs: [MIDIInputEndpoint], - tag: String, - lifecycle: MIDIThruConnection.Lifecycle = .nonPersistent, - params: MIDIThruConnection.Parameters = .init() - ) throws { fatalError() } - - // MARK: - Remove Methods - - public func remove( - _ type: MIDIManager.ManagedType, - _ tagSelection: MIDIManager.TagSelection - ) { fatalError() } - - // MARK: State - - public func start() throws { fatalError() } - } - - // MARK: Network Session - - @available( - *, unavailable, - message: "setMIDINetworkSession() is now a top-level global method." - ) - public static func setMIDINetworkSession(policy: MIDIIONetworkConnectionPolicy?) { - fatalError() - } - - // MARK: UniqueIDPersistence -> MIDIIdentifierPersistence - - @available(*, unavailable, message: "Renamed to MIDIIdentifierPersistence") - public enum UniqueIDPersistence { - case none - case preferred(MIDIIdentifier) - case userDefaultsManaged(key: String) - case manualStorage( - readHandler: () -> MIDIIdentifier?, - storeHandler: (MIDIIdentifier?) -> Void - ) - } - } -} - // MARK: MIDIUniqueID -> MIDIIdentifier extension Set where Element == MIDIIdentifier { diff --git a/Sources/MIDIKitIO/API/CoreMIDIAPIVersion.swift b/Sources/MIDIKitIO/API/CoreMIDIAPIVersion.swift index 1f4202c723..5a075e8c21 100644 --- a/Sources/MIDIKitIO/API/CoreMIDIAPIVersion.swift +++ b/Sources/MIDIKitIO/API/CoreMIDIAPIVersion.swift @@ -1,7 +1,7 @@ // // CoreMIDIAPIVersion.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// Describes the Core MIDI API used internally in all MIDIKit I/O operations. diff --git a/Sources/MIDIKitIO/API/MIDIProtocolVersion Extensions.swift b/Sources/MIDIKitIO/API/MIDIProtocolVersion Extensions.swift index 6442fc6ccd..bf46ff73a1 100644 --- a/Sources/MIDIKitIO/API/MIDIProtocolVersion Extensions.swift +++ b/Sources/MIDIKitIO/API/MIDIProtocolVersion Extensions.swift @@ -1,7 +1,7 @@ // // MIDIProtocolVersion Extensions.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // @_implementationOnly import CoreMIDI diff --git a/Sources/MIDIKitIO/AnyMIDIEndpoint/AnyMIDIEndpoint Collection.swift b/Sources/MIDIKitIO/AnyMIDIEndpoint/AnyMIDIEndpoint Collection.swift index d70095e956..4e0cb502c2 100644 --- a/Sources/MIDIKitIO/AnyMIDIEndpoint/AnyMIDIEndpoint Collection.swift +++ b/Sources/MIDIKitIO/AnyMIDIEndpoint/AnyMIDIEndpoint Collection.swift @@ -1,7 +1,7 @@ // // AnyMIDIEndpoint Collection.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/AnyMIDIEndpoint/AnyMIDIEndpoint.swift b/Sources/MIDIKitIO/AnyMIDIEndpoint/AnyMIDIEndpoint.swift index 0b4385b847..155a7963ab 100644 --- a/Sources/MIDIKitIO/AnyMIDIEndpoint/AnyMIDIEndpoint.swift +++ b/Sources/MIDIKitIO/AnyMIDIEndpoint/AnyMIDIEndpoint.swift @@ -1,7 +1,7 @@ // // AnyMIDIEndpoint.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/AnyMIDIIOObject/AnyMIDIIOObject.swift b/Sources/MIDIKitIO/AnyMIDIIOObject/AnyMIDIIOObject.swift index ca6e8dedfc..a6e2a4c27a 100644 --- a/Sources/MIDIKitIO/AnyMIDIIOObject/AnyMIDIIOObject.swift +++ b/Sources/MIDIKitIO/AnyMIDIIOObject/AnyMIDIIOObject.swift @@ -1,7 +1,7 @@ // // AnyMIDIIOObject.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -12,7 +12,8 @@ import SwiftUI /// Box to contain an instance of a strongly-typed system MIDI object. /// -/// Allows for simple switch case unwrapping when object type needs to be erased, such as ``MIDIManager``'s handler for Core MIDI system notifications. +/// Allows for simple switch case unwrapping when object type needs to be erased, such as +/// ``MIDIManager``'s handler for Core MIDI system notifications. public enum AnyMIDIIOObject { case device(MIDIDevice) case entity(MIDIEntity) @@ -111,7 +112,8 @@ extension AnyMIDIIOObject { } } - /// Returns a MIDIKit object wrapped in a strongly-typed enum case, optionally returning the cached object from the `MIDIManager`. + /// Returns a MIDIKit object wrapped in a strongly-typed enum case, optionally returning the + /// cached object from the ``MIDIManager``. internal init?( coreMIDIObjectRef: MIDIObjectRef, coreMIDIObjectType: MIDIObjectType, @@ -185,7 +187,8 @@ extension AnyMIDIIOObject: CustomStringConvertible { // MARK: - Collection Methods extension Collection where Element: MIDIIOObject { - /// Return as `[` ``AnyMIDIIOObject`` `]`, type-erased representations of MIDIKit objects conforming to ``MIDIIOObject``. + /// Return as `[` ``AnyMIDIIOObject`` `]`, type-erased representations of MIDIKit objects + /// conforming to ``MIDIIOObject``. public func asAnyMIDIIOObjects() -> [AnyMIDIIOObject] { map { $0.asAnyMIDIIOObject() } } diff --git a/Sources/MIDIKitIO/Core MIDI/Core MIDI Devices.swift b/Sources/MIDIKitIO/Core MIDI/Core MIDI Devices.swift index 0bbc5bd578..0ea944f89d 100644 --- a/Sources/MIDIKitIO/Core MIDI/Core MIDI Devices.swift +++ b/Sources/MIDIKitIO/Core MIDI/Core MIDI Devices.swift @@ -1,7 +1,7 @@ // // Core MIDI Devices.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/Core MIDI/Core MIDI Endpoints.swift b/Sources/MIDIKitIO/Core MIDI/Core MIDI Endpoints.swift index 9bda8b1bc4..db5d449b6a 100755 --- a/Sources/MIDIKitIO/Core MIDI/Core MIDI Endpoints.swift +++ b/Sources/MIDIKitIO/Core MIDI/Core MIDI Endpoints.swift @@ -1,7 +1,7 @@ // // Core MIDI Endpoints.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -64,7 +64,8 @@ internal func getSystemSourceEndpoints( } /// Internal: -/// Returns the first source `MIDIEndpointRef` in the system with a unique ID matching `uniqueID`. If not found, returns `nil`. +/// Returns the first source `MIDIEndpointRef` in the system with a unique ID matching `uniqueID`. +/// If not found, returns `nil`. /// /// - Parameter uniqueID: MIDI port unique ID to search for. internal func getSystemSourceEndpoint( @@ -96,7 +97,8 @@ internal func getSystemDestinationEndpoints( } /// Internal: -/// Returns the first destination `MIDIEndpointRef` in the system with a unique ID matching `uniqueID`. If not found, returns `nil`. +/// Returns the first destination `MIDIEndpointRef` in the system with a unique ID matching +/// `uniqueID`. If not found, returns `nil`. /// /// - Parameter uniqueID: MIDI port unique ID to search for. internal func getSystemDestinationEndpoint( diff --git a/Sources/MIDIKitIO/Core MIDI/Core MIDI Entities.swift b/Sources/MIDIKitIO/Core MIDI/Core MIDI Entities.swift index b5b8f86972..60c7fddfa9 100644 --- a/Sources/MIDIKitIO/Core MIDI/Core MIDI Entities.swift +++ b/Sources/MIDIKitIO/Core MIDI/Core MIDI Entities.swift @@ -1,7 +1,7 @@ // // Core MIDI Entities.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/Core MIDI/Core MIDI Object.swift b/Sources/MIDIKitIO/Core MIDI/Core MIDI Object.swift index 454e7ef7f4..ee5ab87563 100644 --- a/Sources/MIDIKitIO/Core MIDI/Core MIDI Object.swift +++ b/Sources/MIDIKitIO/Core MIDI/Core MIDI Object.swift @@ -1,7 +1,7 @@ // // Core MIDI Object.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/Core MIDI/Core MIDI Properties Get.swift b/Sources/MIDIKitIO/Core MIDI/Core MIDI Properties Get.swift index a45e6637ca..3d2d8027e7 100644 --- a/Sources/MIDIKitIO/Core MIDI/Core MIDI Properties Get.swift +++ b/Sources/MIDIKitIO/Core MIDI/Core MIDI Properties Get.swift @@ -1,7 +1,7 @@ // // Core MIDI Properties Get.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -37,8 +37,10 @@ internal func getProperties( ) } - // "takeRetainedValue() is the right choice here because it is the caller's responsibility to release the string. - // This is different from the usual Core Foundation memory management rules, but documented in the MIDI Services Reference" + // "takeRetainedValue() is the right choice here because it is the caller's responsibility to + // release the string. + // This is different from the usual Core Foundation memory management rules, but documented in + // the MIDI Services Reference" // -- https://stackoverflow.com/a/27171498/2805570 return unwrappedProps @@ -71,8 +73,10 @@ internal func getDictionary( ) } - // "takeRetainedValue() is the right choice here because it is the caller's responsibility to release the string. - // This is different from the usual Core Foundation memory management rules, but documented in the MIDI Services Reference" + // "takeRetainedValue() is the right choice here because it is the caller's responsibility to + // release the string. + // This is different from the usual Core Foundation memory management rules, but documented in + // the MIDI Services Reference" // -- https://stackoverflow.com/a/27171498/2805570 return unwrappedDict as NSDictionary @@ -105,8 +109,10 @@ internal func getString( ) } - // "takeRetainedValue() is the right choice here because it is the caller's responsibility to release the string. - // This is different from the usual Core Foundation memory management rules, but documented in the MIDI Services Reference" + // "takeRetainedValue() is the right choice here because it is the caller's responsibility to + // release the string. + // This is different from the usual Core Foundation memory management rules, but documented in + // the MIDI Services Reference" // -- https://stackoverflow.com/a/27171498/2805570 return unwrappedVal as String @@ -132,9 +138,11 @@ internal func getInteger( /// Get user-visible endpoint name. /// (`kMIDIPropertyName`) /// -/// Devices, entities, and endpoints may all have names. The standard way to display an endpoint’s name is to ask it for its name and display it only if unique. If not, prepend the device name. +/// Devices, entities, and endpoints may all have names. The standard way to display an endpoint’s +/// name is to ask it for its name and display it only if unique. If not, prepend the device name. /// -/// A studio setup editor may allow the user to set the names of both driver-owned and external devices. +/// A studio setup editor may allow the user to set the names of both driver-owned and external +/// devices. /// /// - Throws: ``MIDIIOError`` internal func getName(of ref: CoreMIDI.MIDIObjectRef) throws -> String { @@ -170,7 +178,8 @@ internal func getManufacturer(of ref: CoreMIDI.MIDIObjectRef) throws -> String { /// Get unique ID. /// (`kMIDIPropertyUniqueID`) /// -/// The system assigns unique IDs to all objects. Creators of virtual endpoints may set this property on their endpoints, though doing so may fail if the chosen ID is not unique. +/// The system assigns unique IDs to all objects. Creators of virtual endpoints may set this +/// property on their endpoints, though doing so may fail if the chosen ID is not unique. internal func getUniqueID(of ref: CoreMIDI.MIDIObjectRef) -> MIDIUniqueID { getInteger(forProperty: kMIDIPropertyUniqueID, of: ref) } @@ -178,26 +187,30 @@ internal func getUniqueID(of ref: CoreMIDI.MIDIObjectRef) -> MIDIUniqueID { /// Get the user-visible System Exclusive (SysEx) identifier of a device or entity. /// (`kMIDIPropertyDeviceID`) /// -/// MIDI drivers can set this property on their devices or entities. Studio setup editors can allow the user to set this property on external devices. +/// MIDI drivers can set this property on their devices or entities. Studio setup editors can allow +/// the user to set this property on external devices. internal func getDeviceManufacturerID(of ref: CoreMIDI.MIDIObjectRef) -> Int32 { getInteger(forProperty: kMIDIPropertyDeviceID, of: ref) } // MARK: Capabilities -/// Get a Boolean value that indicates whether the device or entity implements the MIDI Machine Control portion of the MIDI specification. +/// Get a Boolean value that indicates whether the device or entity implements the MIDI Machine +/// Control portion of the MIDI specification. /// (`kMIDIPropertySupportsMMC`) internal func getSupportsMMC(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertySupportsMMC, of: ref) == 1 } -/// Get a Boolean value that indicates whether the device or entity implements the General MIDI specification. +/// Get a Boolean value that indicates whether the device or entity implements the General MIDI +/// specification. /// (`kMIDIPropertySupportsGeneralMIDI`) internal func getSupportsGeneralMIDI(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertySupportsGeneralMIDI, of: ref) == 1 } -/// Get a Boolean value that indicates whether the device implements the MIDI Show Control specification. +/// Get a Boolean value that indicates whether the device implements the MIDI Show Control +/// specification. /// (`kMIDIPropertySupportsShowControl`) internal func getSupportsShowControl(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertySupportsShowControl, of: ref) == 1 @@ -216,7 +229,8 @@ internal func getNameConfigurationDictionary( try getDictionary(forProperty: kMIDIPropertyNameConfigurationDictionary, of: ref) } -/// Get the maximum rate, in bytes per second, at which the system may reliably send System Exclusive (SysEx) messages to this object. +/// Get the maximum rate, in bytes per second, at which the system may reliably send System +/// Exclusive (SysEx) messages to this object. /// (`kMIDIPropertyMaxSysExSpeed`) /// /// The owning driver may set an integer value for this property. @@ -240,7 +254,8 @@ internal func getDriverDeviceEditorApp(of ref: CoreMIDI.MIDIObjectRef) throws -> /// Get the full path to a device icon on the system. /// (`kMIDIPropertyImage`) /// -/// You can provide an image stored in any standard graphic file format, such as JPEG, GIF, or PNG. The maximum size for this image is 128 by 128 pixels. +/// You can provide an image stored in any standard graphic file format, such as JPEG, GIF, or PNG. +/// The maximum size for this image is 128 by 128 pixels. /// /// A studio setup editor should allow the user to choose icons for external devices. /// @@ -254,7 +269,8 @@ internal func getImage(of ref: CoreMIDI.MIDIObjectRef) throws -> URL { /// (Apple-recommended user-visible name) /// (`kMIDIPropertyDisplayName`) /// -/// For objects other than endpoints, the display name is (sometimes) the same as its `kMIDIPropertyName` value. +/// For objects other than endpoints, the display name is (sometimes) the same as its +/// `kMIDIPropertyName` value. /// /// - Throws: ``MIDIIOError`` internal func getDisplayName(of ref: CoreMIDI.MIDIObjectRef) throws -> String { @@ -263,7 +279,8 @@ internal func getDisplayName(of ref: CoreMIDI.MIDIObjectRef) throws -> String { // MARK: Audio -/// Get a Boolean value that indicates whether the MIDI pan messages sent to the device or entity cause undesirable effects when playing stereo sounds. +/// Get a Boolean value that indicates whether the MIDI pan messages sent to the device or entity +/// cause undesirable effects when playing stereo sounds. /// (`kMIDIPropertyPanDisruptsStereo`) internal func getPanDisruptsStereo(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyPanDisruptsStereo, of: ref) == 1 @@ -274,7 +291,8 @@ internal func getPanDisruptsStereo(of ref: CoreMIDI.MIDIObjectRef) -> Bool { /// Get the native protocol in which the endpoint communicates. /// (`kMIDIPropertyProtocolID`) /// -/// The system sets this value on endpoints when it creates them. Drivers can dynamically change the endpoint’s protocol as a result of a MIDI-CI negotiation, by setting this property. +/// The system sets this value on endpoints when it creates them. Drivers can dynamically change the +/// endpoint’s protocol as a result of a MIDI-CI negotiation, by setting this property. /// /// Clients can observe changes to this property. /// @@ -288,25 +306,29 @@ internal func getProtocolID(of ref: CoreMIDI.MIDIObjectRef) -> CoreMIDI.MIDIProt // MARK: Timing -/// Get a Boolean value that indicates whether the device or entity transmits MIDI Time Code messages. +/// Get a Boolean value that indicates whether the device or entity transmits MIDI Time Code +/// messages. /// (`kMIDIPropertyTransmitsMTC`) internal func getTransmitsMTC(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyTransmitsMTC, of: ref) == 1 } -/// Get a Boolean value that indicates whether the device or entity responds to MIDI Time Code messages. +/// Get a Boolean value that indicates whether the device or entity responds to MIDI Time Code +/// messages. /// (`kMIDIPropertyReceivesMTC`) internal func getReceivesMTC(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyReceivesMTC, of: ref) == 1 } -/// Get a Boolean value that indicates whether the device or entity transmits MIDI beat clock messages. +/// Get a Boolean value that indicates whether the device or entity transmits MIDI beat clock +/// messages. /// (`kMIDIPropertyTransmitsClock`) internal func getTransmitsClock(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyTransmitsClock, of: ref) == 1 } -/// Get a Boolean value that indicates whether the device or entity responds to MIDI beat clock messages. +/// Get a Boolean value that indicates whether the device or entity responds to MIDI beat clock +/// messages. /// (`kMIDIPropertyReceivesClock`) internal func getReceivesClock(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyReceivesClock, of: ref) == 1 @@ -317,9 +339,16 @@ internal func getReceivesClock(of ref: CoreMIDI.MIDIObjectRef) -> Bool { /// /// Only the driver that owns the object may set this property. /// -/// If this property value is nonzero, clients should treat the value as a minimum. For devices with a nonzero advance schedule time, drivers receive outgoing messages to the device at the time the client sends them using `MIDISend(_:_:_:)`. The driver is responsible for scheduling events to play at the right times, according to their timestamps. +/// If this property value is nonzero, clients should treat the value as a minimum. For devices with +/// a nonzero advance schedule time, drivers receive outgoing messages to the device at the time the +/// client sends them using `MIDISend(_:_:_:)`. The driver is responsible for scheduling events to +/// play at the right times, according to their timestamps. /// -/// You can also set this property on any virtual destinations you create. When clients send messages to a virtual destination with an advance schedule time of 0, the destination receives the messages at the scheduled delivery time. If a virtual destination has a nonzero advance schedule time, it receives timestamped messages as soon as they’re sent, and must do its own internal scheduling of events it receives. +/// You can also set this property on any virtual destinations you create. When clients send +/// messages to a virtual destination with an advance schedule time of 0, the destination receives +/// the messages at the scheduled delivery time. If a virtual destination has a nonzero advance +/// schedule time, it receives timestamped messages as soon as they’re sent, and must do its own +/// internal scheduling of events it receives. /// /// - Throws: ``MIDIIOError`` internal func getAdvanceScheduleTimeMuSec(of ref: CoreMIDI.MIDIObjectRef) throws -> String { @@ -334,19 +363,22 @@ internal func getIsMixer(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyIsMixer, of: ref) == 1 } -/// Get a Boolean value that indicates whether the device or entity plays audio samples in response to MIDI note messages. +/// Get a Boolean value that indicates whether the device or entity plays audio samples in response +/// to MIDI note messages. /// (`kMIDIPropertyIsSampler`) internal func getIsSampler(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyIsSampler, of: ref) == 1 } -/// Get a Boolean value that indicates whether the device or entity primarily acts as a MIDI-controlled audio effect. +/// Get a Boolean value that indicates whether the device or entity primarily acts as a +/// MIDI-controlled audio effect. /// (`kMIDIPropertyIsEffectUnit`) internal func getIsEffectUnit(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyIsEffectUnit, of: ref) == 1 } -/// Get a Boolean value that indicates whether the device or entity’s samples aren’t transposable, as with a drum kit. +/// Get a Boolean value that indicates whether the device or entity’s samples aren’t transposable, +/// as with a drum kit. /// (`kMIDIPropertyIsDrumMachine`) internal func getIsDrumMachine(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyIsDrumMachine, of: ref) == 1 @@ -366,7 +398,8 @@ internal func getIsOffline(of ref: CoreMIDI.MIDIObjectRef) -> Bool { /// Get a Boolean value that indicates whether the system hides an endpoint from other clients. /// -/// You can set this property on a device or entity, but it still appears in the API; the system only hides the object’s owned endpoints. +/// You can set this property on a device or entity, but it still appears in the API; the system +/// only hides the object’s owned endpoints. /// /// (`kMIDIPropertyPrivate`) internal func getIsPrivate(of ref: CoreMIDI.MIDIObjectRef) -> Bool { @@ -378,7 +411,8 @@ internal func getIsPrivate(of ref: CoreMIDI.MIDIObjectRef) -> Bool { /// Get name of the driver that owns a device, entity, or endpoint. /// (`kMIDIPropertyDriverOwner`) /// -/// Set by the owning driver, on the device; should not be touched by other clients. Property is inherited from the device by its entities and endpoints. +/// Set by the owning driver, on the device; should not be touched by other clients. Property is +/// inherited from the device by its entities and endpoints. /// /// - Throws: ``MIDIIOError`` internal func getDriverOwner(of ref: CoreMIDI.MIDIObjectRef) throws -> String { @@ -393,7 +427,8 @@ internal func getDriverVersion(of ref: CoreMIDI.MIDIObjectRef) -> Int32 { // MARK: Connections -/// Get a Boolean value that indicates whether the device or entity can route messages to or from external MIDI devices. +/// Get a Boolean value that indicates whether the device or entity can route messages to or from +/// external MIDI devices. /// (`kMIDIPropertyCanRoute`) /// /// Don’t set this property value on driver-owned devices. @@ -401,7 +436,8 @@ internal func getCanRoute(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyCanRoute, of: ref) == 1 } -/// Get a Boolean value that indicates whether the endpoint broadcasts messages to all of the other endpoints in the device. +/// Get a Boolean value that indicates whether the endpoint broadcasts messages to all of the other +/// endpoints in the device. /// (`kMIDIPropertyIsBroadcast`) /// /// Only the owning driver may set this property. @@ -412,20 +448,23 @@ internal func getIsBroadcast(of ref: CoreMIDI.MIDIObjectRef) -> Bool { /// Get the unique identifier of an external device attached to this connection. /// (`kMIDIPropertyConnectionUniqueID`) /// -/// The value provided may be an integer. To indicate that a driver connects to multiple external objects, pass the array of big-endian SInt32 values as a CFData object. +/// The value provided may be an integer. To indicate that a driver connects to multiple external +/// objects, pass the array of big-endian SInt32 values as a CFData object. /// /// The property is nonexistent or 0 if there’s no connection. internal func getConnectionUniqueID(of ref: CoreMIDI.MIDIObjectRef) -> CoreMIDI.MIDIUniqueID { getInteger(forProperty: kMIDIPropertyConnectionUniqueID, of: ref) } -/// Get a Boolean value that indicates whether this entity or endpoint has external MIDI connections. +/// Get a Boolean value that indicates whether this entity or endpoint has external MIDI +/// connections. /// (`kMIDIPropertyIsEmbeddedEntity`) internal func getIsEmbeddedEntity(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyIsEmbeddedEntity, of: ref) == 1 } -/// Get the 0-based index of the entity on which incoming real-time messages from the device appear to have originated. +/// Get the 0-based index of the entity on which incoming real-time messages from the device appear +/// to have originated. /// (`kMIDIPropertySingleRealtimeEntity`) internal func getSingleRealtimeEntity(of ref: CoreMIDI.MIDIObjectRef) -> Int32 { getInteger(forProperty: kMIDIPropertySingleRealtimeEntity, of: ref) @@ -457,7 +496,8 @@ internal func getMaxReceiveChannels(of ref: CoreMIDI.MIDIObjectRef) -> Int32 { getInteger(forProperty: kMIDIPropertyMaxReceiveChannels, of: ref) } -/// Get the maximum number of MIDI channels on which a device may simultaneously transmit channel messages. +/// Get the maximum number of MIDI channels on which a device may simultaneously transmit channel +/// messages. /// (`kMIDIPropertyMaxTransmitChannels`) /// /// Common values are 0, 1, or 16. @@ -467,25 +507,29 @@ internal func getMaxTransmitChannels(of ref: CoreMIDI.MIDIObjectRef) -> Int32 { // MARK: Banks -/// Get a Boolean value that indicates whether the device or entity responds to MIDI bank select LSB messages. +/// Get a Boolean value that indicates whether the device or entity responds to MIDI bank select LSB +/// messages. /// (`kMIDIPropertyReceivesBankSelectLSB`) internal func getReceivesBankSelectLSB(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyReceivesBankSelectLSB, of: ref) == 1 } -/// Get a Boolean value that indicates whether the device or entity responds to MIDI bank select MSB messages. +/// Get a Boolean value that indicates whether the device or entity responds to MIDI bank select MSB +/// messages. /// (`kMIDIPropertyReceivesBankSelectMSB`) internal func getReceivesBankSelectMSB(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyReceivesBankSelectMSB, of: ref) == 1 } -/// Get a Boolean value that indicates whether the device or entity transmits MIDI bank select LSB messages. +/// Get a Boolean value that indicates whether the device or entity transmits MIDI bank select LSB +/// messages. /// (`kMIDIPropertyTransmitsBankSelectLSB`) internal func getTransmitsBankSelectLSB(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyTransmitsBankSelectLSB, of: ref) == 1 } -/// Get a Boolean value that indicates whether the device or entity transmits MIDI bank select MSB messages. +/// Get a Boolean value that indicates whether the device or entity transmits MIDI bank select MSB +/// messages. /// (`kMIDIPropertyTransmitsBankSelectMSB`) internal func getTransmitsBankSelectMSB(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyTransmitsBankSelectMSB, of: ref) == 1 @@ -493,7 +537,8 @@ internal func getTransmitsBankSelectMSB(of ref: CoreMIDI.MIDIObjectRef) -> Bool // MARK: Notes -/// Get a Boolean value that indicates whether the device or entity responds to MIDI Note On messages. +/// Get a Boolean value that indicates whether the device or entity responds to MIDI Note On +/// messages. /// (`kMIDIPropertyReceivesNotes`) internal func getReceivesNotes(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyReceivesNotes, of: ref) == 1 @@ -507,13 +552,15 @@ internal func getTransmitsNotes(of ref: CoreMIDI.MIDIObjectRef) -> Bool { // MARK: Program Changes -/// Get a Boolean value that indicates whether the device or entity responds to MIDI Program Change messages. +/// Get a Boolean value that indicates whether the device or entity responds to MIDI Program Change +/// messages. /// (`kMIDIPropertyReceivesProgramChanges`) internal func getReceivesProgramChanges(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyReceivesProgramChanges, of: ref) == 1 } -/// Get a Boolean value that indicates whether the device or entity transmits MIDI Program Change messages. +/// Get a Boolean value that indicates whether the device or entity transmits MIDI Program Change +/// messages. /// (`kMIDIPropertyTransmitsProgramChanges`) internal func getTransmitsProgramChanges(of ref: CoreMIDI.MIDIObjectRef) -> Bool { getInteger(forProperty: kMIDIPropertyTransmitsProgramChanges, of: ref) == 1 @@ -548,7 +595,7 @@ internal func getTransmitsProgramChanges(of ref: CoreMIDI.MIDIObjectRef) -> Bool // deprecated kMIDIPropertyNameConfiguration CFDictionary // *|•| | | kMIDIPropertyNameConfigurationDictionary CFDictionary // *|?|?|?| kMIDIPropertyMaxSysExSpeed int32 -// *|•| | | kMIDIPropertyDriverDeviceEditorApp string (path to app that can configure the device) +// *|•| | | kMIDIPropertyDriverDeviceEditorApp string (path to app to configure device) // -------------------------------------------------------------- // | | | | Presentation: // *|•| | | kMIDIPropertyImage string (POSIX path to image file) diff --git a/Sources/MIDIKitIO/Core MIDI/Core MIDI Properties Set.swift b/Sources/MIDIKitIO/Core MIDI/Core MIDI Properties Set.swift index 73725b404f..4f14f7927c 100644 --- a/Sources/MIDIKitIO/Core MIDI/Core MIDI Properties Set.swift +++ b/Sources/MIDIKitIO/Core MIDI/Core MIDI Properties Set.swift @@ -1,7 +1,7 @@ // // Core MIDI Properties Set.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -104,9 +104,11 @@ internal func setDictionary( /// Set user-visible endpoint name. /// (`kMIDIPropertyName`) /// -/// Devices, entities, and endpoints may all have names. The standard way to display an endpoint’s name is to ask it for its name and display it only if unique. If not, prepend the device name. +/// Devices, entities, and endpoints may all have names. The standard way to display an endpoint’s +/// name is to ask it for its name and display it only if unique. If not, prepend the device name. /// -/// A studio setup editor may allow the user to set the names of both driver-owned and external devices. +/// A studio setup editor may allow the user to set the names of both driver-owned and external +/// devices. /// /// - Throws: ``MIDIIOError`` internal func setName( @@ -166,7 +168,8 @@ internal func setManufacturer( /// Set unique ID. /// (`kMIDIPropertyUniqueID`) /// -/// The system assigns unique IDs to all objects. Creators of virtual endpoints may set this property on their endpoints, though doing so may fail if the chosen ID is not unique. +/// The system assigns unique IDs to all objects. Creators of virtual endpoints may set this +/// property on their endpoints, though doing so may fail if the chosen ID is not unique. /// /// - Throws: ``MIDIIOError`` internal func setUniqueID( diff --git a/Sources/MIDIKitIO/Core MIDI/Core MIDI Ref Types.swift b/Sources/MIDIKitIO/Core MIDI/Core MIDI Ref Types.swift index 6b7606d9ce..2fa6a4b759 100644 --- a/Sources/MIDIKitIO/Core MIDI/Core MIDI Ref Types.swift +++ b/Sources/MIDIKitIO/Core MIDI/Core MIDI Ref Types.swift @@ -1,7 +1,7 @@ // // Core MIDI Ref Types.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // /// MIDIKit analogue for Core MIDI's `MIDIObjectRef`. diff --git a/Sources/MIDIKitIO/Core MIDI/Core MIDI Thru Connections.swift b/Sources/MIDIKitIO/Core MIDI/Core MIDI Thru Connections.swift index aa174f42d4..f5aff6186b 100644 --- a/Sources/MIDIKitIO/Core MIDI/Core MIDI Thru Connections.swift +++ b/Sources/MIDIKitIO/Core MIDI/Core MIDI Thru Connections.swift @@ -1,7 +1,7 @@ // // Core MIDI Thru Connections.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -10,7 +10,8 @@ /// Returns `true` if current platform supports MIDI play-thru connections. /// -/// MIDI play-thru connections only function on **macOS Catalina or earlier** due to Core MIDI bugs on later macOS releases. +/// MIDI play-thru connections only function on **macOS Catalina or earlier** due to Core MIDI bugs +/// on later macOS releases. internal var isThruConnectionsSupportedOnCurrentPlatform: Bool { if #available(macOS 11.0, /* iOS ???, */ *) { return false @@ -20,11 +21,13 @@ internal var isThruConnectionsSupportedOnCurrentPlatform: Bool { } /// Internal: -/// Queries Core MIDI for existing persistent play-thru connections stored in the system matching the specified persistent owner ID. +/// Queries Core MIDI for existing persistent play-thru connections stored in the system matching +/// the specified persistent owner ID. /// /// To delete them all, see sister function `removeAllSystemThruConnectionsPersistentEntries(:)`. /// -/// - Parameter persistentOwnerID: Reverse-DNS domain that was used when the connection was first made +/// - Parameter persistentOwnerID: Reverse-DNS domain that was used when the connection was first +/// made /// /// - Throws: ``MIDIIOError/osStatus(_:)`` internal func getSystemThruConnectionsPersistentEntries( @@ -66,7 +69,8 @@ internal func getSystemThruConnectionsPersistentEntries( /// Internal: /// Deletes all system-held Core MIDI MIDI play-thru connections matching an owner ID. /// -/// - Parameter persistentOwnerID: Reverse-DNS domain that was used when the connection was first made +/// - Parameter persistentOwnerID: Reverse-DNS domain that was used when the connection was first +/// made. /// /// - Throws: ``MIDIIOError/osStatus(_:)`` /// @@ -124,7 +128,8 @@ extension MIDIThruConnectionParams { } /// Internal: - /// Converts params from `CFData` returned from Core MIDI when getting params for a thru connection that exists in the system via `MIDIThruConnectionGetParams`. + /// Converts params from `CFData` returned from Core MIDI when getting params for a thru + /// connection that exists in the system via `MIDIThruConnectionGetParams`. internal init?(cfData: CFData) { self.init() diff --git a/Sources/MIDIKitIO/Core MIDI/IO Constants.swift b/Sources/MIDIKitIO/Core MIDI/IO Constants.swift index d4ff76baa4..88756cfec5 100644 --- a/Sources/MIDIKitIO/Core MIDI/IO Constants.swift +++ b/Sources/MIDIKitIO/Core MIDI/IO Constants.swift @@ -1,7 +1,7 @@ // // IO Constants.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // @_implementationOnly import CoreMIDI @@ -20,13 +20,15 @@ internal let kSizeOfMIDIPacket = MemoryLayout.size /// /// The packet is an "open-ended array of variable-length MIDIPackets" of `numPackets` count. /// -/// To determine the size of the header, we can get the size of a `UInt32`, or subtract the size of a single packet from the size of a packet list. +/// To determine the size of the header, we can get the size of a `UInt32`, or subtract the size of +/// a single packet from the size of a packet list. @usableFromInline internal let kSizeOfMIDIPacketListHeader = kSizeOfMIDIPacketList - kSizeOfMIDIPacket /// Size of Core MIDI `MIDIPacket` header. /// -/// The `MIDIPacket` struct consists of a `MIDITimeStamp` timestamp, a `UInt16` length, followed by data bytes of the length specified. +/// The `MIDIPacket` struct consists of a `MIDITimeStamp` timestamp, a `UInt16` length, followed by +/// data bytes of the length specified. /// /// To determine the size of the header, add the size of the `timestamp` and `length` portions. @usableFromInline diff --git a/Sources/MIDIKitIO/Core MIDI/MIDI Packet Utilities.swift b/Sources/MIDIKitIO/Core MIDI/MIDI Packet Utilities.swift new file mode 100644 index 0000000000..6de4ff2b42 --- /dev/null +++ b/Sources/MIDIKitIO/Core MIDI/MIDI Packet Utilities.swift @@ -0,0 +1,40 @@ +// +// MIDI Packet Utilities.swift +// MIDIKit • https://github.com/orchetect/MIDIKit +// © 2021-2022 Steffan Andrews • Licensed under MIT License +// + +#if !os(tvOS) && !os(watchOS) + +import Foundation +@_implementationOnly import CoreMIDI + +/// Utility: +/// Attempts to extract data from a refCon pointer supplied by `CoreMIDI.MIDIReceiveBlock` and +/// `CoreMIDI.MIDIReadBlock` identifying the sender of the event packets. +/// +/// This pointer is untyped and Optional, and is not expected to contain data of any certain type +/// unless is it a refCon that is created by MIDIKit. +internal func unpackMIDIRefCon( + refCon: UnsafeMutableRawPointer?, + known: Bool +) -> MIDIOutputEndpoint? { + // we can only safely use refCons that we set originally + guard known else { return nil } + + guard let refCon = refCon else { return nil } + + // note that this is only stable if we already know + // that this is the pointer type and refcount semantics, + // both of which are known if it originates from MIDIInputConnection + let srcRefNS = Unmanaged.fromOpaque(refCon).takeUnretainedValue() + let srcRef = UInt32(truncating: srcRefNS) + + // filter out invalid ref data + let uID = getUniqueID(of: srcRef) + guard uID != .invalidMIDIIdentifier else { return nil } + + return MIDIOutputEndpoint(from: srcRef) +} + +#endif diff --git a/Sources/MIDIKitIO/Core MIDI/MIDIEventList/MIDIEventList Packets.swift b/Sources/MIDIKitIO/Core MIDI/MIDIEventList/MIDIEventList Packets.swift index 12a2199299..06014377e4 100644 --- a/Sources/MIDIKitIO/Core MIDI/MIDIEventList/MIDIEventList Packets.swift +++ b/Sources/MIDIKitIO/Core MIDI/MIDIEventList/MIDIEventList Packets.swift @@ -1,7 +1,7 @@ // // MIDIEventList Packets.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -13,10 +13,15 @@ import Foundation extension UnsafePointer where Pointee == CoreMIDI.MIDIEventList { /// Internal: /// Returns array of MIDIKit `UniversalPacketData` instances. - internal func packets() -> [UniversalMIDIPacketData] { + internal func packets( + refCon: UnsafeMutableRawPointer?, + refConKnown: Bool + ) -> [UniversalMIDIPacketData] { if pointee.numPackets == 0 { return [] } + + let source = unpackMIDIRefCon(refCon: refCon, known: refConKnown) // Core MIDI's unsafeSequence() is not available on tvOS or watchOS at all let sequencedPackets = unsafeSequence().map { @@ -37,7 +42,8 @@ extension UnsafePointer where Pointee == CoreMIDI.MIDIEventList { for umpWords in parse(packetWords: sequencedPacket.words) { let ump = UniversalMIDIPacketData( words: umpWords, - timeStamp: sequencedPacket.timeStamp + timeStamp: sequencedPacket.timeStamp, + source: source ) packets.append(ump) } diff --git a/Sources/MIDIKitIO/Core MIDI/MIDIEventList/MIDIEventList Utilities.swift b/Sources/MIDIKitIO/Core MIDI/MIDIEventList/MIDIEventList Utilities.swift index 85cf2e4b3a..6405d359a4 100644 --- a/Sources/MIDIKitIO/Core MIDI/MIDIEventList/MIDIEventList Utilities.swift +++ b/Sources/MIDIKitIO/Core MIDI/MIDIEventList/MIDIEventList Utilities.swift @@ -1,7 +1,7 @@ // // MIDIEventList Utilities.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -89,7 +89,8 @@ extension CoreMIDI.MIDIEventPacket { extension CoreMIDI.MIDIEventList { /// Internal: - /// Assembles a single Core MIDI `MIDIEventPacket` from a Universal MIDI Packet `UInt32` word array and wraps it in a Core MIDI `MIDIEventList`. + /// Assembles a single Core MIDI `MIDIEventPacket` from a Universal MIDI Packet `UInt32` word + /// array and wraps it in a Core MIDI `MIDIEventList`. @available(macOS 11, iOS 14, macCatalyst 14, *) internal init( protocol midiProtocol: CoreMIDI.MIDIProtocolID, diff --git a/Sources/MIDIKitIO/Core MIDI/MIDIPacketLIst/MIDIPacketList Packets.swift b/Sources/MIDIKitIO/Core MIDI/MIDIPacketLIst/MIDIPacketList Packets.swift index be2e109e6a..77be6cb0da 100755 --- a/Sources/MIDIKitIO/Core MIDI/MIDIPacketLIst/MIDIPacketList Packets.swift +++ b/Sources/MIDIKitIO/Core MIDI/MIDIPacketLIst/MIDIPacketList Packets.swift @@ -1,7 +1,7 @@ // // MIDIPacketList Packets.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -12,7 +12,10 @@ import Foundation extension UnsafePointer where Pointee == CoreMIDI.MIDIPacketList { /// Internal: /// Returns array of MIDIKit ``MIDIPacketData`` instances. - internal func packets() -> [MIDIPacketData] { + internal func packets( + refCon: UnsafeMutableRawPointer?, + refConKnown: Bool + ) -> [MIDIPacketData] { if pointee.numPackets == 0 { return [] } @@ -21,12 +24,12 @@ extension UnsafePointer where Pointee == CoreMIDI.MIDIPacketList { if #available(macOS 10.15, iOS 13.0, macCatalyst 13.0, *) { return unsafeSequence().map { - MIDIPacketData($0) + MIDIPacketData($0, refCon: refCon, refConKnown: refConKnown) } } else { var packetDatas: [MIDIPacketData] = [] pointee.forEachPacket { - packetDatas.append(MIDIPacketData($0)) + packetDatas.append(MIDIPacketData($0, refCon: refCon, refConKnown: refConKnown)) } return packetDatas } @@ -36,7 +39,8 @@ extension UnsafePointer where Pointee == CoreMIDI.MIDIPacketList { extension CoreMIDI.MIDIPacketList { /// Iterates packets in a `MIDIPacketList` and calls the closure for each packet. /// This is confirmed working on Mojave. - /// There were numerous difficulties in reading `MIDIPacketList` on Mojave and earlier and this solution was stable. + /// There were numerous difficulties in reading `MIDIPacketList` on Mojave and earlier and this + /// solution was stable. fileprivate func forEachPacket(_ closure: (UnsafeMutablePointer) -> Void) { withUnsafePointer(to: packet) { ptr in var idx: UInt32 = 0 diff --git a/Sources/MIDIKitIO/Core MIDI/MIDIPacketLIst/MIDIPacketList Utilities.swift b/Sources/MIDIKitIO/Core MIDI/MIDIPacketLIst/MIDIPacketList Utilities.swift index 8c603fa501..23d1b21623 100644 --- a/Sources/MIDIKitIO/Core MIDI/MIDIPacketLIst/MIDIPacketList Utilities.swift +++ b/Sources/MIDIKitIO/Core MIDI/MIDIPacketLIst/MIDIPacketList Utilities.swift @@ -1,7 +1,7 @@ // // MIDIPacketList Utilities.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -10,7 +10,8 @@ extension MIDIPacketList { /// Internal: - /// Assembles a single Core MIDI `MIDIPacket` from a MIDI message byte array and wraps it in a Core MIDI `MIDIPacketList`. + /// Assembles a single Core MIDI `MIDIPacket` from a MIDI message byte array and wraps it in a + /// Core MIDI `MIDIPacketList`. internal init(data: [UInt8]) { let packetList = UnsafeMutablePointer(data: data) self = packetList.pointee @@ -18,7 +19,8 @@ extension MIDIPacketList { } /// Internal: - /// Assembles an array of `UInt8` arrays into Core MIDI `MIDIPacket`s and wraps them in a `MIDIPacketList`. + /// Assembles an array of `UInt8` arrays into Core MIDI `MIDIPacket`s and wraps them in a + /// `MIDIPacketList`. internal init(data: [[UInt8]]) throws { let packetList = try UnsafeMutablePointer(data: data) self = packetList.pointee @@ -28,7 +30,8 @@ extension MIDIPacketList { extension UnsafeMutablePointer where Pointee == MIDIPacketList { /// Internal: - /// Assembles a single Core MIDI `MIDIPacket` from a MIDI message byte array and wraps it in a Core MIDI `MIDIPacketList`. + /// Assembles a single Core MIDI `MIDIPacket` from a MIDI message byte array and wraps it in a + /// Core MIDI `MIDIPacketList`. /// /// - Note: You must deallocate the pointer when finished with it. internal init(data: [UInt8]) { @@ -66,10 +69,12 @@ extension UnsafeMutablePointer where Pointee == MIDIPacketList { } /// Internal: - /// Assembles an array of `UInt8` arrays into Core MIDI `MIDIPacket`s and wraps them in a `MIDIPacketList`. + /// Assembles an array of `UInt8` arrays into Core MIDI `MIDIPacket`s and wraps them in a + /// `MIDIPacketList`. /// /// - Note: You must deallocate the pointer when finished with it. - /// - Note: System Exclusive messages must each be packed in a dedicated MIDIPacketList with no other events, otherwise MIDIPacketList may fail. + /// - Note: System Exclusive messages must each be packed in a dedicated MIDIPacketList with no + /// other events, otherwise MIDIPacketList may fail. internal init(data: [[UInt8]]) throws { // Create a buffer that is big enough to hold the data to be sent and // all the necessary headers. @@ -77,14 +82,16 @@ extension UnsafeMutablePointer where Pointee == MIDIPacketList { .reduce(0) { $0 + $1.count + kSizeOfMIDIPacketHeader } + kSizeOfMIDIPacketListHeader - // MIDIPacketListAdd's discussion section states that "The maximum size of a packet list is 65536 bytes." + // MIDIPacketListAdd's discussion section states that "The maximum size of a packet list is + // 65536 bytes." guard bufferSize <= 65536 else { throw MIDIIOError.malformed( "Data array is too large (\(bufferSize) bytes). Maximum size is 65536 bytes." ) } - // As per Apple docs, timeTag must not be 0 when a packet is sent with `MIDIReceived()`. It must be a proper timeTag. + // As per Apple docs, timeTag must not be 0 when a packet is sent with `MIDIReceived()`. It + // must be a proper timeTag. let timeTag: UInt64 = mach_absolute_time() let packetListPointer: UnsafeMutablePointer = .allocate(capacity: 1) diff --git a/Sources/MIDIKitIO/Core MIDI/Property.swift b/Sources/MIDIKitIO/Core MIDI/Property.swift index d910ffb0c0..ee38385210 100644 --- a/Sources/MIDIKitIO/Core MIDI/Property.swift +++ b/Sources/MIDIKitIO/Core MIDI/Property.swift @@ -1,7 +1,7 @@ // // Property.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -215,7 +215,8 @@ extension AnyMIDIIOObject.Property { case kMIDIPropertySupportsShowControl: self = .supportsShowControl // MARK: Configuration - // case kMIDIPropertyNameConfigurationDictionary: self = .nameConfigurationDictionary // -- has OS requirements, handled separately + // case kMIDIPropertyNameConfigurationDictionary: self = .nameConfigurationDictionary + // --> has OS requirements, handled separately case kMIDIPropertyMaxSysExSpeed: self = .maxSysExSpeed case kMIDIPropertyDriverDeviceEditorApp: self = .driverDeviceEditorApp @@ -227,7 +228,8 @@ extension AnyMIDIIOObject.Property { case kMIDIPropertyPanDisruptsStereo: self = .panDisruptsStereo // MARK: Protocols - // case kMIDIPropertyProtocolID: self = .protocolID // -- has OS requirements, handled separately + // case kMIDIPropertyProtocolID: self = .protocolID + // --> has OS requirements, handled separately // MARK: Timing case kMIDIPropertyTransmitsMTC: self = .transmitsMTC diff --git a/Sources/MIDIKitIO/Errors/MIDIIOError.swift b/Sources/MIDIKitIO/Errors/MIDIIOError.swift index 2cae16a0d2..6af0c2fd25 100644 --- a/Sources/MIDIKitIO/Errors/MIDIIOError.swift +++ b/Sources/MIDIKitIO/Errors/MIDIIOError.swift @@ -1,7 +1,7 @@ // // MIDIIOError.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -29,7 +29,8 @@ public enum MIDIIOError: Error, Hashable { extension MIDIIOError { /// Internal: - /// Convenience to return a case of ``osStatus(_:)`` with its associated ``CoreMIDIOSStatus`` formed from a raw Core MIDI `OSStatus` (Int32) integer value. + /// Convenience to return a case of ``osStatus(_:)`` with its associated ``CoreMIDIOSStatus`` + /// formed from a raw Core MIDI `OSStatus` (Int32) integer value. internal static func osStatus(_ rawValue: CoreMIDIOSStatus) -> Self { .osStatus(.init(rawValue: rawValue)) } diff --git a/Sources/MIDIKitIO/Errors/MIDIOSStatus.swift b/Sources/MIDIKitIO/Errors/MIDIOSStatus.swift index d509124649..9c7aca05f9 100644 --- a/Sources/MIDIKitIO/Errors/MIDIOSStatus.swift +++ b/Sources/MIDIKitIO/Errors/MIDIOSStatus.swift @@ -1,14 +1,15 @@ // // MIDIOSStatus.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @_implementationOnly import CoreMIDI -/// An enumeration representing `CoreMIDI.MIDIServices` `OSStatus` error codes, with verbose descriptions. +/// An enumeration representing `CoreMIDI.MIDIServices` `OSStatus` error codes, with verbose +/// descriptions. public enum MIDIOSStatus: Hashable { /// `CoreMIDI.kMIDIInvalidClient`: /// An invalid `MIDIClientRef` was passed. @@ -55,7 +56,8 @@ public enum MIDIOSStatus: Hashable { case setupFormatErr /// `CoreMIDI.kMIDIWrongThread`: - /// A driver is calling a non-I/O function in the server from a thread other than the server's main thread. + /// A driver is calling a non-I/O function in the server from a thread other than the server's + /// main thread. case wrongThread /// `CoreMIDI.kMIDIObjectNotFound`: @@ -94,7 +96,8 @@ public enum MIDIOSStatus: Hashable { extension MIDIOSStatus { /// Returns the corresponding Core MIDI `OSStatus` raw value. /// - /// Core MIDI headers note: "These are the OSStatus error constants that are unique to Core MIDI. Note that Core MIDI functions may return other codes that are not listed here." + /// Core MIDI headers note: "These are the OSStatus error constants that are unique to Core + /// MIDI. Note that Core MIDI functions may return other codes that are not listed here." public var rawValue: CoreMIDIOSStatus { // swiftformat:disable spacearoundoperators switch self { diff --git a/Sources/MIDIKitIO/MIDIConnectionMode/MIDIConnectionMode.swift b/Sources/MIDIKitIO/MIDIConnectionMode/MIDIConnectionMode.swift index a4b0b87394..9fe59f81b8 100644 --- a/Sources/MIDIKitIO/MIDIConnectionMode/MIDIConnectionMode.swift +++ b/Sources/MIDIKitIO/MIDIConnectionMode/MIDIConnectionMode.swift @@ -1,7 +1,7 @@ // // MIDIConnectionMode.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -11,7 +11,8 @@ public enum MIDIConnectionMode: Equatable, Hashable { /// Specific endpoint criteria. case definedEndpoints - /// Automatically adds all endpoints in the system and adds any new endpoints that appear in the system at any time thereafter. + /// Automatically adds all endpoints in the system and adds any new endpoints that appear in the + /// system at any time thereafter. /// (Endpoint filters are respected.) /// /// Note that this mode overrides endpoints / identity criteria. diff --git a/Sources/MIDIKitIO/MIDIDevice/MIDIDevice.swift b/Sources/MIDIKitIO/MIDIDevice/MIDIDevice.swift index 72d362c65b..83c0ee989c 100644 --- a/Sources/MIDIKitIO/MIDIDevice/MIDIDevice.swift +++ b/Sources/MIDIKitIO/MIDIDevice/MIDIDevice.swift @@ -1,7 +1,7 @@ // // MIDIDevice.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -12,7 +12,8 @@ /// /// Although this is a value-type struct, do not store or cache it as it will not remain updated. /// -/// Instead, read device arrays and individual device properties from ``MIDIManager/devices`` ad-hoc when they are needed. +/// Instead, read device arrays and individual device properties from ``MIDIManager/devices`` ad-hoc +/// when they are needed. public struct MIDIDevice: MIDIIOObject { // MARK: MIDIIOObject @@ -87,7 +88,7 @@ extension MIDIDevice { extension MIDIDevice: CustomDebugStringConvertible { public var debugDescription: String { - "MIDIDevice(name: \(name.quoted), uniqueID: \(uniqueID), exists: \(exists)" + "MIDIDevice(name: \(name.quoted), uniqueID: \(uniqueID), exists: \(exists))" } } diff --git a/Sources/MIDIKitIO/MIDIDevices/MIDIDevices.swift b/Sources/MIDIKitIO/MIDIDevices/MIDIDevices.swift index 7efdae8cdc..a0cfc20042 100644 --- a/Sources/MIDIKitIO/MIDIDevices/MIDIDevices.swift +++ b/Sources/MIDIKitIO/MIDIDevices/MIDIDevices.swift @@ -1,26 +1,29 @@ // // MIDIDevices.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) import Foundation -// this protocol may not be necessary, it was experimental so that the `MIDIManager.devices` property could be swapped out with a different Devices class with Combine support +// this protocol may not be necessary, it was experimental so that the `MIDIManager.devices` +// property could be swapped out with a different Devices class with Combine support public protocol MIDIIODevicesProtocol { /// List of MIDI devices in the system var devices: [MIDIDevice] { get } /// Manually update the locally cached contents from the system. - /// This method does not need to be manually invoked, as it is handled internally when MIDI system endpoints change. + /// This method does not need to be manually invoked, as it is handled internally when MIDI + /// system endpoints change. func update() } /// Manages system MIDI devices information cache. /// -/// Do not instance this class directly. Instead, access the ``MIDIManager/devices`` property of your central ``MIDIManager`` instance. +/// Do not instance this class directly. Instead, access the ``MIDIManager/devices`` property of +/// your central ``MIDIManager`` instance. public final class MIDIDevices: NSObject, MIDIIODevicesProtocol { public internal(set) dynamic var devices: [MIDIDevice] = [] @@ -30,7 +33,8 @@ public final class MIDIDevices: NSObject, MIDIIODevicesProtocol { /// Manually update the locally cached contents from the system. /// - /// It is not necessary to call this method as the ``MIDIManager`` will automate updating device cache. + /// It is not necessary to call this method as the ``MIDIManager`` will automate updating device + /// cache. public func update() { devices = getSystemDevices() } diff --git a/Sources/MIDIKitIO/MIDIEndpoint/MIDIEndpointIdentity.swift b/Sources/MIDIKitIO/MIDIEndpoint/MIDIEndpointIdentity.swift index c4a7408793..6799921066 100644 --- a/Sources/MIDIKitIO/MIDIEndpoint/MIDIEndpointIdentity.swift +++ b/Sources/MIDIKitIO/MIDIEndpoint/MIDIEndpointIdentity.swift @@ -1,7 +1,7 @@ // // MIDIEndpointIdentity.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -10,34 +10,42 @@ /// Criterium with which to identify a MIDI endpoint. /// -/// It is recommended to use ``uniqueID(_:)`` primarily. For added resiliency, it is also possible to use ``uniqueIDWithFallback(id:fallbackDisplayName:)`` with fallback criteria in the event the endpoint provider does not correctly restore its unique identifier number. +/// It is recommended to use ``uniqueID(_:)`` primarily. For added resiliency, it is also possible +/// to use ``uniqueIDWithFallback(id:fallbackDisplayName:)`` with fallback criteria in the event the +/// endpoint provider does not correctly restore its unique identifier number. public enum MIDIEndpointIdentity { /// Utilizes first endpoint matching the endpoint name. (Convenience, not recommended.) /// - /// ⚠️ Use of this is discouraged outside of debugging, since multiple endpoints can potentially share the same name in the system. + /// ⚠️ Use of this is discouraged outside of debugging, since multiple endpoints can potentially + /// share the same name in the system. /// /// The best method is to use ``uniqueID(_:)``. case name(String) /// Utilizes first endpoint matching the display name. (Convenience, not recommended.) /// - /// ⚠️ Use of this is discouraged outside of debugging, since multiple endpoints can potentially share the same display name in the system. + /// ⚠️ Use of this is discouraged outside of debugging, since multiple endpoints can potentially + /// share the same display name in the system. /// /// The best method is to use ``uniqueID(_:)``. case displayName(String) /// Endpoint matching the unique ID. (Recommended) /// - /// This is typically the primary piece of criterium that should be used to persistently identify a unique endpoint in the system. + /// This is typically the primary piece of criterium that should be used to persistently + /// identify a unique endpoint in the system. case uniqueID(MIDIIdentifier) /// Endpoint matching the unique ID primarily, with fallback display name criterium. /// - /// Priority is given to the endpoint matching the given unique ID. If an endpoint is not found with that ID, the first endpoint matching the display name is used. + /// Priority is given to the endpoint matching the given unique ID. If an endpoint is not found + /// with that ID, the first endpoint matching the display name is used. /// - /// This may be useful in the event an endpoint vendor does not correctly maintain its own unique identifier number persistently. + /// This may be useful in the event an endpoint vendor does not correctly maintain its own + /// unique identifier number persistently. /// - /// ⚠️ However it is still recommended to use the ``uniqueID(_:)`` exclusive case where possible and not rely on falling back to fuzzy criteria such as display name. + /// ⚠️ However it is still recommended to use the ``uniqueID(_:)`` exclusive case where possible + /// and not rely on falling back to fuzzy criteria such as display name. case uniqueIDWithFallback( id: MIDIIdentifier, fallbackDisplayName: String diff --git a/Sources/MIDIKitIO/MIDIEndpoint/MIDIEndpointType.swift b/Sources/MIDIKitIO/MIDIEndpoint/MIDIEndpointType.swift index 7200afa09c..54719ef2f5 100644 --- a/Sources/MIDIKitIO/MIDIEndpoint/MIDIEndpointType.swift +++ b/Sources/MIDIKitIO/MIDIEndpoint/MIDIEndpointType.swift @@ -1,7 +1,7 @@ // // MIDIEndpointType.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIEndpoint/MIDIIOEndpointProtocol Collection.swift b/Sources/MIDIKitIO/MIDIEndpoint/MIDIIOEndpointProtocol Collection.swift index 930f63f2a1..129ff305c1 100644 --- a/Sources/MIDIKitIO/MIDIEndpoint/MIDIIOEndpointProtocol Collection.swift +++ b/Sources/MIDIKitIO/MIDIEndpoint/MIDIIOEndpointProtocol Collection.swift @@ -1,7 +1,7 @@ // // MIDIIOEndpointProtocol Collection.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIEndpoint/MIDIIOEndpointProtocol Comparison.swift b/Sources/MIDIKitIO/MIDIEndpoint/MIDIIOEndpointProtocol Comparison.swift index 98532e8c20..711f7d1d81 100644 --- a/Sources/MIDIKitIO/MIDIEndpoint/MIDIIOEndpointProtocol Comparison.swift +++ b/Sources/MIDIKitIO/MIDIEndpoint/MIDIIOEndpointProtocol Comparison.swift @@ -1,14 +1,15 @@ // // MIDIIOEndpointProtocol Comparison.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) // MARK: - Equatable default implementation -// (conforming types to MIDIIOObject just need to conform to Equatable and this implementation will be used) +// (conforming types to MIDIIOObject just need to conform to Equatable +// and this implementation will be used) extension MIDIIOEndpointProtocol { public static func == (lhs: Self, rhs: Self) -> Bool { @@ -18,7 +19,8 @@ extension MIDIIOEndpointProtocol { // MARK: - Hashable default implementation -// (conforming types to MIDIIOObject just need to conform to Hashable and this implementation will be used) +// (conforming types to MIDIIOObject just need to conform to Hashable +// and this implementation will be used) extension MIDIIOEndpointProtocol { public func hash(into hasher: inout Hasher) { @@ -28,7 +30,8 @@ extension MIDIIOEndpointProtocol { // MARK: - Identifiable default implementation -// (conforming types to MIDIIOObject just need to conform to Identifiable and this implementation will be used) +// (conforming types to MIDIIOObject just need to conform to Identifiable +// and this implementation will be used) extension MIDIIOEndpointProtocol { public typealias ID = MIDIIdentifier diff --git a/Sources/MIDIKitIO/MIDIEndpoint/MIDIIOEndpointProtocol.swift b/Sources/MIDIKitIO/MIDIEndpoint/MIDIIOEndpointProtocol.swift index 277f4e42c4..014a3c2dbe 100644 --- a/Sources/MIDIKitIO/MIDIEndpoint/MIDIIOEndpointProtocol.swift +++ b/Sources/MIDIKitIO/MIDIEndpoint/MIDIIOEndpointProtocol.swift @@ -1,7 +1,7 @@ // // MIDIIOEndpointProtocol.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -15,9 +15,14 @@ public protocol MIDIIOEndpointProtocol: MIDIIOObject { // implemented in extension _MIDIIOEndpointProtocol - /// Returns the entity the endpoint originates from. For virtual endpoints, this will return `nil`. + /// Returns the entity the endpoint originates from. + /// For virtual endpoints, this will return `nil`. func getEntity() -> MIDIEntity? + /// Returns the device the endpoint originates from. + /// For virtual endpoints, this will return `nil`. + func getDevice() -> MIDIDevice? + /// Returns the endpoint as a type-erased ``AnyMIDIEndpoint``. func asAnyEndpoint() -> AnyMIDIEndpoint } @@ -32,6 +37,11 @@ extension _MIDIIOEndpointProtocol { public func getEntity() -> MIDIEntity? { try? getSystemEntity(for: coreMIDIObjectRef) } + + public func getDevice() -> MIDIDevice? { + guard let entity = getEntity() else { return nil } + return try? getSystemDevice(for: entity.coreMIDIObjectRef) + } } // MARK: - Additional properties diff --git a/Sources/MIDIKitIO/MIDIEndpoints/MIDIEndpointFilter.swift b/Sources/MIDIKitIO/MIDIEndpoints/MIDIEndpointFilter.swift index ceb0c88bea..e897d4eb51 100644 --- a/Sources/MIDIKitIO/MIDIEndpoints/MIDIEndpointFilter.swift +++ b/Sources/MIDIKitIO/MIDIEndpoints/MIDIEndpointFilter.swift @@ -1,7 +1,7 @@ // // MIDIEndpointFilter.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIEndpoints/MIDIEndpoints.swift b/Sources/MIDIKitIO/MIDIEndpoints/MIDIEndpoints.swift index a071faaa3c..c71b831f97 100644 --- a/Sources/MIDIKitIO/MIDIEndpoints/MIDIEndpoints.swift +++ b/Sources/MIDIKitIO/MIDIEndpoints/MIDIEndpoints.swift @@ -1,29 +1,33 @@ // // MIDIEndpoints.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) import Foundation -// this protocol may not be necessary, it was experimental so that the `MIDIManager.endpoints` property could be swapped out with a different Endpoints class with Combine support +// this protocol may not be necessary, it was experimental so that the `MIDIManager.endpoints` +// property could be swapped out with a different Endpoints class with Combine support public protocol MIDIIOEndpointsProtocol { /// List of MIDI input endpoints in the system. var inputs: [MIDIInputEndpoint] { get } - /// List of MIDI input endpoints in the system omitting virtual endpoints owned by the ``MIDIManager`` instance. + /// List of MIDI input endpoints in the system omitting virtual endpoints owned by the + /// ``MIDIManager`` instance. var inputsUnowned: [MIDIInputEndpoint] { get } /// List of MIDI output endpoints in the system. var outputs: [MIDIOutputEndpoint] { get } - /// List of MIDI output endpoints in the system omitting virtual endpoints owned by the ``MIDIManager`` instance. + /// List of MIDI output endpoints in the system omitting virtual endpoints owned by the + /// ``MIDIManager`` instance. var outputsUnowned: [MIDIOutputEndpoint] { get } /// Manually update the locally cached contents from the system. - /// This method does not need to be manually invoked, as it is called automatically by the ``MIDIManager`` when MIDI system endpoints change. + /// This method does not need to be manually invoked, as it is called automatically by the + /// ``MIDIManager`` when MIDI system endpoints change. mutating func update() } diff --git a/Sources/MIDIKitIO/MIDIEntity/MIDIEntity.swift b/Sources/MIDIKitIO/MIDIEntity/MIDIEntity.swift index a7851d0f57..7328aae06e 100644 --- a/Sources/MIDIKitIO/MIDIEntity/MIDIEntity.swift +++ b/Sources/MIDIKitIO/MIDIEntity/MIDIEntity.swift @@ -1,7 +1,7 @@ // // MIDIEntity.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObject.swift b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObject.swift index 1511c091c2..9c6cda3ab9 100644 --- a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObject.swift +++ b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObject.swift @@ -1,7 +1,7 @@ // // MIDIIOObject.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -29,7 +29,8 @@ public protocol MIDIIOObject { /// The Core MIDI object reference. var coreMIDIObjectRef: CoreMIDIObjectRef { get } - /// Return as ``AnyMIDIIOObject``, a type-erased representation of a MIDIKit object conforming to ``MIDIIOObject``. + /// Return as ``AnyMIDIIOObject``, a type-erased representation of a MIDIKit object conforming + /// to ``MIDIIOObject``. func asAnyMIDIIOObject() -> AnyMIDIIOObject // MARK: - MIDIIOObject Comparison.swift diff --git a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectCache.swift b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectCache.swift index 59e893e159..583966cb5d 100644 --- a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectCache.swift +++ b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectCache.swift @@ -1,7 +1,7 @@ // // MIDIIOObjectCache.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Collection.swift b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Collection.swift index ee0cd875f8..64db93f20c 100644 --- a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Collection.swift +++ b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Collection.swift @@ -1,7 +1,7 @@ // // MIDIIOObjectProtocol Collection.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Comparison.swift b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Comparison.swift index 499ff9eb82..b40ea87441 100644 --- a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Comparison.swift +++ b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Comparison.swift @@ -1,14 +1,15 @@ // // MIDIIOObjectProtocol Comparison.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) // MARK: - Equatable default implementation -// (conforming types to MIDIIOObject just need to conform to Equatable and this implementation will be used) +// (conforming types to MIDIIOObject just need to conform to Equatable +// and this implementation will be used) extension MIDIIOObject { public static func == (lhs: Self, rhs: Self) -> Bool { @@ -18,7 +19,8 @@ extension MIDIIOObject { // MARK: - Hashable default implementation -// (conforming types to MIDIIOObject just need to conform to Hashable and this implementation will be used) +// (conforming types to MIDIIOObject just need to conform to Hashable +// and this implementation will be used) extension MIDIIOObject { public func hash(into hasher: inout Hasher) { diff --git a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Properties Dictionary.swift b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Properties Dictionary.swift index 28a26a7d4d..f4bc050c8f 100644 --- a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Properties Dictionary.swift +++ b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Properties Dictionary.swift @@ -1,7 +1,7 @@ // // MIDIIOObjectProtocol Properties Dictionary.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Properties.swift b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Properties.swift index 06991e345a..547881e16b 100644 --- a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Properties.swift +++ b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectProtocol Properties.swift @@ -1,7 +1,7 @@ // // MIDIIOObjectProtocol Properties.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -25,9 +25,12 @@ extension MIDIIOObject { /// Get user-visible endpoint name. /// (`kMIDIPropertyName`) /// - /// Devices, entities, and endpoints may all have names. The standard way to display an endpoint’s name is to ask it for its name and display it only if unique. If not, prepend the device name. + /// Devices, entities, and endpoints may all have names. The standard way to display an + /// endpoint’s name is to ask it for its name and display it only if unique. If not, prepend the + /// device name. /// - /// A studio setup editor may allow the user to set the names of both driver-owned and external devices. + /// A studio setup editor may allow the user to set the names of both driver-owned and external + /// devices. /// /// - Throws: ``MIDIIOError`` public func getName() -> String? { @@ -63,7 +66,8 @@ extension MIDIIOObject { /// Get unique ID. /// (`kMIDIPropertyUniqueID`) /// - /// The system assigns unique IDs to all objects. Creators of virtual endpoints may set this property on their endpoints, though doing so may fail if the chosen ID is not unique. + /// The system assigns unique IDs to all objects. Creators of virtual endpoints may set this + /// property on their endpoints, though doing so may fail if the chosen ID is not unique. public func getUniqueID() -> MIDIIdentifier { MIDIIdentifier(MIDIKitIO.getUniqueID(of: coreMIDIObjectRef)) } @@ -71,26 +75,30 @@ extension MIDIIOObject { /// Get the user-visible System Exclusive (SysEx) identifier of a device or entity. /// (`kMIDIPropertyDeviceID`) /// - /// MIDI drivers can set this property on their devices or entities. Studio setup editors can allow the user to set this property on external devices. + /// MIDI drivers can set this property on their devices or entities. Studio setup editors can + /// allow the user to set this property on external devices. public func getDeviceManufacturerID() -> Int32 { MIDIKitIO.getDeviceManufacturerID(of: coreMIDIObjectRef) } // MARK: Capabilities - /// Get a Boolean value that indicates whether the device or entity implements the MIDI Machine Control portion of the MIDI specification. + /// Get a Boolean value that indicates whether the device or entity implements the MIDI Machine + /// Control portion of the MIDI specification. /// (`kMIDIPropertySupportsMMC`) public func getSupportsMMC() -> Bool { MIDIKitIO.getSupportsMMC(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the device or entity implements the General MIDI specification. + /// Get a Boolean value that indicates whether the device or entity implements the General MIDI + /// specification. /// (`kMIDIPropertySupportsGeneralMIDI`) public func getSupportsGeneralMIDI() -> Bool { MIDIKitIO.getSupportsGeneralMIDI(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the device implements the MIDI Show Control specification. + /// Get a Boolean value that indicates whether the device implements the MIDI Show Control + /// specification. /// (`kMIDIPropertySupportsShowControl`) public func getSupportsShowControl() -> Bool { MIDIKitIO.getSupportsShowControl(of: coreMIDIObjectRef) @@ -98,7 +106,8 @@ extension MIDIIOObject { // MARK: Configuration - /// Get the device’s current patch, note, and control name values in MIDINameDocument XML format. + /// Get the device’s current patch, note, and control name values in MIDINameDocument XML + /// format. /// (`kMIDIPropertyNameConfigurationDictionary`) /// /// - Requires: macOS 10.15, macCatalyst 13.0, iOS 13.0 @@ -107,7 +116,8 @@ extension MIDIIOObject { try? MIDIKitIO.getNameConfigurationDictionary(of: coreMIDIObjectRef) } - /// Get the maximum rate, in bytes per second, at which the system may reliably send System Exclusive (SysEx) messages to this object. + /// Get the maximum rate, in bytes per second, at which the system may reliably send System + /// Exclusive (SysEx) messages to this object. /// (`kMIDIPropertyMaxSysExSpeed`) /// /// The owning driver may set an integer value for this property. @@ -130,7 +140,8 @@ extension MIDIIOObject { /// Get the full path to a device icon on the system. /// (`kMIDIPropertyImage`) /// - /// You can provide an image stored in any standard graphic file format, such as JPEG, GIF, or PNG. The maximum size for this image is 128 by 128 pixels. + /// You can provide an image stored in any standard graphic file format, such as JPEG, GIF, or + /// PNG. The maximum size for this image is 128 by 128 pixels. /// /// A studio setup editor should allow the user to choose icons for external devices. /// @@ -160,7 +171,8 @@ extension MIDIIOObject { /// (Apple-recommended user-visible name) /// (`kMIDIPropertyDisplayName`) /// - /// For objects other than endpoints, the display name is the same as its `kMIDIPropertyName` value. + /// For objects other than endpoints, the display name is the same as its `kMIDIPropertyName` + /// value. /// /// - Throws: ``MIDIIOError`` public func getDisplayName() -> String? { @@ -169,7 +181,8 @@ extension MIDIIOObject { // MARK: Audio - /// Get a Boolean value that indicates whether the MIDI pan messages sent to the device or entity cause undesirable effects when playing stereo sounds. + /// Get a Boolean value that indicates whether the MIDI pan messages sent to the device or + /// entity cause undesirable effects when playing stereo sounds. /// (`kMIDIPropertyPanDisruptsStereo`) public func getPanDisruptsStereo() -> Bool { MIDIKitIO.getPanDisruptsStereo(of: coreMIDIObjectRef) @@ -180,7 +193,8 @@ extension MIDIIOObject { /// Get the native protocol in which the endpoint communicates. /// (`kMIDIPropertyProtocolID`) /// - /// The system sets this value on endpoints when it creates them. Drivers can dynamically change the endpoint’s protocol as a result of a MIDI-CI negotiation, by setting this property. + /// The system sets this value on endpoints when it creates them. Drivers can dynamically change + /// the endpoint’s protocol as a result of a MIDI-CI negotiation, by setting this property. /// /// Clients can observe changes to this property. /// @@ -193,25 +207,29 @@ extension MIDIIOObject { // MARK: Timing - /// Get a Boolean value that indicates whether the device or entity transmits MIDI Time Code messages. + /// Get a Boolean value that indicates whether the device or entity transmits MIDI Time Code + /// messages. /// (`kMIDIPropertyTransmitsMTC`) public func getTransmitsMTC() -> Bool { MIDIKitIO.getTransmitsMTC(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the device or entity responds to MIDI Time Code messages. + /// Get a Boolean value that indicates whether the device or entity responds to MIDI Time Code + /// messages. /// (`kMIDIPropertyReceivesMTC`) public func getReceivesMTC() -> Bool { MIDIKitIO.getReceivesMTC(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the device or entity transmits MIDI beat clock messages. + /// Get a Boolean value that indicates whether the device or entity transmits MIDI beat clock + /// messages. /// (`kMIDIPropertyTransmitsClock`) public func getTransmitsClock() -> Bool { MIDIKitIO.getTransmitsClock(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the device or entity responds to MIDI beat clock messages. + /// Get a Boolean value that indicates whether the device or entity responds to MIDI beat clock + /// messages. /// (`kMIDIPropertyReceivesClock`) public func getReceivesClock() -> Bool { MIDIKitIO.getReceivesClock(of: coreMIDIObjectRef) @@ -222,9 +240,16 @@ extension MIDIIOObject { /// /// Only the driver that owns the object may set this property. /// - /// If this property value is nonzero, clients should treat the value as a minimum. For devices with a nonzero advance schedule time, drivers receive outgoing messages to the device at the time the client sends them using `MIDISend(_:_:_:)`. The driver is responsible for scheduling events to play at the right times, according to their timestamps. + /// If this property value is nonzero, clients should treat the value as a minimum. For devices + /// with a nonzero advance schedule time, drivers receive outgoing messages to the device at the + /// time the client sends them using `MIDISend(_:_:_:)`. The driver is responsible for + /// scheduling events to play at the right times, according to their timestamps. /// - /// You can also set this property on any virtual destinations you create. When clients send messages to a virtual destination with an advance schedule time of 0, the destination receives the messages at the scheduled delivery time. If a virtual destination has a nonzero advance schedule time, it receives timestamped messages as soon as they’re sent, and must do its own internal scheduling of events it receives. + /// You can also set this property on any virtual destinations you create. When clients send + /// messages to a virtual destination with an advance schedule time of 0, the destination + /// receives the messages at the scheduled delivery time. If a virtual destination has a nonzero + /// advance schedule time, it receives timestamped messages as soon as they’re sent, and must do + /// its own internal scheduling of events it receives. /// /// - Throws: ``MIDIIOError`` public func getAdvanceScheduleTimeMuSec() -> String? { @@ -233,25 +258,29 @@ extension MIDIIOObject { // MARK: Roles - /// Get a Boolean value that indicates whether the device or entity mixes external audio signals. + /// Get a Boolean value that indicates whether the device or entity mixes external audio + /// signals. /// (`kMIDIPropertyIsMixer`) public func getIsMixer() -> Bool { MIDIKitIO.getIsMixer(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the device or entity plays audio samples in response to MIDI note messages. + /// Get a Boolean value that indicates whether the device or entity plays audio samples in + /// response to MIDI note messages. /// (`kMIDIPropertyIsSampler`) public func getIsSampler() -> Bool { MIDIKitIO.getIsSampler(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the device or entity primarily acts as a MIDI-controlled audio effect. + /// Get a Boolean value that indicates whether the device or entity primarily acts as a + /// MIDI-controlled audio effect. /// (`kMIDIPropertyIsEffectUnit`) public func getIsEffectUnit() -> Bool { MIDIKitIO.getIsEffectUnit(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the device or entity’s samples aren’t transposable, as with a drum kit. + /// Get a Boolean value that indicates whether the device or entity’s samples aren’t + /// transposable, as with a drum kit. /// (`kMIDIPropertyIsDrumMachine`) public func getIsDrumMachine() -> Bool { MIDIKitIO.getIsDrumMachine(of: coreMIDIObjectRef) @@ -271,7 +300,8 @@ extension MIDIIOObject { /// Get a Boolean value that indicates whether the system hides an endpoint from other clients. /// - /// You can set this property on a device or entity, but it still appears in the API; the system only hides the object’s owned endpoints. + /// You can set this property on a device or entity, but it still appears in the API; the system + /// only hides the object’s owned endpoints. /// /// (`kMIDIPropertyPrivate`) public func getIsPrivate() -> Bool { @@ -283,7 +313,8 @@ extension MIDIIOObject { /// Get name of the driver that owns a device, entity, or endpoint. /// (`kMIDIPropertyDriverOwner`) /// - /// Set by the owning driver, on the device; should not be touched by other clients. Property is inherited from the device by its entities and endpoints. + /// Set by the owning driver, on the device; should not be touched by other clients. Property is + /// inherited from the device by its entities and endpoints. /// /// - Throws: ``MIDIIOError`` public func getDriverOwner() -> String? { @@ -298,7 +329,8 @@ extension MIDIIOObject { // MARK: Connections - /// Get a Boolean value that indicates whether the device or entity can route messages to or from external MIDI devices. + /// Get a Boolean value that indicates whether the device or entity can route messages to or + /// from external MIDI devices. /// (`kMIDIPropertyCanRoute`) /// /// Don’t set this property value on driver-owned devices. @@ -306,7 +338,8 @@ extension MIDIIOObject { MIDIKitIO.getCanRoute(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the endpoint broadcasts messages to all of the other endpoints in the device. + /// Get a Boolean value that indicates whether the endpoint broadcasts messages to all of the + /// other endpoints in the device. /// (`kMIDIPropertyIsBroadcast`) /// /// Only the owning driver may set this property. @@ -317,20 +350,23 @@ extension MIDIIOObject { /// Get the unique identifier of an external device attached to this connection. /// (`kMIDIPropertyConnectionUniqueID`) /// - /// The value provided may be an integer. To indicate that a driver connects to multiple external objects, pass the array of big-endian SInt32 values as a CFData object. + /// The value provided may be an integer. To indicate that a driver connects to multiple + /// external objects, pass the array of big-endian SInt32 values as a CFData object. /// /// The property is nonexistent or 0 if there’s no connection. public func getConnectionUniqueID() -> MIDIIdentifier { MIDIKitIO.getConnectionUniqueID(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether this entity or endpoint has external MIDI connections. + /// Get a Boolean value that indicates whether this entity or endpoint has external MIDI + /// connections. /// (`kMIDIPropertyIsEmbeddedEntity`) public func getIsEmbeddedEntity() -> Bool { MIDIKitIO.getIsEmbeddedEntity(of: coreMIDIObjectRef) } - /// Get the 0-based index of the entity on which incoming real-time messages from the device appear to have originated. + /// Get the 0-based index of the entity on which incoming real-time messages from the device + /// appear to have originated. /// (`kMIDIPropertySingleRealtimeEntity`) public func getSingleRealtimeEntity() -> Int32 { MIDIKitIO.getSingleRealtimeEntity(of: coreMIDIObjectRef) @@ -362,7 +398,8 @@ extension MIDIIOObject { MIDIKitIO.getMaxReceiveChannels(of: coreMIDIObjectRef) } - /// Get the maximum number of MIDI channels on which a device may simultaneously transmit channel messages. + /// Get the maximum number of MIDI channels on which a device may simultaneously transmit + /// channel messages. /// (`kMIDIPropertyMaxTransmitChannels`) /// /// Common values are 0, 1, or 16. @@ -372,25 +409,29 @@ extension MIDIIOObject { // MARK: Banks - /// Get a Boolean value that indicates whether the device or entity responds to MIDI bank select LSB messages. + /// Get a Boolean value that indicates whether the device or entity responds to MIDI bank select + /// LSB messages. /// (`kMIDIPropertyReceivesBankSelectLSB`) public func getReceivesBankSelectLSB() -> Bool { MIDIKitIO.getReceivesBankSelectLSB(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the device or entity responds to MIDI bank select MSB messages. + /// Get a Boolean value that indicates whether the device or entity responds to MIDI bank select + /// MSB messages. /// (`kMIDIPropertyReceivesBankSelectMSB`) public func getReceivesBankSelectMSB() -> Bool { MIDIKitIO.getReceivesBankSelectMSB(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the device or entity transmits MIDI bank select LSB messages. + /// Get a Boolean value that indicates whether the device or entity transmits MIDI bank select + /// LSB messages. /// (`kMIDIPropertyTransmitsBankSelectLSB`) public func getTransmitsBankSelectLSB() -> Bool { MIDIKitIO.getTransmitsBankSelectLSB(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the device or entity transmits MIDI bank select MSB messages. + /// Get a Boolean value that indicates whether the device or entity transmits MIDI bank select + /// MSB messages. /// (`kMIDIPropertyTransmitsBankSelectMSB`) public func getTransmitsBankSelectMSB() -> Bool { MIDIKitIO.getTransmitsBankSelectMSB(of: coreMIDIObjectRef) @@ -398,13 +439,15 @@ extension MIDIIOObject { // MARK: Notes - /// Get a Boolean value that indicates whether the device or entity responds to MIDI Note On messages. + /// Get a Boolean value that indicates whether the device or entity responds to MIDI Note On + /// messages. /// (`kMIDIPropertyReceivesNotes`) public func getReceivesNotes() -> Bool { MIDIKitIO.getReceivesNotes(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the device or entity transmits MIDI note messages. + /// Get a Boolean value that indicates whether the device or entity transmits MIDI note + /// messages. /// (`kMIDIPropertyTransmitsNotes`) public func getTransmitsNotes() -> Bool { MIDIKitIO.getTransmitsNotes(of: coreMIDIObjectRef) @@ -412,13 +455,15 @@ extension MIDIIOObject { // MARK: Program Changes - /// Get a Boolean value that indicates whether the device or entity responds to MIDI Program Change messages. + /// Get a Boolean value that indicates whether the device or entity responds to MIDI Program + /// Change messages. /// (`kMIDIPropertyReceivesProgramChanges`) public func getReceivesProgramChanges() -> Bool { MIDIKitIO.getReceivesProgramChanges(of: coreMIDIObjectRef) } - /// Get a Boolean value that indicates whether the device or entity transmits MIDI Program Change messages. + /// Get a Boolean value that indicates whether the device or entity transmits MIDI Program + /// Change messages. /// (`kMIDIPropertyTransmitsProgramChanges`) public func getTransmitsProgramChanges() -> Bool { MIDIKitIO.getTransmitsProgramChanges(of: coreMIDIObjectRef) diff --git a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectType.swift b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectType.swift index 8a6ab37225..a1d227b70a 100644 --- a/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectType.swift +++ b/Sources/MIDIKitIO/MIDIIOObject/MIDIIOObjectType.swift @@ -1,7 +1,7 @@ // // MIDIIOObjectType.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIIdentifier/MIDIIdentifier.swift b/Sources/MIDIKitIO/MIDIIdentifier/MIDIIdentifier.swift index b58e087d17..50a829602d 100644 --- a/Sources/MIDIKitIO/MIDIIdentifier/MIDIIdentifier.swift +++ b/Sources/MIDIKitIO/MIDIIdentifier/MIDIIdentifier.swift @@ -1,7 +1,7 @@ // // MIDIIdentifier.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -20,7 +20,8 @@ extension MIDIIdentifier { // MARK: - Collection extension Set where Element == MIDIIdentifier { - /// Returns endpoint identity criteria formed from endpoints matching the collection's MIDI identifiers. + /// Returns endpoint identity criteria formed from endpoints matching the collection's MIDI + /// identifiers. public func asIdentities() -> Set { // for some reason Set(map { ... }) was not working // so we have to use reduce @@ -32,7 +33,8 @@ extension Set where Element == MIDIIdentifier { } extension Array where Element == MIDIIdentifier { - /// Returns endpoint identity criteria formed from endpoints matching the collection's MIDI identifiers. + /// Returns endpoint identity criteria formed from endpoints matching the collection's MIDI + /// identifiers. @_disfavoredOverload public func asIdentities() -> [MIDIEndpointIdentity] { map { .uniqueID($0) } diff --git a/Sources/MIDIKitIO/MIDIIdentifier/MIDIIdentifierPersistence.swift b/Sources/MIDIKitIO/MIDIIdentifier/MIDIIdentifierPersistence.swift index d8110e7bfd..bbe40614e0 100644 --- a/Sources/MIDIKitIO/MIDIIdentifier/MIDIIdentifierPersistence.swift +++ b/Sources/MIDIKitIO/MIDIIdentifier/MIDIIdentifierPersistence.swift @@ -1,7 +1,7 @@ // // MIDIIdentifierPersistence.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -11,40 +11,52 @@ import Foundation /// Defines persistence behavior of a MIDI unique ID in the system. public enum MIDIIdentifierPersistence { /// Ad-Hoc identifier generation. - /// The unique ID will be randomly generated every time the endpoint is created in the system -- with no persistent storage provided. + /// The unique ID will be randomly generated every time the endpoint is created in the system -- + /// with no persistent storage provided. /// This is default Core MIDI behavior when no identifier is provided. /// /// ⚠️ This is generally not recommended and is provided mainly for testing purposes. /// - /// Use `.userDefaultsManaged(key:)` where possible, or provide your own storage with `manualStorage(::)` + /// Use `.userDefaultsManaged(key:)` where possible, or provide your own storage with + /// `manualStorage(::)` case adHoc /// Unmanaged. /// You are responsible for persistently storing the unique identifier. - /// Note that this identifier may change if the event of a collision where another endpoint already has the identifier. - /// This means at the end of your application's lifecycle you must query the `uniqueID` property on any ``MIDIInput`` or ``MIDIOutput`` ports you have created and update your persistent storage with them. + /// Note that this identifier may change if the event of a collision where another endpoint + /// already has the identifier. + /// This means at the end of your application's lifecycle you must query the `uniqueID` property + /// on any ``MIDIInput`` or ``MIDIOutput`` ports you have created and update your persistent + /// storage with them. /// - /// In the event a collision with an existing unique ID in the system, a new random ID will be generated until there are no collisions. + /// In the event a collision with an existing unique ID in the system, a new random ID will be + /// generated until there are no collisions. case unmanaged(MIDIIdentifier) /// Managed with UserDefaults backing (recommended). - /// The MIDI endpoint's unique ID is managed automatically and persistently stored in `UserDefaults`. The `standard` suite is used by default unless specified. + /// The MIDI endpoint's unique ID is managed automatically and persistently stored in + /// `UserDefaults`. The `standard` suite is used by default unless specified. /// /// If a unique ID does not yet exist for this object, one will be generated randomly. /// - /// In the event a collision with an existing MIDI endpoint unique ID in the system, a new random ID will be generated until there are no collisions. - /// The ID will then be cached in `UserDefaults` using the key string provided - if the key exists, it will be overwritten. + /// In the event a collision with an existing MIDI endpoint unique ID in the system, a new + /// random ID will be generated until there are no collisions. + /// The ID will then be cached in `UserDefaults` using the key string provided - if the key + /// exists, it will be overwritten. case userDefaultsManaged( key: String, suite: UserDefaults = .standard ) /// Managed with custom storage backing (recommended). - /// Supply handlers to facilitate persistently reading and storing the MIDI endpoint's unique ID. + /// Supply handlers to facilitate persistently reading and storing the MIDI endpoint's unique + /// ID. /// - /// This is useful if you need more control over where you want to persist this information in the system. + /// This is useful if you need more control over where you want to persist this information in + /// the system. /// - /// In the event a collision with an existing MIDI endpoint unique ID in the system, a new random ID will be generated until there are no collisions. + /// In the event a collision with an existing MIDI endpoint unique ID in the system, a new + /// random ID will be generated until there are no collisions. /// The ID will then be passed into the `storeHandler` closure in order to store the updated ID. case managedStorage( readHandler: () -> MIDIIdentifier?, diff --git a/Sources/MIDIKitIO/MIDIInput/MIDIInput.swift b/Sources/MIDIKitIO/MIDIInput/MIDIInput.swift index a67b210f92..1e95840a8f 100644 --- a/Sources/MIDIKitIO/MIDIInput/MIDIInput.swift +++ b/Sources/MIDIKitIO/MIDIInput/MIDIInput.swift @@ -1,7 +1,7 @@ // // MIDIInput.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -11,9 +11,16 @@ import Foundation /// A managed virtual MIDI input endpoint created in the system by the MIDI I/O ``MIDIManager``. /// -/// > Note: Avoid storing or caching this object unless it is unavoidable. Instead, whenever possible access it via the ``MIDIManager/managedInputs`` collection. The ``MIDIManager`` owns this object and maintains its lifecycle. +/// > Note: Avoid storing or caching this object unless it is unavoidable. Instead, whenever +/// possible access it via the ``MIDIManager/managedInputs`` collection. The ``MIDIManager`` owns +/// this object and maintains its lifecycle. /// > -/// > Ensure that it is only stored weakly and only passed by reference temporarily in order to execute an operation. If it absolutely must be stored strongly, ensure it is stored for no longer than the lifecycle of the managed thru connection (which is either at such time the ``MIDIManager`` is de-initialized, or when calling ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/input`` or ``MIDIManager/removeAll()`` to destroy the managed endpoint.) +/// > Ensure that it is only stored weakly and only passed by reference temporarily in order to +/// execute an operation. If it absolutely must be stored strongly, ensure it is stored for no +/// longer than the lifecycle of the managed thru connection (which is either at such time the +/// ``MIDIManager`` is de-initialized, or when calling ``MIDIManager/remove(_:_:)`` with +/// ``MIDIManager/ManagedType/input`` or ``MIDIManager/removeAll()`` to destroy the managed +/// endpoint.) public final class MIDIInput: _MIDIIOManagedProtocol { // _MIDIIOManagedProtocol internal weak var midiManager: MIDIManager? @@ -39,7 +46,11 @@ public final class MIDIInput: _MIDIIOManagedProtocol { // init /// Internal init. - /// This object is not meant to be instanced by the user. This object is automatically created and managed by the MIDI I/O ``MIDIManager`` instance when calling ``MIDIManager/addInputConnection(toOutputs:tag:mode:filter:receiver:)-5xxyz``, and destroyed when calling ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/input`` or ``MIDIManager/removeAll()``. + /// This object is not meant to be instanced by the user. This object is automatically created + /// and managed by the MIDI I/O ``MIDIManager`` instance when calling + /// ``MIDIManager/addInputConnection(toOutputs:tag:mode:filter:receiver:)-5xxyz``, and destroyed + /// when calling ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/input`` or + /// ``MIDIManager/removeAll()``. /// /// - Parameters: /// - name: The port name as displayed in the system. @@ -79,7 +90,8 @@ extension MIDIInput { .init(from: coreMIDIInputPortRef ?? 0) } - /// Queries the system and returns true if the endpoint exists (by matching port name and unique ID) + /// Queries the system and returns true if the endpoint exists + /// (by matching port name and unique ID) internal var uniqueIDExistsInSystem: MIDIEndpointRef? { guard let unwrappedUniqueID = uniqueID else { return nil @@ -101,9 +113,9 @@ extension MIDIInput { // this should prevent errors thrown due to ID collisions in the system uniqueID = nil } - + var newPortRef = MIDIPortRef() - + switch api { case .legacyCoreMIDI: // MIDIDestinationCreateWithBlock is deprecated after macOS 11 / iOS 14 @@ -114,7 +126,7 @@ extension MIDIInput { { [weak self] packetListPtr, srcConnRefCon in guard let strongSelf = self else { return } - let packets = packetListPtr.packets() + let packets = packetListPtr.packets(refCon: srcConnRefCon, refConKnown: false) strongSelf.midiManager?.eventQueue.async { strongSelf.receiveHandler.packetListReceived(packets) @@ -122,14 +134,14 @@ extension MIDIInput { } ) .throwIfOSStatusErr() - + case .newCoreMIDI: guard #available(macOS 11, iOS 14, macCatalyst 14, *) else { throw MIDIIOError.internalInconsistency( "New Core MIDI API is not accessible on this platform." ) } - + try MIDIDestinationCreateWithProtocol( manager.coreMIDIClientRef, endpointName as CFString, @@ -137,10 +149,10 @@ extension MIDIInput { &newPortRef, { [weak self] eventListPtr, srcConnRefCon in guard let strongSelf = self else { return } - - let packets = eventListPtr.packets() + + let packets = eventListPtr.packets(refCon: srcConnRefCon, refConKnown: false) let midiProtocol = MIDIProtocolVersion(eventListPtr.pointee.protocol) - + strongSelf.midiManager?.eventQueue.async { strongSelf.receiveHandler.eventListReceived( packets, @@ -151,9 +163,9 @@ extension MIDIInput { ) .throwIfOSStatusErr() } - + coreMIDIInputPortRef = newPortRef - + // set meta data properties; ignore errors in case of failure try? setModel(of: newPortRef, to: manager.model) try? setManufacturer(of: newPortRef, to: manager.manufacturer) @@ -171,7 +183,8 @@ extension MIDIInput { } } - /// Disposes of the the virtual port if it's already been created in the system via the `create()` method. + /// Disposes of the the virtual port if it's already been created in the system via the + /// ``create(in:)`` method. /// /// Errors thrown can be safely ignored and are typically only useful for debugging purposes. internal func dispose() throws { @@ -190,7 +203,7 @@ extension MIDIInput: CustomStringConvertible { if let unwrappedUniqueID = uniqueID { uniqueIDString = "\(unwrappedUniqueID)" } - + return "MIDIInput(name: \(endpointName.quoted), uniqueID: \(uniqueIDString))" } } diff --git a/Sources/MIDIKitIO/MIDIInputConnection/MIDIInputConnection.swift b/Sources/MIDIKitIO/MIDIInputConnection/MIDIInputConnection.swift index 7b84800f0f..13454fbffc 100644 --- a/Sources/MIDIKitIO/MIDIInputConnection/MIDIInputConnection.swift +++ b/Sources/MIDIKitIO/MIDIInputConnection/MIDIInputConnection.swift @@ -1,7 +1,7 @@ // // MIDIInputConnection.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -11,11 +11,20 @@ import Foundation /// A managed MIDI input connection created in the system by the MIDI I/O ``MIDIManager``. /// -/// This connects to one or more outputs in the system and subscribes to receive their MIDI events. It can also be instanced without providing any initial outputs and then outputs can be added or removed later. +/// This connects to one or more outputs in the system and subscribes to receive their MIDI events. +/// It can also be instanced without providing any initial outputs and then outputs can be added or +/// removed later. /// -/// > Note: Do not store or cache this object unless it is unavoidable. Instead, whenever possible call it by accessing the ``MIDIManager/managedInputConnections`` collection. The ``MIDIManager`` owns this object and maintains its lifecycle. +/// > Note: Do not store or cache this object unless it is unavoidable. Instead, whenever possible +/// call it by accessing the ``MIDIManager/managedInputConnections`` collection. The ``MIDIManager`` +/// owns this object and maintains its lifecycle. /// > -/// > Ensure that it is only stored weakly and only passed by reference temporarily in order to execute an operation. If it absolutely must be stored strongly, ensure it is stored for no longer than the lifecycle of the managed input connection (which is either at such time the ``MIDIManager`` is de-initialized, or when calling ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/inputConnection`` or ``MIDIManager/removeAll()`` to destroy the managed connection.) +/// > Ensure that it is only stored weakly and only passed by reference temporarily in order to +/// execute an operation. If it absolutely must be stored strongly, ensure it is stored for no +/// longer than the lifecycle of the managed input connection (which is either at such time the +/// ``MIDIManager`` is de-initialized, or when calling ``MIDIManager/remove(_:_:)`` with +/// ``MIDIManager/ManagedType/inputConnection`` or ``MIDIManager/removeAll()`` to destroy the +/// managed connection.) public final class MIDIInputConnection: _MIDIIOManagedProtocol { // _MIDIIOManagedProtocol internal weak var midiManager: MIDIManager? @@ -58,6 +67,11 @@ public final class MIDIInputConnection: _MIDIIOManagedProtocol { /// The Core MIDI output endpoint(s) reference(s). public private(set) var coreMIDIOutputEndpointRefs: Set = [] + /// Internal: + /// The Core MIDI output endpoint(s) reference(s) stored as `NSNumber` classes. + /// This is only so that `MIDIPortConnectSource()` can take stable pointer references. + internal var coreMIDIOutputEndpointRefCons: Set = [] + /// Operating mode. /// /// Changes take effect immediately. @@ -99,12 +113,18 @@ public final class MIDIInputConnection: _MIDIIOManagedProtocol { // init /// Internal init. - /// This object is not meant to be instanced by the user. This object is automatically created and managed by the MIDI I/O ``MIDIManager`` instance when calling ``MIDIManager/addInputConnection(toOutputs:tag:mode:filter:receiver:)-5xxyz``, and destroyed when calling ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/inputConnection`` or ``MIDIManager/removeAll()``. + /// This object is not meant to be instanced by the user. This object is automatically created + /// and managed by the MIDI I/O ``MIDIManager`` instance when calling + /// ``MIDIManager/addInputConnection(toOutputs:tag:mode:filter:receiver:)-5xxyz``, and destroyed + /// when calling ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/inputConnection`` + /// or ``MIDIManager/removeAll()``. /// /// - Parameters: /// - criteria: Output(s) to connect to. - /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides `criteria`. - /// - filter: Optional filter allowing or disallowing certain endpoints from being added to the connection. + /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides + /// `criteria`. + /// - filter: Optional filter allowing or disallowing certain endpoints from being added to + /// the connection. /// - receiver: Receive handler to use for incoming MIDI messages. /// - midiManager: Reference to parent ``MIDIManager`` object. /// - api: Core MIDI API version. @@ -162,11 +182,11 @@ extension MIDIInputConnection { // so just return; don't throw an error return } - + var newInputPortRef = MIDIPortRef() - + // connection name must be unique, otherwise process might hang (?) - + switch api { case .legacyCoreMIDI: // MIDIInputPortCreateWithBlock is deprecated after macOS 11 / iOS 14 @@ -176,23 +196,26 @@ extension MIDIInputConnection { &newInputPortRef, { [weak self] packetListPtr, srcConnRefCon in guard let strongSelf = self else { return } - - let packets = packetListPtr.packets() - + + let packets = packetListPtr.packets( + refCon: srcConnRefCon, + refConKnown: true + ) + strongSelf.midiManager?.eventQueue.async { strongSelf.receiveHandler.packetListReceived(packets) } } ) .throwIfOSStatusErr() - + case .newCoreMIDI: guard #available(macOS 11, iOS 14, macCatalyst 14, *) else { throw MIDIIOError.internalInconsistency( "New Core MIDI API is not accessible on this platform." ) } - + try MIDIInputPortCreateWithProtocol( manager.coreMIDIClientRef, UUID().uuidString as CFString, @@ -200,10 +223,13 @@ extension MIDIInputConnection { &newInputPortRef, { [weak self] eventListPtr, srcConnRefCon in guard let strongSelf = self else { return } - - let packets = eventListPtr.packets() + + let packets = eventListPtr.packets( + refCon: srcConnRefCon, + refConKnown: true + ) let midiProtocol = MIDIProtocolVersion(eventListPtr.pointee.protocol) - + strongSelf.midiManager?.eventQueue.async { strongSelf.receiveHandler.eventListReceived( packets, @@ -214,7 +240,7 @@ extension MIDIInputConnection { ) .throwIfOSStatusErr() } - + coreMIDIInputPortRef = newInputPortRef } @@ -242,30 +268,36 @@ extension MIDIInputConnection { if coreMIDIInputPortRef == nil { try listen(in: manager) } - + guard let unwrappedInputPortRef = coreMIDIInputPortRef else { throw MIDIIOError.connectionError( "Not in a listening state; can't connect to endpoints." ) } - + // if previously connected, clean the old connections. ignore errors. try? disconnect() - + // resolve criteria to endpoints in the system let getOutputEndpointRefs = outputsCriteria .compactMap { $0.locate(in: manager.endpoints.outputs)? .coreMIDIObjectRef } - + coreMIDIOutputEndpointRefs = Set(getOutputEndpointRefs) - - for outputEndpointRef in getOutputEndpointRefs { + + coreMIDIOutputEndpointRefCons = Set(coreMIDIOutputEndpointRefs.map { + NSNumber(value: $0) + }) + + for nsNumRef in coreMIDIOutputEndpointRefCons { + // supply the endpoint object ref + // FYI: this method does not hold a strong reference to refCon. you MUST have a strong stable reference even for value types. or we get lovely crashes. try? MIDIPortConnectSource( unwrappedInputPortRef, - outputEndpointRef, - nil + nsNumRef.uint32Value, + Unmanaged.passUnretained(nsNumRef).toOpaque() ) .throwIfOSStatusErr() } @@ -283,9 +315,9 @@ extension MIDIInputConnection { "Attempted to disconnect outputs but was not in a listening state; nothing to disconnect." ) } - + let refs = endpointRefs ?? coreMIDIOutputEndpointRefs - + for outputEndpointRef in refs { do { try MIDIPortDisconnectSource( @@ -300,18 +332,19 @@ extension MIDIInputConnection { } /// Refresh the connection. - /// This is typically called after receiving a Core MIDI notification that system port configuration has changed or endpoints were added/removed. + /// This is typically called after receiving a Core MIDI notification that system port + /// configuration has changed or endpoints were added/removed. internal func refreshConnection(in manager: MIDIManager) throws { // call (re-)connect only if at least one matching endpoint exists in the system - + let getSystemOutputs = manager.endpoints.outputs - + var matchedEndpointCount = 0 - + for criteria in outputsCriteria { if criteria.locate(in: getSystemOutputs) != nil { matchedEndpointCount += 1 } } - + try connect(in: manager) } } @@ -326,7 +359,7 @@ extension MIDIInputConnection { ) { let combined = outputsCriteria.union(outputs) updateCriteria(combined) - + if let midiManager = midiManager { // this will re-generate coreMIDIOutputEndpointRefs and call connect() try? refreshConnection(in: midiManager) @@ -350,17 +383,17 @@ extension MIDIInputConnection { ) { let removed = outputsCriteria.subtracting(outputs) updateCriteria(removed) - + if let midiManager = midiManager { let refs = outputs .compactMap { $0.locate(in: midiManager.endpoints.outputs)? .coreMIDIObjectRef } - + // disconnect removed endpoints first try? disconnect(endpointRefs: Set(refs)) - + // this will regenerate cached refs try? refreshConnection(in: midiManager) } @@ -400,7 +433,7 @@ extension MIDIInputConnection { if let midiManager = midiManager { try? refreshConnection(in: midiManager) } - + default: break } @@ -412,14 +445,14 @@ extension MIDIInputConnection: CustomStringConvertible { let outputEndpointsString: [String] = coreMIDIOutputEndpointRefs.map { // ref var str = "\($0):" - + // name if let getName = try? getName(of: $0) { str += "\(getName)".quoted } else { str += "nil" } - + return str } @@ -427,7 +460,7 @@ extension MIDIInputConnection: CustomStringConvertible { if let unwrappedInputPortRef = coreMIDIInputPortRef { inputPortRefString = "\(unwrappedInputPortRef)" } - + return "MIDIInputConnection(criteria: \(outputsCriteria), outputEndpointRefs: \(outputEndpointsString), inputPortRef: \(inputPortRefString))" } } diff --git a/Sources/MIDIKitIO/MIDIInputEndpoint/MIDIInputEndpoint Collection.swift b/Sources/MIDIKitIO/MIDIInputEndpoint/MIDIInputEndpoint Collection.swift index 47120bf1ed..867c2fdf4d 100644 --- a/Sources/MIDIKitIO/MIDIInputEndpoint/MIDIInputEndpoint Collection.swift +++ b/Sources/MIDIKitIO/MIDIInputEndpoint/MIDIInputEndpoint Collection.swift @@ -1,7 +1,7 @@ // // MIDIInputEndpoint Collection.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIInputEndpoint/MIDIInputEndpoint.swift b/Sources/MIDIKitIO/MIDIInputEndpoint/MIDIInputEndpoint.swift index b19a36d0f9..539e147e2b 100644 --- a/Sources/MIDIKitIO/MIDIInputEndpoint/MIDIInputEndpoint.swift +++ b/Sources/MIDIKitIO/MIDIInputEndpoint/MIDIInputEndpoint.swift @@ -1,7 +1,7 @@ // // MIDIInputEndpoint.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -12,7 +12,8 @@ /// /// Although this is a value-type struct, do not store or cache it as it will not remain updated. /// -/// Instead, read endpoint arrays and individual endpoint properties from ``MIDIManager/endpoints`` ad-hoc when they are needed. +/// Instead, read endpoint arrays and individual endpoint properties from ``MIDIManager/endpoints`` +/// ad-hoc when they are needed. public struct MIDIInputEndpoint: _MIDIIOEndpointProtocol { // MARK: MIDIIOObject diff --git a/Sources/MIDIKitIO/MIDIKitIO.swift b/Sources/MIDIKitIO/MIDIKitIO.swift index 46de284c22..7560033e6c 100644 --- a/Sources/MIDIKitIO/MIDIKitIO.swift +++ b/Sources/MIDIKitIO/MIDIKitIO.swift @@ -1,7 +1,7 @@ // // MIDIKitIO.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // @_exported import MIDIKitCore diff --git a/Sources/MIDIKitIO/MIDIManager/MIDIManager ManagedType.swift b/Sources/MIDIKitIO/MIDIManager/MIDIManager ManagedType.swift index 65bbf93c59..88245fc1a7 100644 --- a/Sources/MIDIKitIO/MIDIManager/MIDIManager ManagedType.swift +++ b/Sources/MIDIKitIO/MIDIManager/MIDIManager ManagedType.swift @@ -1,7 +1,7 @@ // // MIDIManager ManagedType.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIManager/MIDIManager Network Session.swift b/Sources/MIDIKitIO/MIDIManager/MIDIManager Network Session.swift index e4f79f0bce..7e00b24113 100644 --- a/Sources/MIDIKitIO/MIDIManager/MIDIManager Network Session.swift +++ b/Sources/MIDIKitIO/MIDIManager/MIDIManager Network Session.swift @@ -1,7 +1,7 @@ // // MIDIManager Network Session.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIManager/MIDIManager State.swift b/Sources/MIDIKitIO/MIDIManager/MIDIManager State.swift index 082a51742d..c4fb9f86c8 100644 --- a/Sources/MIDIKitIO/MIDIManager/MIDIManager State.swift +++ b/Sources/MIDIKitIO/MIDIManager/MIDIManager State.swift @@ -1,7 +1,7 @@ // // MIDIManager State.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIManager/MIDIManager addInput.swift b/Sources/MIDIKitIO/MIDIManager/MIDIManager addInput.swift index e6420e333f..f8548b6763 100644 --- a/Sources/MIDIKitIO/MIDIManager/MIDIManager addInput.swift +++ b/Sources/MIDIKitIO/MIDIManager/MIDIManager addInput.swift @@ -1,7 +1,7 @@ // // MIDIManager addInput.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -10,17 +10,26 @@ import Foundation @_implementationOnly import CoreMIDI extension MIDIManager { - /// Adds a new managed virtual input to the ``MIDIManager/managedInputs`` dictionary of the ``MIDIManager`` and creates the MIDI port in the system. + /// Adds a new managed virtual input to the ``MIDIManager/managedInputs`` dictionary of the + /// ``MIDIManager`` and creates the MIDI port in the system. /// - /// The lifecycle of the MIDI port exists for as long as the ``MIDIManager`` instance exists, or until ``MIDIManager/remove(_:_:)`` is called. + /// The lifecycle of the MIDI port exists for as long as the ``MIDIManager`` instance exists, or + /// until ``MIDIManager/remove(_:_:)`` is called. /// /// > A note on `uniqueID`: /// > - /// > It is best practise that the `uniqueID` be stored persistently in a data store of your choosing, and supplied when recreating the same port. This allows other applications to identify the port and reconnect to it, as the port name is not used to identify a MIDI port since MIDI ports are allowed to have the same name, but must have unique IDs. + /// > It is best practise that the `uniqueID` be stored persistently in a data store of your + /// choosing, and supplied when recreating the same port. This allows other applications to + /// identify the port and reconnect to it, as the port name is not used to identify a MIDI port + /// since MIDI ports are allowed to have the same name, but must have unique IDs. /// > - /// > It is best practise to re-store the `uniqueID` every time this method is called, since these IDs are temporal and not registered or permanently reserved in the system. Since ID collisions are possible, a new available random ID will be obtained and used if that happens, and that updated ID should be stored in-place of the old one in your data store. + /// > It is best practise to re-store the `uniqueID` every time this method is called, since + /// these IDs are temporal and not registered or permanently reserved in the system. Since ID + /// collisions are possible, a new available random ID will be obtained and used if that + /// happens, and that updated ID should be stored in-place of the old one in your data store. /// > - /// > Do not generate the ID number yourself - it is always system-generated and then we should store and persist it. ``MIDIIdentifierPersistence`` offers mechanisms to simplify this. + /// > Do not generate the ID number yourself - it is always system-generated and then we should + /// store and persist it. ``MIDIIdentifierPersistence`` offers mechanisms to simplify this. /// /// - Parameters: /// - name: Name of the endpoint as seen in the system. diff --git a/Sources/MIDIKitIO/MIDIManager/MIDIManager addInputConnection.swift b/Sources/MIDIKitIO/MIDIManager/MIDIManager addInputConnection.swift index 3e9b414ab8..7f8e010f46 100644 --- a/Sources/MIDIKitIO/MIDIManager/MIDIManager addInputConnection.swift +++ b/Sources/MIDIKitIO/MIDIManager/MIDIManager addInputConnection.swift @@ -1,7 +1,7 @@ // // MIDIManager addInputConnection.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -10,15 +10,21 @@ import Foundation @_implementationOnly import CoreMIDI extension MIDIManager { - /// Adds a new managed input connection to the ``MIDIManager/managedInputConnections`` dictionary of the ``MIDIManager``. + /// Adds a new managed input connection to the ``MIDIManager/managedInputConnections`` + /// dictionary of the ``MIDIManager``. /// - /// This connects to one or more outputs in the system and subscribes to receive their MIDI events. It can also be instanced without providing any initial inputs and then inputs can be added or removed later. + /// This connects to one or more outputs in the system and subscribes to receive their MIDI + /// events. It can also be instanced without providing any initial inputs and then inputs can be + /// added or removed later. /// /// - Parameters: - /// - toOutputs: Criteria for identifying target MIDI endpoint(s). These may be added or removed later. + /// - toOutputs: Criteria for identifying target MIDI endpoint(s). These may be added or + /// removed later. /// - tag: Internal unique tag to reference the managed item in the ``MIDIManager``. - /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides any criteria supplied in `toOutputs`. - /// - filter: Optional filter allowing or disallowing certain endpoints from being added to the connection. + /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides any + /// criteria supplied in `toOutputs`. + /// - filter: Optional filter allowing or disallowing certain endpoints from being added to + /// the connection. /// - receiver: Receive handler to use for incoming MIDI messages. /// /// - Throws: ``MIDIIOError`` @@ -48,15 +54,21 @@ extension MIDIManager { } } - /// Adds a new managed input connection to the ``MIDIManager/managedInputConnections`` dictionary of the ``MIDIManager``. + /// Adds a new managed input connection to the ``MIDIManager/managedInputConnections`` + /// dictionary of the ``MIDIManager``. /// - /// This connects to one or more outputs in the system and subscribes to receive their MIDI events. It can also be instanced without providing any initial inputs and then inputs can be added or removed later. + /// This connects to one or more outputs in the system and subscribes to receive their MIDI + /// events. It can also be instanced without providing any initial inputs and then inputs can be + /// added or removed later. /// /// - Parameters: - /// - toOutputs: Criteria for identifying target MIDI endpoint(s). These may be added or removed later. + /// - toOutputs: Criteria for identifying target MIDI endpoint(s). These may be added or + /// removed later. /// - tag: Internal unique tag to reference the managed item in the ``MIDIManager``. - /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides any criteria supplied in `toOutputs`. - /// - filter: Optional filter allowing or disallowing certain endpoints from being added to the connection. + /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides any + /// criteria supplied in `toOutputs`. + /// - filter: Optional filter allowing or disallowing certain endpoints from being added to + /// the connection. /// - receiver: Receive handler to use for incoming MIDI messages. /// /// - Throws: ``MIDIIOError`` @@ -76,15 +88,20 @@ extension MIDIManager { ) } - /// Adds a new managed input connection to the ``MIDIManager/managedInputConnections`` dictionary of the ``MIDIManager``. + /// Adds a new managed input connection to the ``MIDIManager/managedInputConnections`` + /// dictionary of the ``MIDIManager``. /// - /// This connects to one or more outputs in the system and subscribes to receive their MIDI events. It can also be instanced without providing any initial inputs and then inputs can be added or removed later. + /// This connects to one or more outputs in the system and subscribes to receive their MIDI + /// events. It can also be instanced without providing any initial inputs and then inputs can be + /// added or removed later. /// /// - Parameters: /// - toOutputs: Target MIDI endpoint(s). These may be added or removed later. /// - tag: Internal unique tag to reference the managed item in the ``MIDIManager``. - /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides any criteria supplied in `toOutputs`. - /// - filter: Optional filter allowing or disallowing certain endpoints from being added to the connection. + /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides any + /// criteria supplied in `toOutputs`. + /// - filter: Optional filter allowing or disallowing certain endpoints from being added to + /// the connection. /// - receiver: Receive handler to use for incoming MIDI messages. /// /// - Throws: ``MIDIIOError`` diff --git a/Sources/MIDIKitIO/MIDIManager/MIDIManager addOutput.swift b/Sources/MIDIKitIO/MIDIManager/MIDIManager addOutput.swift index fd423a7d7b..e5075afad0 100644 --- a/Sources/MIDIKitIO/MIDIManager/MIDIManager addOutput.swift +++ b/Sources/MIDIKitIO/MIDIManager/MIDIManager addOutput.swift @@ -1,7 +1,7 @@ // // MIDIManager addOutput.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -10,17 +10,26 @@ import Foundation @_implementationOnly import CoreMIDI extension MIDIManager { - /// Adds new a managed virtual output to the ``MIDIManager/managedOutputs`` dictionary of the ``MIDIManager``. + /// Adds new a managed virtual output to the ``MIDIManager/managedOutputs`` dictionary of the + /// ``MIDIManager``. /// - /// The lifecycle of the MIDI port exists for as long as the ``MIDIManager`` instance exists, or until ``MIDIManager/remove(_:_:)`` is called. + /// The lifecycle of the MIDI port exists for as long as the ``MIDIManager`` instance exists, or + /// until ``MIDIManager/remove(_:_:)`` is called. /// /// > A note on `uniqueID`: /// > - /// > It is best practise that the `uniqueID` be stored persistently in a data store of your choosing, and supplied when recreating the same port. This allows other applications to identify the port and reconnect to it, as the port name is not used to identify a MIDI port since MIDI ports are allowed to have the same name, but must have unique IDs. + /// > It is best practise that the `uniqueID` be stored persistently in a data store of your + /// choosing, and supplied when recreating the same port. This allows other applications to + /// identify the port and reconnect to it, as the port name is not used to identify a MIDI port + /// since MIDI ports are allowed to have the same name, but must have unique IDs. /// > - /// > It is best practise to re-store the `uniqueID` every time this method is called, since these IDs are temporal and not registered or permanently reserved in the system. Since ID collisions are possible, a new available random ID will be obtained and used if that happens, and that updated ID should be stored in-place of the old one in your data store. + /// > It is best practise to re-store the `uniqueID` every time this method is called, since + /// these IDs are temporal and not registered or permanently reserved in the system. Since ID + /// collisions are possible, a new available random ID will be obtained and used if that + /// happens, and that updated ID should be stored in-place of the old one in your data store. /// > - /// > Do not generate the ID number yourself - it is always system-generated and then we should store and persist it. ``MIDIIdentifierPersistence`` offers mechanisms to simplify this. + /// > Do not generate the ID number yourself - it is always system-generated and then we should + /// store and persist it. ``MIDIIdentifierPersistence`` offers mechanisms to simplify this. /// /// - Parameters: /// - name: Name of the endpoint as seen in the system. diff --git a/Sources/MIDIKitIO/MIDIManager/MIDIManager addOutputConnection.swift b/Sources/MIDIKitIO/MIDIManager/MIDIManager addOutputConnection.swift index c92b5b020c..ca77ea6bd0 100644 --- a/Sources/MIDIKitIO/MIDIManager/MIDIManager addOutputConnection.swift +++ b/Sources/MIDIKitIO/MIDIManager/MIDIManager addOutputConnection.swift @@ -1,7 +1,7 @@ // // MIDIManager addOutputConnection.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -10,15 +10,21 @@ import Foundation @_implementationOnly import CoreMIDI extension MIDIManager { - /// Adds a new managed connected output to the ``MIDIManager/managedOutputConnections`` dictionary of the ``MIDIManager``. + /// Adds a new managed connected output to the ``MIDIManager/managedOutputConnections`` + /// dictionary of the ``MIDIManager``. /// - /// This connects to one or more inputs in the system and outputs MIDI events to them. It can also be instanced without providing any initial inputs and then inputs can be added or removed later. + /// This connects to one or more inputs in the system and outputs MIDI events to them. It can + /// also be instanced without providing any initial inputs and then inputs can be added or + /// removed later. /// /// - Parameters: - /// - toInputs: Criteria for identifying target MIDI endpoint(s). These may be added or removed later. + /// - toInputs: Criteria for identifying target MIDI endpoint(s). These may be added or + /// removed later. /// - tag: Internal unique tag to reference the managed item in the ``MIDIManager``. - /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides any criteria supplied in `toInputs`. - /// - filter: Optional filter allowing or disallowing certain endpoints from being added to the connection. + /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides any + /// criteria supplied in `toInputs`. + /// - filter: Optional filter allowing or disallowing certain endpoints from being added to + /// the connection. /// /// - Throws: ``MIDIIOError`` public func addOutputConnection( @@ -45,15 +51,21 @@ extension MIDIManager { } } - /// Adds a new managed connected output to the ``MIDIManager/managedOutputConnections`` dictionary of the ``MIDIManager``. + /// Adds a new managed connected output to the ``MIDIManager/managedOutputConnections`` + /// dictionary of the ``MIDIManager``. /// - /// This connects to one or more inputs in the system and outputs MIDI events to them. It can also be instanced without providing any initial inputs and then inputs can be added or removed later. + /// This connects to one or more inputs in the system and outputs MIDI events to them. It can + /// also be instanced without providing any initial inputs and then inputs can be added or + /// removed later. /// /// - Parameters: - /// - toInputs: Criteria for identifying target MIDI endpoint(s). These may be added or removed later. + /// - toInputs: Criteria for identifying target MIDI endpoint(s). These may be added or + /// removed later. /// - tag: Internal unique tag to reference the managed item in the ``MIDIManager``. - /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides any criteria supplied in `toInputs`. - /// - filter: Optional filter allowing or disallowing certain endpoints from being added to the connection. + /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides any + /// criteria supplied in `toInputs`. + /// - filter: Optional filter allowing or disallowing certain endpoints from being added to + /// the connection. /// /// - Throws: ``MIDIIOError`` public func addOutputConnection( @@ -70,15 +82,20 @@ extension MIDIManager { ) } - /// Adds a new managed connected output to the ``MIDIManager/managedOutputConnections`` dictionary of the ``MIDIManager``. + /// Adds a new managed connected output to the ``MIDIManager/managedOutputConnections`` + /// dictionary of the ``MIDIManager``. /// - /// This connects to one or more inputs in the system and outputs MIDI events to them. It can also be instanced without providing any initial inputs and then inputs can be added or removed later. + /// This connects to one or more inputs in the system and outputs MIDI events to them. It can + /// also be instanced without providing any initial inputs and then inputs can be added or + /// removed later. /// /// - Parameters: /// - toInputs: Target MIDI endpoint(s). These may be added or removed later. /// - tag: Internal unique tag to reference the managed item in the ``MIDIManager``. - /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides any criteria supplied in `toInputs`. - /// - filter: Optional filter allowing or disallowing certain endpoints from being added to the connection. + /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides any + /// criteria supplied in `toInputs`. + /// - filter: Optional filter allowing or disallowing certain endpoints from being added to + /// the connection. /// /// - Throws: ``MIDIIOError`` @_disfavoredOverload diff --git a/Sources/MIDIKitIO/MIDIManager/MIDIManager addThruConnection.swift b/Sources/MIDIKitIO/MIDIManager/MIDIManager addThruConnection.swift index f3aa093dbb..a24918dd10 100644 --- a/Sources/MIDIKitIO/MIDIManager/MIDIManager addThruConnection.swift +++ b/Sources/MIDIKitIO/MIDIManager/MIDIManager addThruConnection.swift @@ -1,7 +1,7 @@ // // MIDIManager addThruConnection.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -13,23 +13,36 @@ extension MIDIManager { /// Creates a new MIDI play-through (thru) connection. /// /// > Warning: - /// > ⚠️ MIDI play-thru connections only function on **macOS Catalina or earlier** due to Core MIDI bugs on later macOS releases. Attempting to create thru connections on macOS Big Sur or later will throw an error. + /// > ⚠️ MIDI play-thru connections only function on **macOS Catalina or earlier** due to Core + /// MIDI bugs on later macOS releases. Attempting to create thru connections on macOS Big Sur or + /// later will throw an error. /// - /// If the connection is non-persistent, a managed thru connection will be added to ``MIDIManager/managedThruConnections`` and its lifecycle will be that of the ``MIDIManager`` or until ``MIDIManager/remove(_:_:)`` is called for the connection. + /// If the connection is non-persistent, a managed thru connection will be added to + /// ``MIDIManager/managedThruConnections`` and its lifecycle will be that of the ``MIDIManager`` + /// or until ``MIDIManager/remove(_:_:)`` is called for the connection. /// - /// If the connection is persistent, it is instead stored persistently by the system and references will not be directly held in the ``MIDIManager``. To access persistent connections, ``MIDIManager/unmanagedPersistentThruConnections(ownerID:)`` will retrieve a list of connections from the system, if any match the owner ID passed as argument. + /// If the connection is persistent, it is instead stored persistently by the system and + /// references will not be directly held in the ``MIDIManager``. To access persistent + /// connections, ``MIDIManager/unmanagedPersistentThruConnections(ownerID:)`` will retrieve a + /// list of connections from the system, if any match the owner ID passed as argument. /// - /// For every persistent thru connection your app creates, they should be assigned the same persistent ID (reverse-DNS domain) so they can be managed or removed in future. + /// For every persistent thru connection your app creates, they should be assigned the same + /// persistent ID (reverse-DNS domain) so they can be managed or removed in future. /// - /// - Warning: Be careful when creating persistent thru connections, as they can become stale and orphaned if the endpoints used to create them cease to be relevant at any point in time. + /// - Warning: Be careful when creating persistent thru connections, as they can become stale + /// and orphaned if the endpoints used to create them cease to be relevant at any point in time. /// /// - Note: Max 8 outputs and max 8 inputs are allowed when forming a thru connection. /// /// - Parameters: /// - outputs: Maximum of 8 ``MIDIOutputEndpoint``. /// - inputs: Maximum of 8 ``MIDIInputEndpoint``. - /// - tag: Unique `String` key to refer to the new object that gets added to ``MIDIManager/managedThruConnections`` dictionary. - /// - lifecycle: If ``MIDIThruConnection/Lifecycle-swift.enum/nonPersistent``, thru connection will expire when the app terminates. If ``MIDIThruConnection/Lifecycle-swift.enum/persistent(ownerID:)``, the connection persists in the system indefinitely (even after system reboots) until explicitly removed. + /// - tag: Unique `String` key to refer to the new object that gets added to + /// ``MIDIManager/managedThruConnections`` dictionary. + /// - lifecycle: If ``MIDIThruConnection/Lifecycle-swift.enum/nonPersistent``, thru connection + /// will expire when the app terminates. If + /// ``MIDIThruConnection/Lifecycle-swift.enum/persistent(ownerID:)``, the connection persists in + /// the system indefinitely (even after system reboots) until explicitly removed. /// - params: Optionally define custom ``MIDIThruConnection/Parameters-swift.struct``. /// /// - Throws: ``MIDIIOError`` diff --git a/Sources/MIDIKitIO/MIDIManager/MIDIManager remove.swift b/Sources/MIDIKitIO/MIDIManager/MIDIManager remove.swift index ec37a4c024..655be3d56a 100644 --- a/Sources/MIDIKitIO/MIDIManager/MIDIManager remove.swift +++ b/Sources/MIDIKitIO/MIDIManager/MIDIManager remove.swift @@ -1,7 +1,7 @@ // // MIDIManager remove.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -60,7 +60,8 @@ extension MIDIManager { } } - /// Removes all unmanaged persistent MIDI thru connections stored in the system matching the given owner ID. + /// Removes all unmanaged persistent MIDI thru connections stored in the system matching the + /// given owner ID. /// /// - Parameter ownerID: Reverse-DNS domain that was used when the connection was first made /// diff --git a/Sources/MIDIKitIO/MIDIManager/MIDIManager.swift b/Sources/MIDIKitIO/MIDIManager/MIDIManager.swift index 9ffde8c245..73b7093479 100644 --- a/Sources/MIDIKitIO/MIDIManager/MIDIManager.swift +++ b/Sources/MIDIKitIO/MIDIManager/MIDIManager.swift @@ -1,7 +1,7 @@ // // MIDIManager.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -11,7 +11,8 @@ import Foundation /// Central MIDI Port and Connection Manager and MIDI system data provider. /// -/// One ``MIDIManager`` instance stored in a global lifecycle context can manage multiple MIDI ports and connections, and is usually sufficient for all of an application's MIDI needs. +/// One ``MIDIManager`` instance stored in a global lifecycle context can manage multiple MIDI ports +/// and connections, and is usually sufficient for all of an application's MIDI needs. public final class MIDIManager: NSObject { // MARK: - Properties @@ -21,15 +22,19 @@ public final class MIDIManager: NSObject { /// Core MIDI Client Reference. public internal(set) var coreMIDIClientRef = CoreMIDIClientRef() - /// MIDI Model: The name of your software, which will be visible to the end-user in ports created by the manager. + /// MIDI Model: The name of your software, which will be visible to the end-user in ports + /// created by the manager. public internal(set) var model: String = "" - /// MIDI Manufacturer: The name of your company, which may be visible to the end-user in ports created by the manager. + /// MIDI Manufacturer: The name of your company, which may be visible to the end-user in ports + /// created by the manager. public internal(set) var manufacturer: String = "" - /// Preferred underlying Core MIDI API to use as default when creating new managed endpoints. This value defaults to the best API for the current platform. + /// Preferred underlying Core MIDI API to use as default when creating new managed endpoints. + /// This value defaults to the best API for the current platform. /// - /// The preferred API will be used where possible, unless operating system requirements force the use of a specific. + /// The preferred API will be used where possible, unless operating system requirements force + /// the use of a specific. public var preferredAPI: CoreMIDIAPIVersion { didSet { // prevent setting of an invalid API @@ -54,11 +59,14 @@ public final class MIDIManager: NSObject { /// Dictionary of non-persistent MIDI thru connections managed by this instance. public internal(set) var managedThruConnections: [String: MIDIThruConnection] = [:] - /// Array of persistent MIDI thru connections which persist indefinitely (even after system reboots) until explicitly removed. + /// Array of persistent MIDI thru connections which persist indefinitely (even after system + /// reboots) until explicitly removed. /// - /// For every persistent thru connection your app creates, they should be assigned the same persistent ID (domain) so they can be managed or removed in future. + /// For every persistent thru connection your app creates, they should be assigned the same + /// persistent ID (domain) so they can be managed or removed in future. /// - /// - Warning: Be careful when creating persistent thru connections, as they can become stale and orphaned if the endpoints used to create them cease to be relevant at any point in time. + /// - Warning: Be careful when creating persistent thru connections, as they can become stale + /// and orphaned if the endpoints used to create them cease to be relevant at any point in time. /// /// - Parameter ownerID: reverse-DNS domain that was used when the connection was first made /// - Throws: ``MIDIIOError`` @@ -89,9 +97,12 @@ public final class MIDIManager: NSObject { /// Initialize the MIDI manager (and Core MIDI client). /// /// - Parameters: - /// - clientName: Name identifying this instance, used as Core MIDI client ID. This is internal and not visible to the end-user. - /// - model: The name of your software, which will be visible to the end-user in ports created by the manager. - /// - manufacturer: The name of your company, which may be visible to the end-user in ports created by the manager. + /// - clientName: Name identifying this instance, used as Core MIDI client ID. + /// This is internal and not visible to the end-user. + /// - model: The name of your software, which will be visible to the end-user in ports created + /// by the manager. + /// - manufacturer: The name of your company, which may be visible to the end-user in ports + /// created by the manager. /// - notificationHandler: Optionally supply a callback handler for MIDI system notifications. public init( clientName: String, @@ -136,7 +147,10 @@ public final class MIDIManager: NSObject { deinit { eventQueue.sync { // Apple docs: - // "Don’t explicitly dispose of your client; the system automatically disposes all clients when an app terminates. However, if you call this method to dispose the last or only client owned by an app, the MIDI server may exit if there are no other clients remaining in the system" + // "Don’t explicitly dispose of your client; the system automatically disposes all + // clients when an app terminates. However, if you call this method to dispose the last + // or only client owned by an app, the MIDI server may exit if there are no other + // clients remaining in the system" // _ = MIDIClientDispose(coreMIDIClientRef) NotificationCenter.default.removeObserver(self) @@ -162,7 +176,9 @@ public final class MIDIManager: NSObject { iOS 13, /* tvOS 13, watchOS 6, */ * ) { - // calling this means we don't need to use @Published on local variables in order for Combine/SwiftUI to be notified that ObservableObject class property values have changed + // calling this means we don't need to use @Published on local variables in order for + // Combine/SwiftUI to be notified that ObservableObject class property values have + // changed objectWillChange.send() } #endif diff --git a/Sources/MIDIKitIO/MIDIOutput/MIDIOutput.swift b/Sources/MIDIKitIO/MIDIOutput/MIDIOutput.swift index 9f250e1edd..781430871e 100644 --- a/Sources/MIDIKitIO/MIDIOutput/MIDIOutput.swift +++ b/Sources/MIDIKitIO/MIDIOutput/MIDIOutput.swift @@ -1,7 +1,7 @@ // // MIDIOutput.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -11,9 +11,16 @@ import Foundation /// A managed virtual MIDI output endpoint created in the system by the MIDI I/O ``MIDIManager``. /// -/// > Note: Do not store or cache this object unless it is unavoidable. Instead, whenever possible call it by accessing the ``MIDIManager/managedOutputs`` collection. The ``MIDIManager`` owns this object and maintains its lifecycle. +/// > Note: Do not store or cache this object unless it is unavoidable. Instead, whenever possible +/// call it by accessing the ``MIDIManager/managedOutputs`` collection. The ``MIDIManager`` owns +/// this object and maintains its lifecycle. /// > -/// > Ensure that it is only stored weakly and only passed by reference temporarily in order to execute an operation. If it absolutely must be stored strongly, ensure it is stored for no longer than the lifecycle of the endpoint (which is either at such time the ``MIDIManager`` is de-initialized, or when calling ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/output`` or ``MIDIManager/removeAll()`` to destroy the managed endpoint.) +/// > Ensure that it is only stored weakly and only passed by reference temporarily in order to +/// execute an operation. If it absolutely must be stored strongly, ensure it is stored for no +/// longer than the lifecycle of the endpoint (which is either at such time the ``MIDIManager`` is +/// de-initialized, or when calling ``MIDIManager/remove(_:_:)`` with +/// ``MIDIManager/ManagedType/output`` or ``MIDIManager/removeAll()`` to destroy the managed +/// endpoint.) public final class MIDIOutput: _MIDIIOManagedProtocol { // _MIDIIOManagedProtocol internal weak var midiManager: MIDIManager? @@ -38,7 +45,11 @@ public final class MIDIOutput: _MIDIIOManagedProtocol { // init /// Internal init. - /// This object is not meant to be instanced by the user. This object is automatically created and managed by the MIDI I/O ``MIDIManager`` instance when calling ``MIDIManager/addOutput(name:tag:uniqueID:)`` , and destroyed when calling ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/output`` or ``MIDIManager/removeAll()``. + /// This object is not meant to be instanced by the user. This object is automatically created + /// and managed by the MIDI I/O ``MIDIManager`` instance when calling + /// ``MIDIManager/addOutput(name:tag:uniqueID:)`` , and destroyed when calling + /// ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/output`` or + /// ``MIDIManager/removeAll()``. /// /// - Parameters: /// - name: The port name as displayed in the system. @@ -68,7 +79,8 @@ extension MIDIOutput { .init(from: coreMIDIOutputPortRef ?? 0) } - /// Queries the system and returns the endpoint ref if the endpoint exists (by matching port name and unique ID) + /// Queries the system and returns the endpoint ref if the endpoint exists (by matching port + /// name and unique ID) internal var uniqueIDExistsInSystem: MIDIEndpointRef? { guard let unwrappedUniqueID = uniqueID else { return nil @@ -138,7 +150,8 @@ extension MIDIOutput { } } - /// Disposes of the the virtual port if it's already been created in the system via the `create()` method. + /// Disposes of the the virtual port if it's already been created in the system via the + /// `create()` method. /// /// Errors thrown can be safely ignored and are typically only useful for debugging purposes. internal func dispose() throws { diff --git a/Sources/MIDIKitIO/MIDIOutputConnection/MIDIOutputConnection.swift b/Sources/MIDIKitIO/MIDIOutputConnection/MIDIOutputConnection.swift index 60944497e4..4370829609 100644 --- a/Sources/MIDIKitIO/MIDIOutputConnection/MIDIOutputConnection.swift +++ b/Sources/MIDIKitIO/MIDIOutputConnection/MIDIOutputConnection.swift @@ -1,7 +1,7 @@ // // MIDIOutputConnection.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -11,11 +11,19 @@ import Foundation /// A managed MIDI output connection created in the system by the MIDI I/O ``MIDIManager``. /// -/// This connects to one or more inputs in the system and outputs MIDI events to them. It can also be instanced without providing any initial inputs and then inputs can be added or removed later. +/// This connects to one or more inputs in the system and outputs MIDI events to them. It can also +/// be instanced without providing any initial inputs and then inputs can be added or removed later. /// -/// > Note: Do not store or cache this object unless it is unavoidable. Instead, whenever possible call it by accessing the ``MIDIManager/managedOutputConnections`` collection. The ``MIDIManager`` owns this object and maintains its lifecycle. +/// > Note: Do not store or cache this object unless it is unavoidable. Instead, whenever possible +/// call it by accessing the ``MIDIManager/managedOutputConnections`` collection. The +/// ``MIDIManager`` owns this object and maintains its lifecycle. /// > -/// > Ensure that it is only stored weakly and only passed by reference temporarily in order to execute an operation. If it absolutely must be stored strongly, ensure it is stored for no longer than the lifecycle of the managed output connection (which is either at such time the ``MIDIManager`` is de-initialized, or when calling ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/outputConnection`` or ``MIDIManager/removeAll()`` to destroy the managed connection.) +/// > Ensure that it is only stored weakly and only passed by reference temporarily in order to +/// execute an operation. If it absolutely must be stored strongly, ensure it is stored for no +/// longer than the lifecycle of the managed output connection (which is either at such time the +/// ``MIDIManager`` is de-initialized, or when calling ``MIDIManager/remove(_:_:)`` with +/// ``MIDIManager/ManagedType/outputConnection`` or ``MIDIManager/removeAll()`` to destroy the +/// managed connection.) public final class MIDIOutputConnection: _MIDIIOManagedProtocol { // _MIDIIOManagedProtocol internal weak var midiManager: MIDIManager? @@ -98,12 +106,18 @@ public final class MIDIOutputConnection: _MIDIIOManagedProtocol { // init /// Internal init. - /// This object is not meant to be instanced by the user. This object is automatically created and managed by the MIDI I/O ``MIDIManager`` instance when calling ``MIDIManager/addOutputConnection(toInputs:tag:mode:filter:)-3a56s``, and destroyed when calling ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/outputConnection`` or ``MIDIManager/removeAll()`` to destroy the managed connection.) + /// This object is not meant to be instanced by the user. This object is automatically created + /// and managed by the MIDI I/O ``MIDIManager`` instance when calling + /// ``MIDIManager/addOutputConnection(toInputs:tag:mode:filter:)-3a56s``, and destroyed when + /// calling ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/outputConnection`` or + /// ``MIDIManager/removeAll()`` to destroy the managed connection.) /// /// - Parameters: /// - criteria: Input(s) to connect to. - /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides `criteria`. - /// - filter: Optional filter allowing or disallowing certain endpoints from being added to the connection. + /// - mode: Operation mode. Note that ``MIDIConnectionMode/allEndpoints`` mode overrides + /// `criteria`. + /// - filter: Optional filter allowing or disallowing certain endpoints from being added to + /// the connection. /// - midiManager: Reference to parent ``MIDIManager`` object. /// - api: Core MIDI API version. internal init( @@ -191,7 +205,8 @@ extension MIDIOutputConnection { } /// Refresh the connection. - /// This is typically called after receiving a Core MIDI notification that system port configuration has changed or endpoints were added/removed. + /// This is typically called after receiving a Core MIDI notification that system port + /// configuration has changed or endpoints were added/removed. internal func refreshConnection(in manager: MIDIManager) throws { // re-resolve endpoints only if at least one matching endpoint exists in the system @@ -332,7 +347,8 @@ extension MIDIOutputConnection: _MIDIIOSendsMIDIMessagesProtocol { // but we can use the same output port for inputEndpointRef in coreMIDIInputEndpointRefs { - // ignore errors with try? since we don't want to return early in the event that sending to subsequent inputs may succeed + // ignore errors with try? since we don't want to return early in the event that sending + // to subsequent inputs may succeed try? MIDISend( unwrappedOutputPortRef, inputEndpointRef, @@ -354,7 +370,8 @@ extension MIDIOutputConnection: _MIDIIOSendsMIDIMessagesProtocol { // but we can use the same output port for inputEndpointRef in coreMIDIInputEndpointRefs { - // ignore errors with try? since we don't want to return early in the event that sending to subsequent inputs may succeed + // ignore errors with try? since we don't want to return early in the event that sending + // to subsequent inputs may succeed try? MIDISendEventList( unwrappedOutputPortRef, inputEndpointRef, diff --git a/Sources/MIDIKitIO/MIDIOutputEndpoint/MIDIOutputEndpoint Collection.swift b/Sources/MIDIKitIO/MIDIOutputEndpoint/MIDIOutputEndpoint Collection.swift index c89a0ac988..356507e1b4 100644 --- a/Sources/MIDIKitIO/MIDIOutputEndpoint/MIDIOutputEndpoint Collection.swift +++ b/Sources/MIDIKitIO/MIDIOutputEndpoint/MIDIOutputEndpoint Collection.swift @@ -1,7 +1,7 @@ // // MIDIOutputEndpoint Collection.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIOutputEndpoint/MIDIOutputEndpoint.swift b/Sources/MIDIKitIO/MIDIOutputEndpoint/MIDIOutputEndpoint.swift index ee1fc4c2c2..6b76e2cd64 100644 --- a/Sources/MIDIKitIO/MIDIOutputEndpoint/MIDIOutputEndpoint.swift +++ b/Sources/MIDIKitIO/MIDIOutputEndpoint/MIDIOutputEndpoint.swift @@ -1,7 +1,7 @@ // // MIDIOutputEndpoint.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -12,7 +12,8 @@ /// /// Although this is a value-type struct, do not store or cache it as it will not remain updated. /// -/// Instead, read endpoint arrays and individual endpoint properties from ``MIDIManager/endpoints`` ad-hoc when they are needed. +/// Instead, read endpoint arrays and individual endpoint properties from ``MIDIManager/endpoints`` +/// ad-hoc when they are needed. public struct MIDIOutputEndpoint: _MIDIIOEndpointProtocol { // MARK: MIDIIOObject diff --git a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/Events.swift b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/Events.swift index cd3959d6e3..caf29725b5 100644 --- a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/Events.swift +++ b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/Events.swift @@ -1,29 +1,32 @@ // // Events.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) extension MIDIReceiver { - public typealias EventsHandler = (_ events: [MIDIEvent]) -> Void + public typealias EventsHandler = ( + _ events: [MIDIEvent] + ) -> Void } extension MIDIReceiveHandler { /// MIDI Event receive handler. class Events: MIDIIOReceiveHandlerProtocol { public var handler: MIDIReceiver.EventsHandler - + internal let midi1Parser = MIDI1Parser() internal let midi2Parser = MIDI2Parser() - + public func packetListReceived( _ packets: [MIDIPacketData] ) { for midiPacket in packets { let events = midi1Parser.parsedEvents(in: midiPacket) guard !events.isEmpty else { continue } + handler(events) } } @@ -39,7 +42,7 @@ extension MIDIReceiveHandler { handler(events) } } - + internal init( translateMIDI1NoteOnZeroVelocityToNoteOff: Bool = true, _ handler: @escaping MIDIReceiver.EventsHandler diff --git a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/EventsLogging.swift b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/EventsLogging.swift index abc6cfdcb2..82103a167d 100644 --- a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/EventsLogging.swift +++ b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/EventsLogging.swift @@ -1,7 +1,7 @@ // // EventsLogging.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -14,8 +14,10 @@ extension MIDIReceiver { extension MIDIReceiveHandler { /// MIDI Event logging handler (event description strings). - /// If `handler` is nil, all events are logged to the console (but only in `DEBUG` preprocessor flag builds). - /// If `handler` is provided, the event description string is supplied as a parameter and not automatically logged. + /// If `handler` is nil, all events are logged to the console (but only in `DEBUG` preprocessor + /// flag builds). + /// If `handler` is provided, the event description string is supplied as a parameter and not + /// automatically logged. class EventsLogging: MIDIIOReceiveHandlerProtocol { public var handler: MIDIReceiver.EventsLoggingHandler @@ -30,7 +32,11 @@ extension MIDIReceiveHandler { for midiPacket in packets { let events = midi1Parser.parsedEvents(in: midiPacket) guard !events.isEmpty else { continue } - logEvents(events) + logEvents( + events: events, + timeStamp: midiPacket.timeStamp, + source: midiPacket.source + ) } } @@ -42,7 +48,11 @@ extension MIDIReceiveHandler { for midiPacket in packets { let events = midi2Parser.parsedEvents(in: midiPacket) guard !events.isEmpty else { continue } - logEvents(events) + logEvents( + events: events, + timeStamp: midiPacket.timeStamp, + source: midiPacket.source + ) } } @@ -65,17 +75,27 @@ extension MIDIReceiveHandler { } } - internal func logEvents(_ events: [MIDIEvent]) { + internal func logEvents( + events: [MIDIEvent], + timeStamp: CoreMIDITimeStamp, + source: MIDIOutputEndpoint? + ) { var events = events - + if filterActiveSensingAndClock { events = events.filter(sysRealTime: .dropTypes([.activeSensing, .timingClock])) } - - let stringOutput: String = events + + var stringOutput: String = events .map { "\($0)" } .joined(separator: ", ") - + + " timeStamp:\(timeStamp)" + + // not all packets will contain source refs + if let source = source { + stringOutput += " source: \(source.displayName)" + } + handler(stringOutput) } } diff --git a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/EventsWithMetadata.swift b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/EventsWithMetadata.swift new file mode 100644 index 0000000000..b354a5bf0b --- /dev/null +++ b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/EventsWithMetadata.swift @@ -0,0 +1,61 @@ +// +// EventsWithMetadata.swift +// MIDIKit • https://github.com/orchetect/MIDIKit +// © 2021-2022 Steffan Andrews • Licensed under MIT License +// + +#if !os(tvOS) && !os(watchOS) + +extension MIDIReceiver { + public typealias EventsWithMetadataHandler = ( + _ events: [MIDIEvent], + _ timeStamp: CoreMIDITimeStamp, + _ source: MIDIOutputEndpoint? + ) -> Void +} + +extension MIDIReceiveHandler { + /// MIDI Event receive handler including packet timestamp and source endpoint metadata. + /// Source endpoint is only available when used with ``MIDIInputConnection`` and will always be + /// `nil` when used with ``MIDIInput``. + class EventsWithMetadata: MIDIIOReceiveHandlerProtocol { + public var handler: MIDIReceiver.EventsWithMetadataHandler + + internal let midi1Parser = MIDI1Parser() + internal let midi2Parser = MIDI2Parser() + + public func packetListReceived( + _ packets: [MIDIPacketData] + ) { + for midiPacket in packets { + let events = midi1Parser.parsedEvents(in: midiPacket) + guard !events.isEmpty else { continue } + + handler(events, midiPacket.timeStamp, midiPacket.source) + } + } + + @available(macOS 11, iOS 14, macCatalyst 14, *) + public func eventListReceived( + _ packets: [UniversalMIDIPacketData], + protocol midiProtocol: MIDIProtocolVersion + ) { + for midiPacket in packets { + let events = midi2Parser.parsedEvents(in: midiPacket) + guard !events.isEmpty else { continue } + handler(events, midiPacket.timeStamp, midiPacket.source) + } + } + + internal init( + translateMIDI1NoteOnZeroVelocityToNoteOff: Bool = true, + _ handler: @escaping MIDIReceiver.EventsWithMetadataHandler + ) { + midi1Parser.translateNoteOnZeroVelocityToNoteOff = + translateMIDI1NoteOnZeroVelocityToNoteOff + self.handler = handler + } + } +} + +#endif diff --git a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/Group.swift b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/Group.swift index de45c5a3ec..b9efba0635 100644 --- a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/Group.swift +++ b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/Group.swift @@ -1,7 +1,7 @@ // // Group.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/RawData.swift b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/RawData.swift index 5c0cffdd74..ccbab0232b 100644 --- a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/RawData.swift +++ b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/RawData.swift @@ -1,7 +1,7 @@ // // RawData.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -11,8 +11,9 @@ extension MIDIReceiver { } extension MIDIReceiveHandler { - /// Basic raw packet data receive handler. - /// This handler is provided for debugging and data introspection but is discouraged for manually parsing MIDI packets. It is recommended to use a MIDI event handler instead. + /// Raw packet data receive handler. + /// This handler is provided for debugging and data introspection but is discouraged for + /// manually parsing MIDI packets. It is recommended to use a MIDI event handler instead. class RawData: MIDIIOReceiveHandlerProtocol { public var handler: MIDIReceiver.RawDataHandler diff --git a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/RawDataLogging.swift b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/RawDataLogging.swift index e2197b1e9a..a0f0ce8330 100644 --- a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/RawDataLogging.swift +++ b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/RawDataLogging.swift @@ -1,7 +1,7 @@ // // RawDataLogging.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -15,9 +15,13 @@ extension MIDIReceiver { extension MIDIReceiveHandler { /// Raw data logging handler (hex byte strings). + /// On systems that use legacy MIDI 1.0 packets, their raw bytes will be logged. + /// On systems that support UMP and MIDI 2.0, the raw UMP packet data is logged. /// - /// If `handler` is `nil`, all raw packet data is logged to the console (but only in `DEBUG` preprocessor flag builds). - /// If `handler` is provided, the hex byte string is supplied as a parameter and not automatically logged. + /// If `handler` is `nil`, all raw packet data is logged to the console (but only in `DEBUG` + /// preprocessor flag builds). + /// If `handler` is provided, the hex byte string is supplied as a parameter and not + /// automatically logged. class RawDataLogging: MIDIIOReceiveHandlerProtocol { public var handler: MIDIReceiver.RawDataLoggingHandler @@ -27,7 +31,11 @@ extension MIDIReceiveHandler { _ packets: [MIDIPacketData] ) { for midiPacket in packets { - handleBytes(midiPacket.bytes) + handleBytes( + bytes: midiPacket.bytes, + timeStamp: midiPacket.timeStamp, + source: midiPacket.source + ) } } @@ -37,7 +45,11 @@ extension MIDIReceiveHandler { protocol midiProtocol: MIDIProtocolVersion ) { for midiPacket in packets { - handleBytes(midiPacket.bytes) + handleBytes( + bytes: midiPacket.bytes, + timeStamp: midiPacket.timeStamp, + source: midiPacket.source + ) } } @@ -60,16 +72,26 @@ extension MIDIReceiveHandler { } } - internal func handleBytes(_ bytes: [UInt8]) { + internal func handleBytes( + bytes: [UInt8], + timeStamp: CoreMIDITimeStamp, + source: MIDIOutputEndpoint? + ) { if filterActiveSensingAndClock { guard bytes.first != 0xF8, // midi clock pulse bytes.first != 0xFE // active sensing else { return } } - - let stringOutput = bytes + + var stringOutput = bytes .hexString(padEachTo: 2, prefixes: false) - + + " timeStamp:\(timeStamp)" + + // not all packets will contain source refs + if let source = source { + stringOutput += " source: \(source.displayName)" + } + handler(stringOutput) } } diff --git a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/StrongEventsReceiver.swift b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/StrongEventsReceiver.swift index 3e2f3a93ef..5fd416bbbf 100644 --- a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/StrongEventsReceiver.swift +++ b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/StrongEventsReceiver.swift @@ -1,13 +1,14 @@ // // StrongEventsReceiver.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) extension MIDIReceiveHandler { - /// MIDI Event receive handler that holds a strong reference to a receiver object that conforms to the ``ReceivesMIDIEvents`` protocol. + /// MIDI Event receive handler that holds a strong reference to a receiver object that conforms + /// to the ``ReceivesMIDIEvents`` protocol. class StrongEventsReceiver: MIDIIOReceiveHandlerProtocol { public let receiver: ReceivesMIDIEvents diff --git a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/WeakEventsReceiver.swift b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/WeakEventsReceiver.swift index 682a9fa36b..bd497f9a1b 100644 --- a/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/WeakEventsReceiver.swift +++ b/Sources/MIDIKitIO/MIDIReceiveHandler/Handlers/WeakEventsReceiver.swift @@ -1,7 +1,7 @@ // // WeakEventsReceiver.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/MIDIReceiveHandler/MIDIIOReceiveHandlerProtocol.swift b/Sources/MIDIKitIO/MIDIReceiveHandler/MIDIIOReceiveHandlerProtocol.swift index 514e0f00fa..0b5c7db018 100644 --- a/Sources/MIDIKitIO/MIDIReceiveHandler/MIDIIOReceiveHandlerProtocol.swift +++ b/Sources/MIDIKitIO/MIDIReceiveHandler/MIDIIOReceiveHandlerProtocol.swift @@ -1,9 +1,11 @@ // // MIDIIOReceiveHandlerProtocol.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // +#if !os(tvOS) && !os(watchOS) + /// MIDI I/O Receive Handler Protocol. /// /// For backwards compatibility with older operating systems, @@ -24,3 +26,5 @@ public protocol MIDIIOReceiveHandlerProtocol { protocol midiProtocol: MIDIProtocolVersion ) } + +#endif diff --git a/Sources/MIDIKitIO/MIDIReceiveHandler/MIDIReceiveHandler.swift b/Sources/MIDIKitIO/MIDIReceiveHandler/MIDIReceiveHandler.swift index 1e06706070..4a9615b764 100644 --- a/Sources/MIDIKitIO/MIDIReceiveHandler/MIDIReceiveHandler.swift +++ b/Sources/MIDIKitIO/MIDIReceiveHandler/MIDIReceiveHandler.swift @@ -1,7 +1,7 @@ // // MIDIReceiveHandler.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -24,7 +24,8 @@ internal class MIDIReceiveHandler: MIDIIOReceiveHandlerProtocol { handler.packetListReceived(packets) } - /// Parses a Universal MIDI Packet (UMP; MIDI 2.0, new Core MIDI API) and passes parsed data to the handler. + /// Parses a Universal MIDI Packet (UMP; MIDI 2.0, new Core MIDI API) and passes parsed data to + /// the handler. @available(macOS 11, iOS 14, macCatalyst 14, *) public func eventListReceived( _ packets: [UniversalMIDIPacketData], diff --git a/Sources/MIDIKitIO/MIDIReceiveHandler/MIDIReceiver.swift b/Sources/MIDIKitIO/MIDIReceiveHandler/MIDIReceiver.swift index 95cb226f1a..5902d861ea 100644 --- a/Sources/MIDIKitIO/MIDIReceiveHandler/MIDIReceiver.swift +++ b/Sources/MIDIKitIO/MIDIReceiveHandler/MIDIReceiver.swift @@ -1,7 +1,7 @@ // // MIDIReceiver.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -12,36 +12,51 @@ import Foundation public enum MIDIReceiver { /// One or more receivers in series. case group([MIDIReceiver]) - + /// Provides a closure to handle strongly-typed MIDI events. (Recommended) case events( translateMIDI1NoteOnZeroVelocityToNoteOff: Bool = true, EventsHandler ) - + + /// Provides a closure to handle strongly-typed MIDI events including packet timestamp and + /// source endpoint metadata. + /// Source endpoint is only available when used with ``MIDIInputConnection`` and will always be + /// `nil` when used with ``MIDIInput``. + case eventsWithMetadata( + translateMIDI1NoteOnZeroVelocityToNoteOff: Bool = true, + EventsWithMetadataHandler + ) + /// Provides a convenience to automatically log MIDI events to the console. /// (Only logs events in `DEBUG` preprocessor flag builds.) case eventsLogging( filterActiveSensingAndClock: Bool = false, _ handler: EventsLoggingHandler? = nil ) - - /// Basic raw packet data receive handler. - /// This handler is provided for debugging and data introspection but is discouraged for manually parsing MIDI packets. + + /// Raw packet data receive handler. + /// This handler is provided for debugging and data introspection but is discouraged for + /// manually parsing MIDI packets. /// It is recommended to use a MIDI event handler instead. case rawData(RawDataHandler) - + /// Raw data logging handler (hex byte strings). + /// On systems that use legacy MIDI 1.0 packets, their raw bytes will be logged. + /// On systems that support UMP and MIDI 2.0, the raw UMP packet data is logged. /// - /// If `handler` is `nil`, all raw packet data is logged to the console (but only in `DEBUG` preprocessor flag builds). - /// If `handler` is provided, the hex byte string is supplied as a parameter and not automatically logged. + /// If `handler` is `nil`, all raw packet data is logged to the console (but only in `DEBUG` + /// preprocessor flag builds). + /// If `handler` is provided, the hex byte string is supplied as a parameter and not + /// automatically logged. case rawDataLogging( filterActiveSensingAndClock: Bool = false, _ handler: RawDataLoggingHandler? = nil ) /// Pass to a receiver object instance. - /// MIDI Event receive handler that holds a reference to a receiver object that conforms to the ``ReceivesMIDIEvents`` protocol. + /// MIDI Event receive handler that holds a reference to a receiver object that conforms to the + /// ``ReceivesMIDIEvents`` protocol. /// The object reference may be held strongly or weakly. case object( ReceivesMIDIEvents, @@ -78,6 +93,17 @@ extension MIDIReceiver { ) ) + case let .eventsWithMetadata( + translateMIDI1NoteOnZeroVelocityToNoteOff, + handler + ): + return .init( + MIDIReceiveHandler.EventsWithMetadata( + translateMIDI1NoteOnZeroVelocityToNoteOff: translateMIDI1NoteOnZeroVelocityToNoteOff, + handler + ) + ) + case let .eventsLogging( filterActiveSensingAndClock, handler diff --git a/Sources/MIDIKitIO/MIDIThruConnection/MIDIThruConnection Lifecycle.swift b/Sources/MIDIKitIO/MIDIThruConnection/MIDIThruConnection Lifecycle.swift index 2dc2f3003c..546dbfb3ab 100644 --- a/Sources/MIDIKitIO/MIDIThruConnection/MIDIThruConnection Lifecycle.swift +++ b/Sources/MIDIKitIO/MIDIThruConnection/MIDIThruConnection Lifecycle.swift @@ -1,7 +1,7 @@ // // MIDIThruConnection Lifecycle.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -14,7 +14,8 @@ extension MIDIThruConnection { /// The play-through connection exists as long as the ``MIDIManager`` exists. case nonPersistent - /// The play-through connection is stored in the system and persists indefinitely (even after system reboots) until explicitly removed. + /// The play-through connection is stored in the system and persists indefinitely (even + /// after system reboots) until explicitly removed. /// /// - parameter ownerID: Reverse-DNS domain string; usually the application's bundle ID. case persistent(ownerID: String) diff --git a/Sources/MIDIKitIO/MIDIThruConnection/MIDIThruConnection Parameters.swift b/Sources/MIDIKitIO/MIDIThruConnection/MIDIThruConnection Parameters.swift index bfacef2a96..ca727ef936 100644 --- a/Sources/MIDIKitIO/MIDIThruConnection/MIDIThruConnection Parameters.swift +++ b/Sources/MIDIKitIO/MIDIThruConnection/MIDIThruConnection Parameters.swift @@ -1,7 +1,7 @@ // // MIDIThruConnection Parameters.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -43,13 +43,14 @@ extension MIDIThruConnection.Parameters { // MIDIThruConnectionParams Properties: // .outputs - // MIDIThruConnectionEndpoint tuple (initial size: 8). All MIDI generated by these outputs is - // routed into this connection for processing and distribution to inputs. + // MIDIThruConnectionEndpoint tuple (initial size: 8). + // All MIDI generated by these outputs is routed into + // this connection for processing and distribution to inputs. // .numSources // The number of valid outputs in the .outputs tuple. // .inputs - // MIDIThruConnectionEndpoint tuple (initial size: 8). All MIDI output from the connection is - // routed to these inputs. + // MIDIThruConnectionEndpoint tuple (initial size: 8). + // All MIDI output from the connection is routed to these inputs. // .numDestinations // The number of valid outputs in the .inputs tuple. // (many more properties available including filters) diff --git a/Sources/MIDIKitIO/MIDIThruConnection/MIDIThruConnection.swift b/Sources/MIDIKitIO/MIDIThruConnection/MIDIThruConnection.swift index 33448254d6..4b0a0ae6b4 100644 --- a/Sources/MIDIKitIO/MIDIThruConnection/MIDIThruConnection.swift +++ b/Sources/MIDIKitIO/MIDIThruConnection/MIDIThruConnection.swift @@ -1,7 +1,7 @@ // // MIDIThruConnection.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // // Apple Core MIDI play-through connection documentation: @@ -12,14 +12,18 @@ // but you can't manually modify the plist file. // TODO: Core MIDI Thru Bug -// There is a bug in Core MIDI's Swift bridging whereby passing nil into MIDIThruConnectionCreate fails to create a non-persistent thru connection and actually creates a persistent thru connection, despite what the Core MIDI documentation states. +// There is a bug in Core MIDI's Swift bridging whereby passing nil into MIDIThruConnectionCreate +// fails to create a non-persistent thru connection and actually creates a persistent thru +// connection, despite what the Core MIDI documentation states. // - Radar filed: https://openradar.appspot.com/radar?id=5043482339049472 // - So having passed .nonPersistent has the effect of creating a persistent // connection with an empty ownerID. // TODO: Core MIDI Thru Bug -// A new issue seems to be present on macOS Big Sur and later where thru connections do not flow any MIDI events. -// - https://stackoverflow.com/questions/54871326/how-is-a-coremidi-thru-connection-made-in-swift-4-2 +// A new issue seems to be present on macOS Big Sur and later where thru connections do not flow any +// MIDI events. +// - +// https://stackoverflow.com/questions/54871326/how-is-a-coremidi-thru-connection-made-in-swift-4-2 #if !os(tvOS) && !os(watchOS) @@ -28,14 +32,25 @@ import Foundation /// A managed MIDI thru connection created in the system by the MIDI I/O ``MIDIManager``. /// -/// Core MIDI play-through connections can be non-persistent (client-owned, auto-disposed when ``MIDIManager`` de-initializes) or persistent (maintained even after system reboots). +/// Core MIDI play-through connections can be non-persistent (client-owned, auto-disposed when +/// ``MIDIManager`` de-initializes) or persistent (maintained even after system reboots). /// /// > Warning: -/// > ⚠️ MIDI play-thru connections only function on **macOS Catalina or earlier** due to Core MIDI bugs on later macOS releases. Attempting to create thru connections on macOS Big Sur or later will throw an error. +/// > ⚠️ MIDI play-thru connections only function on **macOS Catalina or earlier** due to Core MIDI +/// bugs on later macOS releases. Attempting to create thru connections on macOS Big Sur or later +/// will throw an error. /// -/// > Note: Do not store or cache this object unless it is unavoidable. Instead, whenever possible call it by accessing non-persistent thru connections using the ``MIDIManager/managedThruConnections`` collection. The ``MIDIManager`` owns this object and maintains non-persistent thru connections' lifecycle. +/// > Note: Do not store or cache this object unless it is unavoidable. Instead, whenever possible +/// call it by accessing non-persistent thru connections using the +/// ``MIDIManager/managedThruConnections`` collection. The ``MIDIManager`` owns this object and +/// maintains non-persistent thru connections' lifecycle. /// > -/// > Ensure that it is only stored weakly and only passed by reference temporarily in order to execute an operation. If it absolutely must be stored strongly, ensure it is stored for no longer than the lifecycle of the managed thru connection (which is either at such time the ``MIDIManager`` is de-initialized, or when calling ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/nonPersistentThruConnection`` or ``MIDIManager/removeAll()`` to destroy the managed thru connection.) +/// > Ensure that it is only stored weakly and only passed by reference temporarily in order to +/// execute an operation. If it absolutely must be stored strongly, ensure it is stored for no +/// longer than the lifecycle of the managed thru connection (which is either at such time the +/// ``MIDIManager`` is de-initialized, or when calling ``MIDIManager/remove(_:_:)`` with +/// ``MIDIManager/ManagedType/nonPersistentThruConnection`` or ``MIDIManager/removeAll()`` to +/// destroy the managed thru connection.) public final class MIDIThruConnection: _MIDIIOManagedProtocol { // _MIDIIOManagedProtocol internal weak var midiManager: MIDIManager? @@ -54,7 +69,11 @@ public final class MIDIThruConnection: _MIDIIOManagedProtocol { // init /// Internal init. - /// This object is not meant to be instanced by the user. This object is automatically created and managed by the MIDI I/O ``MIDIManager`` instance when calling ``MIDIManager/addThruConnection(outputs:inputs:tag:lifecycle:params:)``, and destroyed when calling ``MIDIManager/remove(_:_:)`` with ``MIDIManager/ManagedType/nonPersistentThruConnection`` or ``MIDIManager/removeAll()``. + /// This object is not meant to be instanced by the user. This object is automatically created + /// and managed by the MIDI I/O ``MIDIManager`` instance when calling + /// ``MIDIManager/addThruConnection(outputs:inputs:tag:lifecycle:params:)``, and destroyed when + /// calling ``MIDIManager/remove(_:_:)`` with + /// ``MIDIManager/ManagedType/nonPersistentThruConnection`` or ``MIDIManager/removeAll()``. /// /// - Parameters: /// - outputs: One or more output endpoints, maximum of 8. @@ -115,7 +134,8 @@ extension MIDIThruConnection { coreMIDIThruConnectionRef = newConnection } - /// Disposes of the the thru connection if it's already been created in the system via the `create()` method. + /// Disposes of the the thru connection if it's already been created in the system via the + /// ``create(in:)`` method. /// /// Errors thrown can be safely ignored and are typically only useful for debugging purposes. internal func dispose() throws { diff --git a/Sources/MIDIKitIO/Network Session/MIDI Network Session.swift b/Sources/MIDIKitIO/Network Session/MIDI Network Session.swift index 85194455a1..2de317a6ba 100644 --- a/Sources/MIDIKitIO/Network Session/MIDI Network Session.swift +++ b/Sources/MIDIKitIO/Network Session/MIDI Network Session.swift @@ -1,7 +1,7 @@ // // MIDI Network Session.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -29,7 +29,9 @@ public func setMIDINetworkSession(policy: MIDIIONetworkConnectionPolicy?) { extension NSNotification.Name { /// a.k.a. `MIDINetworkNotificationSessionDidChange` /// - /// > Core MIDI documentation: Indicates that other aspects of the session changed, such as the connection list, connection policy, and so on. + /// > Core MIDI Documentation: + /// > Indicates that other aspects of the session changed, such as the + /// > connection list, connection policy, and so on. @_disfavoredOverload @available(macOS 10.15, macCatalyst 13.0, iOS 4.2, *) public static let midiNetworkSessionDidChange = NSNotification.Name( @@ -38,7 +40,8 @@ extension NSNotification.Name { /// a.k.a. `MIDINetworkNotificationContactsDidChange` /// - /// > Core MIDI documentation: Indicates that the list of contacts changed. + /// > Core MIDI Documentation: + /// > Indicates that the list of contacts changed. @_disfavoredOverload @available(macOS 10.15, macCatalyst 13.0, iOS 4.2, *) public static let midiNetworkContactsDidChange = NSNotification.Name( diff --git a/Sources/MIDIKitIO/Network Session/MIDIIONetworkConnectionPolicy.swift b/Sources/MIDIKitIO/Network Session/MIDIIONetworkConnectionPolicy.swift index 795ed86ee1..90622654f0 100644 --- a/Sources/MIDIKitIO/Network Session/MIDIIONetworkConnectionPolicy.swift +++ b/Sources/MIDIKitIO/Network Session/MIDIIONetworkConnectionPolicy.swift @@ -1,7 +1,7 @@ // // MIDIIONetworkConnectionPolicy.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitIO/Notifications/MIDIIOInternalNotification.swift b/Sources/MIDIKitIO/Notifications/MIDIIOInternalNotification.swift index 40463cdca9..200178b88b 100644 --- a/Sources/MIDIKitIO/Notifications/MIDIIOInternalNotification.swift +++ b/Sources/MIDIKitIO/Notifications/MIDIIOInternalNotification.swift @@ -1,7 +1,7 @@ // // MIDIIOInternalNotification.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -11,7 +11,8 @@ import Foundation /// Internal MIDI subsystem notification with raw values. /// -/// This must be converted to an instance of ``MIDIIONotification`` before sending to the ``MIDIManager``'s public notification handler. +/// This must be converted to an instance of ``MIDIIONotification`` before sending to the +/// ``MIDIManager``'s public notification handler. internal enum MIDIIOInternalNotification { case setupChanged @@ -44,7 +45,8 @@ internal enum MIDIIOInternalNotification { error: MIDIIOError ) - /// Typically will never happen unless Apple adds additional cases to Core MIDI's `MIDINotificationMessageID` enum. + /// Typically will never happen unless Apple adds additional cases to Core MIDI's + /// `MIDINotificationMessageID` enum. case other(messageIDRawValue: Int32) } diff --git a/Sources/MIDIKitIO/Notifications/MIDIIONotification.swift b/Sources/MIDIKitIO/Notifications/MIDIIONotification.swift index 18b2bc78f4..ac1e22f611 100644 --- a/Sources/MIDIKitIO/Notifications/MIDIIONotification.swift +++ b/Sources/MIDIKitIO/Notifications/MIDIIONotification.swift @@ -1,7 +1,7 @@ // // MIDIIONotification.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -13,7 +13,8 @@ import Foundation public enum MIDIIONotification: Equatable, Hashable { /// Some aspect of the current MIDI setup changed. /// - /// This notification carries no data. This message is redundant if you’re explicitly handling other notifications. + /// This notification carries no data. This message is redundant if you’re explicitly handling + /// other notifications. case setupChanged /// The system added a device, entity, or endpoint. @@ -52,14 +53,16 @@ public enum MIDIIONotification: Equatable, Hashable { /// Other/unknown notification. /// - /// Typically will never happen unless Apple adds additional cases to Core MIDI's `MIDINotificationMessageID` enum. + /// Typically will never happen unless Apple adds additional cases to Core MIDI's + /// `MIDINotificationMessageID` enum. case other(messageIDRawValue: Int32) } extension MIDIIONotification { /// Converts a ``MIDIIOInternalNotification`` to ``MIDIIONotification``. /// - /// Cache must be supplied if there is a possibility of a ``removed(parent:child:)`` notification, otherwise metadata will be missing. + /// Cache must be supplied if there is a possibility of a ``removed(parent:child:)`` + /// notification, otherwise metadata will be missing. internal init?( _ internalNotification: MIDIIOInternalNotification, cache: MIDIIOObjectCache? diff --git a/Sources/MIDIKitIO/Packet/AnyMIDIPacket.swift b/Sources/MIDIKitIO/Packet/AnyMIDIPacket.swift index d1c0774d5f..e8ad2b4863 100644 --- a/Sources/MIDIKitIO/Packet/AnyMIDIPacket.swift +++ b/Sources/MIDIKitIO/Packet/AnyMIDIPacket.swift @@ -1,18 +1,20 @@ // // AnyMIDIPacket.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // +#if !os(tvOS) && !os(watchOS) + /// A box that can hold any MIDI packet type. public enum AnyMIDIPacket { - /// MIDI 1.0 MIDI Packet + /// MIDI 1.0 MIDI Packet. case packet(MIDIPacketData) - /// MIDI 2.0 Universal MIDI Packet + /// MIDI 2.0 Universal MIDI Packet. case universalPacket(UniversalMIDIPacketData) - /// Flat array of raw bytes + /// Flat array of raw bytes. public var bytes: [UInt8] { switch self { case let .packet(packetData): @@ -23,7 +25,7 @@ public enum AnyMIDIPacket { } } - /// Core MIDI packet timestamp + /// Core MIDI packet timestamp. public var timeStamp: CoreMIDITimeStamp { switch self { case let .packet(packetData): @@ -33,4 +35,18 @@ public enum AnyMIDIPacket { return universalPacketData.timeStamp } } + + /// The MIDI endpoint from which the packet originated. + /// If this information is not available, it may be `nil`. + public var source: MIDIOutputEndpoint? { + switch self { + case let .packet(packetData): + return packetData.source + + case let .universalPacket(universalPacketData): + return universalPacketData.source + } + } } + +#endif diff --git a/Sources/MIDIKitIO/Packet/MIDIPacketData/MIDIPacketData.swift b/Sources/MIDIKitIO/Packet/MIDIPacketData/MIDIPacketData.swift index b0737691f6..b3bd953f45 100644 --- a/Sources/MIDIKitIO/Packet/MIDIPacketData/MIDIPacketData.swift +++ b/Sources/MIDIKitIO/Packet/MIDIPacketData/MIDIPacketData.swift @@ -1,9 +1,11 @@ // // MIDIPacketData.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // +#if !os(tvOS) && !os(watchOS) + @_implementationOnly import CoreMIDI /// Clean consolidated data encapsulation of raw data from a Core MIDI `MIDIPacket` (MIDI 1.0). @@ -13,36 +15,52 @@ public struct MIDIPacketData { /// Core MIDI packet timestamp let timeStamp: CoreMIDITimeStamp + /// The MIDI endpoint from which the packet originated. + /// If this information is not available, it may be `nil`. + let source: MIDIOutputEndpoint? + public init( bytes: [UInt8], - timeStamp: CoreMIDITimeStamp + timeStamp: CoreMIDITimeStamp, + source: MIDIOutputEndpoint? = nil ) { self.bytes = bytes self.timeStamp = timeStamp + self.source = source } } extension MIDIPacketData { - internal init(_ midiPacketPtr: UnsafePointer) { - self = Self.unwrapPacket(midiPacketPtr) + internal init( + _ midiPacketPtr: UnsafePointer, + refCon: UnsafeMutableRawPointer?, + refConKnown: Bool + ) { + self = Self.unwrapPacket(midiPacketPtr, refCon: refCon, refConKnown: refConKnown) } fileprivate static let midiPacketDataOffset: Int = MemoryLayout.offset(of: \MIDIPacket.data)! fileprivate static func unwrapPacket( - _ midiPacketPtr: UnsafePointer + _ midiPacketPtr: UnsafePointer, + refCon: UnsafeMutableRawPointer?, + refConKnown: Bool ) -> MIDIPacketData { let packetDataCount = Int(midiPacketPtr.pointee.length) - + + let source = unpackMIDIRefCon(refCon: refCon, known: refConKnown) + guard packetDataCount > 0 else { return MIDIPacketData( bytes: [], - timeStamp: midiPacketPtr.pointee.timeStamp + timeStamp: midiPacketPtr.pointee.timeStamp, + source: source ) } // Access the raw memory instead of using the .pointee - // This workaround is needed due to a variety of crashes that can occur when either the thread sanitizer is on, or large/malformed MIDI packet lists / packets arrive + // This workaround is needed due to a variety of crashes that can occur when either the + // thread sanitizer is on, or large/malformed MIDI packet lists / packets arrive let rawMIDIPacketDataPtr = UnsafeRawBufferPointer( start: UnsafeRawPointer(midiPacketPtr) + midiPacketDataOffset, count: packetDataCount @@ -50,7 +68,10 @@ extension MIDIPacketData { return MIDIPacketData( bytes: [UInt8](rawMIDIPacketDataPtr), - timeStamp: midiPacketPtr.pointee.timeStamp + timeStamp: midiPacketPtr.pointee.timeStamp, + source: source ) } } + +#endif diff --git a/Sources/MIDIKitIO/Packet/UniversalPacketData/UniversalPacketData.swift b/Sources/MIDIKitIO/Packet/UniversalPacketData/UniversalPacketData.swift index bcd3f967e7..647b8a5834 100644 --- a/Sources/MIDIKitIO/Packet/UniversalPacketData/UniversalPacketData.swift +++ b/Sources/MIDIKitIO/Packet/UniversalPacketData/UniversalPacketData.swift @@ -1,12 +1,15 @@ // // UniversalPacketData.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // +#if !os(tvOS) && !os(watchOS) + @_implementationOnly import CoreMIDI -/// Clean consolidated data encapsulation of raw data from a Core MIDI `MIDIEventPacket` (Universal MIDI Packet). +/// Clean consolidated data encapsulation of raw data from a Core MIDI `MIDIEventPacket` (Universal +/// MIDI Packet). public struct UniversalMIDIPacketData { // /// Universal MIDI Packet Words // public let words: [UInt32] @@ -17,40 +20,65 @@ public struct UniversalMIDIPacketData { /// Core MIDI packet timestamp public let timeStamp: CoreMIDITimeStamp - public init(bytes: [UInt8], timeStamp: CoreMIDITimeStamp) { + /// The MIDI endpoint from which the packet originated. + /// If this information is not available, it may be `nil`. + let source: MIDIOutputEndpoint? + + public init( + bytes: [UInt8], + timeStamp: CoreMIDITimeStamp, + source: MIDIOutputEndpoint? = nil + ) { self.bytes = bytes self.timeStamp = timeStamp + self.source = source } - public init(words: [UMPWord], timeStamp: CoreMIDITimeStamp) { + public init( + words: [UMPWord], + timeStamp: CoreMIDITimeStamp, + source: MIDIOutputEndpoint? = nil + ) { bytes = words.umpWordsToBytes() self.timeStamp = timeStamp + self.source = source } } -#if !os(tvOS) && !os(watchOS) - @available(macOS 11, iOS 14, macCatalyst 14, *) extension UniversalMIDIPacketData { /// Universal MIDI Packet - internal init(_ eventPacketPtr: UnsafePointer) { - self = Self.unwrapPacket(eventPacketPtr) + internal init( + _ eventPacketPtr: UnsafePointer, + refCon: UnsafeMutableRawPointer?, + refConKnown: Bool + ) { + self = Self.unwrapPacket(eventPacketPtr, refCon: refCon, refConKnown: refConKnown) } /// Universal MIDI Packet - internal init(_ eventPacket: MIDIEventPacket) { - self = Self.packetUnwrapper(eventPacket) + internal init( + _ eventPacket: MIDIEventPacket, + refCon: UnsafeMutableRawPointer?, + refConKnown: Bool + ) { + self = Self.packetUnwrapper(eventPacket, refCon: refCon, refConKnown: refConKnown) } fileprivate static func unwrapPacket( - _ eventPacketPtr: UnsafePointer + _ eventPacketPtr: UnsafePointer, + refCon: UnsafeMutableRawPointer?, + refConKnown: Bool ) -> UniversalMIDIPacketData { let wordCollection = eventPacketPtr.words() - + + let source = unpackMIDIRefCon(refCon: refCon, known: refConKnown) + guard !wordCollection.isEmpty else { return UniversalMIDIPacketData( words: [], - timeStamp: eventPacketPtr.pointee.timeStamp + timeStamp: eventPacketPtr.pointee.timeStamp, + source: source ) } @@ -60,7 +88,8 @@ extension UniversalMIDIPacketData { ) return UniversalMIDIPacketData( words: [], - timeStamp: eventPacketPtr.pointee.timeStamp + timeStamp: eventPacketPtr.pointee.timeStamp, + source: source ) } @@ -73,22 +102,28 @@ extension UniversalMIDIPacketData { return UniversalMIDIPacketData( words: words, - timeStamp: eventPacketPtr.pointee.timeStamp + timeStamp: eventPacketPtr.pointee.timeStamp, + source: source ) } fileprivate static func packetUnwrapper( - _ eventPacket: MIDIEventPacket + _ eventPacket: MIDIEventPacket, + refCon: UnsafeMutableRawPointer?, + refConKnown: Bool ) -> UniversalMIDIPacketData { var localEventPacket = eventPacket - + + let source = unpackMIDIRefCon(refCon: refCon, known: refConKnown) + return withUnsafePointer(to: localEventPacket) { unsafePtr -> UniversalMIDIPacketData in let wordCollection = MIDIEventPacket.WordCollection(&localEventPacket) guard !wordCollection.isEmpty else { return UniversalMIDIPacketData( words: [], - timeStamp: localEventPacket.timeStamp + timeStamp: localEventPacket.timeStamp, + source: source ) } @@ -98,7 +133,8 @@ extension UniversalMIDIPacketData { ) return UniversalMIDIPacketData( words: [], - timeStamp: localEventPacket.timeStamp + timeStamp: localEventPacket.timeStamp, + source: source ) } @@ -111,7 +147,8 @@ extension UniversalMIDIPacketData { return UniversalMIDIPacketData( words: words, - timeStamp: localEventPacket.timeStamp + timeStamp: localEventPacket.timeStamp, + source: source ) } } diff --git a/Sources/MIDIKitIO/Parser/MIDI1Parser.swift b/Sources/MIDIKitIO/Parser/MIDI1Parser.swift index e6c1f7199d..ca8cfad0ee 100644 --- a/Sources/MIDIKitIO/Parser/MIDI1Parser.swift +++ b/Sources/MIDIKitIO/Parser/MIDI1Parser.swift @@ -1,17 +1,22 @@ // // MIDI1Parser.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // +#if !os(tvOS) && !os(watchOS) + /// Parser for MIDI 1.0 events. /// -/// State is maintained internally. Use one parser class instance per MIDI endpoint for the lifecycle of that endpoint. (ie: Do not generate new parser classes on every event received, and do not use a single global parser class instance for all MIDI endpoints.) +/// State is maintained internally. Use one parser class instance per MIDI endpoint for the +/// lifecycle of that endpoint. (ie: Do not generate new parser classes on every event received, and +/// do not use a single global parser class instance for all MIDI endpoints.) public final class MIDI1Parser { // MARK: - Internal Default Instance /// Internal: - /// Default static instance for MIDIKit objects that support parsing events without requiring a parser to be instanced first. + /// Default static instance for MIDIKit objects that support parsing events without requiring a + /// parser to be instanced first. internal static let `default` = MIDI1Parser() // MARK: - Parser State @@ -65,9 +70,12 @@ public final class MIDI1Parser { case sysExOpenEnded } - /// Parses raw packet data into an array of MIDI Events, without instancing a MIDI parser object. + /// Parses raw packet data into an array of MIDI Events, without instancing a MIDI parser + /// object. /// - /// Persisted status data is normally the role of the parser class, but this method gives access to an abstracted parsing method by way of injecting and emitting persistent state (ie: running status). + /// Persisted status data is normally the role of the parser class, but this method gives access + /// to an abstracted parsing method by way of injecting and emitting persistent state (ie: + /// running status). internal static func parsedEvents( in bytes: [UInt8], runningStatus: UInt8? = nil, @@ -201,7 +209,8 @@ public final class MIDI1Parser { // System Common - Undefined // [0xF4] / [0xF5] - // MIDI 1.0 Spec: ignore these undefined statuses, but we should clear running status + // MIDI 1.0 Spec: ignore these undefined statuses, but we should clear running + // status expectedDataBytes = .none runningStatus = nil @@ -219,7 +228,8 @@ public final class MIDI1Parser { // System Common - System Exclusive End (EOX / End Of Exclusive) // [variable number of SysEx bytes ... , 0xF7] - // 0xF7 is not always present at the end of a SysEx message. A SysEx message can end in any one of several cases: + // 0xF7 is not always present at the end of a SysEx message. A SysEx message can + // end in any one of several cases: // - byte 0xF7 // - parsing reaches the end of the MIDI message bytes // - another Status byte, thus starting a new message @@ -233,7 +243,9 @@ public final class MIDI1Parser { // [0xF8] // MIDI 1.0 Spec: - // "Real-Time messages can be sent at any time and may be inserted anywhere in a MIDI data stream, including between Status and Data bytes of any other MIDI messages." + // "Real-Time messages can be sent at any time and may be inserted anywhere in + // a MIDI data stream, including between Status and Data bytes of any other + // MIDI messages." // "Real-Time messages should not affect Running Status." // don't change expectedExactNumberOfDataBytes here! @@ -244,7 +256,9 @@ public final class MIDI1Parser { // [0xF9] // MIDI 1.0 Spec: - // "Real-Time messages can be sent at any time and may be inserted anywhere in a MIDI data stream, including between Status and Data bytes of any other MIDI messages." + // "Real-Time messages can be sent at any time and may be inserted anywhere in + // a MIDI data stream, including between Status and Data bytes of any other + // MIDI messages." // "Real-Time messages should not affect Running Status." // don't change expectedExactNumberOfDataBytes here! @@ -256,7 +270,9 @@ public final class MIDI1Parser { // [0xFA] // MIDI 1.0 Spec: - // "Real-Time messages can be sent at any time and may be inserted anywhere in a MIDI data stream, including between Status and Data bytes of any other MIDI messages." + // "Real-Time messages can be sent at any time and may be inserted anywhere in + // a MIDI data stream, including between Status and Data bytes of any other + // MIDI messages." // "Real-Time messages should not affect Running Status." // don't change expectedExactNumberOfDataBytes here! @@ -268,8 +284,10 @@ public final class MIDI1Parser { // [0xFB] // MIDI 1.0 Spec: - // "Real-Time messages can be sent at any time and may be inserted anywhere in a MIDI data stream, including between Status and Data bytes of any other MIDI messages." - // "Real-Time messages should not affect Running Status." + // "Real-Time messages can be sent at any time and may be inserted anywhere in + // a MIDI data stream, including between Status and Data bytes of any other + // MIDI messages." + // "Real-Time messages should not affect Running Status." // don't change expectedExactNumberOfDataBytes here! // don't change runningStatus here! @@ -280,7 +298,9 @@ public final class MIDI1Parser { // [0xFC] // MIDI 1.0 Spec: - // "Real-Time messages can be sent at any time and may be inserted anywhere in a MIDI data stream, including between Status and Data bytes of any other MIDI messages." + // "Real-Time messages can be sent at any time and may be inserted anywhere in + // a MIDI data stream, including between Status and Data bytes of any other + // MIDI messages." // "Real-Time messages should not affect Running Status." // don't change expectedExactNumberOfDataBytes here! @@ -292,7 +312,9 @@ public final class MIDI1Parser { // [0xFD] // MIDI 1.0 Spec: - // "Real-Time messages can be sent at any time and may be inserted anywhere in a MIDI data stream, including between Status and Data bytes of any other MIDI messages." + // "Real-Time messages can be sent at any time and may be inserted anywhere in + // a MIDI data stream, including between Status and Data bytes of any other + // MIDI messages." // "Real-Time messages should not affect Running Status." break @@ -302,7 +324,9 @@ public final class MIDI1Parser { // [0xFE] // MIDI 1.0 Spec: - // "Real-Time messages can be sent at any time and may be inserted anywhere in a MIDI data stream, including between Status and Data bytes of any other MIDI messages." + // "Real-Time messages can be sent at any time and may be inserted anywhere in + // a MIDI data stream, including between Status and Data bytes of any other + // MIDI messages." // "Real-Time messages should not affect Running Status." // don't change expectedExactNumberOfDataBytes here! @@ -314,8 +338,10 @@ public final class MIDI1Parser { // [0xFF] // MIDI 1.0 Spec: - // "Real-Time messages can be sent at any time and may be inserted anywhere in a MIDI data stream, including between Status and Data bytes of any other MIDI messages." - // "Real-Time messages should not affect Running Status." + // "Real-Time messages can be sent at any time and may be inserted anywhere in + // a MIDI data stream, including between Status and Data bytes of any other + // MIDI messages." + // "Real-Time messages should not affect Running Status." // don't change expectedExactNumberOfDataBytes here! // don't change runningStatus here! @@ -329,7 +355,8 @@ public final class MIDI1Parser { default: // data byte - // if current message is empty, we assume the Running Status byte should be used if it's cached + // if current message is empty, we assume the Running Status byte should be used if + // it's cached if currentMessageBuffer.isEmpty, let runningStatus = runningStatus { @@ -613,3 +640,5 @@ extension AnyMIDIPacket { MIDI1Parser.default.parsedEvents(in: bytes) } } + +#endif diff --git a/Sources/MIDIKitIO/Parser/MIDI2Parser.swift b/Sources/MIDIKitIO/Parser/MIDI2Parser.swift index b18a4141de..f90cd61547 100644 --- a/Sources/MIDIKitIO/Parser/MIDI2Parser.swift +++ b/Sources/MIDIKitIO/Parser/MIDI2Parser.swift @@ -1,17 +1,22 @@ // // MIDI2Parser.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // +#if !os(tvOS) && !os(watchOS) + /// Parser for MIDI 2.0 events. /// -/// State is maintained internally. Use one parser class instance per MIDI endpoint for the lifecycle of that endpoint. (ie: Do not generate new parser classes on every event received, and do not use a single global parser class instance for all MIDI endpoints.) +/// State is maintained internally. Use one parser class instance per MIDI endpoint for the +/// lifecycle of that endpoint. (ie: Do not generate new parser classes on every event received, and +/// do not use a single global parser class instance for all MIDI endpoints.) public final class MIDI2Parser { // MARK: - Internal Default Instance /// Internal: - /// Default static instance for MIDIKit objects that support parsing events without requiring a parser to be instanced first. + /// Default static instance for MIDIKit objects that support parsing events without requiring a + /// parser to be instanced first. internal static let `default` = MIDI2Parser() // MARK: - Parser State @@ -170,7 +175,8 @@ public final class MIDI2Parser { group: UInt4 ) -> MIDIEvent? { // ensure packet is 32-bits (4 bytes / 1 UInt32 word) wide - // (first byte is stripped when bytes are passed into this function so we expect 3 bytes here) + // (first byte is stripped when bytes are passed into this function + // so we expect 3 bytes here) guard bytes.count == 3 else { return nil } let statusByte = bytes[bytes.startIndex] @@ -256,7 +262,8 @@ public final class MIDI2Parser { group: UInt4 ) -> MIDIEvent? { // ensure packet is 32-bits (4 bytes / 1 UInt32 word) wide - // (first byte is stripped when bytes are passed into this function so we expect 3 bytes here) + // (first byte is stripped when bytes are passed into this function + // so we expect 3 bytes here) guard bytes.count == 3 else { return nil } let statusNibble = bytes[bytes.startIndex].nibbles.high @@ -379,7 +386,8 @@ public final class MIDI2Parser { group: UInt4 ) -> MIDIEvent? { // ensure packet is 64-bits (8 bytes / 2 UInt32 words) wide - // (first byte is stripped when bytes are passed into this function so we expect 7 bytes here) + // (first byte is stripped when bytes are passed into this function + // so we expect 7 bytes here) guard bytes.count == 7 else { return nil } // byte 1: [status] @@ -577,10 +585,16 @@ public final class MIDI2Parser { group: UInt4 ) -> MIDIEvent? { // MIDI 2.0 Spec: - // "The MIDI 1.0 Protocol bracketing method with 0xF0 Start and 0xF7 End Status bytes is not used in the UMP Format. Instead, the SysEx payload is carried in one or more 64-bit UMPs, discarding the 0xF0 and 0xF7 bytes. The standard ID Number (Manufacturer ID, Special ID 0x7D, or Universal System Exclusive ID), Device ID, and Sub-ID#1 & Sub-ID#2 (if applicable) are included in the initial data bytes, just as they are in MIDI 1.0 Protocol message equivalents." + // "The MIDI 1.0 Protocol bracketing method with 0xF0 Start and 0xF7 End Status bytes is not + // used in the UMP Format. Instead, the SysEx payload is carried in one or more 64-bit UMPs, + // discarding the 0xF0 and 0xF7 bytes. The standard ID Number (Manufacturer ID, Special ID + // 0x7D, or Universal System Exclusive ID), Device ID, and Sub-ID#1 & Sub-ID#2 (if + // applicable) are included in the initial data bytes, just as they are in MIDI 1.0 Protocol + // message equivalents." // ensure packet is 64-bits (8 bytes / 2 UInt32 words) wide - // (first byte is stripped when bytes are passed into this function so we expect 7 bytes here) + // (first byte is stripped when bytes are passed into this function so we expect 7 bytes + // here) guard bytes.count == 7 else { return nil } let byte1Nibbles = bytes[bytes.startIndex].nibbles @@ -649,10 +663,15 @@ public final class MIDI2Parser { group: UInt4 ) -> MIDIEvent? { // MIDI 2.0 Spec: - // "System Exclusive 8 messages have many similarities to the MIDI 1.0 Protocol’s original System Exclusive messages, but with the added advantage of allowing all 8 bits of each data byte to be used. By contrast, MIDI 1.0 Protocol System Exclusive requires a 0 in the high bit of every data byte, leaving only 7 bits to carry actual data. A System Exclusive 8 Message is carried in one or more 128-bit UMPs with Message Type 0x5." + // "System Exclusive 8 messages have many similarities to the MIDI 1.0 Protocol’s original + // System Exclusive messages, but with the added advantage of allowing all 8 bits of each + // data byte to be used. By contrast, MIDI 1.0 Protocol System Exclusive requires a 0 in the + // high bit of every data byte, leaving only 7 bits to carry actual data. A System Exclusive + // 8 Message is carried in one or more 128-bit UMPs with Message Type 0x5." // ensure packet is 128-bits (16 bytes / 4 UInt32 words) wide - // (first byte is stripped when bytes are passed into this function so we expect 15 bytes here) + // (first byte is stripped when bytes are passed into this function so we expect 15 bytes + // here) guard bytes.count == 15 else { return nil } let byte1Nibbles = bytes[bytes.startIndex].nibbles @@ -748,7 +767,9 @@ public final class MIDI2Parser { followingBytes: Array.SubSequence )? { // MIDI 2.0 Spec: - // "The UMP Format provides a set of Utility Messages. Utility Messages include but are not limited to NOOP and timestamps, and might in the future include UMP transport-related functions." + // "The UMP Format provides a set of Utility Messages. Utility Messages include but are not + // limited to NOOP and timestamps, and might in the future include UMP transport-related + // functions." // These messages can be standalone 32-bit UMPs or prepend other UMP messages. // byte 0: [high nibble: message type, low nibble: group] @@ -775,7 +796,8 @@ public final class MIDI2Parser { // since a status of 0x0 is NOOP and it carries no data // so we could skip checking these bytes. - // NOOP is always a self-contained message and never prepends other UMPs like timestamps could. + // NOOP is always a self-contained message and never prepends + // other UMPs like timestamps could. return (.noOp(group: group), []) @@ -829,3 +851,5 @@ extension AnyMIDIPacket { MIDI2Parser.default.parsedEvents(in: bytes) } } + +#endif diff --git a/Sources/MIDIKitIO/Protocols/MIDIIOManagedProtocol.swift b/Sources/MIDIKitIO/Protocols/MIDIIOManagedProtocol.swift index ddb11df7f9..aed657643a 100644 --- a/Sources/MIDIKitIO/Protocols/MIDIIOManagedProtocol.swift +++ b/Sources/MIDIKitIO/Protocols/MIDIIOManagedProtocol.swift @@ -1,7 +1,7 @@ // // MIDIIOManagedProtocol.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -9,7 +9,8 @@ // MARK: - Public Protocol public protocol MIDIIOManagedProtocol: AnyObject { - /// Core MIDI API version used to create the endpoint and send/receive MIDI messages (if applicable). + /// Core MIDI API version used to create the endpoint + /// and send/receive MIDI messages (if applicable). /* public private(set) */ var api: CoreMIDIAPIVersion { get } } diff --git a/Sources/MIDIKitIO/Protocols/MIDIIOReceivesMIDIMessagesProtocol.swift b/Sources/MIDIKitIO/Protocols/MIDIIOReceivesMIDIMessagesProtocol.swift index dff704cbc0..0a23c799ec 100644 --- a/Sources/MIDIKitIO/Protocols/MIDIIOReceivesMIDIMessagesProtocol.swift +++ b/Sources/MIDIKitIO/Protocols/MIDIIOReceivesMIDIMessagesProtocol.swift @@ -1,7 +1,7 @@ // // MIDIIOReceivesMIDIMessagesProtocol.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) diff --git a/Sources/MIDIKitIO/Protocols/MIDIIOSendsMIDIMessagesProtocol.swift b/Sources/MIDIKitIO/Protocols/MIDIIOSendsMIDIMessagesProtocol.swift index a366a4314a..c9717c264b 100644 --- a/Sources/MIDIKitIO/Protocols/MIDIIOSendsMIDIMessagesProtocol.swift +++ b/Sources/MIDIKitIO/Protocols/MIDIIOSendsMIDIMessagesProtocol.swift @@ -1,7 +1,7 @@ // // MIDIIOSendsMIDIMessagesProtocol.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if !os(tvOS) && !os(watchOS) @@ -36,7 +36,8 @@ internal protocol _MIDIIOSendsMIDIMessagesProtocol: MIDIIOSendsMIDIMessagesProto func send(rawMessage: [UInt8]) throws /// Internal: - /// Send one or more legacy MIDI 1.0 message(s), automatically assembling it into a `MIDIPacketList`. + /// Send one or more legacy MIDI 1.0 message(s), automatically assembling it into a + /// `MIDIPacketList`. /// /// This method is internal-only and its use is discouraged. /// diff --git a/Sources/MIDIKitInternals/MIDIKitInternals.swift b/Sources/MIDIKitInternals/MIDIKitInternals.swift index 342f388cfb..002194dc6a 100644 --- a/Sources/MIDIKitInternals/MIDIKitInternals.swift +++ b/Sources/MIDIKitInternals/MIDIKitInternals.swift @@ -1,3 +1,9 @@ +// +// MIDIKitInternals.swift +// MIDIKit • https://github.com/orchetect/MIDIKit +// © 2021-2022 Steffan Andrews • Licensed under MIT License +// + // // MIDIKitInternals.swift // MIDIKit • https://github.com/orchetect/MIDIKit diff --git a/Sources/MIDIKitInternals/Utilities/ASCII String and Data.swift b/Sources/MIDIKitInternals/Utilities/ASCII String and Data.swift index e1997b5fe8..aaad1a9891 100644 --- a/Sources/MIDIKitInternals/Utilities/ASCII String and Data.swift +++ b/Sources/MIDIKitInternals/Utilities/ASCII String and Data.swift @@ -1,7 +1,7 @@ // // ASCII String and Data.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitInternals/Utilities/Exception.swift b/Sources/MIDIKitInternals/Utilities/Exception.swift index fa58471f58..d61b7786f4 100644 --- a/Sources/MIDIKitInternals/Utilities/Exception.swift +++ b/Sources/MIDIKitInternals/Utilities/Exception.swift @@ -1,7 +1,7 @@ // // Exception.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitInternals/Utilities/Hex and Binary String.swift b/Sources/MIDIKitInternals/Utilities/Hex and Binary String.swift index c21d3d1ad8..6410158a82 100644 --- a/Sources/MIDIKitInternals/Utilities/Hex and Binary String.swift +++ b/Sources/MIDIKitInternals/Utilities/Hex and Binary String.swift @@ -1,7 +1,7 @@ // // Hex and Binary String.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -37,7 +37,8 @@ extension Collection where Element: BinaryInteger { .joined(separator: separator) } - /// Returns a collection of integers as a flat string of hex strings padded to _n_ characters after the prefix. + /// Returns a collection of integers as a flat string of hex strings + /// padded to _n_ characters after the prefix. /// Prefixes optional. public func hexString( padEachTo: Int, @@ -80,7 +81,8 @@ extension Collection where Element: BinaryInteger { .joined(separator: separator) } - /// Returns a collection of integers as a flat string of binary strings padded to _n_ characters after the prefix. + /// Returns a collection of integers as a flat string of binary strings + /// padded to _n_ characters after the prefix. /// Prefixes optional. public func binaryString( padEachTo: Int, diff --git a/Sources/MIDIKitInternals/Utilities/Number Formatting.swift b/Sources/MIDIKitInternals/Utilities/Number Formatting.swift index bb9e5efd8e..d77b5fa9eb 100644 --- a/Sources/MIDIKitInternals/Utilities/Number Formatting.swift +++ b/Sources/MIDIKitInternals/Utilities/Number Formatting.swift @@ -1,7 +1,7 @@ // // Number Formatting.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitInternals/Utilities/Outsourced/ASCII.swift b/Sources/MIDIKitInternals/Utilities/Outsourced/ASCII.swift index 2a3387bf09..138825ed1c 100644 --- a/Sources/MIDIKitInternals/Utilities/Outsourced/ASCII.swift +++ b/Sources/MIDIKitInternals/Utilities/Outsourced/ASCII.swift @@ -17,11 +17,14 @@ extension StringProtocol { /// Converts a `String` to ASCII string lossily. /// - /// Performs a lossy conversion, transforming characters to printable ASCII substitutions where necessary. + /// Performs a lossy conversion, transforming characters to printable ASCII substitutions where + /// necessary. /// - /// Note that some characters may be transformed to representations that occupy more than one ASCII character. For example: char 189 (½) will be converted to "1/2" + /// Note that some characters may be transformed to representations that occupy more than one + /// ASCII character. For example: char 189 (½) will be converted to "1/2" /// - /// Where a suitable character substitution can't reasonably be performed, a question-mark "?" will be substituted. + /// Where a suitable character substitution can't reasonably be performed, a question-mark "?" + /// will be substituted. @available(OSX 10.11, iOS 9.0, *) internal var asciiStringLossy: String { let transformed = applyingTransform( diff --git a/Sources/MIDIKitInternals/Utilities/Outsourced/Collections.swift b/Sources/MIDIKitInternals/Utilities/Outsourced/Collections.swift index 5d0ed5e6c5..9056462dce 100644 --- a/Sources/MIDIKitInternals/Utilities/Outsourced/Collections.swift +++ b/Sources/MIDIKitInternals/Utilities/Outsourced/Collections.swift @@ -14,7 +14,8 @@ import Foundation // MARK: - Split extension Collection { - /// Splits a `Collection` or `String` into groups of `every` _n_ number of characters, grouping from left-to-right. If `backwards` is `true`, right-to-left. + /// Splits a `Collection` or `String` into groups of `every` _n_ number of characters, grouping + /// from left-to-right. If `backwards` is `true`, right-to-left. @_disfavoredOverload public func split( every: Int, diff --git a/Sources/MIDIKitInternals/Utilities/Outsourced/Data.swift b/Sources/MIDIKitInternals/Utilities/Outsourced/Data.swift index f9ecb8723a..90ec3a0144 100644 --- a/Sources/MIDIKitInternals/Utilities/Outsourced/Data.swift +++ b/Sources/MIDIKitInternals/Utilities/Outsourced/Data.swift @@ -12,7 +12,12 @@ // Endianness: All Apple platforms are currently little-endian // Floating endianness: -// On some machines, while integers were represented in little-endian form, floating point numbers were represented in big-endian form. Because there are many floating point formats, and a lack of a standard "network" representation, no standard for transferring floating point values has been made. This means that floating point data written on one machine may not be readable on another, and this is the case even if both use IEEE 754 floating point arithmetic since the endianness of the memory representation is not part of the IEEE specification. +// On some machines, while integers were represented in little-endian form, floating point numbers +// were represented in big-endian form. Because there are many floating point formats, and a lack of +// a standard "network" representation, no standard for transferring floating point values has been +// made. This means that floating point data written on one machine may not be readable on another, +// and this is the case even if both use IEEE 754 floating point arithmetic since the endianness of +// the memory representation is not part of the IEEE specification. // int32 // 32-bit big-endian two's complement integer @@ -200,7 +205,8 @@ extension Data { // this crashes if Data alignment isn't correct // let number = { self.withUnsafeBytes { $0.load(as: Float32.self) } }() - // since .load(as:) is not memory alignment safe, memcpy is the current workaround (as of Swift 5.3) + // since .load(as:) is not memory alignment safe, memcpy is the current workaround (as of + // Swift 5.3) // see for more info: https://bugs.swift.org/browse/SR-10273 let number: Float32 = withUnsafeBytes { var value = Float32() @@ -307,7 +313,8 @@ extension Data { // this crashes if Data alignment isn't correct // let number: Double = { self.withUnsafeBytes { $0.load(as: Double.self) } }() - // since .load(as:) is not memory alignment safe, memcpy is the current workaround (as of Swift 5.3) + // since .load(as:) is not memory alignment safe, memcpy is the current workaround (as of + // Swift 5.3) // see for more info: https://bugs.swift.org/browse/SR-10273 let number: Double = withUnsafeBytes { var value = Double() @@ -360,7 +367,8 @@ extension Data { // MARK: - .toData extension FixedWidthInteger { - /// Returns Data representation of an integer. (Endianness has no effect on single-byte integers.) + /// Returns Data representation of an integer. (Endianness has no effect on single-byte + /// integers.) @_disfavoredOverload public func toData(_ endianness: NumberEndianness = .platformDefault) -> Data { var int: Self @@ -400,7 +408,8 @@ extension Data { // this crashes if Data alignment isn't correct // let int: T = { self.withUnsafeBytes { $0.load(as: T.self) } }() - // since .load(as:) is not memory alignment safe, memcpy is the current workaround (as of Swift 5.3) + // since .load(as:) is not memory alignment safe, memcpy is the current workaround (as of + // Swift 5.3) // see for more info: https://bugs.swift.org/browse/SR-10273 let int: T = withUnsafeBytes { var value = T() diff --git a/Sources/MIDIKitInternals/Utilities/Outsourced/PassiveDataReader.swift b/Sources/MIDIKitInternals/Utilities/Outsourced/PassiveDataReader.swift index 23325c9d61..10018f55d8 100644 --- a/Sources/MIDIKitInternals/Utilities/Outsourced/PassiveDataReader.swift +++ b/Sources/MIDIKitInternals/Utilities/Outsourced/PassiveDataReader.swift @@ -49,7 +49,8 @@ public struct PassiveDataReader { // MARK: - Methods /// Manually advance by _n_ number of bytes from current read offset. - /// Note that this method is unchecked which may result in an offset beyond the end of the data stream. + /// Note that this method is unchecked which may result in an offset beyond the end of the data + /// stream. public mutating func advanceBy(_ count: Int) { readOffset += count } diff --git a/Sources/MIDIKitInternals/Utilities/Outsourced/Ranges.swift b/Sources/MIDIKitInternals/Utilities/Outsourced/Ranges.swift index 8b4e8b7cfd..35cf862cb2 100644 --- a/Sources/MIDIKitInternals/Utilities/Outsourced/Ranges.swift +++ b/Sources/MIDIKitInternals/Utilities/Outsourced/Ranges.swift @@ -42,7 +42,8 @@ extension Comparable { } // ie: 5.0.clamped(to: 7.0..<10.0) - // not a good idea to implement this -- floating point numbers don't make sense in a ..< type range + // not a good idea to implement this -- floating point numbers don't make sense in a ..< type + // range // because would the max of 7.0..<10.0 be 9.999999999...? It can't be 10.0. // func clamped(to limits: Range) -> Self { } } diff --git a/Sources/MIDIKitInternals/Utilities/Outsourced/String.swift b/Sources/MIDIKitInternals/Utilities/Outsourced/String.swift index 758974a815..f290f1c080 100644 --- a/Sources/MIDIKitInternals/Utilities/Outsourced/String.swift +++ b/Sources/MIDIKitInternals/Utilities/Outsourced/String.swift @@ -95,7 +95,8 @@ extension StringProtocol { .joined() } - /// Returns a string preserving only characters from the passed string and removing all other characters. + /// Returns a string preserving only characters from the passed string and removing all other + /// characters. @_disfavoredOverload public func only(characters: String) -> String { only(CharacterSet(charactersIn: characters)) diff --git a/Sources/MIDIKitInternals/Utilities/Outsourced/ThreadSafeAccess.swift b/Sources/MIDIKitInternals/Utilities/Outsourced/ThreadSafeAccess.swift index 7b7273b8b9..6415574e18 100644 --- a/Sources/MIDIKitInternals/Utilities/Outsourced/ThreadSafeAccess.swift +++ b/Sources/MIDIKitInternals/Utilities/Outsourced/ThreadSafeAccess.swift @@ -14,11 +14,13 @@ import Foundation /// `ThreadSafeAccess`: A property wrapper that ensures thread-safe atomic access to a value. /// Multiple read accesses can potentially read at the same time, just not during a write. /// -/// By using `pthread` to do the locking, this safer than using a `DispatchQueue/barrier` as there isn't a chance of priority inversion. +/// By using `pthread` to do the locking, this safer than using a `DispatchQueue/barrier` as there +/// isn't a chance of priority inversion. /// /// This is safe to use on collection types (`Array`, `Dictionary`, etc.). /// -/// - Warning: Do not instantiate this wrapper on a variable declaration inside a function body or closure body. Only wrap static or instance variables. +/// - Warning: Do not instantiate this wrapper on a variable declaration inside a function body or +/// closure body. Only wrap static or instance variables. @propertyWrapper public final class ThreadSafeAccess { private var value: T @@ -54,14 +56,17 @@ public final class ThreadSafeAccess { } } -/// Defines a basic signature to which all locks will conform. Provides the basis for atomic access to stuff. +/// Defines a basic signature to which all locks will conform. Provides the basis for atomic access +/// to stuff. private protocol ThreadLock { init() - /// Lock a resource for writing. So only one thing can write, and nothing else can read or write. + /// Lock a resource for writing. So only one thing can write, and nothing else can read or + /// write. func writeLock() - /// Lock a resource for reading. Other things can also lock for reading at the same time, but nothing else can write at that time. + /// Lock a resource for reading. Other things can also lock for reading at the same time, but + /// nothing else can write at that time. func readLock() /// Unlock a resource diff --git a/Sources/MIDIKitInternals/Utilities/Outsourced/Timespec.swift b/Sources/MIDIKitInternals/Utilities/Outsourced/Timespec.swift index 9772696eb3..a12ebe8345 100644 --- a/Sources/MIDIKitInternals/Utilities/Outsourced/Timespec.swift +++ b/Sources/MIDIKitInternals/Utilities/Outsourced/Timespec.swift @@ -17,22 +17,29 @@ import Darwin // Apple docs: // // CLOCK_MONOTONIC -// clock that increments monotonically, tracking the time since an arbitrary point, and will continue to increment while the system is asleep. +// clock that increments monotonically, tracking the time since an arbitrary point, and will +// continue to increment while the system is asleep. // // CLOCK_MONOTONIC_RAW -// clock that increments monotonically, tracking the time since an arbitrary point like CLOCK_MONOTONIC. However, this clock is unaffected by frequency or time adjustments. It should not be compared to other system time sources. +// clock that increments monotonically, tracking the time since an arbitrary point like +// CLOCK_MONOTONIC. However, this clock is unaffected by frequency or time adjustments. It should +// not be compared to other system time sources. // // CLOCK_MONOTONIC_RAW_APPROX -// like CLOCK_MONOTONIC_RAW, but reads a value cached by the system at context switch. This can be read faster, but at a loss of accuracy as it may return values that are milliseconds old. +// like CLOCK_MONOTONIC_RAW, but reads a value cached by the system at context switch. This can be +// read faster, but at a loss of accuracy as it may return values that are milliseconds old. // // CLOCK_UPTIME_RAW -// clock that increments monotonically, in the same manner as CLOCK_MONOTONIC_RAW, but that does not increment while the system is asleep. The returned value is identical to the result of mach_absolute_time() after the appropriate mach_timebase conversion is applied. +// clock that increments monotonically, in the same manner as CLOCK_MONOTONIC_RAW, but that does not +// increment while the system is asleep. The returned value is identical to the result of +// mach_absolute_time() after the appropriate mach_timebase conversion is applied. /// Returns high-precision system uptime. /// /// This is preferable to using `mach_absolute_time()` since it is macOS-only. /// -/// - Returns: `timespec(tv_sec: Int, tv_nsec: Int)` where `tv_sec` is seconds and `tc_nsec` is nanoseconds. +/// - Returns: `timespec(tv_sec: Int, tv_nsec: Int)` where `tv_sec` is seconds and `tc_nsec` is +/// nanoseconds. @available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) @_disfavoredOverload public func clock_gettime_monotonic_raw() -> timespec { diff --git a/Sources/MIDIKitInternals/Utilities/RandomAccessCollection.swift b/Sources/MIDIKitInternals/Utilities/RandomAccessCollection.swift index 39af7951cd..1e67190c69 100644 --- a/Sources/MIDIKitInternals/Utilities/RandomAccessCollection.swift +++ b/Sources/MIDIKitInternals/Utilities/RandomAccessCollection.swift @@ -1,7 +1,7 @@ // // RandomAccessCollection.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitInternals/Utilities/SafeDispatchTimer.swift b/Sources/MIDIKitInternals/Utilities/SafeDispatchTimer.swift index 78b012cecd..1a47c56479 100644 --- a/Sources/MIDIKitInternals/Utilities/SafeDispatchTimer.swift +++ b/Sources/MIDIKitInternals/Utilities/SafeDispatchTimer.swift @@ -1,18 +1,22 @@ // // SafeDispatchTimer.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Dispatch /// Simple custom safe `DispatchSourceTimer` wrapper. /// -/// Timer does not start automatically when initializing. Call `start()` after initialization to begin the timer. +/// Timer does not start automatically when initializing. Call ``start()`` after initialization to +/// begin the timer. /// -/// The timer will fire at intervals of a `rate` in Hz, starting immediately from the time at which `start()` is called. +/// The timer will fire at intervals of a `rate` in Hz, starting immediately from the time at which +/// ``start()`` is called. /// -/// All timer methods are safe and can be called in any order without worrying about `DispatchSourceTimer`-related peculiarities (start/suspend balancing or cancelling without resuming). +/// All timer methods are safe and can be called in any order without worrying about +/// `DispatchSourceTimer`-related peculiarities (start/suspend balancing or cancelling without +/// resuming). public final class SafeDispatchTimer { internal var timer: DispatchSourceTimer internal weak var queue: DispatchQueue? @@ -56,7 +60,8 @@ public final class SafeDispatchTimer { timer.setEventHandler(handler: eventHandler) } - /// Starts the timer. The timer will occur at intervals measured since the creation of the timer, regardless of when `start()` is called. + /// Starts the timer. The timer will occur at intervals measured since the creation of the + /// timer, regardless of when ``start()`` is called. /// /// If the timer has already started, this will have no effect. public func start() { @@ -68,12 +73,17 @@ public final class SafeDispatchTimer { /// Restarts the origin time (deadline) of the timer to "now". /// - /// If the timer has already been started, the origin time will be set to "now" and the timer will continue to run at intervals from "now". + /// If the timer has already been started, the origin time will be set to "now" and the timer + /// will continue to run at intervals from "now". /// - /// If the timer has not yet been started or was previously suspended using `stop()`, the timer will be restarted and the origin time will be set to "now". + /// If the timer has not yet been started or was previously suspended using ``stop()``, the + /// timer + /// will be restarted and the origin time will be set to "now". /// /// - Parameters: - /// - immediate: If `true`, restarts timer and fires immediately then again at each interval. If `false`, restarts timer but first fire does not happen until the first interval is reached then again at each subsequent interval. + /// - immediate: If `true`, restarts timer and fires immediately then again at each interval. + /// If `false`, restarts timer but first fire does not happen until the first interval is + /// reached then again at each subsequent interval. public func restart(firingNow: Bool = true) { // if timer is already running, reschedule the currently running timer // if timer is not running, schedule the timer then start it @@ -91,7 +101,8 @@ public final class SafeDispatchTimer { /// Suspends the timer if it was running. /// - /// The timer can be started again by calling `start()`, preserving the origin time, or `restart()` to reset the origin time to "now". + /// The timer can be started again by calling ``start()``, preserving the origin time, or + /// ``restart(firingNow:)`` to reset the origin time to "now". public func stop() { guard running else { return } running = false diff --git a/Sources/MIDIKitSMF/API Evolution/MIDIKit-0.6.0.swift b/Sources/MIDIKitSMF/API Evolution/MIDIKit-0.6.0.swift index d5bddee565..b7a56defb3 100644 --- a/Sources/MIDIKitSMF/API Evolution/MIDIKit-0.6.0.swift +++ b/Sources/MIDIKitSMF/API Evolution/MIDIKit-0.6.0.swift @@ -1,7 +1,7 @@ // // MIDIKit-0.6.0.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitSMF/MIDIFile/Chunk/Chunk.swift b/Sources/MIDIKitSMF/MIDIFile/Chunk/Chunk.swift index ee7f00a2ad..38e3e682b9 100644 --- a/Sources/MIDIKitSMF/MIDIFile/Chunk/Chunk.swift +++ b/Sources/MIDIKitSMF/MIDIFile/Chunk/Chunk.swift @@ -1,7 +1,7 @@ // // Chunk.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -10,9 +10,11 @@ import MIDIKitCore extension MIDIFile { /// MIDI File Chunk. /// - /// As of the Standard MIDI File 1.0 Spec, `MThd` (header) and `MTrk` (track) are the only defined MIDI file chunks. However, others may be defined in the future. + /// As of the Standard MIDI File 1.0 Spec, `MThd` (header) and `MTrk` (track) are the only + /// defined MIDI file chunks. However, others may be defined in the future. /// - /// In ``MIDIFile``, the ``Chunk/Header`` chunk is managed automatically and is not instanced as a ``MIDIFile/chunks`` member. + /// In ``MIDIFile``, the ``Chunk/Header`` chunk is managed automatically and is not instanced as + /// a ``MIDIFile/chunks`` member. public enum Chunk: Equatable { case track(Track) case other(UnrecognizedChunk) @@ -43,7 +45,8 @@ CustomDebugStringConvertible { } extension MIDIFile.Chunk { - /// Unwraps the enum case and returns the ``MIDIFile/Chunk`` contained within, typed as ``MIDIFileChunk`` protocol. + /// Unwraps the enum case and returns the ``MIDIFile/Chunk`` contained within, typed as + /// ``MIDIFileChunk`` protocol. public var unwrappedChunk: MIDIFileChunk { switch self { case let .track(chunk): diff --git a/Sources/MIDIKitSMF/MIDIFile/Chunk/Header.swift b/Sources/MIDIKitSMF/MIDIFile/Chunk/Header.swift index 5666a858bf..0de3881674 100644 --- a/Sources/MIDIKitSMF/MIDIFile/Chunk/Header.swift +++ b/Sources/MIDIKitSMF/MIDIFile/Chunk/Header.swift @@ -1,7 +1,7 @@ // // Header.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -11,22 +11,27 @@ import MIDIKitCore // // Header Chunks // -// The header chunk at the beginning of the file specifies some basic information about the data in the file. Here's the syntax of the complete chunk: +// The header chunk at the beginning of the file specifies some basic information about the data in +// the file. Here's the syntax of the complete chunk: // //
= // -// is the four ASCII characters 'MThd'; is a 32-bit representation of the number 6 (high byte first). +// is the four ASCII characters 'MThd'; is a 32-bit representation of the +// number 6 (high byte first). // // The data section contains three 16-bit words, stored most-significant byte first. // -// The first word, , specifies the overall organization of the file. Only three values of are specified: +// The first word, , specifies the overall organization of the file. Only three values of +// are specified: // - 0 the file contains a single multi-channel track // - 1 the file contains one or more simultaneous tracks (or MIDI outputs) of a sequence // - 2 the file contains one or more sequentially independent single-track patterns // -// The next word, , is the number of track chunks in the file. It will always be 1 for a format 0 file. +// The next word, , is the number of track chunks in the file. It will always be 1 for a +// format 0 file. // -// The third word, , specifies the meaning of the delta-times. It has two formats, one for metrical time, and one for time-code-based time: +// The third word, , specifies the meaning of the delta-times. It has two formats, one for +// metrical time, and one for time-code-based time: // --------------------------------------------- // | 0 | ticks per quarter-note | // --------------------------------------------- @@ -35,20 +40,38 @@ import MIDIKitCore // --------------------------------------------- // 15 14 8 7 0 // -// If bit 15 of is a zero, the bits 14 thru 0 represent the number of delta-time "ticks" which make up a quarter-note. -// For instance, if is 96, then a time interval of an eighth-note between two events in the file would be 48. +// If bit 15 of is a zero, the bits 14 thru 0 represent the number of delta-time "ticks" +// which make up a quarter-note. +// For instance, if is 96, then a time interval of an eighth-note between two events in +// the file would be 48. // -// If bit 15 of is a one, delta-times in a file correspond to subdivisions of a second, in a way consistent with SMPTE and MIDI time code. Bits 14 thru 8 contain one of the four values -24, -25, -29, or -30, corresponding to the four standard SMPTE and MIDI time code formats (-29 corresponds to 30 drop frame), and represents the number of frames per second. These negative numbers are stored in two's complement form. The second byte (stored positive) is the resolution within a frame: typical values may be 4 (MIDI time code resolution), 8, 10, 80 (bit resolution), or 100. This system allows exact specification of time-code-based tracks, but also allows millisecond-based tracks by specifying 25 frames/sec and a resolution of 40 units per frame. If the events in a file are stored with bit resolution of thirty-frame time code, the division word would be E250 hex. +// If bit 15 of is a one, delta-times in a file correspond to subdivisions of a second, +// in a way consistent with SMPTE and MIDI time code. Bits 14 thru 8 contain one of the four values +// -24, -25, -29, or -30, corresponding to the four standard SMPTE and MIDI time code formats (-29 +// corresponds to 30 drop frame), and represents the number of frames per second. These negative +// numbers are stored in two's complement form. The second byte (stored positive) is the resolution +// within a frame: typical values may be 4 (MIDI time code resolution), 8, 10, 80 (bit resolution), +// or 100. This system allows exact specification of time-code-based tracks, but also allows +// millisecond-based tracks by specifying 25 frames/sec and a resolution of 40 units per frame. If +// the events in a file are stored with bit resolution of thirty-frame time code, the division word +// would be E250 hex. // // MIDI File Format: -// A Format 0 file has a header chunk followed by one track chunk. It is the most interchangeable representation of data. +// A Format 0 file has a header chunk followed by one track chunk. It is the most interchangeable +// representation of data. // A Format 1 or 2 file has a header chunk followed by one or more track chunks. // // Tempo: -// All MIDI Files should specify tempo and time signature. If they don't, the time signature is assumed to be 4/4, and the tempo 120 beats per minute. In format 0, these meta-events should occur at least at the beginning of the single multi-channel track. In format 1, these meta- events should be contained in the first track. In format 2, each of the temporally independent patterns should contain at least initial time signature and tempo information. +// All MIDI Files should specify tempo and time signature. If they don't, the time signature is +// assumed to be 4/4, and the tempo 120 beats per minute. In format 0, these meta-events should +// occur at least at the beginning of the single multi-channel track. In format 1, these meta- +// events should be contained in the first track. In format 2, each of the temporally independent +// patterns should contain at least initial time signature and tempo information. // NOTE: -// To allow for future expansion, a MIDI file reader should skip over (ie ignore) any chunk types that it does not know about (ie: besides MThd and MTrk), which it can easily do by reading the offending chunk's chunklen. +// To allow for future expansion, a MIDI file reader should skip over (ie ignore) any chunk types +// that it does not know about (ie: besides MThd and MTrk), which it can easily do by reading the +// offending chunk's chunklen. // MARK: - Header @@ -194,12 +217,15 @@ extension MIDIFile.Chunk.Header { data += UInt16(1).toData(.bigEndian) // only 1 track allowed } else { - // For format 1 or 2 files, track count can be any value. There is no limitation as far as the file format is concerned, though sequencer software will generally impose a practical limit. + // For format 1 or 2 files, track count can be any value. There is no limitation as far + // as the file format is concerned, though sequencer software will generally impose a + // practical limit. data += UInt16(withChunkCount).toData(.bigEndian) } // Time division: ticks per quarter note - // Specifies the timing interval to be used, and whether timecode (Hrs.Mins.Secs.Frames) or metrical (Bar.Beat) timeBase is to be used. + // Specifies the timing interval to be used, and whether timecode (Hrs.Mins.Secs.Frames) or + // metrical (Bar.Beat) timeBase is to be used. // 15-bit variable-length encoded value: big endian, with top bit reserved for timecode flag // Bit 15 = 0 : metrical timeBase // Bit 15 = 1 : timecode diff --git a/Sources/MIDIKitSMF/MIDIFile/Chunk/Track.swift b/Sources/MIDIKitSMF/MIDIFile/Chunk/Track.swift index 07df1d8e68..5f6509c484 100644 --- a/Sources/MIDIKitSMF/MIDIFile/Chunk/Track.swift +++ b/Sources/MIDIKitSMF/MIDIFile/Chunk/Track.swift @@ -1,7 +1,7 @@ // // Track.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -207,7 +207,8 @@ extension MIDIFile.Chunk.Track { } } else { - // throw an error since no events could be decoded and there are still bytes remaining in the chunk + // throw an error since no events could be decoded and there are still bytes + // remaining in the chunk let byteOffsetString = dataReader.readOffset .hexString(padTo: 1, prefix: true) diff --git a/Sources/MIDIKitSMF/MIDIFile/Chunk/UnrecognizedChunk.swift b/Sources/MIDIKitSMF/MIDIFile/Chunk/UnrecognizedChunk.swift index e43b4b39bf..ffcb895fd6 100644 --- a/Sources/MIDIKitSMF/MIDIFile/Chunk/UnrecognizedChunk.swift +++ b/Sources/MIDIKitSMF/MIDIFile/Chunk/UnrecognizedChunk.swift @@ -1,7 +1,7 @@ // // UnrecognizedChunk.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitSMF/MIDIFile/MIDIFile Constants.swift b/Sources/MIDIKitSMF/MIDIFile/MIDIFile Constants.swift index f696d252fa..35814746de 100644 --- a/Sources/MIDIKitSMF/MIDIFile/MIDIFile Constants.swift +++ b/Sources/MIDIKitSMF/MIDIFile/MIDIFile Constants.swift @@ -1,7 +1,7 @@ // // MIDIFile Constants.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitSMF/MIDIFile/MIDIFile CustomStringConvertible.swift b/Sources/MIDIKitSMF/MIDIFile/MIDIFile CustomStringConvertible.swift index e91fbaa091..e634af1592 100644 --- a/Sources/MIDIKitSMF/MIDIFile/MIDIFile CustomStringConvertible.swift +++ b/Sources/MIDIKitSMF/MIDIFile/MIDIFile CustomStringConvertible.swift @@ -1,7 +1,7 @@ // // MIDIFile CustomStringConvertible.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitSMF/MIDIFile/MIDIFile Errors.swift b/Sources/MIDIKitSMF/MIDIFile/MIDIFile Errors.swift index 2a5d163434..4ebfab9229 100644 --- a/Sources/MIDIKitSMF/MIDIFile/MIDIFile Errors.swift +++ b/Sources/MIDIKitSMF/MIDIFile/MIDIFile Errors.swift @@ -1,7 +1,7 @@ // // MIDIFile Errors.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitSMF/MIDIFile/MIDIFile Utilities.swift b/Sources/MIDIKitSMF/MIDIFile/MIDIFile Utilities.swift index cdc619223e..a9f7290aee 100644 --- a/Sources/MIDIKitSMF/MIDIFile/MIDIFile Utilities.swift +++ b/Sources/MIDIKitSMF/MIDIFile/MIDIFile Utilities.swift @@ -1,7 +1,7 @@ // // MIDIFile Utilities.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -46,20 +46,23 @@ extension MIDIFile { /// Utility: /// Returns the decoded value and the number of bytes read from the bytes array if successful. - /// Returns nil if bytes is empty or variable length value could not be read in the expected format (ie: malformed or unexpected data) + /// Returns nil if bytes is empty or variable length value could not be read in the expected + /// format (ie: malformed or unexpected data) /// Currently returns nil if value overflows a 28-bit unsigned value. static func decodeVariableLengthValue(from bytes: D) -> ( value: Int, byteLength: Int )? { - // make mutable so we can call the `inout` overload of this method and not duplicate code here + // make mutable so we can call the `inout` overload of this method and not duplicate code + // here var bytes = bytes return decodeVariableLengthValue(from: &bytes) } /// Utility: /// Returns the decoded value and the number of bytes read from the bytes array if successful. - /// Returns nil if bytes is empty or variable length value could not be read in the expected format (ie: malformed or unexpected data) + /// Returns nil if bytes is empty or variable length value could not be read in the expected + /// format (ie: malformed or unexpected data) /// Currently returns nil if value overflows a 28-bit unsigned value. static func decodeVariableLengthValue(from bytes: inout D) -> ( value: Int, @@ -110,7 +113,8 @@ extension MIDIFile { extension MutableDataProtocol { mutating func append(deltaTime ticks: UInt32) { // Variable length delta timestamp representing the number of ticks that have elapsed - // According to the Standard MIDI File 1.0 Spec, the entire delta-time should be at most 4 bytes long. + // According to the Standard MIDI File 1.0 Spec, the entire delta-time should be at most 4 + // bytes long. append(contentsOf: MIDIFile.encodeVariableLengthValue(ticks) as Self) } diff --git a/Sources/MIDIKitSMF/MIDIFile/MIDIFile decode.swift b/Sources/MIDIKitSMF/MIDIFile/MIDIFile decode.swift index 3636915e34..5e9bb6a9fa 100644 --- a/Sources/MIDIKitSMF/MIDIFile/MIDIFile decode.swift +++ b/Sources/MIDIKitSMF/MIDIFile/MIDIFile decode.swift @@ -1,7 +1,7 @@ // // MIDIFile decode.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitSMF/MIDIFile/MIDIFile encode.swift b/Sources/MIDIKitSMF/MIDIFile/MIDIFile encode.swift index dd07b0a7b5..0cd59aa0d7 100644 --- a/Sources/MIDIKitSMF/MIDIFile/MIDIFile encode.swift +++ b/Sources/MIDIKitSMF/MIDIFile/MIDIFile encode.swift @@ -1,7 +1,7 @@ // // MIDIFile encode.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitSMF/MIDIFile/MIDIFile.swift b/Sources/MIDIKitSMF/MIDIFile/MIDIFile.swift index d264c95ed9..769d7eebb7 100644 --- a/Sources/MIDIKitSMF/MIDIFile/MIDIFile.swift +++ b/Sources/MIDIKitSMF/MIDIFile/MIDIFile.swift @@ -1,7 +1,7 @@ // // MIDIFile.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -29,7 +29,8 @@ public struct MIDIFile: Equatable { /// Storage for tracks in the MIDI file. /// - /// The ``Chunk/Header`` chunk is managed automatically and is not instanced as a ``MIDIFile/chunks`` member. + /// The ``Chunk/Header`` chunk is managed automatically and is not instanced as a + /// ``MIDIFile/chunks`` member. public var chunks: [Chunk] = [] // MARK: - Init diff --git a/Sources/MIDIKitSMF/MIDIFile/Types/Format.swift b/Sources/MIDIKitSMF/MIDIFile/Types/Format.swift index c0f10c2b92..e0e8c30807 100644 --- a/Sources/MIDIKitSMF/MIDIFile/Types/Format.swift +++ b/Sources/MIDIKitSMF/MIDIFile/Types/Format.swift @@ -1,7 +1,7 @@ // // Format.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore @@ -11,11 +11,14 @@ import MIDIKitCore extension MIDIFile { public enum Format: UInt8, CaseIterable, Equatable { /// Type 0: - /// MIDI file contains one single track containing midi data on possibly all 16 midi channels. + /// MIDI file contains one single track containing midi data on possibly all 16 midi + /// channels. case singleTrack = 0 /// Type 1: - /// MIDI file contains one or more simultaneous (ie, all start from an assumed time of 0) tracks, perhaps each on a single midi channel. Together, all of these tracks are considered one sequence or pattern. + /// MIDI file contains one or more simultaneous (ie, all start from an assumed time of 0) + /// tracks, perhaps each on a single midi channel. Together, all of these tracks are + /// considered one sequence or pattern. case multipleTracksSynchronous = 1 /// Type 2: diff --git a/Sources/MIDIKitSMF/MIDIFile/Types/FrameRate.swift b/Sources/MIDIKitSMF/MIDIFile/Types/FrameRate.swift index 4fcc92ae6e..8b32ecd06c 100644 --- a/Sources/MIDIKitSMF/MIDIFile/Types/FrameRate.swift +++ b/Sources/MIDIKitSMF/MIDIFile/Types/FrameRate.swift @@ -1,7 +1,7 @@ // // FrameRate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore @@ -10,10 +10,13 @@ import MIDIKitCore extension MIDIFile { /// Timecode Frame Rate - /// (For use in the MIDI file header when ``TimeBase-swift.enum/timecode(smpteFormat:ticksPerFrame:)`` timebase is selected.) + /// (For use in the MIDI file header when + /// ``TimeBase-swift.enum/timecode(smpteFormat:ticksPerFrame:)`` timebase is selected.) /// /// MIDI file header time division 2-byte value: - /// Bits 8 - 15 (i.e. the first byte) specifies the number of frames per second (fps), and will be one of the four SMPTE standards - 24, 25, 29d or 30, though expressed as a negative value (using 2's complement notation), as follows: + /// Bits 8 - 15 (i.e. the first byte) specifies the number of frames per second (fps), and will + /// be one of the four SMPTE standards - 24, 25, 29d or 30, though expressed as a negative value + /// (using 2's complement notation), as follows: /// /// - 24fps: `0xE8` /// - 25fps: `0xE7` diff --git a/Sources/MIDIKitSMF/MIDIFile/Types/SMPTEOffsetFrameRate.swift b/Sources/MIDIKitSMF/MIDIFile/Types/SMPTEOffsetFrameRate.swift index c03460698b..851de2ba9f 100644 --- a/Sources/MIDIKitSMF/MIDIFile/Types/SMPTEOffsetFrameRate.swift +++ b/Sources/MIDIKitSMF/MIDIFile/Types/SMPTEOffsetFrameRate.swift @@ -1,7 +1,7 @@ // // SMPTEOffsetFrameRate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitSMF/MIDIFile/Types/TimeBase.swift b/Sources/MIDIKitSMF/MIDIFile/Types/TimeBase.swift index f314301601..2c100c9369 100644 --- a/Sources/MIDIKitSMF/MIDIFile/Types/TimeBase.swift +++ b/Sources/MIDIKitSMF/MIDIFile/Types/TimeBase.swift @@ -1,7 +1,7 @@ // // TimeBase.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -21,9 +21,11 @@ extension MIDIFile { /// SMPTE Timecode /// - /// Typical `ticksPerFrame` values are 4 (corresponding to MIDI Timecode), 8, 10, 80 (corresponding to SMPTE bit resolution), or 100. + /// Typical `ticksPerFrame` values are 4 (corresponding to MIDI Timecode), 8, 10, + /// 80 (corresponding to SMPTE bit resolution), or 100. /// - /// (A timing resolution of 1 ms can be achieved by specifying 25 fps and 40 sub-frames, which would be encoded in hex as E7 28.) + /// (A timing resolution of 1 ms can be achieved by specifying 25 fps and 40 sub-frames, + /// which would be encoded in hex as E7 28.) case timecode(smpteFormat: FrameRate, ticksPerFrame: UInt8) } } diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/DeltaTime/DeltaTime.swift b/Sources/MIDIKitSMF/MIDIFileEvent/DeltaTime/DeltaTime.swift index 88bf0d7be8..924339ea51 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/DeltaTime/DeltaTime.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/DeltaTime/DeltaTime.swift @@ -1,7 +1,7 @@ // // DeltaTime.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Darwin diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Event Conversion.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Event Conversion.swift index f466e688b7..45e761320e 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Event Conversion.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Event Conversion.swift @@ -1,13 +1,14 @@ // // Event Conversion.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore extension MIDIEvent { - /// Convert the MIDIKit I/O event case (``MIDIEvent``) to a MIDIKitSMF event case (``MIDIFileEvent``). + /// Convert the MIDIKit I/O event case (``MIDIEvent``) to a MIDIKitSMF event case + /// (``MIDIFileEvent``). /// /// Not all MIDI I/O events translate to MIDI File events, in which case `nil` will be returned. public func smfEvent(delta: MIDIFileEvent.DeltaTime) -> MIDIFileEvent? { @@ -83,7 +84,8 @@ extension MIDIEvent { } extension MIDIFileEvent { - /// Convert the MIDIKitSMF event case (``MIDIFileEvent``) to a MIDIKit I/O event case (``MIDIEvent``). + /// Convert the MIDIKitSMF event case (``MIDIFileEvent``) to a MIDIKit I/O event case + /// (``MIDIEvent``). /// /// Not all MIDI File events translate to MIDI I/O events, in which case `nil` will be returned. public func event() -> MIDIEvent? { diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event CC.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event CC.swift index afb3f4ca93..967998cc0f 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event CC.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event CC.swift @@ -1,7 +1,7 @@ // // Event CC.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event ChannelPrefix.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event ChannelPrefix.swift index 5464ba6cbb..59eea834df 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event ChannelPrefix.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event ChannelPrefix.swift @@ -1,7 +1,7 @@ // // Event ChannelPrefix.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -22,7 +22,12 @@ extension MIDIFileEvent { /// /// > Standard MIDI File 1.0 Spec: /// > - /// > The MIDI channel (`0 ... 15`) contained in this event may be used to associate a MIDI channel with all events which follow, including System Exclusive and meta-events. This channel is "effective" until the next normal MIDI event (which contains a channel) or the next MIDI Channel Prefix meta-event. If MIDI channels refer to "tracks", this message may help jam several tracks into a format 0 file, keeping their non-MIDI data associated with a track. This capability is also present in Yamaha's ESEQ file format. + /// > The MIDI channel (`0 ... 15`) contained in this event may be used to associate a MIDI + /// channel with all events which follow, including System Exclusive and meta-events. This + /// channel is "effective" until the next normal MIDI event (which contains a channel) or the + /// next MIDI Channel Prefix meta-event. If MIDI channels refer to "tracks", this message may + /// help jam several tracks into a format 0 file, keeping their non-MIDI data associated with a + /// track. This capability is also present in Yamaha's ESEQ file format. public struct ChannelPrefix: Equatable, Hashable { /// Channel (`1 ... 16`) is stored zero-based (`0 ... 15`). public var channel: UInt4 = 0 @@ -42,7 +47,12 @@ extension MIDIFileEvent { /// /// > Standard MIDI File 1.0 Spec: /// > - /// > The MIDI channel (`0 ... 15`) contained in this event may be used to associate a MIDI channel with all events which follow, including System Exclusive and meta-events. This channel is "effective" until the next normal MIDI event (which contains a channel) or the next MIDI Channel Prefix meta-event. If MIDI channels refer to "tracks", this message may help jam several tracks into a format 0 file, keeping their non-MIDI data associated with a track. This capability is also present in Yamaha's ESEQ file format. + /// > The MIDI channel (`0 ... 15`) contained in this event may be used to associate a MIDI + /// channel with all events which follow, including System Exclusive and meta-events. This + /// channel is "effective" until the next normal MIDI event (which contains a channel) or the + /// next MIDI Channel Prefix meta-event. If MIDI channels refer to "tracks", this message may + /// help jam several tracks into a format 0 file, keeping their non-MIDI data associated with a + /// track. This capability is also present in Yamaha's ESEQ file format. public static func channelPrefix( delta: DeltaTime = .none, channel: UInt4 diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event KeySignature.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event KeySignature.swift index dd1b09d691..0a109541b0 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event KeySignature.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event KeySignature.swift @@ -1,7 +1,7 @@ // // Event KeySignature.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -21,7 +21,8 @@ import MIDIKitInternals extension MIDIFileEvent { /// Key Signature event. /// - /// For a format 1 MIDI file, Key Signature Meta events should only occur within the first `MTrk` chunk. + /// For a format 1 MIDI file, Key Signature Meta events should only occur within the first + /// `MTrk` chunk. /// /// If there are no key signature events in a MIDI file, C major is assumed. public struct KeySignature: Equatable, Hashable { @@ -57,7 +58,8 @@ extension MIDIFileEvent { extension MIDIFileEvent { /// Key Signature event. /// - /// For a format 1 MIDI file, Key Signature Meta events should only occur within the first `MTrk` chunk. + /// For a format 1 MIDI file, Key Signature Meta events should only occur within the first + /// `MTrk` chunk. /// /// If there are no key signature events in a MIDI file, C major is assumed. public static func keySignature( @@ -121,7 +123,8 @@ extension MIDIFileEvent.KeySignature: MIDIFileEventPayload { public func midi1SMFRawBytes() -> D { // FF 59 02(length) sf mi - // sf is a byte specifying the number of flats (-ve) or sharps (+ve) that identifies the key signature (-7 = 7 flats, -1 = 1 flat, 0 = key of C, 1 = 1 sharp, etc). + // sf is a byte specifying the number of flats (-ve) or sharps (+ve) that identifies the + // key signature (-7 = 7 flats, -1 = 1 flat, 0 = key of C, 1 = 1 sharp, etc). // mi is a byte specifying a major (0) or minor (1) key. D( diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Note Off.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Note Off.swift index f677dadbfe..aca81e2e32 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Note Off.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Note Off.swift @@ -1,7 +1,7 @@ // // Event Note Off.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Note On.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Note On.swift index 4cdf34bfcd..562ce6a0be 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Note On.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Note On.swift @@ -1,7 +1,7 @@ // // Event Note On.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Note Pressure.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Note Pressure.swift index 29c4342b0b..52566a4ce6 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Note Pressure.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Note Pressure.swift @@ -1,7 +1,7 @@ // // Event Note Pressure.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event PitchBend.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event PitchBend.swift index 5d93d3af34..541090eaa8 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event PitchBend.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event PitchBend.swift @@ -1,7 +1,7 @@ // // Event PitchBend.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event PortPrefix.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event PortPrefix.swift index 3bc1c3f6cb..0ee0a106a1 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event PortPrefix.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event PortPrefix.swift @@ -1,7 +1,7 @@ // // Event PortPrefix.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Pressure.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Pressure.swift index 110104d5d3..a0da33fbbf 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Pressure.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Pressure.swift @@ -1,7 +1,7 @@ // // Event Pressure.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event ProgramChange.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event ProgramChange.swift index 71cdb865e1..eb60431340 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event ProgramChange.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event ProgramChange.swift @@ -1,7 +1,7 @@ // // Event ProgramChange.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -20,7 +20,9 @@ import MIDIKitCore extension MIDIFileEvent { /// Channel Voice Message: Program Change /// - /// > Note: When decoding, bank information is not decoded as part of the Program Change event but will be decoded as individual CC messages. This may be addressed in a future release of MIDIKit. + /// > Note: When decoding, bank information is not decoded as part of the Program Change event + /// but will be decoded as individual CC messages. This may be addressed in a future release of + /// MIDIKit. public typealias ProgramChange = MIDIEvent.ProgramChange } @@ -29,7 +31,9 @@ extension MIDIFileEvent { extension MIDIFileEvent { /// Channel Voice Message: Program Change /// - /// > Note: When decoding, bank information is not decoded as part of the Program Change event but will be decoded as individual CC messages. This may be addressed in a future release of MIDIKit. + /// > Note: When decoding, bank information is not decoded as part of the Program Change event + /// but will be decoded as individual CC messages. This may be addressed in a future release of + /// MIDIKit. public static func programChange( delta: DeltaTime = .none, program: UInt7, diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SMPTEOffset.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SMPTEOffset.swift index 11353de2bb..8db67dfe19 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SMPTEOffset.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SMPTEOffset.swift @@ -1,7 +1,7 @@ // // Event SMPTEOffset.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -26,10 +26,11 @@ extension MIDIFileEvent { /// /// > Standard MIDI File 1.0 Spec: /// > - /// > MIDI SMPTE Offset subframes (fractional frames) are always in 100ths of a frame, even in SMPTE-based tracks which specify a different frame subdivision for delta-times. + /// > MIDI SMPTE Offset subframes (fractional frames) are always in 100ths of a frame, even in + /// SMPTE-based tracks which specify a different frame subdivision for delta-times. public struct SMPTEOffset: Equatable, Hashable { /// Timecode hour. - /// Valid range: 0-23. + /// Valid range: ` 0 ... 23`. public var hours: UInt8 = 0 { didSet { if oldValue != hours { hours_Validate() } @@ -41,7 +42,7 @@ extension MIDIFileEvent { } /// Timecode minutes. - /// Valid range: 0-59. + /// Valid range: `0 ... 59`. public var minutes: UInt8 = 0 { didSet { if oldValue != minutes { minutes_Validate() } @@ -53,7 +54,7 @@ extension MIDIFileEvent { } /// Timecode seconds. - /// Valid range: 0-59. + /// Valid range: `0 ... 59`. public var seconds: UInt8 = 0 { didSet { if oldValue != seconds { seconds_Validate() } @@ -65,7 +66,8 @@ extension MIDIFileEvent { } /// Timecode frames. - /// Valid range is dependent on the `frameRate` property (0-23 for 24fps, 0-29 for 30fps, etc.). + /// Valid range is dependent on the `frameRate` property + /// (`0 ... 23` for 24fps, `0 ... 29` for 30fps, etc.). public var frames: UInt8 = 0 { didSet { if oldValue != frames { frames_Validate() } @@ -81,8 +83,9 @@ extension MIDIFileEvent { } /// Timecode subframes. - /// Valid range: 0-99. - /// The number of fractional frames, in 100ths of a frame (even in SMPTE-based tracks using a different frame subdivision, defined in the MThd MIDI file header chunk). + /// Valid range: `0 ... 99`. + /// The number of fractional frames, in 100ths of a frame (even in SMPTE-based tracks using + /// a different frame subdivision, defined in the `MThd` MIDI file header chunk). public var subframes: UInt8 = 0 { didSet { if oldValue != subframes { subframes_Validate() } @@ -164,7 +167,8 @@ extension MIDIFileEvent { /// /// > Standard MIDI File 1.0 Spec: /// > - /// > MIDI SMPTE Offset subframes (fractional frames) are always in 100ths of a frame, even in SMPTE-based tracks which specify a different frame subdivision for delta-times. + /// > MIDI SMPTE Offset subframes (fractional frames) are always in 100ths of a frame, even in + /// SMPTE-based tracks which specify a different frame subdivision for delta-times. public static func smpteOffset( delta: DeltaTime = .none, hr: UInt8, @@ -194,7 +198,8 @@ extension MIDIFileEvent { /// /// > Standard MIDI File 1.0 Spec: /// > - /// > MIDI SMPTE Offset subframes (fractional frames) are always in 100ths of a frame, even in SMPTE-based tracks which specify a different frame subdivision for delta-times. + /// > MIDI SMPTE Offset subframes (fractional frames) are always in 100ths of a frame, even in + /// SMPTE-based tracks which specify a different frame subdivision for delta-times. public static func smpteOffset( delta: DeltaTime = .none, scaling: Timecode @@ -290,12 +295,18 @@ extension MIDIFileEvent.SMPTEOffset: MIDIFileEventPayload { // // 05 is length // - // hr is a byte specifying the hour, which is also encoded with the SMPTE format (frame rate), just as it is in MIDI Time Code + // hr is a byte specifying the hour, which is also encoded with the SMPTE format (frame + // rate), just as it is in MIDI Time Code // 8 bits: 0rrhhhhh, where: - // rr = frame rate : 00 = 24 fps, 01 = 25 fps, 10 = 30 fps (drop frame), 11 = 30 fps (non-drop frame) - // hhhhh = hour (0-23) + // - rr = frame rate: + // 00 = 24 fps + // 01 = 25 fps + // 10 = 30 fps (drop frame) + // 11 = 30 fps (non-drop frame) + // - hhhhh = hour (0-23) // - // ff is a byte specifying the number of fractional frames, in 100ths of a frame (even in SMPTE-based tracks using a different frame subdivision, defined in the MThd chunk). + // ff is a byte specifying the number of fractional frames, in 100ths of a frame (even in + // SMPTE-based tracks using a different frame subdivision, defined in the MThd chunk). var data = D() @@ -350,11 +361,14 @@ extension MIDIFileEvent.SMPTEOffset: MIDIFileEventPayload { // MARK: - Helpers extension Timecode { - /// Determines the best corresponding MIDI File SMPTE Offset frame rate to represent this timecode, converts the timecode to that frame rate, and converts the subframes to be scaled to a 100 subframe divisor if needed. + /// Determines the best corresponding MIDI File SMPTE Offset frame rate to represent this + /// timecode, converts the timecode to that frame rate, and converts the subframes to be scaled + /// to a 100 subframe divisor if needed. /// /// > Standard MIDI File 1.0 Spec: /// > - /// > MIDI SMPTE Offset subframes (fractional frames) are always in 100ths of a frame, even in SMPTE- based tracks which specify a different frame subdivision for delta-times. + /// > MIDI SMPTE Offset subframes (fractional frames) are always in 100ths of a frame, even in + /// SMPTE- based tracks which specify a different frame subdivision for delta-times. public var scaledToMIDIFileSMPTEFrameRate: ( scaledTimecode: Timecode?, smpteFR: MIDIFile.SMPTEOffsetFrameRate @@ -388,7 +402,8 @@ extension Timecode { } extension Timecode.FrameRate { - /// Returns the best corresponding MIDI File SMPTE Offset frame rate to represent the timecode framerate. + /// Returns the best corresponding MIDI File SMPTE Offset frame rate to represent the timecode + /// framerate. public var midiFileSMPTEOffsetRate: MIDIFile.SMPTEOffsetFrameRate { switch self { case ._23_976: return ._24fps // as output from Pro Tools diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SequenceNumber.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SequenceNumber.swift index c347e1f55e..24f45c74b6 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SequenceNumber.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SequenceNumber.swift @@ -1,7 +1,7 @@ // // Event SequenceNumber.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -20,7 +20,9 @@ import MIDIKitCore extension MIDIFileEvent { /// Sequence Number event. /// - /// - For MIDI file type 0/1, this should only be on the first track. This is used to identify each track. If omitted, the sequences are numbered sequentially in the order the tracks appear. + /// - For MIDI file type 0/1, this should only be on the first track. This is used to identify + /// each track. If omitted, the sequences are numbered sequentially in the order the tracks + /// appear. /// /// - For MIDI file type 2, each track can contain a sequence number event. public struct SequenceNumber: Equatable, Hashable { @@ -48,7 +50,9 @@ extension MIDIFileEvent { extension MIDIFileEvent { /// Sequence Number event. /// - /// - For MIDI file type 0/1, this should only be on the first track. This is used to identify each track. If omitted, the sequences are numbered sequentially in the order the tracks appear. + /// - For MIDI file type 0/1, this should only be on the first track. This is used to identify + /// each track. If omitted, the sequences are numbered sequentially in the order the tracks + /// appear. /// /// - For MIDI file type 2, each track can contain a sequence number event. public static func sequenceNumber( diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SequencerSpecific.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SequencerSpecific.swift index cf59c94d08..0bac4ffbd9 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SequencerSpecific.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SequencerSpecific.swift @@ -1,7 +1,7 @@ // // Event SequencerSpecific.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SysEx.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SysEx.swift index 21ee9196ff..550a106c23 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SysEx.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event SysEx.swift @@ -1,7 +1,7 @@ // // Event SysEx.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -122,7 +122,8 @@ extension MIDIEvent.SysEx7: MIDIFileEventPayload { extension MIDIFileEvent { /// Universal System Exclusive (7-bit) /// - /// Some standard Universal System Exclusive messages have been defined by the MIDI Spec. See the official MIDI 1.0 and 2.0 specs for details. + /// Some standard Universal System Exclusive messages have been defined by the MIDI Spec. See + /// the official MIDI 1.0 and 2.0 specs for details. /// /// - `deviceID` of `0x7F` indicates "All Devices". public typealias UniversalSysEx7 = MIDIEvent.UniversalSysEx7 @@ -133,7 +134,8 @@ extension MIDIFileEvent { extension MIDIFileEvent { /// Universal System Exclusive (7-bit) /// - /// Some standard Universal System Exclusive messages have been defined by the MIDI Spec. See the official MIDI 1.0 and 2.0 specs for details. + /// Some standard Universal System Exclusive messages have been defined by the MIDI Spec. See + /// the official MIDI 1.0 and 2.0 specs for details. /// /// - `deviceID` of `0x7F` indicates "All Devices". public static func universalSysEx7( diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Tempo.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Tempo.swift index 65c488b42b..f9aa8b9471 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Tempo.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Tempo.swift @@ -1,7 +1,7 @@ // // Event Tempo.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -45,7 +45,8 @@ extension MIDIFileEvent { /// /// - Get: Calculates microseconds-per-quarter note based on `bpm` property. /// - /// - Set: Sets ``bpm`` property to the calculated tempo from the passed microseconds-per-quarter note value. + /// - Set: Sets ``bpm`` property to the calculated tempo from the passed + /// microseconds-per-quarter note value. public var microseconds: UInt32 { get { Self.bpmToMicroseconds(bpm: bpm) diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Text.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Text.swift index 03c345d0bc..5d6f325920 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Text.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event Text.swift @@ -1,7 +1,7 @@ // // Event Text.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -19,16 +19,19 @@ import MIDIKitCore extension MIDIFileEvent { /// Text event. - /// Includes copyright, marker, cue point, track/sequence name, instrument name, generic text, program name, device name, or lyric. + /// Includes copyright, marker, cue point, track/sequence name, instrument name, generic text, + /// program name, device name, or lyric. /// - /// Text is restricted to ASCII format only. If extended characters or encodings are used, it will be converted to ASCII lossily before encoding into the MIDI file. + /// Text is restricted to ASCII format only. If extended characters or encodings are used, it + /// will be converted to ASCII lossily before encoding into the MIDI file. public struct Text: Equatable, Hashable { /// Type of text event. public var textType: EventType = .text /// Text content. /// - /// ASCII text only. If extended characters or encodings are used, it will be converted to ASCII before encoding into the MIDI file. + /// ASCII text only. If extended characters or encodings are used, it will be converted to + /// ASCII before encoding into the MIDI file. /// /// (Arbitrary limit imposed: truncates at 65,536 characters long.) public var text: String = "" { @@ -101,9 +104,11 @@ extension MIDIFileEvent { extension MIDIFileEvent { /// Text event. - /// Includes copyright, marker, cue point, track/sequence name, instrument name, generic text, program name, device name, or lyric. + /// Includes copyright, marker, cue point, track/sequence name, instrument name, generic text, + /// program name, device name, or lyric. /// - /// Text is restricted to ASCII format only. If extended characters or encodings are used, it will be converted to ASCII lossily before encoding into the MIDI file. + /// Text is restricted to ASCII format only. If extended characters or encodings are used, it + /// will be converted to ASCII lossily before encoding into the MIDI file. public static func text( delta: DeltaTime = .none, type: Text.EventType, diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event TimeSignature.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event TimeSignature.swift index ea1fca34b7..0c4bbfa646 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event TimeSignature.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event TimeSignature.swift @@ -1,7 +1,7 @@ // // Event TimeSignature.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -19,7 +19,8 @@ import MIDIKitCore extension MIDIFileEvent { /// Time Signature event. - /// For a format 1 MIDI file, Time Signature meta events should only occur within the first `MTrk` chunk. + /// For a format 1 MIDI file, Time Signature meta events should only occur within the first + /// `MTrk` chunk. /// If there are no Time Signature events in a MIDI file, 4/4 is assumed. public struct TimeSignature: Equatable, Hashable { /// Numerator in time signature fraction: Literal numerator @@ -33,7 +34,8 @@ extension MIDIFileEvent { public var midiClocksBetweenMetronomeClicks: UInt8 = 0x18 /// Number of notated 32nd-notes in a MIDI quarter-note. - /// The usual value for this parameter is 8, though some sequencers allow the user to specify that what MIDI thinks of as a quarter note, should be notated as something else. + /// The usual value for this parameter is 8, though some sequencers allow the user to + /// specify that what MIDI thinks of as a quarter note, should be notated as something else. public var numberOf32ndNotesInAQuarterNote: UInt8 = 8 // MARK: - Init @@ -58,7 +60,8 @@ extension MIDIFileEvent { extension MIDIFileEvent { /// Time Signature event. - /// For a format 1 MIDI file, Time Signature meta events should only occur within the first `MTrk` chunk. + /// For a format 1 MIDI file, Time Signature meta events should only occur within the first + /// `MTrk` chunk. /// If there are no Time Signature events in a MIDI file, 4/4 is assumed. public static func timeSignature( delta: DeltaTime = .none, @@ -117,7 +120,8 @@ extension MIDIFileEvent.TimeSignature: MIDIFileEventPayload { data += [midiClocksBetweenMetronomeClicks] // number of notated 32nd-notes in a MIDI quarter-note (24 MIDI Clocks) - // The usual value for this parameter is 8, though some sequencers allow the user to specify that what MIDI thinks of as a quarter note, should be notated as something else. + // The usual value for this parameter is 8, though some sequencers allow the user to specify + // that what MIDI thinks of as a quarter note, should be notated as something else. data += [numberOf32ndNotesInAQuarterNote] // 8 32nd-notes return data diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event UnrecognizedMeta.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event UnrecognizedMeta.swift index bd7cffeebb..3854621ba7 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event UnrecognizedMeta.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event UnrecognizedMeta.swift @@ -1,7 +1,7 @@ // // Event UnrecognizedMeta.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -20,13 +20,24 @@ import MIDIKitCore extension MIDIFileEvent { /// Unrecognized Meta Event /// - /// > Note: This is not designed to be instanced, but is instead a placeholder for unrecognized or malformed data while parsing the contents of a MIDI file. In then allows for manual parsing or introspection of the unrecognized data. + /// > Note: This is not designed to be instanced, but is instead a placeholder for unrecognized + /// or malformed data while parsing the contents of a MIDI file. In then allows for manual + /// parsing or introspection of the unrecognized data. /// /// > Standard MIDI File 1.0 Spec: /// > - /// > All meta-events begin with `0xFF`, then have an event type byte (which is always less than 128), and then have the length of the data stored as a variable-length quantity, and then the data itself. If there is no data, the length is `0`. As with chunks, future meta-events may be designed which may not be known to existing programs, so programs must properly ignore meta-events which they do not recognize, and indeed, should expect to see them. Programs must never ignore the length of a meta-event which they do recognize, and they shouldn't be surprised if it's bigger than they expected. If so, they must ignore everything past what they know about. However, they must not add anything of their own to the end of a meta-event. + /// > All meta-events begin with `0xFF`, then have an event type byte (which is always less than + /// 128), and then have the length of the data stored as a variable-length quantity, and then + /// the data itself. If there is no data, the length is `0`. As with chunks, future meta-events + /// may be designed which may not be known to existing programs, so programs must properly + /// ignore meta-events which they do not recognize, and indeed, should expect to see them. + /// Programs must never ignore the length of a meta-event which they do recognize, and they + /// shouldn't be surprised if it's bigger than they expected. If so, they must ignore everything + /// past what they know about. However, they must not add anything of their own to the end of a + /// meta-event. /// > - /// > SysEx events and meta-events cancel any running status which was in effect. Running status does not apply to and may not be used for these messages. + /// > SysEx events and meta-events cancel any running status which was in effect. Running status + /// does not apply to and may not be used for these messages. public struct UnrecognizedMeta: Equatable, Hashable { // 0x00 is a known meta type, but just default to it here any way public var metaType: UInt8 = 0x00 @@ -52,13 +63,24 @@ extension MIDIFileEvent { extension MIDIFileEvent { /// Unrecognized Meta Event /// - /// > Note: This is not designed to be instanced, but is instead a placeholder for unrecognized or malformed data while parsing the contents of a MIDI file. In then allows for manual parsing or introspection of the unrecognized data. + /// > Note: This is not designed to be instanced, but is instead a placeholder for unrecognized + /// or malformed data while parsing the contents of a MIDI file. In then allows for manual + /// parsing or introspection of the unrecognized data. /// /// > Standard MIDI File 1.0 Spec: /// > - /// > All meta-events begin with `0xFF`, then have an event type byte (which is always less than 128), and then have the length of the data stored as a variable-length quantity, and then the data itself. If there is no data, the length is `0`. As with chunks, future meta-events may be designed which may not be known to existing programs, so programs must properly ignore meta-events which they do not recognize, and indeed, should expect to see them. Programs must never ignore the length of a meta-event which they do recognize, and they shouldn't be surprised if it's bigger than they expected. If so, they must ignore everything past what they know about. However, they must not add anything of their own to the end of a meta-event. + /// > All meta-events begin with `0xFF`, then have an event type byte (which is always less than + /// 128), and then have the length of the data stored as a variable-length quantity, and then + /// the data itself. If there is no data, the length is `0`. As with chunks, future meta-events + /// may be designed which may not be known to existing programs, so programs must properly + /// ignore meta-events which they do not recognize, and indeed, should expect to see them. + /// Programs must never ignore the length of a meta-event which they do recognize, and they + /// shouldn't be surprised if it's bigger than they expected. If so, they must ignore everything + /// past what they know about. However, they must not add anything of their own to the end of a + /// meta-event. /// > - /// > SysEx events and meta-events cancel any running status which was in effect. Running status does not apply to and may not be used for these messages. + /// > SysEx events and meta-events cancel any running status which was in effect. Running status + /// does not apply to and may not be used for these messages. public static func unrecognizedMeta( delta: DeltaTime = .none, metaType: UInt8, diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event XMFPatchTypePrefix.swift b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event XMFPatchTypePrefix.swift index 3f9339601e..fffcba3f35 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event XMFPatchTypePrefix.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/Events/Event XMFPatchTypePrefix.swift @@ -1,7 +1,7 @@ // // Event XMFPatchTypePrefix.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -22,11 +22,20 @@ extension MIDIFileEvent { /// /// > Standard MIDI File 1.0 Spec: /// > - /// > XMF Type 0 and Type 1 files contain Standard MIDI Files (SMF). Each SMF Track in such XMF files may be designated to use either standard General MIDI 1 or General MIDI 2 instruments supplied by the player, or custom DLS instruments supplied via the XMF file. This document defines a new SMF Meta-Event to be used for this purpose. + /// > XMF Type 0 and Type 1 files contain Standard MIDI Files (SMF). Each SMF Track in such XMF + /// > files may be designated to use either standard General MIDI 1 or General MIDI 2 instruments + /// > supplied by the player, or custom DLS instruments supplied via the XMF file. This document + /// > defines a new SMF Meta-Event to be used for this purpose. /// > - /// > In a Type 0 or Type 1 XMF File, this meta-event specifies how to interpret subsequent Program Change and Bank Select messages appearing in the same SMF Track: as General MIDI 1, General MIDI 2, or DLS. In the absence of an initial XMF Patch Type Prefix Meta-Event, General MIDI 1 (instrument set and system behavior) is chosen by default. + /// > In a Type 0 or Type 1 XMF File, this meta-event specifies how to interpret subsequent + /// > Program Change and Bank Select messages appearing in the same SMF Track: as General MIDI 1, + /// > General MIDI 2, or DLS. In the absence of an initial XMF Patch Type Prefix Meta-Event, + /// > General MIDI 1 (instrument set and system behavior) is chosen by default. /// > - /// > In a Type 0 or Type 1 XMF File, no SMF Track may be reassigned to a different instrument set (GM1, GM2, or DLS) at any time. Therefore, this meta-event should only be processed if it appears as the first message in an SMF Track; if it appears anywhere else in an SMF Track, it must be ignored. + /// > In a Type 0 or Type 1 XMF File, no SMF Track may be reassigned to a different instrument + /// > set (GM1, GM2, or DLS) at any time. Therefore, this meta-event should only be processed if + /// > it appears as the first message in an SMF Track; if it appears anywhere else in an SMF + /// > Track, it must be ignored. /// > /// > See [RP-032](https://www.midi.org/specifications/file-format-specifications/standard-midi-files/xmf-patch-type-prefix-meta-event). public struct XMFPatchTypePrefix: Equatable, Hashable { diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/MIDIFileEvent Properties.swift b/Sources/MIDIKitSMF/MIDIFileEvent/MIDIFileEvent Properties.swift index 7387dc7cc0..3fa35df118 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/MIDIFileEvent Properties.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/MIDIFileEvent Properties.swift @@ -1,7 +1,7 @@ // // MIDIFileEvent Properties.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -36,7 +36,8 @@ extension MIDIFileEvent { } extension MIDIFileEvent { - /// Returns the concrete type that contains the event payload, typed as ``MIDIFileEventPayload`` protocol. + /// Returns the concrete type that contains the event payload, typed as ``MIDIFileEventPayload`` + /// protocol. public var concreteType: MIDIFileEventPayload.Type { switch self { case .cc: return CC.self @@ -64,7 +65,8 @@ extension MIDIFileEvent { } extension MIDIFileEvent { - /// Unwraps the enum case and returns the ``MIDIFileEvent`` contained within, typed as ``MIDIFileEventPayload`` protocol. + /// Unwraps the enum case and returns the ``MIDIFileEvent`` contained within, typed as + /// ``MIDIFileEventPayload`` protocol. public var smfUnwrappedEvent: ( delta: DeltaTime, event: MIDIFileEventPayload diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/MIDIFileEvent.swift b/Sources/MIDIKitSMF/MIDIFileEvent/MIDIFileEvent.swift index da82a6d7cf..88a0f4154f 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/MIDIFileEvent.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/MIDIFileEvent.swift @@ -1,7 +1,7 @@ // // MIDIFileEvent.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore @@ -23,7 +23,12 @@ public enum MIDIFileEvent: Equatable, Hashable { /// /// > Standard MIDI File 1.0 Spec: /// > - /// > The MIDI channel (`0 ... 15`) contained in this event may be used to associate a MIDI channel with all events which follow, including System Exclusive and meta-events. This channel is "effective" until the next normal MIDI event (which contains a channel) or the next MIDI Channel Prefix meta-event. If MIDI channels refer to "tracks", this message may help jam several tracks into a format 0 file, keeping their non-MIDI data associated with a track. This capability is also present in Yamaha's ESEQ file format. + /// > The MIDI channel (`0 ... 15`) contained in this event may be used to associate a MIDI + /// > channel with all events which follow, including System Exclusive and meta-events. This + /// > channel is "effective" until the next normal MIDI event (which contains a channel) or the + /// > next MIDI Channel Prefix meta-event. If MIDI channels refer to "tracks", this message may + /// > help jam several tracks into a format 0 file, keeping their non-MIDI data associated with + /// > a track. This capability is also present in Yamaha's ESEQ file format. case channelPrefix(delta: DeltaTime, event: ChannelPrefix) /// Key Signature event. @@ -118,24 +123,45 @@ public enum MIDIFileEvent: Equatable, Hashable { /// Unrecognized Meta Event. /// - /// > Note: This is not designed to be instanced, but is instead a placeholder for unrecognized or malformed data while parsing the contents of a MIDI file. In then allows for manual parsing or introspection of the unrecognized data. + /// > Note: This is not designed to be instanced, but is instead a placeholder for unrecognized + /// > or malformed data while parsing the contents of a MIDI file. In then allows for manual + /// > parsing or introspection of the unrecognized data. /// /// > Standard MIDI File 1.0 Spec: /// > - /// > All meta-events begin with `0xFF`, then have an event type byte (which is always less than 128), and then have the length of the data stored as a variable-length quantity, and then the data itself. If there is no data, the length is `0`. As with chunks, future meta-events may be designed which may not be known to existing programs, so programs must properly ignore meta-events which they do not recognize, and indeed, should expect to see them. Programs must never ignore the length of a meta-event which they do recognize, and they shouldn't be surprised if it's bigger than they expected. If so, they must ignore everything past what they know about. However, they must not add anything of their own to the end of a meta-event. + /// > All meta-events begin with `0xFF`, then have an event type byte (which is always less than + /// > 128), and then have the length of the data stored as a variable-length quantity, and then + /// > the data itself. If there is no data, the length is `0`. As with chunks, future + /// > meta-events may be designed which may not be known to existing programs, so programs must + /// > properly ignore meta-events which they do not recognize, and indeed, should expect to see + /// > them. + /// > Programs must never ignore the length of a meta-event which they do recognize, and they + /// > shouldn't be surprised if it's bigger than they expected. If so, they must ignore + /// > everything past what they know about. However, they must not add anything of their own to + /// > the end of a meta-event. /// > - /// > SysEx events and meta-events cancel any running status which was in effect. Running status does not apply to and may not be used for these messages. + /// > SysEx events and meta-events cancel any running status which was in effect. Running status + /// > does not apply to and may not be used for these messages. case unrecognizedMeta(delta: DeltaTime, event: UnrecognizedMeta) /// XMF Patch Type Prefix event. /// /// > Standard MIDI File 1.0 Spec: /// > - /// > XMF Type 0 and Type 1 files contain Standard MIDI Files (SMF). Each SMF Track in such XMF files may be designated to use either standard General MIDI 1 or General MIDI 2 instruments supplied by the player, or custom DLS instruments supplied via the XMF file. This document defines a new SMF Meta-Event to be used for this purpose. + /// > XMF Type 0 and Type 1 files contain Standard MIDI Files (SMF). Each SMF Track in such XMF + /// > files may be designated to use either standard General MIDI 1 or General MIDI 2 + /// > instruments supplied by the player, or custom DLS instruments supplied via the XMF file. + /// > This document defines a new SMF Meta-Event to be used for this purpose. /// > - /// > In a Type 0 or Type 1 XMF File, this meta-event specifies how to interpret subsequent Program Change and Bank Select messages appearing in the same SMF Track: as General MIDI 1, General MIDI 2, or DLS. In the absence of an initial XMF Patch Type Prefix Meta-Event, General MIDI 1 (instrument set and system behavior) is chosen by default. + /// > In a Type 0 or Type 1 XMF File, this meta-event specifies how to interpret subsequent + /// > Program Change and Bank Select messages appearing in the same SMF Track: as General MIDI + /// > 1, General MIDI 2, or DLS. In the absence of an initial XMF Patch Type Prefix Meta-Event, + /// > General MIDI 1 (instrument set and system behavior) is chosen by default. /// > - /// > In a Type 0 or Type 1 XMF File, no SMF Track may be reassigned to a different instrument set (GM1, GM2, or DLS) at any time. Therefore, this meta-event should only be processed if it appears as the first message in an SMF Track; if it appears anywhere else in an SMF Track, it must be ignored. + /// > In a Type 0 or Type 1 XMF File, no SMF Track may be reassigned to a different instrument + /// > set (GM1, GM2, or DLS) at any time. Therefore, this meta-event should only be processed if + /// > it appears as the first message in an SMF Track; if it appears anywhere else in an SMF + /// > Track, it must be ignored. /// > /// > See [RP-032](https://www.midi.org/specifications/file-format-specifications/standard-midi-files/xmf-patch-type-prefix-meta-event). case xmfPatchTypePrefix(delta: DeltaTime, event: XMFPatchTypePrefix) diff --git a/Sources/MIDIKitSMF/MIDIFileEvent/MIDIFileEventType.swift b/Sources/MIDIKitSMF/MIDIFileEvent/MIDIFileEventType.swift index ef5111d7a6..ad478d76cb 100644 --- a/Sources/MIDIKitSMF/MIDIFileEvent/MIDIFileEventType.swift +++ b/Sources/MIDIKitSMF/MIDIFileEvent/MIDIFileEventType.swift @@ -1,7 +1,7 @@ // // MIDIFileEventType.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitSMF/MIDIKitSMF.swift b/Sources/MIDIKitSMF/MIDIKitSMF.swift index df30fe611e..238b8050ab 100644 --- a/Sources/MIDIKitSMF/MIDIKitSMF.swift +++ b/Sources/MIDIKitSMF/MIDIKitSMF.swift @@ -1,7 +1,7 @@ // // MIDIKitSMF.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // @_exported import MIDIKitCore diff --git a/Sources/MIDIKitSMF/Protocols/MIDIFileChunk.swift b/Sources/MIDIKitSMF/Protocols/MIDIFileChunk.swift index f6c10bd80b..c80153f57c 100644 --- a/Sources/MIDIKitSMF/Protocols/MIDIFileChunk.swift +++ b/Sources/MIDIKitSMF/Protocols/MIDIFileChunk.swift @@ -1,7 +1,7 @@ // // MIDIFileChunk.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // public protocol MIDIFileChunk { diff --git a/Sources/MIDIKitSMF/Protocols/MIDIFileEventPayload.swift b/Sources/MIDIKitSMF/Protocols/MIDIFileEventPayload.swift index 15cfd9e542..ce5b2a5fe7 100644 --- a/Sources/MIDIKitSMF/Protocols/MIDIFileEventPayload.swift +++ b/Sources/MIDIKitSMF/Protocols/MIDIFileEventPayload.swift @@ -1,7 +1,7 @@ // // MIDIFileEventPayload.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -22,7 +22,9 @@ public protocol MIDIFileEventPayload { /// Returns the new event and MIDI file buffer length (number of bytes). typealias StreamDecodeResult = (newEvent: Self, bufferLength: Int) - /// If it is possible to initialize a new instance of this event from the head of the data buffer, a new instance will be returned along with the byte length traversed from the buffer. + /// If it is possible to initialize a new instance of this event from the head of the data + /// stream, a new instance will be returned along with the byte length traversed from the + /// stream. static func initFrom( midi1SMFRawBytesStream stream: D ) throws -> StreamDecodeResult diff --git a/Sources/MIDIKitSync/MIDIKitSync.swift b/Sources/MIDIKitSync/MIDIKitSync.swift index 9b258099cf..bd198f5c26 100644 --- a/Sources/MIDIKitSync/MIDIKitSync.swift +++ b/Sources/MIDIKitSync/MIDIKitSync.swift @@ -1,7 +1,7 @@ // // MIDIKitSync.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // @_exported import MIDIKitCore @@ -12,15 +12,28 @@ // Protocol information: // https://en.wikipedia.org/wiki/MIDI_timecode // -// "MTC allows the synchronization of a sequencer or DAW with other devices that can synchronize to MTC" +// "MTC allows the synchronization of a sequencer or DAW with other devices that can synchronize to +// MTC" // -// "MIDI time code (MTC) embeds the same timing information as standard SMPTE timecode as a series of small 'quarter-frame' MIDI messages. There is no provision for the user bits in the standard MIDI time code messages, and SysEx messages are used to carry this information instead. The quarter-frame messages are transmitted in a sequence of eight messages, thus a complete timecode value is specified every two frames. If the MIDI data stream is running close to capacity, the MTC data may arrive a little behind schedule which has the effect of introducing a small amount of jitter. In order to avoid this it is ideal to use a completely separate MIDI port for MTC data. Larger full-frame messages, which encapsulate a frame worth of timecode in a single message, are used to locate to a time while timecode is not running." +// "MIDI time code (MTC) embeds the same timing information as standard SMPTE timecode as a series +// of small 'quarter-frame' MIDI messages. There is no provision for the user bits in the standard +// MIDI time code messages, and SysEx messages are used to carry this information instead. The +// quarter-frame messages are transmitted in a sequence of eight messages, thus a complete timecode +// value is specified every two frames. If the MIDI data stream is running close to capacity, the +// MTC data may arrive a little behind schedule which has the effect of introducing a small amount +// of jitter. In order to avoid this it is ideal to use a completely separate MIDI port for MTC +// data. Larger full-frame messages, which encapsulate a frame worth of timecode in a single +// message, are used to locate to a time while timecode is not running." // -// "Unlike standard SMPTE timecode, MIDI timecode's quarter-frame and full-frame messages carry a two-bit flag value that identifies the rate of the timecode, specifying it as either: +// "Unlike standard SMPTE timecode, MIDI timecode's quarter-frame and full-frame messages carry a +// two-bit flag value that identifies the rate of the timecode, specifying it as either: // // - 24 frame/s (standard rate for film work) // - 25 frame/s (standard rate for PAL video) // - 29.97 frame/s (drop-frame timecode for NTSC video) // - 30 frame/s (non-drop timecode for NTSC video)" // -// It is important to note that not all DAWs implement all features of MTC. For example, Pro Tools can generate or slave to MTC quarter frames, but does not transmit or receive full-frame messages - meaning Pro Tools will not locate to new timecodes when the MTC stream is not running. However, some other DAWs will. +// It is important to note that not all DAWs implement all features of MTC. For example, Pro Tools +// can generate or slave to MTC quarter frames, but does not transmit or receive full-frame messages +// - meaning Pro Tools will not locate to new timecodes when the MTC stream is not running. However, +// some other DAWs will. diff --git a/Sources/MIDIKitSync/MTC/MTC Utilities.swift b/Sources/MIDIKitSync/MTC/MTC Utilities.swift index 382a849e25..8c23022cfc 100644 --- a/Sources/MIDIKitSync/MTC/MTC Utilities.swift +++ b/Sources/MIDIKitSync/MTC/MTC Utilities.swift @@ -1,7 +1,7 @@ // // MTC Utilities.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitSync/MTC/MTCDirection.swift b/Sources/MIDIKitSync/MTC/MTCDirection.swift index c0c8f3761c..3be494dcf5 100644 --- a/Sources/MIDIKitSync/MTC/MTCDirection.swift +++ b/Sources/MIDIKitSync/MTC/MTCDirection.swift @@ -1,7 +1,7 @@ // // MTCDirection.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore @@ -19,9 +19,13 @@ public enum MTCDirection { } extension MTCDirection { - /// Infers playback direction by comparing previous and current quarter-frames received, taking into account value wrapping around min/max. + /// Infers playback direction by comparing previous and current quarter-frames received, taking + /// into account value wrapping around min/max. /// - /// Returns nil if direction cannot be reasonably inferred. This may happen if both values are identical, or if values are not adjacent +/- 1 of each other, which may indicate the quarter-frame stream has been interrupted ie: when the transmitter has located to a new timecode entirely. + /// Returns nil if direction cannot be reasonably inferred. This may happen if both values are + /// identical, or if values are not adjacent +/- 1 of each other, which may indicate the + /// quarter-frame stream has been interrupted ie: when the transmitter has located to a new + /// timecode entirely. /// /// - Parameters: /// - previousQF: the last quarter-frame received diff --git a/Sources/MIDIKitSync/MTC/MTCFrameRate Translation.swift b/Sources/MIDIKitSync/MTC/MTCFrameRate Translation.swift index c71613bab9..ce8e24911e 100644 --- a/Sources/MIDIKitSync/MTC/MTCFrameRate Translation.swift +++ b/Sources/MIDIKitSync/MTC/MTCFrameRate Translation.swift @@ -1,7 +1,7 @@ // // MTCFrameRate Translation.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore @@ -35,7 +35,8 @@ extension MTCFrameRate { } extension Timecode.FrameRate { - /// Returns the base MTC frame rate that DAWs use to transmit timecode (scaling frame number if necessary) + /// Returns the base MTC frame rate that DAWs use to transmit timecode (scaling frame number if + /// necessary) public var mtcFrameRate: MTCFrameRate { switch self { case ._23_976: return .mtc24 @@ -72,22 +73,27 @@ extension Timecode.FrameRate { extension MTCFrameRate { /// Scales MTC frames at `self` MTC base rate to frames at other timecode frame rate. /// - /// - Note: This is a specialized calculation, and is intended to act upon raw MTC frames as decoded from quarter-frame messages; not intended to be a generalized scale function. + /// - Note: This is a specialized calculation, and is intended to act upon raw MTC frames as + /// decoded from quarter-frame messages; not intended to be a generalized scale function. /// - /// This is a double-duty function which first checks frame rate compatibility (and returns `nil` if rates are not H:MM:SS stable), then returns the scaled frames value if they are compatible. + /// This is a double-duty function which first checks frame rate compatibility (and returns + /// `nil` if rates are not H:MM:SS stable), then returns the scaled frames value if they are + /// compatible. /// /// - Parameters: /// - fromRawMTCFrames: Raw MTC frame number, as decoded from quarter-frame messages. /// - quarterFrames: Number of QFs elapsed (0...7). /// - timecodeRate: Real timecode frame rate to scale to. /// - /// - Returns: A `Double` is returned with the integer part representing frame number and the fractional part representing the fraction of the frame derived from quarter-frames. + /// - Returns: A `Double` is returned with the integer part representing frame number and the + /// fractional part representing the fraction of the frame derived from quarter-frames. internal func scaledFrames( fromRawMTCFrames: Int, quarterFrames: UInt8, to timecodeRate: Timecode.FrameRate ) -> Double? { - // if real timecode frame rates are not compatible (H:MM:SS stable), frame value scaling is not possible + // if real timecode frame rates are not compatible (H:MM:SS stable), frame value scaling is + // not possible guard derivedFrameRates.contains(timecodeRate) else { return nil } @@ -96,7 +102,8 @@ extension MTCFrameRate { let rawMTCFrames = max(0, fromRawMTCFrames) let rawMTCQuarterFrames = min(max(0, quarterFrames), 7) - // baseline check: if MTC frame rate is exactly equivalent to resultant timecode frame rate, skip the scale math + // baseline check: if MTC frame rate is exactly equivalent to resultant timecode frame rate, + // skip the scale math if directEquivalentFrameRate == timecodeRate { return rawMTCQuarterFrames == 0 ? Double(rawMTCFrames) @@ -111,7 +118,8 @@ extension MTCFrameRate { var scaled = (_rawMTCFrames + _frameFraction) * timecodeRate.mtcScaleFactor // account for 24.98fps rounding weirdness - // due to it being transmit as MTC-24fps, the scaled value will always be underestimated so adding a static offset is a clumsy but effective workaround + // due to it being transmit as MTC-24fps, the scaled value will always be underestimated so + // adding a static offset is a clumsy but effective workaround if timecodeRate == ._24_98 { if scaled > 0.0 { scaled += 0.24 @@ -126,11 +134,15 @@ extension MTCFrameRate { extension Timecode.FrameRate { /// Scales frames at other timecode frame rate to MTC frames at `self` MTC base rate. /// - /// - Note: This is a specialized calculation, and is intended to produce raw MTC frames and quarter-frame messages; not intended to be a generalized scale function. + /// - Note: This is a specialized calculation, and is intended to produce raw MTC frames and + /// quarter-frame messages; not intended to be a generalized scale function. /// - /// - Parameter fromTimecodeFrames: A `Double` with the integer part representing frame number and the fractional part representing the fraction of the frame. + /// - Parameter fromTimecodeFrames: A `Double` with the integer part representing frame number + /// and the fractional part representing the fraction of the frame. /// - /// - Returns: `(rawMTCFrames: Int, rawMTCQuarterFrames: UInt8)` where `rawMTCFrames` is raw MTC frame number, as decoded from quarter-frame messages and `rawMTCQuarterFrames` is number of QFs elapsed (`0 ... 7`). + /// - Returns: `(rawMTCFrames: Int, rawMTCQuarterFrames: UInt8)` where `rawMTCFrames` is raw MTC + /// frame number, as decoded from quarter-frame messages and `rawMTCQuarterFrames` is number of + /// QFs elapsed (`0 ... 7`). internal func scaledFrames( fromTimecodeFrames: Double ) -> ( diff --git a/Sources/MIDIKitSync/MTC/MTCFrameRate.swift b/Sources/MIDIKitSync/MTC/MTCFrameRate.swift index 290dc2bfce..ffdd9987ab 100644 --- a/Sources/MIDIKitSync/MTC/MTCFrameRate.swift +++ b/Sources/MIDIKitSync/MTC/MTCFrameRate.swift @@ -1,7 +1,7 @@ // // MTCFrameRate.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore @@ -56,8 +56,11 @@ import TimecodeKit /// Standard base timecode frame rate families expressed in MTC. /// -/// This does not always directly correlate to the actual frame rate the transmitting and receiving DAW is using. -/// When DAWs transmit MTC, the frame rate gets scaled down to one of the four base MTC frame rates. It is the job of the receiving DAW to scale the MTC frame data back up to the desired actual frame rate. +/// This does not always directly correlate to the actual frame rate the transmitting and receiving +/// DAW is using. +/// When DAWs transmit MTC, the frame rate gets scaled down to one of the four base MTC frame rates. +/// It is the job of the receiving DAW to scale the MTC frame data back up to the desired actual +/// frame rate. public enum MTCFrameRate: Hashable, CaseIterable { /// MTC frame rate classification of 24 fps and related rates case mtc24 diff --git a/Sources/MIDIKitSync/MTC/MTCGenerator/MTCEncoder FullFrameBehavior.swift b/Sources/MIDIKitSync/MTC/MTCGenerator/MTCEncoder FullFrameBehavior.swift index 733ad875b3..1bf722a438 100644 --- a/Sources/MIDIKitSync/MTC/MTCGenerator/MTCEncoder FullFrameBehavior.swift +++ b/Sources/MIDIKitSync/MTC/MTCGenerator/MTCEncoder FullFrameBehavior.swift @@ -1,7 +1,7 @@ // // MTCEncoder FullFrameBehavior.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore @@ -12,14 +12,18 @@ extension MTCEncoder { /// Always trigger a MTC Full-Frame MIDI message, with no data thinning. case always - /// Trigger a MTC Full-Frame MIDI message only if different from the last Full-Frame message formed by the ``MTCEncoder``. (default) + /// Trigger a MTC Full-Frame MIDI message only if different from the last Full-Frame message + /// formed by the ``MTCEncoder``. (default) /// - /// This is the default and best-practise option, since there is no benefit to the receiver of MTC messages to get duplicate Full-Frame messages and it is ideal to optimize the amount of unnecessary data transmitted. + /// This is the default and best-practise option, since there is no benefit to the receiver + /// of MTC messages to get duplicate Full-Frame messages and it is ideal to optimize the + /// amount of unnecessary data transmitted. case ifDifferent /// Do not trigger a MTC Full-Frame MIDI message. /// - /// This is not a typical condition and may likely only be used for debugging. It is recommended to use ``ifDifferent``. + /// This is not a typical condition and may likely only be used for debugging. It is + /// recommended to use ``ifDifferent``. case never } } diff --git a/Sources/MIDIKitSync/MTC/MTCGenerator/MTCEncoder.swift b/Sources/MIDIKitSync/MTC/MTCGenerator/MTCEncoder.swift index 2809061fa7..f61fbe923a 100644 --- a/Sources/MIDIKitSync/MTC/MTCGenerator/MTCEncoder.swift +++ b/Sources/MIDIKitSync/MTC/MTCGenerator/MTCEncoder.swift @@ -1,7 +1,7 @@ // // MTCEncoder.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore @@ -12,7 +12,9 @@ import TimecodeKit /// /// Takes timecode values and produces a stream of MIDI events. /// -/// > Tip: This object is not affected by or reliant on timing at all and simply processes events as they are received. For outbound MTC sync, use the ``MTCGenerator`` wrapper object which adds additional abstraction for generating MTC sync. +/// > Tip: This object is not affected by or reliant on timing at all and simply processes events as +/// they are received. For outbound MTC sync, use the ``MTCGenerator`` wrapper object which adds +/// additional abstraction for generating MTC sync. public final class MTCEncoder: SendsMIDIEvents { // MARK: - Public properties @@ -69,7 +71,9 @@ public final class MTCEncoder: SendsMIDIEvents { public internal(set) var mtcQuarterFrame: UInt8 = 0 /// Internal: - /// Flag indicating whether the quarter-frame output stream has already started since the last ``locate(to:transmitFullFrame:)`` (or since initializing the class if ``locate(to:transmitFullFrame:)`` has not yet been called). + /// Flag indicating whether the quarter-frame output stream has already started since the last + /// ``locate(to:transmitFullFrame:)`` (or since initializing the class if + /// ``locate(to:transmitFullFrame:)`` has not yet been called). @ThreadSafeAccess internal var mtcQuarterFrameStreamHasStartedSinceLastLocate = false @@ -161,9 +165,12 @@ public final class MTCEncoder: SendsMIDIEvents { } } - /// Advances to the next quarter-frame and triggers a quarter-frame MIDI message sent to the MIDI handler. + /// Advances to the next quarter-frame and triggers a quarter-frame MIDI message sent to the + /// MIDI handler. /// - /// - Note: If it is the first time ``increment()`` is being called since the last call to ``locate(to:transmitFullFrame:)`` (or since initializing the class), this method will transmit the current quarter-frame without incrementing. + /// - Note: If it is the first time ``increment()`` is being called since the last call to + /// ``locate(to:transmitFullFrame:)`` (or since initializing the class), this method will + /// transmit the current quarter-frame without incrementing. /// /// Used when playhead is moving later in time. public func increment() { @@ -187,9 +194,12 @@ public final class MTCEncoder: SendsMIDIEvents { mtcQuarterFrameStreamHasStartedSinceLastLocate = true } - /// Decrements to the previous quarter-frame and triggers a quarter-frame MIDI message sent to the MIDI handler. + /// Decrements to the previous quarter-frame and triggers a quarter-frame MIDI message sent to + /// the MIDI handler. /// - /// - Note: If it is the first time ``decrement()`` is being called since the last call to ``locate(to:transmitFullFrame:)`` (or since initializing the class), this method will transmit the current quarter-frame without decrementing. + /// - Note: If it is the first time ``decrement()`` is being called since the last call to + /// ``locate(to:transmitFullFrame:)`` (or since initializing the class), this method will + /// transmit the current quarter-frame without decrementing. /// /// Used when playhead is moving earlier in time. public func decrement() { @@ -213,7 +223,8 @@ public final class MTCEncoder: SendsMIDIEvents { mtcQuarterFrameStreamHasStartedSinceLastLocate = true } - /// Manually trigger a MIDI handler event to transmit a full-frame message at the current timecode. + /// Manually trigger a MIDI handler event to transmit a full-frame message at the current + /// timecode. public func sendFullFrameMIDIMessage() { let ffMessage = generateFullFrameMIDIMessage() diff --git a/Sources/MIDIKitSync/MTC/MTCGenerator/MTCGenerator State.swift b/Sources/MIDIKitSync/MTC/MTCGenerator/MTCGenerator State.swift index 5c0ba0e1dc..894593560b 100644 --- a/Sources/MIDIKitSync/MTC/MTCGenerator/MTCGenerator State.swift +++ b/Sources/MIDIKitSync/MTC/MTCGenerator/MTCGenerator State.swift @@ -1,7 +1,7 @@ // // MTCGenerator State.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore diff --git a/Sources/MIDIKitSync/MTC/MTCGenerator/MTCGenerator.swift b/Sources/MIDIKitSync/MTC/MTCGenerator/MTCGenerator.swift index 3bf5b4df20..f5fb540192 100644 --- a/Sources/MIDIKitSync/MTC/MTCGenerator/MTCGenerator.swift +++ b/Sources/MIDIKitSync/MTC/MTCGenerator/MTCGenerator.swift @@ -1,7 +1,7 @@ // // MTCGenerator.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -17,7 +17,10 @@ public final class MTCGenerator: SendsMIDIEvents { /// The MTC SMPTE frame rate (24, 25, 29.97d, or 30) that was last transmitted by the generator. /// - /// This property should only be inspected purely for developer informational or diagnostic purposes. For production code or any logic related to MTC, it should be ignored -- only the local ``timecode``.`frameRate` property is used for automatic selection of MTC SMPTE frame rate and scaling of outgoing timecode accordingly. + /// This property should only be inspected purely for developer informational or diagnostic + /// purposes. For production code or any logic related to MTC, it should be ignored -- only the + /// local ``timecode``.`frameRate` property is used for automatic selection of MTC SMPTE frame + /// rate and scaling of outgoing timecode accordingly. public var mtcFrameRate: MTCFrameRate { var getMTCFrameRate: MTCFrameRate! @@ -58,7 +61,8 @@ public final class MTCGenerator: SendsMIDIEvents { /// Behavior determining when MTC Full-Frame MIDI messages should be generated. /// - /// ``MTCEncoder/FullFrameBehavior/ifDifferent`` is recommended and suitable for most implementations. + /// ``MTCEncoder/FullFrameBehavior/ifDifferent`` is recommended and suitable for most + /// implementations. @ThreadSafeAccess public var locateBehavior: MTCEncoder.FullFrameBehavior = .ifDifferent @@ -176,7 +180,9 @@ public final class MTCGenerator: SendsMIDIEvents { /// Locate to a new timecode, while not generating continuous playback MIDI message stream. /// Sends a MTC full-frame message. /// - /// - Note: `timecode` may contain `subframes > 0`. Subframes will be stripped prior to transmitting the full-frame message since the resolution of MTC full-frame messages is 1 frame. + /// - Note: `timecode` may contain `subframes > 0`. Subframes will be stripped prior to + /// transmitting the full-frame message since the resolution of MTC full-frame messages is 1 + /// frame. public func locate(to timecode: Timecode) { queue.sync { encoder.locate(to: timecode, transmitFullFrame: locateBehavior) @@ -187,7 +193,9 @@ public final class MTCGenerator: SendsMIDIEvents { /// Locate to a new timecode, while not generating continuous playback MIDI message stream. /// Sends a MTC full-frame message. /// - /// > Note: `components` may contain `subframes > 0`. Subframes will be stripped prior to transmitting the full-frame message since the resolution of MTC full-frame messages is 1 frame. + /// > Note: `components` may contain `subframes > 0`. Subframes will be stripped prior to + /// transmitting the full-frame message since the resolution of MTC full-frame messages is 1 + /// frame. public func locate(to components: Timecode.Components) { queue.sync { encoder.locate(to: components, transmitFullFrame: locateBehavior) @@ -200,7 +208,8 @@ public final class MTCGenerator: SendsMIDIEvents { /// /// Frame rate will be derived from the `timecode` instance passed in. /// - /// > Note: It is not necessary to send a ``locate(to:)-1u162`` message simultaneously or immediately prior, and is actually undesirable as it can confuse the receiving entity. + /// > Note: It is not necessary to send a ``locate(to:)-1u162`` message simultaneously or + /// immediately prior, and is actually undesirable as it can confuse the receiving entity. /// /// Call ``stop()`` to stop generating events. public func start(now timecode: Timecode) { @@ -232,7 +241,8 @@ public final class MTCGenerator: SendsMIDIEvents { /// Starts generating MTC continuous playback MIDI message stream events. /// Call this method at the exact time that `realTime` occurs. /// - /// > Note: It is not necessary to send a ``locate(to:)-1u162`` message simultaneously or immediately prior, and is actually undesirable as it can confuse the receiving entity. + /// > Note: It is not necessary to send a ``locate(to:)-1u162`` message simultaneously or + /// immediately prior, and is actually undesirable as it can confuse the receiving entity. /// /// Call ``stop()`` to stop generating events. public func start( @@ -256,7 +266,8 @@ public final class MTCGenerator: SendsMIDIEvents { /// Starts generating MTC continuous playback MIDI message stream events. /// Call this method at the exact time that `realTime` occurs. /// - /// > Note: It is not necessary to send a ``locate(to:)-1u162`` message simultaneously or immediately prior, and is actually undesirable as it can confuse the receiving entity. + /// > Note: It is not necessary to send a ``locate(to:)-1u162`` message simultaneously or + /// immediately prior, and is actually undesirable as it can confuse the receiving entity. /// /// Call ``stop()`` to stop generating events. public func start( @@ -320,7 +331,8 @@ public final class MTCGenerator: SendsMIDIEvents { } } - /// Internal: called from all other `start(...)` methods when they are finally ready to initiate the start of MTC generation. + /// Internal: called from all other `start(...)` methods when they are finally ready to initiate + /// the start of MTC generation. /// - Note: This method assumes `subframes == 0`. /// - Important: This must be called on `self.queue`. internal func locateAndStart( diff --git a/Sources/MIDIKitSync/MTC/MTCMessageType.swift b/Sources/MIDIKitSync/MTC/MTCMessageType.swift index bcabfda99d..5892a8e9b5 100644 --- a/Sources/MIDIKitSync/MTC/MTCMessageType.swift +++ b/Sources/MIDIKitSync/MTC/MTCMessageType.swift @@ -1,7 +1,7 @@ // // MTCMessageType.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitCore @@ -9,7 +9,8 @@ import MIDIKitCore public enum MTCMessageType { /// MTC Full-Frame Message /// - /// Timecode changed as a result of a full-frame message, which a MTC transmitter will send while not playing back but locating to a new timecode + /// Timecode changed as a result of a full-frame message, which a MTC transmitter will send + /// while not playing back but locating to a new timecode case fullFrame /// MTC Quarter-Frame Message diff --git a/Sources/MIDIKitSync/MTC/MTCReceiver/MTCDecoder.swift b/Sources/MIDIKitSync/MTC/MTCReceiver/MTCDecoder.swift index 1b65d9d342..48cbf2908f 100644 --- a/Sources/MIDIKitSync/MTC/MTCReceiver/MTCDecoder.swift +++ b/Sources/MIDIKitSync/MTC/MTCReceiver/MTCDecoder.swift @@ -1,7 +1,7 @@ // // MTCDecoder.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // // Notes: @@ -10,9 +10,15 @@ // --------- // - Pro Tools (as of v2018.4) does not send any full frame messages. // - Essentially, it does not send any location or relocation messages of any kind over MTC. -// - When normal playback begins (forwards in time, at 1:1 speed), PT starts transmitting quarter-frames. When playback stops, it simply stops transmitting quarter-frames. It does not complete a full frame before stopping MTC transmission, it will stop at the last quarter-frame -// - When half-speed playback starts (forwards in time, at half-speed), PT will transmit quarter-frames as normal, but they will transmit at half the speed. This is not necessary meant for the receiver to synchronize playback to, but to simply continue receiving timecode values to update its timecode display. -// - Pro Tools is capable of forwards and backwards scrubbing at various speeds, but does not transmit any MTC data while doing those operations. +// - When normal playback begins (forwards in time, at 1:1 speed), PT starts transmitting +// quarter-frames. When playback stops, it simply stops transmitting quarter-frames. It does not +// complete a full frame before stopping MTC transmission, it will stop at the last quarter-frame +// - When half-speed playback starts (forwards in time, at half-speed), PT will transmit +// quarter-frames as normal, but they will transmit at half the speed. This is not necessary meant +// for the receiver to synchronize playback to, but to simply continue receiving timecode values to +// update its timecode display. +// - Pro Tools is capable of forwards and backwards scrubbing at various speeds, but does not +// transmit any MTC data while doing those operations. // // Cubase // ------ @@ -30,13 +36,20 @@ import TimecodeKit /// /// Takes a stream of MIDI events and produces timecode values. /// -/// This object is not affected by or reliant on timing at all and simply processes events as they are received. For inbound MTC sync, use the ``MTCReceiver`` wrapper object which adds additional abstraction for managing MTC sync state. +/// This object is not affected by or reliant on timing at all and simply processes events as they +/// are received. For inbound MTC sync, use the ``MTCReceiver`` wrapper object which adds additional +/// abstraction for managing MTC sync state. /// /// > Note: /// > -/// > - A running MTC data stream (during playback) only updates the frame number every 2 frames, so this data stream should not be relied on for deriving exact frame position, but rather as a mechanism for displaying running timecode to the user on screen or synchronizing playback to the incoming MTC data stream. +/// > - A running MTC data stream (during playback) only updates the frame number every 2 frames, so +/// this data stream should not be relied on for deriving exact frame position, but rather as a +/// mechanism for displaying running timecode to the user on screen or synchronizing playback to the +/// incoming MTC data stream. /// > -/// > - MTC full frame messages (which only some DAWs support) will however transmit frame-accurate timecodes when scrubbing or locating to different times, but will be limited to the base frame rates supported by MTC. +/// > - MTC full frame messages (which only some DAWs support) will however transmit frame-accurate +/// timecodes when scrubbing or locating to different times, but will be limited to the base frame +/// rates supported by MTC. public final class MTCDecoder { // MARK: - Public properties @@ -54,9 +67,11 @@ public final class MTCDecoder { /// The frame rate the local system is using. /// - /// When set, MTC frame numbers will be scaled to real frame rate frame numbers, but only when the incoming MTC frame rate and the ``localFrameRate`` are compatible. + /// When set, MTC frame numbers will be scaled to real frame rate frame numbers, but only when + /// the incoming MTC frame rate and the ``localFrameRate`` are compatible. /// - /// Remember to also set this any time the local frame rate changes so the receiver can interpret the incoming MTC accordingly. + /// Remember to also set this any time the local frame rate changes so the receiver can + /// interpret the incoming MTC accordingly. public var localFrameRate: Timecode.FrameRate? /// Status of the direction of MTC quarter-frames received @@ -64,9 +79,11 @@ public final class MTCDecoder { // MARK: - Stored closures - /// Called when a meaningful change to the timecode has occurred which would require its display to be updated. + /// Called when a meaningful change to the timecode has occurred which would require its display + /// to be updated. /// - /// Implement this closure for when you only want to display timecode and do not need to sync to MTC. + /// Implement this closure for when you only want to display timecode and do not need to sync to + /// MTC. internal var timecodeChangedHandler: (( _ timecode: Timecode, _ event: MTCMessageType, @@ -74,9 +91,11 @@ public final class MTCDecoder { _ displayNeedsUpdate: Bool ) -> Void)? - /// Sets the closure called when a meaningful change to the timecode has occurred which would require its display to be updated. + /// Sets the closure called when a meaningful change to the timecode has occurred which would + /// require its display to be updated. /// - /// Implement this closure for when you only want to display timecode and do not need to sync to MTC. + /// Implement this closure for when you only want to display timecode and do not need to sync to + /// MTC. public func setTimecodeChangedHandler( _ handler: (( _ timecode: Timecode, @@ -90,12 +109,15 @@ public final class MTCDecoder { /// Called only when the incoming MTC stream changes its frame rate classification. /// - /// This can usually be ignored, as the ``MTCDecoder`` can handle scaling and validation of the frame rate information from the stream transparently. + /// This can usually be ignored, as the ``MTCDecoder`` can handle scaling and validation of the + /// frame rate information from the stream transparently. internal var mtcFrameRateChangedHandler: ((_ rate: MTCFrameRate) -> Void)? - /// Sets the closure called only when the incoming MTC stream changes its frame rate classification. + /// Sets the closure called only when the incoming MTC stream changes its frame rate + /// classification. /// - /// This can usually be ignored, as the ``MTCDecoder`` can handle scaling and validation of the frame rate information from the stream transparently. + /// This can usually be ignored, as the ``MTCDecoder`` can handle scaling and validation of the + /// frame rate information from the stream transparently. public func setMTCFrameRateChangedHandler( _ handler: ((_ rate: MTCFrameRate) -> Void)? ) { @@ -266,8 +288,10 @@ extension MTCDecoder: ReceivesMIDIEvents { /// Quarter-frame messages /// ---------------------- - /// Since it takes eight quarter-frames for a complete time code message, the complete SMPTE time is updated every two frames. - /// A quarter-frame message consists of a status byte of 0xF1, followed by a single 7-bit data value: 3 bits to identify the piece, and 4 bits of partial time code. + /// Since it takes eight quarter-frames for a complete time code message, the complete SMPTE + /// time is updated every two frames. + /// A quarter-frame message consists of a status byte of 0xF1, followed by a single 7-bit data + /// value: 3 bits to identify the piece, and 4 bits of partial time code. internal func processQF(dataByte: UInt8) { // Verbose debugging - careful when enabling this! // ----------------------------------------------- @@ -282,10 +306,19 @@ extension MTCDecoder: ReceivesMIDIEvents { // Quarter-frame messages are received in this order during playback. // Piece 0 is transmitted at the coded moment. - // When time is running forward, the piece numbers increment from 0–7; with the time that piece 0 is transmitted is the coded instant, and the remaining pieces are transmitted later. - // If rewinding, data is received in reverse order. Again, piece 0 is transmitted at the coded moment. - // Since 8 Quarter Frame messages are required to piece together the current SMPTE time, timing lock can't be achieved until the slave has received all 8 messages. This will take from 2 to 4 SMPTE Frames, depending upon when the slave comes online. - // The Frame number (contained in the first 2 Quarter Frame messages) is the SMPTE Frames Time for when the first Quarter Frame message is sent. But, because it takes 7 more quarter-frames to piece together the current SMPTE Time, when the slave does finally piece the time together, it is actually 2 SMPTE Frames behind the real current time. So, for display purposes, the slave should always add 2 frames to the current time. + // When time is running forward, the piece numbers increment from 0–7; with the time that + // piece 0 is transmitted is the coded instant, and the remaining pieces are transmitted + // later. + // If rewinding, data is received in reverse order. Again, piece 0 is transmitted at the + // coded moment. + // Since 8 Quarter Frame messages are required to piece together the current SMPTE time, + // timing lock can't be achieved until the slave has received all 8 messages. This will take + // from 2 to 4 SMPTE Frames, depending upon when the slave comes online. + // The Frame number (contained in the first 2 Quarter Frame messages) is the SMPTE Frames + // Time for when the first Quarter Frame message is sent. But, because it takes 7 more + // quarter-frames to piece together the current SMPTE Time, when the slave does finally + // piece the time together, it is actually 2 SMPTE Frames behind the real current time. So, + // for display purposes, the slave should always add 2 frames to the current time. // // Piece # Data byte Significance // ------- --------- ------------ @@ -491,7 +524,8 @@ extension MTCDecoder: ReceivesMIDIEvents { } } - /// Parses framerate info received from MTC stream and stores value + /// Internal: + /// Parses framerate info received from MTC stream and stores value. /// - Parameter rateBits: two-bit number internal func setMTCFrameRate(rateBits: UInt8) { if let bits = MTCFrameRate(rateBits) { @@ -499,7 +533,9 @@ extension MTCDecoder: ReceivesMIDIEvents { } } - /// Internal: Returns true if all 8 quarter-frames have been received in order to assemble a full MTC timecode + /// Internal: + /// Returns true if all 8 quarter-frames have been received in order to assemble a full MTC + /// timecode. internal func qfBufferComplete() -> Bool { // return cached true value if quarterFrameBufferIsComplete { return true } @@ -525,7 +561,9 @@ extension MTCDecoder: ReceivesMIDIEvents { /// /// You may want to call this, for example, when QF stream is lost or interrupted. /// - /// Flushing the registers will ensure that the next quarter-frame stream received is treated as a new stream and can avoid forming nonsense timecodes prior to receiving the full 8 quarter-frames. + /// Flushing the registers will ensure that the next quarter-frame stream received is treated as + /// a new stream and can avoid forming nonsense timecodes prior to receiving the full 8 + /// quarter-frames. public func resetQFBuffer() { TC_H_lsb_received = false TC_H_msb_received = false diff --git a/Sources/MIDIKitSync/MTC/MTCReceiver/MTCReceiver State.swift b/Sources/MIDIKitSync/MTC/MTCReceiver/MTCReceiver State.swift index 52ea9b95e4..4dc6a01680 100644 --- a/Sources/MIDIKitSync/MTC/MTCReceiver/MTCReceiver State.swift +++ b/Sources/MIDIKitSync/MTC/MTCReceiver/MTCReceiver State.swift @@ -1,7 +1,7 @@ // // MTCReceiver State.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Dispatch @@ -18,7 +18,8 @@ extension MTCReceiver { case idle /// Pre-Sync: - /// MTC quarter-frames are being received in the pre-sync phase prior to transitioning to ``sync``. + /// MTC quarter-frames are being received in the pre-sync phase prior to transitioning to + /// ``sync``. case preSync(predictedLockTime: DispatchTime, lockTimecode: Timecode) /// Sync: @@ -27,11 +28,13 @@ extension MTCReceiver { case sync /// Freewheeling: - /// Incoming MTC data is experiencing jitter (drop out) or data stream has stopped and receiver is in the freewheeling state. + /// Incoming MTC data is experiencing jitter (drop out) or data stream has stopped and + /// receiver is in the freewheeling state. case freewheeling /// Incompatible Frame Rate: - /// The incoming MTC frame rate is not compatible with the ``MTCReceiver/localFrameRate`` and therefore sync is not possible. + /// The incoming MTC frame rate is not compatible with the ``MTCReceiver/localFrameRate`` + /// and therefore sync is not possible. case incompatibleFrameRate } } diff --git a/Sources/MIDIKitSync/MTC/MTCReceiver/MTCReceiver SyncPolicy.swift b/Sources/MIDIKitSync/MTC/MTCReceiver/MTCReceiver SyncPolicy.swift index 4f41a3a764..d011369895 100644 --- a/Sources/MIDIKitSync/MTC/MTCReceiver/MTCReceiver SyncPolicy.swift +++ b/Sources/MIDIKitSync/MTC/MTCReceiver/MTCReceiver SyncPolicy.swift @@ -1,7 +1,7 @@ // // MTCReceiver SyncPolicy.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Foundation @@ -13,10 +13,12 @@ extension MTCReceiver { public struct SyncPolicy: Equatable, Codable { // MARK: - Public properties - /// Sets the number of received continuous timecode frames that must elapse prior to establishing synchronization. + /// Sets the number of received continuous timecode frames that must elapse prior to + /// establishing synchronization. public var lockFrames: Int = 0 - /// Sets the number of timecode frames that must be missed until the receiver enters the stopped/idle state. + /// Sets the number of timecode frames that must be missed until the receiver enters the + /// stopped/idle state. public var dropOutFrames: Int = 0 // MARK: - Init diff --git a/Sources/MIDIKitSync/MTC/MTCReceiver/MTCReceiver.swift b/Sources/MIDIKitSync/MTC/MTCReceiver/MTCReceiver.swift index 3efa46e0f6..430ab18e6a 100644 --- a/Sources/MIDIKitSync/MTC/MTCReceiver/MTCReceiver.swift +++ b/Sources/MIDIKitSync/MTC/MTCReceiver/MTCReceiver.swift @@ -1,7 +1,7 @@ // // MTCReceiver.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import Darwin @@ -16,9 +16,13 @@ import TimecodeKit /// /// > Note: /// > -/// > - A running MTC data stream (during playback) only updates the frame number every 2 frames, so this data stream should not be relied on for deriving exact frame position, but rather as a mechanism for displaying running timecode to the user on screen or synchronizing playback to the incoming MTC data stream. +/// > - A running MTC data stream (during playback) only updates the frame number every 2 frames, so +/// this data stream should not be relied on for deriving exact frame position, but rather as a +/// mechanism for displaying running timecode to the user on screen or synchronizing playback to the +/// incoming MTC data stream. /// > -/// > - MTC full frame messages (which only some DAWs support) will however transmit frame-accurate timecodes when scrubbing or locating to different times. +/// > - MTC full frame messages (which only some DAWs support) will however transmit frame-accurate +/// timecodes when scrubbing or locating to different times. public final class MTCReceiver { // MARK: - Public properties @@ -41,7 +45,8 @@ public final class MTCReceiver { public private(set) var timecode: Timecode /// The frame rate the local system is using. - /// Remember to also set this any time the local frame rate changes so the receiver can interpret the incoming MTC accordingly. + /// Remember to also set this any time the local frame rate changes so the receiver can + /// interpret the incoming MTC accordingly. public var localFrameRate: Timecode.FrameRate? { get { var getMTCFrameRate: Timecode.FrameRate? @@ -61,7 +66,10 @@ public final class MTCReceiver { /// The SMPTE frame rate (24, 25, 29.97d, or 30) that was last received by the receiver. /// - /// This property should only be inspected purely for developer informational or diagnostic purposes. For production code or any logic related to MTC, it should be ignored -- only the ``localFrameRate`` property is used for automatic validation and scaling of incoming timecode. + /// This property should only be inspected purely for developer informational or diagnostic + /// purposes. For production code or any logic related to MTC, it should be ignored -- only the + /// ``localFrameRate`` property is used for automatic validation and scaling of incoming + /// timecode. public var mtcFrameRate: MTCFrameRate { var getMTCFrameRate: MTCFrameRate! @@ -89,9 +97,11 @@ public final class MTCReceiver { // MARK: - Stored closures - /// Called when a meaningful change to the timecode has occurred which would require its display to be updated. + /// Called when a meaningful change to the timecode has occurred which would require its display + /// to be updated. /// - /// Implement this closure for when you only want to display timecode and do not need to sync to MTC. + /// Implement this closure for when you only want to display timecode and do not need to sync to + /// MTC. public var timecodeChangedHandler: (( _ timecode: Timecode, _ event: MTCMessageType, @@ -107,7 +117,8 @@ public final class MTCReceiver { /// Initialize a new MTC Receiver instance. /// /// - Parameters: - /// - name: optionally supply a simple, unique alphanumeric name for the instance, used internally to identify the dispatch thread; random UUID will be used if `nil` + /// - name: optionally supply a simple, unique alphanumeric name for the instance, used + /// internally to identify the dispatch thread; random UUID will be used if `nil` /// - initialLocalFrameRate: set an initial local frame rate /// - syncPolicy: set the MTC sync policy /// - timecodeChanged: handle timecode change callbacks, pass `nil` if not needed @@ -144,8 +155,10 @@ public final class MTCReceiver { ) // set up decoder reset timer - // we're accounting for the largest reasonable interval of time we are willing to wait until we assume non-contiguous MTC stream has stopped or failed - // it would be reasonable to allow for the slowest frame rate (23.976fps) and round up by a modest margin: + // we're accounting for the largest reasonable interval of time we are willing to wait until + // we assume non-contiguous MTC stream has stopped or failed + // it would be reasonable to allow for the slowest frame rate (23.976fps) and round up by a + // modest margin: // 1 frame @ 23.976 = 41.7... ms // 1 quarter-frame = 41.7/4 = 10.4... ms // Timer checking twice per QF = ~5.0ms intervals = 200Hz @@ -210,7 +223,8 @@ public final class MTCReceiver { /// Internal: Fired from our timer object. internal func timerFired() { - // this will be called by the timer which operates on our internal queue, so we don't need to wrap this in queue.async { } + // this will be called by the timer which operates on our internal queue, so we don't need + // to wrap this in queue.async { } let timeNow = clock_gettime_monotonic_raw() @@ -241,7 +255,9 @@ public final class MTCReceiver { let freewheelTimeout = timespec(dropOutFramesDuration) - // if >20ms window of time since last quarter frame, assume MTC message stream has been stopped/interrupted or being received at a speed less than realtime (ie: when Pro Tools plays back at half-speed) and reset our internal tracker + // if >20ms window of time since last quarter frame, assume MTC message stream has been + // stopped/interrupted or being received at a speed less than realtime (ie: when Pro Tools + // plays back at half-speed) and reset our internal tracker if clockDiff > continuousQFTimeout, clockDiff < freewheelTimeout { @@ -261,7 +277,8 @@ public final class MTCReceiver { extension MTCReceiver: ReceivesMIDIEvents { /// Incoming MIDI messages (Async on MTCReceiver queue) public func midiIn(event: MIDIEvent) { - // The decoder's midiIn can trigger handler callbacks as a result, which will in turn all be executed on the queue + // The decoder's midiIn can trigger handler callbacks as a result, which will in turn all be + // executed on the queue queue.sync { self.decoder.midiIn(event: event) diff --git a/Tests/MIDIKitControlSurfacesTests/Character and LED Tables/Character and LED Tests.swift b/Tests/MIDIKitControlSurfacesTests/Character and LED Tables/Character and LED Tests.swift index b0e1cc78a2..94fb87d28d 100644 --- a/Tests/MIDIKitControlSurfacesTests/Character and LED Tables/Character and LED Tests.swift +++ b/Tests/MIDIKitControlSurfacesTests/Character and LED Tables/Character and LED Tests.swift @@ -1,7 +1,7 @@ // // Character and LED Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitControlSurfacesTests/HUI Encode Utilities Tests.swift b/Tests/MIDIKitControlSurfacesTests/HUI Encode Utilities Tests.swift index 3790930f13..59a8e34af5 100644 --- a/Tests/MIDIKitControlSurfacesTests/HUI Encode Utilities Tests.swift +++ b/Tests/MIDIKitControlSurfacesTests/HUI Encode Utilities Tests.swift @@ -1,7 +1,7 @@ // // HUI Encode Utilities Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitControlSurfacesTests/HUIDecoder/HUIHostEventDecoder Tests.swift b/Tests/MIDIKitControlSurfacesTests/HUIDecoder/HUIHostEventDecoder Tests.swift index c0f1c3e05b..9857e256e0 100644 --- a/Tests/MIDIKitControlSurfacesTests/HUIDecoder/HUIHostEventDecoder Tests.swift +++ b/Tests/MIDIKitControlSurfacesTests/HUIDecoder/HUIHostEventDecoder Tests.swift @@ -1,7 +1,7 @@ // // HUIHostEventDecoder Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitControlSurfacesTests/HUIDecoder/HUISurfaceEventDecoder Tests.swift b/Tests/MIDIKitControlSurfacesTests/HUIDecoder/HUISurfaceEventDecoder Tests.swift index 42ae1c81d6..b9227f2d16 100644 --- a/Tests/MIDIKitControlSurfacesTests/HUIDecoder/HUISurfaceEventDecoder Tests.swift +++ b/Tests/MIDIKitControlSurfacesTests/HUIDecoder/HUISurfaceEventDecoder Tests.swift @@ -1,7 +1,7 @@ // // HUISurfaceEventDecoder Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitControlSurfacesTests/HUISurfaceModel/HUISurfaceModel Tests.swift b/Tests/MIDIKitControlSurfacesTests/HUISurfaceModel/HUISurfaceModel Tests.swift index 02b4cdff1d..7f000b9e5e 100644 --- a/Tests/MIDIKitControlSurfacesTests/HUISurfaceModel/HUISurfaceModel Tests.swift +++ b/Tests/MIDIKitControlSurfacesTests/HUISurfaceModel/HUISurfaceModel Tests.swift @@ -1,7 +1,7 @@ // // HUISurfaceModel Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitControlSurfacesTests/HUISwitch/HUISwitch Tests.swift b/Tests/MIDIKitControlSurfacesTests/HUISwitch/HUISwitch Tests.swift index 740e3958b9..e20dafb7df 100644 --- a/Tests/MIDIKitControlSurfacesTests/HUISwitch/HUISwitch Tests.swift +++ b/Tests/MIDIKitControlSurfacesTests/HUISwitch/HUISwitch Tests.swift @@ -1,7 +1,7 @@ // // HUISwitch Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitControlSurfacesTests/MIDIKitControlSurfacesTests.swift b/Tests/MIDIKitControlSurfacesTests/MIDIKitControlSurfacesTests.swift index 5e2c87e97b..abd6a83b36 100644 --- a/Tests/MIDIKitControlSurfacesTests/MIDIKitControlSurfacesTests.swift +++ b/Tests/MIDIKitControlSurfacesTests/MIDIKitControlSurfacesTests.swift @@ -1,7 +1,7 @@ // // MIDIKitControlSurfacesTests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/CC/CC NRPN Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/CC/CC NRPN Tests.swift index 64b440b9ec..82d126b4c8 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/CC/CC NRPN Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/CC/CC NRPN Tests.swift @@ -1,7 +1,7 @@ // // CC NRPN Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/CC/CC RPN Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/CC/CC RPN Tests.swift index f5943d2890..3422019a3e 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/CC/CC RPN Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/CC/CC RPN Tests.swift @@ -1,7 +1,7 @@ // // CC RPN Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/CC/CC Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/CC/CC Tests.swift index 8151dd6473..3498ff744a 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/CC/CC Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/CC/CC Tests.swift @@ -1,7 +1,7 @@ // // CC Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Note/NoteAttribute Pitch7_9 Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Note/NoteAttribute Pitch7_9 Tests.swift index 93e6a19321..38fcfb3746 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Note/NoteAttribute Pitch7_9 Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Note/NoteAttribute Pitch7_9 Tests.swift @@ -1,7 +1,7 @@ // // NoteAttribute Pitch7_9 Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Note/NoteOff Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Note/NoteOff Tests.swift index b42d9a358d..921d7ea23e 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Note/NoteOff Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Note/NoteOff Tests.swift @@ -1,7 +1,7 @@ // // NoteOff Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Note/NoteOn Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Note/NoteOn Tests.swift index 169cbbbf3d..eb1bf1ea8b 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Note/NoteOn Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Note/NoteOn Tests.swift @@ -1,7 +1,7 @@ // // NoteOn Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice Value Conversions Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice Value Conversions Tests.swift index d3c18b3a32..8713ee7586 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice Value Conversions Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice Value Conversions Tests.swift @@ -1,7 +1,7 @@ // // ChanVoice Value Conversions Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice14Bit32BitValue Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice14Bit32BitValue Tests.swift index c9cfe48507..8210798a9b 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice14Bit32BitValue Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice14Bit32BitValue Tests.swift @@ -1,7 +1,7 @@ // // ChanVoice14Bit32BitValue Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice32BitValue Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice32BitValue Tests.swift index 13b2111e34..5257e6d1fe 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice32BitValue Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice32BitValue Tests.swift @@ -1,7 +1,7 @@ // // ChanVoice32BitValue Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit16BitValue Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit16BitValue Tests.swift index 46b8c3254a..db47f2ca6a 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit16BitValue Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit16BitValue Tests.swift @@ -1,7 +1,7 @@ // // ChanVoice7Bit16BitValue Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit32BitValue Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit32BitValue Tests.swift index 10f6527993..3bcad6886e 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit32BitValue Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Channel Voice/Values/ChanVoice7Bit32BitValue Tests.swift @@ -1,7 +1,7 @@ // // ChanVoice7Bit32BitValue Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysEx7 Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysEx7 Tests.swift index 39445a9cb4..3b2acd3f79 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysEx7 Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysEx7 Tests.swift @@ -1,7 +1,7 @@ // // SysEx7 Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysEx8 Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysEx8 Tests.swift index 50a12f623a..4e3dfecf74 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysEx8 Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysEx8 Tests.swift @@ -1,7 +1,7 @@ // // SysEx8 Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysExID Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysExID Tests.swift index 8754c1df7f..768e70df0c 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysExID Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysExID Tests.swift @@ -1,7 +1,7 @@ // // SysExID Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysExManufacturer Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysExManufacturer Tests.swift index d4cf85d622..95761deca4 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysExManufacturer Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/System Exclusive/SysExManufacturer Tests.swift @@ -1,7 +1,7 @@ // // SysExManufacturer Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Utility/JRClock Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Utility/JRClock Tests.swift index e470c406a5..4ed6bac6e5 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Utility/JRClock Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Utility/JRClock Tests.swift @@ -1,7 +1,7 @@ // // JRClock Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Utility/JRTimestamp Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Utility/JRTimestamp Tests.swift index 4373872439..97e4149e86 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Utility/JRTimestamp Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Utility/JRTimestamp Tests.swift @@ -1,7 +1,7 @@ // // JRTimestamp Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Utility/NoOp Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Utility/NoOp Tests.swift index f846292d01..516ba604ab 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEvent/Utility/NoOp Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEvent/Utility/NoOp Tests.swift @@ -1,7 +1,7 @@ // // NoOp Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice Tests.swift index fc6598f612..38d441856c 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice Tests.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter Channel Voice Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice drop Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice drop Tests.swift index fed262bd95..d1ff85860c 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice drop Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice drop Tests.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter Channel Voice drop Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice keep Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice keep Tests.swift index beecaa78b2..6efd76964b 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice keep Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice keep Tests.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter Channel Voice keep Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice only Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice only Tests.swift index 76d4d170d5..afaf5cd68f 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice only Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/Channel Voice/MIDIEvent Filter Channel Voice only Tests.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter Channel Voice only Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter Group Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter Group Tests.swift index 12bd87d248..b414437f08 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter Group Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter Group Tests.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter Group Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter System Common Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter System Common Tests.swift index d25cdf668e..492b6abc7e 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter System Common Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter System Common Tests.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter System Common Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter System Exclusive Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter System Exclusive Tests.swift index ec75a6a735..1faa99254f 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter System Exclusive Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter System Exclusive Tests.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter System Exclusive Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter System Real-Time Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter System Real-Time Tests.swift index ed3f3988b2..b403ad935f 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter System Real-Time Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter System Real-Time Tests.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter System Real-Time Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter Tests Constants.swift b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter Tests Constants.swift index 415e3f33db..a6f8154f90 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter Tests Constants.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter Tests Constants.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter Tests Constants.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter Utility Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter Utility Tests.swift index 0f2ca593e9..b67bb9c141 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter Utility Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDIEventFilter/MIDIEvent Filter Utility Tests.swift @@ -1,7 +1,7 @@ // // MIDIEvent Filter Utility Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDINote/MIDINote Cakewalk Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDINote/MIDINote Cakewalk Tests.swift index 97a9bd7cf1..44a1244a77 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDINote/MIDINote Cakewalk Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDINote/MIDINote Cakewalk Tests.swift @@ -1,7 +1,7 @@ // // MIDINote Cakewalk Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDINote/MIDINote Roland Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDINote/MIDINote Roland Tests.swift index a4700e218f..dbb48938da 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDINote/MIDINote Roland Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDINote/MIDINote Roland Tests.swift @@ -1,7 +1,7 @@ // // MIDINote Roland Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/MIDINote/MIDINote Yamaha Tests.swift b/Tests/MIDIKitCoreTests/Events/MIDINote/MIDINote Yamaha Tests.swift index f5006e7ef3..9e49e94569 100644 --- a/Tests/MIDIKitCoreTests/Events/MIDINote/MIDINote Yamaha Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/MIDINote/MIDINote Yamaha Tests.swift @@ -1,7 +1,7 @@ // // MIDINote Yamaha Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/Type Extensions/Double Extensions Tests.swift b/Tests/MIDIKitCoreTests/Events/Type Extensions/Double Extensions Tests.swift index fd74f92d86..e870c9acd8 100644 --- a/Tests/MIDIKitCoreTests/Events/Type Extensions/Double Extensions Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/Type Extensions/Double Extensions Tests.swift @@ -1,7 +1,7 @@ // // Double Extensions Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Events/Type Extensions/UInt32 Extensions Tests.swift b/Tests/MIDIKitCoreTests/Events/Type Extensions/UInt32 Extensions Tests.swift index 089f1203de..e1ef822546 100644 --- a/Tests/MIDIKitCoreTests/Events/Type Extensions/UInt32 Extensions Tests.swift +++ b/Tests/MIDIKitCoreTests/Events/Type Extensions/UInt32 Extensions Tests.swift @@ -1,7 +1,7 @@ // // UInt32 Extensions Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/MIDIKitCoreTests.swift b/Tests/MIDIKitCoreTests/MIDIKitCoreTests.swift index aaf74876ca..f6a7ae68c8 100644 --- a/Tests/MIDIKitCoreTests/MIDIKitCoreTests.swift +++ b/Tests/MIDIKitCoreTests/MIDIKitCoreTests.swift @@ -1,7 +1,7 @@ // // MIDIKitCoreTests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Types/BytePair Tests.swift b/Tests/MIDIKitCoreTests/Types/BytePair Tests.swift index 6b5c8572a2..f6411e6e7b 100644 --- a/Tests/MIDIKitCoreTests/Types/BytePair Tests.swift +++ b/Tests/MIDIKitCoreTests/Types/BytePair Tests.swift @@ -1,7 +1,7 @@ // // BytePair Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Types/Int7 Tests.swift b/Tests/MIDIKitCoreTests/Types/Int7 Tests.swift index c94e76bb6b..bba17c32bc 100644 --- a/Tests/MIDIKitCoreTests/Types/Int7 Tests.swift +++ b/Tests/MIDIKitCoreTests/Types/Int7 Tests.swift @@ -1,7 +1,7 @@ // // Int7 Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Types/UInt14 Tests.swift b/Tests/MIDIKitCoreTests/Types/UInt14 Tests.swift index 314af1c435..4407922240 100644 --- a/Tests/MIDIKitCoreTests/Types/UInt14 Tests.swift +++ b/Tests/MIDIKitCoreTests/Types/UInt14 Tests.swift @@ -1,7 +1,7 @@ // // UInt14 Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Types/UInt25 Tests.swift b/Tests/MIDIKitCoreTests/Types/UInt25 Tests.swift index aa07071a45..ea50131b87 100644 --- a/Tests/MIDIKitCoreTests/Types/UInt25 Tests.swift +++ b/Tests/MIDIKitCoreTests/Types/UInt25 Tests.swift @@ -1,7 +1,7 @@ // // UInt25 Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Types/UInt4 Tests.swift b/Tests/MIDIKitCoreTests/Types/UInt4 Tests.swift index 1142e07af3..bed5388b7a 100644 --- a/Tests/MIDIKitCoreTests/Types/UInt4 Tests.swift +++ b/Tests/MIDIKitCoreTests/Types/UInt4 Tests.swift @@ -1,7 +1,7 @@ // // UInt4 Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Types/UInt7 Tests.swift b/Tests/MIDIKitCoreTests/Types/UInt7 Tests.swift index d8fad55b55..244f858633 100644 --- a/Tests/MIDIKitCoreTests/Types/UInt7 Tests.swift +++ b/Tests/MIDIKitCoreTests/Types/UInt7 Tests.swift @@ -1,7 +1,7 @@ // // UInt7 Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Types/UInt7Pair Tests.swift b/Tests/MIDIKitCoreTests/Types/UInt7Pair Tests.swift index 17f289debc..76749a83fd 100644 --- a/Tests/MIDIKitCoreTests/Types/UInt7Pair Tests.swift +++ b/Tests/MIDIKitCoreTests/Types/UInt7Pair Tests.swift @@ -1,7 +1,7 @@ // // UInt7Pair Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Types/UInt8 (Byte) Tests.swift b/Tests/MIDIKitCoreTests/Types/UInt8 (Byte) Tests.swift index 7329ffbed1..a26eb3187a 100644 --- a/Tests/MIDIKitCoreTests/Types/UInt8 (Byte) Tests.swift +++ b/Tests/MIDIKitCoreTests/Types/UInt8 (Byte) Tests.swift @@ -1,7 +1,7 @@ // // UInt8 (Byte) Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Types/UInt9 Tests.swift b/Tests/MIDIKitCoreTests/Types/UInt9 Tests.swift index 3fbc1c510b..895e9bc13d 100644 --- a/Tests/MIDIKitCoreTests/Types/UInt9 Tests.swift +++ b/Tests/MIDIKitCoreTests/Types/UInt9 Tests.swift @@ -1,7 +1,7 @@ // // UInt9 Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Types/UMPWord Tests.swift b/Tests/MIDIKitCoreTests/Types/UMPWord Tests.swift index cb140c95e3..c6a202b857 100644 --- a/Tests/MIDIKitCoreTests/Types/UMPWord Tests.swift +++ b/Tests/MIDIKitCoreTests/Types/UMPWord Tests.swift @@ -1,7 +1,7 @@ // // UMPWord Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Utilities/Number Formatting Tests.swift b/Tests/MIDIKitCoreTests/Utilities/Number Formatting Tests.swift index 0996adde80..2a1c0f29ae 100644 --- a/Tests/MIDIKitCoreTests/Utilities/Number Formatting Tests.swift +++ b/Tests/MIDIKitCoreTests/Utilities/Number Formatting Tests.swift @@ -1,7 +1,7 @@ // // Number Formatting Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Utilities/RandomAccessCollection Tests.swift b/Tests/MIDIKitCoreTests/Utilities/RandomAccessCollection Tests.swift index 593d43c2b5..c1319aa4c3 100644 --- a/Tests/MIDIKitCoreTests/Utilities/RandomAccessCollection Tests.swift +++ b/Tests/MIDIKitCoreTests/Utilities/RandomAccessCollection Tests.swift @@ -1,7 +1,7 @@ // // RandomAccessCollection Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitCoreTests/Utilities/String Formatting Tests.swift b/Tests/MIDIKitCoreTests/Utilities/String Formatting Tests.swift index 5812cc06db..cf82f6709a 100644 --- a/Tests/MIDIKitCoreTests/Utilities/String Formatting Tests.swift +++ b/Tests/MIDIKitCoreTests/Utilities/String Formatting Tests.swift @@ -1,7 +1,7 @@ // // String Formatting Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitIOTests/AnyMIDIEndpoint/AnyMIDIEndpoint Tests.swift b/Tests/MIDIKitIOTests/AnyMIDIEndpoint/AnyMIDIEndpoint Tests.swift index c7a84a1190..27786e6d78 100644 --- a/Tests/MIDIKitIOTests/AnyMIDIEndpoint/AnyMIDIEndpoint Tests.swift +++ b/Tests/MIDIKitIOTests/AnyMIDIEndpoint/AnyMIDIEndpoint Tests.swift @@ -1,10 +1,11 @@ // // AnyMIDIEndpoint Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // -// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI ports, so skip these tests on iOS targets +// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI +// ports, so skip these tests on iOS targets #if shouldTestCurrentPlatform && !targetEnvironment(simulator) import XCTest diff --git a/Tests/MIDIKitIOTests/Core MIDI/Core MIDI Thru Connections Tests.swift b/Tests/MIDIKitIOTests/Core MIDI/Core MIDI Thru Connections Tests.swift index 455f2f526d..62c0bd2e1c 100644 --- a/Tests/MIDIKitIOTests/Core MIDI/Core MIDI Thru Connections Tests.swift +++ b/Tests/MIDIKitIOTests/Core MIDI/Core MIDI Thru Connections Tests.swift @@ -1,7 +1,7 @@ // // Core MIDI Thru Connections Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform && !os(tvOS) && !os(watchOS) diff --git a/Tests/MIDIKitIOTests/Core MIDI/MIDIEventList/MIDIEventList Packets Tests.swift b/Tests/MIDIKitIOTests/Core MIDI/MIDIEventList/MIDIEventList Packets Tests.swift index fe8ac6a095..e245f6eac6 100644 --- a/Tests/MIDIKitIOTests/Core MIDI/MIDIEventList/MIDIEventList Packets Tests.swift +++ b/Tests/MIDIKitIOTests/Core MIDI/MIDIEventList/MIDIEventList Packets Tests.swift @@ -1,7 +1,7 @@ // // MIDIEventList Packets Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform && !os(tvOS) && !os(watchOS) @@ -26,7 +26,7 @@ final class MIDIEventListPackets_Tests: XCTestCase { ) func check(_ ptr: UnsafePointer) { - let packets = ptr.packets() + let packets = ptr.packets(refCon: nil, refConKnown: false) XCTAssertEqual( packets.map { $0.bytes }, @@ -56,7 +56,7 @@ final class MIDIEventListPackets_Tests: XCTestCase { ) func check(_ ptr: UnsafePointer) { - let packets = ptr.packets() + let packets = ptr.packets(refCon: nil, refConKnown: false) XCTAssertEqual( packets.map { $0.bytes }, @@ -89,7 +89,7 @@ final class MIDIEventListPackets_Tests: XCTestCase { ) func check(_ ptr: UnsafePointer) { - let packets = ptr.packets() + let packets = ptr.packets(refCon: nil, refConKnown: false) XCTAssertEqual( packets.map { $0.bytes }, @@ -124,7 +124,7 @@ final class MIDIEventListPackets_Tests: XCTestCase { ) func check(_ ptr: UnsafePointer) { - let packets = ptr.packets() + let packets = ptr.packets(refCon: nil, refConKnown: false) XCTAssertEqual( packets.map { $0.bytes }, diff --git a/Tests/MIDIKitIOTests/Errors/MIDIOSStatus Tests.swift b/Tests/MIDIKitIOTests/Errors/MIDIOSStatus Tests.swift index 8e39c1024f..0d5c0b3aef 100644 --- a/Tests/MIDIKitIOTests/Errors/MIDIOSStatus Tests.swift +++ b/Tests/MIDIKitIOTests/Errors/MIDIOSStatus Tests.swift @@ -1,7 +1,7 @@ // // MIDIOSStatus Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform && !os(tvOS) && !os(watchOS) diff --git a/Tests/MIDIKitIOTests/Integration Tests/Round Trip Tests.swift b/Tests/MIDIKitIOTests/Integration Tests/Round Trip Tests.swift index dde31840cd..dae05988dc 100644 --- a/Tests/MIDIKitIOTests/Integration Tests/Round Trip Tests.swift +++ b/Tests/MIDIKitIOTests/Integration Tests/Round Trip Tests.swift @@ -1,10 +1,11 @@ // // Round Trip Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // -// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI ports, so skip these tests on iOS targets +// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI +// ports, so skip these tests on iOS targets #if shouldTestCurrentPlatform && !targetEnvironment(simulator) import XCTest @@ -63,7 +64,7 @@ public class RoundTrip_Tests_Base: XCTestCase { try manager.addOutput( name: "MIDIKit Round Trip Tests Output", tag: outputTag, - uniqueID: .adHoc // allow system to generate random ID each time, without persistence + uniqueID: .adHoc // allow system to generate random ID each time, no persistence ) } catch let err as MIDIIOError { XCTFail(err.localizedDescription); return @@ -319,7 +320,8 @@ public class RoundTrip_Tests_Base: XCTestCase { print("Sent \(sourceEvents.count) events, received \(receivedEvents.count) events.") // itemize which source event(s) are missing from the received events, if any. - // this may reveal events that failed silently, were eaten by Core MIDI, or could not be parsed by the receiver. + // this may reveal events that failed silently, were eaten by Core MIDI, or could not be + // parsed by the receiver. sourceEvents.forEach { if !receivedEvents.contains($0) { print("Missing from received events:", $0) diff --git a/Tests/MIDIKitIOTests/MIDIEndpoint/Endpoint Hashable Tests.swift b/Tests/MIDIKitIOTests/MIDIEndpoint/Endpoint Hashable Tests.swift index 288e9d709b..a021e07bbc 100644 --- a/Tests/MIDIKitIOTests/MIDIEndpoint/Endpoint Hashable Tests.swift +++ b/Tests/MIDIKitIOTests/MIDIEndpoint/Endpoint Hashable Tests.swift @@ -1,7 +1,7 @@ // // Endpoint Hashable Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform && !os(tvOS) && !os(watchOS) diff --git a/Tests/MIDIKitIOTests/MIDIEndpoint/Endpoint Testing Utilities.swift b/Tests/MIDIKitIOTests/MIDIEndpoint/Endpoint Testing Utilities.swift index 56f3deaef1..419268dcec 100644 --- a/Tests/MIDIKitIOTests/MIDIEndpoint/Endpoint Testing Utilities.swift +++ b/Tests/MIDIKitIOTests/MIDIEndpoint/Endpoint Testing Utilities.swift @@ -1,7 +1,7 @@ // // Endpoint Testing Utilities.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform && !os(tvOS) && !os(watchOS) diff --git a/Tests/MIDIKitIOTests/MIDIEndpoint/MIDIEndpoint Collection Tests.swift b/Tests/MIDIKitIOTests/MIDIEndpoint/MIDIEndpoint Collection Tests.swift index 462023508a..8a2f7db9a0 100644 --- a/Tests/MIDIKitIOTests/MIDIEndpoint/MIDIEndpoint Collection Tests.swift +++ b/Tests/MIDIKitIOTests/MIDIEndpoint/MIDIEndpoint Collection Tests.swift @@ -1,7 +1,7 @@ // // MIDIEndpoint Collection Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform && !os(tvOS) && !os(watchOS) diff --git a/Tests/MIDIKitIOTests/MIDIEndpoint/MIDIEndpointIdentity Tests.swift b/Tests/MIDIKitIOTests/MIDIEndpoint/MIDIEndpointIdentity Tests.swift index 18ed5daf56..10741fb933 100644 --- a/Tests/MIDIKitIOTests/MIDIEndpoint/MIDIEndpointIdentity Tests.swift +++ b/Tests/MIDIKitIOTests/MIDIEndpoint/MIDIEndpointIdentity Tests.swift @@ -1,7 +1,7 @@ // // MIDIEndpointIdentity Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform && !os(tvOS) && !os(watchOS) diff --git a/Tests/MIDIKitIOTests/MIDIIOObject/MIDIIOObject Collection Tests.swift b/Tests/MIDIKitIOTests/MIDIIOObject/MIDIIOObject Collection Tests.swift index 8f534248b9..4b9e2e67c0 100644 --- a/Tests/MIDIKitIOTests/MIDIIOObject/MIDIIOObject Collection Tests.swift +++ b/Tests/MIDIKitIOTests/MIDIIOObject/MIDIIOObject Collection Tests.swift @@ -1,7 +1,7 @@ // // MIDIIOObject Collection Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform && !os(tvOS) && !os(watchOS) diff --git a/Tests/MIDIKitIOTests/MIDIInput/MIDIInput Tests.swift b/Tests/MIDIKitIOTests/MIDIInput/MIDIInput Tests.swift index 49dd4b8d08..fd6458fec0 100644 --- a/Tests/MIDIKitIOTests/MIDIInput/MIDIInput Tests.swift +++ b/Tests/MIDIKitIOTests/MIDIInput/MIDIInput Tests.swift @@ -1,10 +1,11 @@ // // MIDIInput Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // -// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI ports, so skip these tests on iOS targets +// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI +// ports, so skip these tests on iOS targets #if shouldTestCurrentPlatform && !targetEnvironment(simulator) import XCTest diff --git a/Tests/MIDIKitIOTests/MIDIInputConnection/MIDIInputConnection Tests.swift b/Tests/MIDIKitIOTests/MIDIInputConnection/MIDIInputConnection Tests.swift index cf7c068a9d..2575876d5c 100644 --- a/Tests/MIDIKitIOTests/MIDIInputConnection/MIDIInputConnection Tests.swift +++ b/Tests/MIDIKitIOTests/MIDIInputConnection/MIDIInputConnection Tests.swift @@ -1,10 +1,11 @@ // // MIDIInputConnection Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // -// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI ports, so skip these tests on iOS targets +// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI +// ports, so skip these tests on iOS targets #if shouldTestCurrentPlatform && !targetEnvironment(simulator) import XCTest @@ -132,7 +133,8 @@ final class MIDIInputConnection_Tests: XCTestCase { connEvents = [] } - /// Test to ensure a new output appearing in the system gets added to the connection. (Allowing manager-owned virtual outputs to be added) + /// Test to ensure a new output appearing in the system gets added to the connection. (Allowing + /// manager-owned virtual outputs to be added) func testInputConnection_allEndpoints() throws { let manager = MIDIManager( clientName: UUID().uuidString, @@ -189,7 +191,8 @@ final class MIDIInputConnection_Tests: XCTestCase { connEvents = [] } - /// Test to ensure creating a new manager-owned virtual output does not get added to the connection if `filter.owned == true` + /// Test to ensure creating a new manager-owned virtual output does not get added to the + /// connection if `filter.owned == true` func testInputConnection_allEndpoints_filterOwned() throws { let manager = MIDIManager( clientName: UUID().uuidString, @@ -247,7 +250,8 @@ final class MIDIInputConnection_Tests: XCTestCase { connEvents = [] } - /// Test to ensure virtual output(s) owned by the manager do not get added to the connection when creating the connection. + /// Test to ensure virtual output(s) owned by the manager do not get added to the connection + /// when creating the connection. func testInputConnection_filterOwned_onInit() throws { let manager = MIDIManager( clientName: UUID().uuidString, diff --git a/Tests/MIDIKitIOTests/MIDIKitIOTests.swift b/Tests/MIDIKitIOTests/MIDIKitIOTests.swift index 87d4e5ffd1..d71dd87832 100644 --- a/Tests/MIDIKitIOTests/MIDIKitIOTests.swift +++ b/Tests/MIDIKitIOTests/MIDIKitIOTests.swift @@ -1,7 +1,7 @@ // // MIDIKitIOTests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitIOTests/MIDIManager/MIDIManager MIDIIONotification Tests.swift b/Tests/MIDIKitIOTests/MIDIManager/MIDIManager MIDIIONotification Tests.swift index d309d88c1f..407ba627c5 100644 --- a/Tests/MIDIKitIOTests/MIDIManager/MIDIManager MIDIIONotification Tests.swift +++ b/Tests/MIDIKitIOTests/MIDIManager/MIDIManager MIDIIONotification Tests.swift @@ -1,10 +1,11 @@ // // MIDIManager MIDIIONotification Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // -// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI ports, so skip these tests on iOS targets +// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI +// ports, so skip these tests on iOS targets #if shouldTestCurrentPlatform && !targetEnvironment(simulator) import XCTest diff --git a/Tests/MIDIKitIOTests/MIDIManager/MIDIManager Public Tests.swift b/Tests/MIDIKitIOTests/MIDIManager/MIDIManager Public Tests.swift index 5ff6fd2b68..5feb65a275 100644 --- a/Tests/MIDIKitIOTests/MIDIManager/MIDIManager Public Tests.swift +++ b/Tests/MIDIKitIOTests/MIDIManager/MIDIManager Public Tests.swift @@ -1,7 +1,7 @@ // // MIDIManager Public Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform && !os(tvOS) && !os(watchOS) diff --git a/Tests/MIDIKitIOTests/MIDIManager/MIDIManager Tests.swift b/Tests/MIDIKitIOTests/MIDIManager/MIDIManager Tests.swift index 45579e1c43..e2964f116a 100644 --- a/Tests/MIDIKitIOTests/MIDIManager/MIDIManager Tests.swift +++ b/Tests/MIDIKitIOTests/MIDIManager/MIDIManager Tests.swift @@ -1,7 +1,7 @@ // // MIDIManager Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform && !os(tvOS) && !os(watchOS) diff --git a/Tests/MIDIKitIOTests/MIDIOutput/MIDIOutput Tests.swift b/Tests/MIDIKitIOTests/MIDIOutput/MIDIOutput Tests.swift index f169f173b4..1d2e42f78e 100644 --- a/Tests/MIDIKitIOTests/MIDIOutput/MIDIOutput Tests.swift +++ b/Tests/MIDIKitIOTests/MIDIOutput/MIDIOutput Tests.swift @@ -1,10 +1,11 @@ // // MIDIOutput Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // -// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI ports, so skip these tests on iOS targets +// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI +// ports, so skip these tests on iOS targets #if shouldTestCurrentPlatform && !targetEnvironment(simulator) import XCTest @@ -31,7 +32,7 @@ final class MIDIOutput_Tests: XCTestCase { try manager.addOutput( name: "MIDIKit IO Tests Source 1", tag: tag1, - uniqueID: .adHoc // allow system to generate random ID each time, without persistence + uniqueID: .adHoc // allow system to generate random ID each time, no persistence ) } catch let err as MIDIIOError { XCTFail(err.localizedDescription); return diff --git a/Tests/MIDIKitIOTests/MIDIOutputConnection/MIDIOutputConnection Tests.swift b/Tests/MIDIKitIOTests/MIDIOutputConnection/MIDIOutputConnection Tests.swift index 418cdca845..28d5d47182 100644 --- a/Tests/MIDIKitIOTests/MIDIOutputConnection/MIDIOutputConnection Tests.swift +++ b/Tests/MIDIKitIOTests/MIDIOutputConnection/MIDIOutputConnection Tests.swift @@ -1,10 +1,11 @@ // // MIDIOutputConnection Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // -// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI ports, so skip these tests on iOS targets +// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI +// ports, so skip these tests on iOS targets #if shouldTestCurrentPlatform && !targetEnvironment(simulator) import XCTest @@ -133,7 +134,8 @@ final class MIDIOutputConnection_Tests: XCTestCase { input2Events = [] } - /// Test to ensure a new input appearing in the system gets added to the connection. (Allowing manager-owned virtual inputs to be added) + /// Test to ensure a new input appearing in the system gets added to the connection. (Allowing + /// manager-owned virtual inputs to be added) func testOutputConnection_allEndpoints() throws { let manager = MIDIManager( clientName: UUID().uuidString, @@ -195,7 +197,8 @@ final class MIDIOutputConnection_Tests: XCTestCase { input2Events = [] } - /// Test to ensure creating a new manager-owned virtual input does not get added to the connection if `filter.owned == true` + /// Test to ensure creating a new manager-owned virtual input does not get added to the + /// connection if `filter.owned == true` func testOutputConnection_allEndpoints_filterOwned() throws { let manager = MIDIManager( clientName: UUID().uuidString, @@ -257,7 +260,8 @@ final class MIDIOutputConnection_Tests: XCTestCase { input2Events = [] } - /// Test to ensure virtual input(s) owned by the manager do not get added to the connection when creating the connection. + /// Test to ensure virtual input(s) owned by the manager do not get added to the connection when + /// creating the connection. func testOutputConnection_filterOwned_onInit() throws { let manager = MIDIManager( clientName: UUID().uuidString, diff --git a/Tests/MIDIKitIOTests/MIDIThruConnection/MIDIThruConnection Tests.swift b/Tests/MIDIKitIOTests/MIDIThruConnection/MIDIThruConnection Tests.swift index ee4999efbd..12c6e3fddd 100644 --- a/Tests/MIDIKitIOTests/MIDIThruConnection/MIDIThruConnection Tests.swift +++ b/Tests/MIDIKitIOTests/MIDIThruConnection/MIDIThruConnection Tests.swift @@ -1,10 +1,11 @@ // // MIDIThruConnection Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // -// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI ports, so skip these tests on iOS targets +// iOS Simulator XCTest testing does not give enough permissions to allow creating virtual MIDI +// ports, so skip these tests on iOS targets #if shouldTestCurrentPlatform && !targetEnvironment(simulator) import XCTest @@ -195,7 +196,8 @@ final class MIDIThruConnection_Tests: XCTestCase { connEvents = [] } - /// Tests getting thru connection parameters from Core MIDI after creating the thru connection and verifying they are correct. + /// Tests getting thru connection parameters from Core MIDI after creating the thru connection + /// and verifying they are correct. func testGetParams() throws { try XCTSkipIf( !isThruConnectionsSupportedOnCurrentPlatform, diff --git a/Tests/MIDIKitIOTests/Parser/MIDI1Parser Tests.swift b/Tests/MIDIKitIOTests/Parser/MIDI1Parser Tests.swift index f58dc3c88b..dc759113d4 100644 --- a/Tests/MIDIKitIOTests/Parser/MIDI1Parser Tests.swift +++ b/Tests/MIDIKitIOTests/Parser/MIDI1Parser Tests.swift @@ -1,10 +1,10 @@ // // MIDI1Parser Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // -#if shouldTestCurrentPlatform +#if shouldTestCurrentPlatform && !os(tvOS) && !os(watchOS) import XCTest @testable import MIDIKitIO @@ -247,7 +247,7 @@ final class MIDI1Parser_Tests: XCTestCase { func testPacketData_parsedEvents_RunningStatus_SeparatePackets_Simple() { MIDI1Parser.default.runningStatus = nil - + var parsed = MIDIPacketData( bytes: [ 0x92, @@ -261,12 +261,12 @@ final class MIDI1Parser_Tests: XCTestCase { parsed, [.noteOn(60, velocity: .midi1(64), channel: 2)] ) - + XCTAssertEqual( MIDI1Parser.default.runningStatus, 0x92 ) - + parsed = MIDIPacketData( bytes: [ 0x3E, 0x42 @@ -274,17 +274,17 @@ final class MIDI1Parser_Tests: XCTestCase { timeStamp: .zero ) .parsedEvents() - + XCTAssertEqual( parsed, [.noteOn(62, velocity: .midi1(66), channel: 2)] ) - + XCTAssertEqual( MIDI1Parser.default.runningStatus, 0x92 ) - + parsed = MIDIPacketData( bytes: [ 0x84, @@ -323,22 +323,23 @@ final class MIDI1Parser_Tests: XCTestCase { 0xFE: [.activeSensing(group: 0)], 0xFF: [.systemReset(group: 0)] ] - + // tests - + // preface: - // MIDI 1.0 Spec: "Real-Time messages can be sent at any time and may be inserted anywhere in a MIDI data stream, including between Status and Data bytes of any other MIDI messages." - + // MIDI 1.0 Spec: "Real-Time messages can be sent at any time and may be inserted anywhere + // in a MIDI data stream, including between Status and Data bytes of any other MIDI + // messages." + // ------------------------------------------------ - + // test: real-time message byte in between status and data byte(s) of a CV message // result: should produce the CV message and the real-time message - + systemRealTimeMessages.forEach { realTimeMessage in - let realTimeByte = realTimeMessage.key let realTimeEvent = realTimeMessage.value - + XCTAssertEqual( parsedEvents( bytes: [0x90, @@ -348,7 +349,7 @@ final class MIDI1Parser_Tests: XCTestCase { realTimeEvent + [.noteOn(60, velocity: .midi1(64), channel: 0)] ) - + XCTAssertEqual( parsedEvents( bytes: [0x90, 0x3C, @@ -368,7 +369,7 @@ final class MIDI1Parser_Tests: XCTestCase { MIDIPacketData(bytes: bytes, timeStamp: .zero) .parsedEvents() } - + let systemRealTimeMessages: [UInt8 : [MIDIEvent]] = [ 0xF8: [.timingClock(group: 0)], 0xF9: [], // undefined @@ -379,19 +380,18 @@ final class MIDI1Parser_Tests: XCTestCase { 0xFE: [.activeSensing(group: 0)], 0xFF: [.systemReset(group: 0)] ] - + // tests - + // premise: test that real-time system messages reset Running Status - + // test: full CV message, real-time system message, CV running status data bytes only // result: should produce two CV messages and a real-time message - + systemRealTimeMessages.forEach { realTimeMessage in - let realTimeByte = realTimeMessage.key let realTimeEvent = realTimeMessage.value - + // channel voice Running Status XCTAssertEqual( parsedEvents( @@ -405,7 +405,7 @@ final class MIDI1Parser_Tests: XCTestCase { + realTimeEvent + [.noteOn(61, velocity: .midi1(65), channel: 0)] ) - + // system real-time events are not a SysEx terminator XCTAssertEqual( parsedEvents( @@ -439,19 +439,18 @@ final class MIDI1Parser_Tests: XCTestCase { [0xF6] : [.tuneRequest(group: 0)], [0xF7] : [] // SysEx end ] - + // tests - + // premise: test that system common messages reset Running Status - + // test: full CV message, system common message, CV running status data bytes only // result: should produce the first CV messages and the system common message but not the second CV message - + systemCommonMessages.forEach { systemCommonMessage in - let commonBytes = systemCommonMessage.key let commonEvent = systemCommonMessage.value - + XCTAssertEqual( parsedEvents( bytes: [0x90, 0x3C, 0x40] // full CV note on message @@ -463,17 +462,16 @@ final class MIDI1Parser_Tests: XCTestCase { + commonEvent ) } - + // premise: a system common status byte should reset Running Status even if previous CV message was incomplete - + // test: incomplete CV message, then system common message starts // result: the incomplete CV message is discarded and the system common message succeeds - + systemCommonMessages.forEach { systemCommonMessage in - let commonBytes = systemCommonMessage.key let commonEvent = systemCommonMessage.value - + XCTAssertEqual( parsedEvents( bytes: [0x90, 0x3C] // first 2/3 bytes of CV note on message @@ -489,19 +487,19 @@ final class MIDI1Parser_Tests: XCTestCase { func testPacketData_parsedEvents_Malformed() { // template method - + func parsedEvents(bytes: [UInt8]) -> [MIDIEvent] { MIDIPacketData(bytes: bytes, timeStamp: .zero) .parsedEvents() } - + // tests - + // data bytes (< 0x80) are meaningless without a status byte or Running Status for byte: UInt8 in 0x00 ... 0x7F { XCTAssertEqual(parsedEvents(bytes: [byte]), []) } - + // note off // requires two data bytes to follow XCTAssertEqual(parsedEvents(bytes: [0x80]), []) @@ -517,7 +515,7 @@ final class MIDI1Parser_Tests: XCTestCase { [.noteOff(0x3C, velocity: .midi1(0x40), channel: 0), .noteOff(0x3D, velocity: .midi1(0x41), channel: 0)] ) - + // note on // requires two data bytes to follow XCTAssertEqual(parsedEvents(bytes: [0x90]), []) @@ -533,7 +531,7 @@ final class MIDI1Parser_Tests: XCTestCase { [.noteOn(0x3C, velocity: .midi1(0x40), channel: 0), .noteOn(0x3D, velocity: .midi1(0x41), channel: 0)] ) - + // poly aftertouch // requires two data bytes to follow XCTAssertEqual(parsedEvents(bytes: [0xA0]), []) @@ -549,7 +547,7 @@ final class MIDI1Parser_Tests: XCTestCase { [.notePressure(note: 0x3C, amount: .midi1(0x40), channel: 0), .notePressure(note: 0x3D, amount: .midi1(0x41), channel: 0)] ) - + // cc // requires two data bytes to follow XCTAssertEqual(parsedEvents(bytes: [0xB0]), []) @@ -565,7 +563,7 @@ final class MIDI1Parser_Tests: XCTestCase { [.cc(0x3C, value: .midi1(0x40), channel: 0), .cc(0x3D, value: .midi1(0x41), channel: 0)] ) - + // program change // requires one data byte to follow XCTAssertEqual(parsedEvents(bytes: [0xC0]), []) @@ -580,7 +578,7 @@ final class MIDI1Parser_Tests: XCTestCase { [.programChange(program: 0x3C, channel: 0), .programChange(program: 0x3D, channel: 0)] ) - + // channel aftertouch // requires one data byte to follow XCTAssertEqual(parsedEvents(bytes: [0xD0]), []) @@ -595,7 +593,7 @@ final class MIDI1Parser_Tests: XCTestCase { [.pressure(amount: .midi1(0x3C), channel: 0), .pressure(amount: .midi1(0x3D), channel: 0)] ) - + // pitch bend // requires two data bytes to follow XCTAssertEqual(parsedEvents(bytes: [0xE0]), []) @@ -611,15 +609,15 @@ final class MIDI1Parser_Tests: XCTestCase { [.pitchBend(value: .midi1(8192), channel: 0), .pitchBend(value: .midi1(8193), channel: 0)] ) - + // System Common - System Exclusive start // [0xF0, ... variable number of SysEx bytes] XCTAssertEqual(parsedEvents(bytes: [0xF0]), []) - + // System Common - Timecode quarter-frame // [0xF1, byte] XCTAssertEqual(parsedEvents(bytes: [0xF1]), []) - + // System Common - Song Position Pointer // [0xF2, lsb byte, msb byte] XCTAssertEqual(parsedEvents(bytes: [0xF2]), []) @@ -629,7 +627,7 @@ final class MIDI1Parser_Tests: XCTestCase { parsedEvents(bytes: [0xF2, 0x08, 0x00, 0x09, 0x00]), [.songPositionPointer(midiBeat: 8)] ) - + // System Common - Song Select // [0xF3, byte] XCTAssertEqual(parsedEvents(bytes: [0xF3]), []) @@ -643,52 +641,52 @@ final class MIDI1Parser_Tests: XCTestCase { parsedEvents(bytes: [0xF3, 0x3C, 0x3D]), [.songSelect(number: 0x3C)] ) - + // System Common - Undefined // [0xF4] // (undefined, not relevant to check in this test) - + // System Common - Undefined // [0xF5] // (undefined, not relevant to check in this test) - + // System Common - Tune Request // [0xF6] // single status byte message, not relevant to check in this test - + // System Common - System Exclusive End (EOX / End Of Exclusive) // [0xF7] // on its own without context, it's meaningless/invalid XCTAssertEqual(parsedEvents(bytes: [0xF7]), []) - + // System Real-Time - Timing Clock // [0xF8] // single status byte message, not relevant to check in this test - + // Real-Time - Undefined // [0xF9] // (undefined, not relevant to check in this test) - + // System Real-Time - Start // [0xFA] // single status byte message, not relevant to check in this test - + // System Real-Time - Continue // [0xFB] // single status byte message, not relevant to check in this test - + // System Real-Time - Stop // [0xFC] // single status byte message, not relevant to check in this test - + // System Real-Time - Undefined // [0xFD] // (undefined, not relevant to check in this test) - + // System Real-Time - Active Sensing // [0xFE] // single status byte message, not relevant to check in this test - + // System Real-Time - System Reset // [0xFF] // single status byte message, not relevant to check in this test @@ -696,31 +694,31 @@ final class MIDI1Parser_Tests: XCTestCase { func testPacketData_parsedEvents_SysEx() { // template method - + func parsedEvents(bytes: [UInt8]) -> [MIDIEvent] { MIDIPacketData(bytes: bytes, timeStamp: .zero) .parsedEvents() } - + // tests - + // test SysEx termination conditions: // - 0xF7 // - no termination byte // - new status byte - + // 0xF7 termination byte XCTAssertEqual( parsedEvents(bytes: [0xF0, 0x41, 0x01, 0x34, 0xF7]), [.sysEx7(manufacturer: .oneByte(0x41), data: [0x01, 0x34], group: 0)] ) - + // no termination byte XCTAssertEqual( parsedEvents(bytes: [0xF0, 0x41, 0x01, 0x34]), [.sysEx7(manufacturer: .oneByte(0x41), data: [0x01, 0x34], group: 0)] ) - + // new status byte (non-realtime) XCTAssertEqual( parsedEvents(bytes: [0xF0, 0x41, 0x01, 0x34, @@ -728,15 +726,16 @@ final class MIDI1Parser_Tests: XCTestCase { [.sysEx7(manufacturer: .oneByte(0x41), data: [0x01, 0x34], group: 0), .noteOn(60, velocity: .midi1(64), channel: 0, group: 0)] ) - - // system real-time events are not a SysEx terminator, as the parser does not look ahead and assumes the SysEx could continue to receive data bytes + + // system real-time events are not a SysEx terminator, as the parser does not + // look ahead and assumes the SysEx could continue to receive data bytes XCTAssertEqual( parsedEvents(bytes: [0xF0, 0x41, 0x01, 0x34, 0xFE]), [.activeSensing(group: 0), .sysEx7(manufacturer: .oneByte(0x41), data: [0x01, 0x34], group: 0)] ) - + // multiple SysEx messages in a single packet XCTAssertEqual( parsedEvents(bytes: [0xF0, 0x41, 0x01, 0x02, 0xF7, // 0xF7 termination @@ -744,7 +743,7 @@ final class MIDI1Parser_Tests: XCTestCase { [.sysEx7(manufacturer: .oneByte(0x41), data: [0x01, 0x02], group: 0), .sysEx7(manufacturer: .oneByte(0x42), data: [0x03, 0x04], group: 0)] ) - + // multiple SysEx messages in a single packet XCTAssertEqual( parsedEvents(bytes: [0xF0, 0x41, 0x01, 0x02, // no 0xF7 termination diff --git a/Tests/MIDIKitIOTests/Parser/MIDI2Parser Tests.swift b/Tests/MIDIKitIOTests/Parser/MIDI2Parser Tests.swift index 1942ecd706..485d8f093c 100644 --- a/Tests/MIDIKitIOTests/Parser/MIDI2Parser Tests.swift +++ b/Tests/MIDIKitIOTests/Parser/MIDI2Parser Tests.swift @@ -1,10 +1,10 @@ // // MIDI2Parser Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // -#if shouldTestCurrentPlatform +#if shouldTestCurrentPlatform && !os(tvOS) && !os(watchOS) import XCTest @testable import MIDIKitIO @@ -345,8 +345,10 @@ final class MIDI2Parser_Tests: XCTestCase { func testUniversalPacketData_parsedEvents_RunningStatus() { // MIDI 2.0 does not support/allow Running Status - // UMP packets containing MIDI 1.0 events must always be the entire, complete message including status byte - // UMP packets only ever contain a single discrete MIDI event, so Running Status within a single packet is not supported either + // UMP packets containing MIDI 1.0 events must always be the entire, complete message + // including status byte. + // UMP packets only ever contain a single discrete MIDI event, so Running Status within a + // single packet is not supported either // nothing to test } @@ -385,28 +387,32 @@ final class MIDI2Parser_Tests: XCTestCase { 0x00, 0x00, 0x00]), []) // note off - // - requires two data bytes to follow, which fills out the entire word without needing null byte padding + // - requires two data bytes to follow, which fills out the entire word without needing null + // byte padding // test data byte(s) > 127 XCTAssertEqual(parsedEvents(bytes: [0x20, 0x80, 0x80, 0x00]), []) XCTAssertEqual(parsedEvents(bytes: [0x20, 0x80, 0x00, 0x80]), []) XCTAssertEqual(parsedEvents(bytes: [0x20, 0x80, 0x80, 0x80]), []) // note on - // - requires two data bytes to follow, which fills out the entire word without needing null byte padding + // - requires two data bytes to follow, which fills out the entire word without needing null + // byte padding // test data byte(s) > 127 XCTAssertEqual(parsedEvents(bytes: [0x20, 0x90, 0x80, 0x00]), []) XCTAssertEqual(parsedEvents(bytes: [0x20, 0x90, 0x00, 0x80]), []) XCTAssertEqual(parsedEvents(bytes: [0x20, 0x90, 0x80, 0x80]), []) // note pressure - // - requires two data bytes to follow, which fills out the entire word without needing null byte padding + // - requires two data bytes to follow, which fills out the entire word without needing null + // byte padding // test data byte(s) > 127 XCTAssertEqual(parsedEvents(bytes: [0x20, 0xA0, 0x80, 0x00]), []) XCTAssertEqual(parsedEvents(bytes: [0x20, 0xA0, 0x00, 0x80]), []) XCTAssertEqual(parsedEvents(bytes: [0x20, 0xA0, 0x80, 0x80]), []) // cc - // - requires two data bytes to follow, which fills out the entire word without needing null byte padding + // - requires two data bytes to follow, which fills out the entire word without needing null + // byte padding // test data byte(s) > 127 XCTAssertEqual(parsedEvents(bytes: [0x20, 0xB0, 0x80, 0x00]), []) XCTAssertEqual(parsedEvents(bytes: [0x20, 0xB0, 0x00, 0x80]), []) @@ -414,7 +420,8 @@ final class MIDI2Parser_Tests: XCTestCase { // program change // - requires one data byte to follow, with one null byte trailing padding - // - trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual( parsedEvents(bytes: [0x20, 0xC0, 0x00, 0x80]), [.programChange(program: 0, channel: 0, group: 0)] @@ -425,7 +432,8 @@ final class MIDI2Parser_Tests: XCTestCase { // channel pressure // - requires one data byte to follow, with one null byte trailing padding - // - trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual( parsedEvents(bytes: [0x20, 0xD0, 0x00, 0x80]), [.pressure(amount: .midi1(0), channel: 0, group: 0)] @@ -435,7 +443,8 @@ final class MIDI2Parser_Tests: XCTestCase { XCTAssertEqual(parsedEvents(bytes: [0x20, 0xD0, 0x80, 0x80]), []) // pitch bend - // - requires two data bytes to follow, which fills out the entire word without needing null byte padding + // - requires two data bytes to follow, which fills out the entire word without needing null + // byte padding // test data byte(s) > 127 XCTAssertEqual(parsedEvents(bytes: [0x20, 0xE0, 0x80, 0x00]), []) XCTAssertEqual(parsedEvents(bytes: [0x20, 0xE0, 0x00, 0x80]), []) @@ -443,7 +452,8 @@ final class MIDI2Parser_Tests: XCTestCase { // System Common - System Exclusive start // - not allowed in UMP packets - test for rejection - // - UMP message type 0x2 (MIDI 1 channel voice) can only be used for MIDI 1 channel voice messages and not MIDI 1 sysex/common/realtime so this must be rejected + // - UMP message type 0x2 (MIDI 1 channel voice) can only be used for MIDI 1 channel voice + // messages and not MIDI 1 sysex/common/realtime so this must be rejected XCTAssertEqual(parsedEvents(bytes: [0x20, 0xF0, 0x00, 0x00]), []) XCTAssertEqual(parsedEvents(bytes: [0x20, 0xF0, 0x01, 0x02]), []) XCTAssertEqual(parsedEvents(bytes: [0x20, 0xF0, 0x01, 0xF7]), []) @@ -454,7 +464,8 @@ final class MIDI2Parser_Tests: XCTestCase { 0x03, 0x04, 0x05, 0x06]), []) XCTAssertEqual(parsedEvents(bytes: [0x20, 0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0xF7]), []) - // - SysEx7 must be 64-bit (8 byte / 2 UInt32 word) packet, so a 4 byte packet will be rejected. + // - SysEx7 must be 64-bit (8 byte / 2 UInt32 word) packet, so a 4 byte packet will be + // rejected. // - also, 0xF0 and 0xF7 bytes must be omitted in UMP SysEx packets XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF0, 0x00, 0x00]), []) XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF0, 0x01, 0x02]), []) @@ -494,7 +505,8 @@ final class MIDI2Parser_Tests: XCTestCase { parsedEvents(bytes: [0x10, 0xF3, 0x3C, 0x00]), [.songSelect(number: 0x3C)] ) - // - trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual( parsedEvents(bytes: [0x10, 0xF3, 0x3C, 0x80]), [.songSelect(number: 0x3C)] @@ -505,7 +517,8 @@ final class MIDI2Parser_Tests: XCTestCase { // System Common - Undefined // [msgtype+group, 0xF4, 0x00, 0x00] XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF4, 0x00, 0x00]), []) - // - trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF4, 0x80, 0x00]), []) XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF4, 0x00, 0x80]), []) XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF4, 0x80, 0x80]), []) @@ -513,7 +526,8 @@ final class MIDI2Parser_Tests: XCTestCase { // System Common - Undefined // [msgtype+group, 0xF5, 0x00, 0x00] XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF5, 0x00, 0x00]), []) - // -trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF5, 0x80, 0x00]), []) XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF5, 0x00, 0x80]), []) XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF5, 0x80, 0x80]), []) @@ -524,7 +538,8 @@ final class MIDI2Parser_Tests: XCTestCase { parsedEvents(bytes: [0x10, 0xF6, 0x00, 0x00]), [.tuneRequest(group: 0x0)] ) - // -trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual( parsedEvents(bytes: [0x10, 0xF6, 0x80, 0x00]), [.tuneRequest(group: 0x0)] @@ -540,9 +555,11 @@ final class MIDI2Parser_Tests: XCTestCase { // System Common - System Exclusive End (EOX / End Of Exclusive) // - not allowed in UMP packets - test for rejection - // - UMP message type 0x2 (MIDI 1 channel voice) can only be used for MIDI 1 channel voice messages and not MIDI 1 sysex/common/realtime so this must be rejected + // - UMP message type 0x2 (MIDI 1 channel voice) can only be used for MIDI 1 channel voice + // messages and not MIDI 1 sysex/common/realtime so this must be rejected XCTAssertEqual(parsedEvents(bytes: [0x20, 0xF7, 0x01, 0x00]), []) - // - SysEx7 must be 64-bit (8 byte / 2 UInt32 word) packet, so a 4 byte packet will be rejected. + // - SysEx7 must be 64-bit (8 byte / 2 UInt32 word) packet, so a 4 byte packet will be + // rejected. // - also, 0xF0 and 0xF7 bytes must be omitted in UMP SysEx packets XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF7, 0x01, 0x00]), []) @@ -552,7 +569,8 @@ final class MIDI2Parser_Tests: XCTestCase { parsedEvents(bytes: [0x10, 0xF8, 0x00, 0x00]), [.timingClock(group: 0x0)] ) - // - trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual( parsedEvents(bytes: [0x10, 0xF8, 0x80, 0x00]), [.timingClock(group: 0x0)] @@ -569,7 +587,8 @@ final class MIDI2Parser_Tests: XCTestCase { // Real-Time - Undefined // [msgtype+group, 0xF9, 0x00, 0x00] XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF9, 0x00, 0x00]), []) - // - trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF9, 0x80, 0x00]), []) XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF9, 0x00, 0x80]), []) XCTAssertEqual(parsedEvents(bytes: [0x10, 0xF9, 0x80, 0x80]), []) @@ -580,7 +599,8 @@ final class MIDI2Parser_Tests: XCTestCase { parsedEvents(bytes: [0x10, 0xFA, 0x00, 0x00]), [.start(group: 0x0)] ) - // - trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual( parsedEvents(bytes: [0x10, 0xFA, 0x80, 0x00]), [.start(group: 0x0)] @@ -600,7 +620,8 @@ final class MIDI2Parser_Tests: XCTestCase { parsedEvents(bytes: [0x10, 0xFB, 0x00, 0x00]), [.continue(group: 0x0)] ) - // - trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual( parsedEvents(bytes: [0x10, 0xFB, 0x80, 0x00]), [.continue(group: 0x0)] @@ -620,7 +641,8 @@ final class MIDI2Parser_Tests: XCTestCase { parsedEvents(bytes: [0x10, 0xFC, 0x00, 0x00]), [.stop(group: 0x0)] ) - // - trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual( parsedEvents(bytes: [0x10, 0xFC, 0x80, 0x00]), [.stop(group: 0x0)] @@ -637,7 +659,8 @@ final class MIDI2Parser_Tests: XCTestCase { // System Real-Time - Undefined // [msgtype+group, 0xFD, 0x00, 0x00] XCTAssertEqual(parsedEvents(bytes: [0x10, 0xFD, 0x00, 0x00]), []) - // - trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual(parsedEvents(bytes: [0x10, 0xFD, 0x80, 0x00]), []) XCTAssertEqual(parsedEvents(bytes: [0x10, 0xFD, 0x00, 0x80]), []) XCTAssertEqual(parsedEvents(bytes: [0x10, 0xFD, 0x80, 0x80]), []) @@ -649,7 +672,8 @@ final class MIDI2Parser_Tests: XCTestCase { parsedEvents(bytes: [0x10, 0xFE, 0x00, 0x00]), [.activeSensing(group: 0x0)] ) - // - trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual( parsedEvents(bytes: [0x10, 0xFE, 0x80, 0x00]), [.activeSensing(group: 0x0)] @@ -669,7 +693,8 @@ final class MIDI2Parser_Tests: XCTestCase { parsedEvents(bytes: [0x10, 0xFF, 0x00, 0x00]), [.systemReset(group: 0x0)] ) - // - trailing bytes should be null (0x00) but it doesn't really matter what they are since they are discarded and merely there to fill out all four bytes of the UInt32 word + // - trailing bytes should be null (0x00) but it doesn't really matter what they are since + // they are discarded and merely there to fill out all four bytes of the UInt32 word XCTAssertEqual( parsedEvents(bytes: [0x10, 0xFF, 0x80, 0x00]), [.systemReset(group: 0x0)] diff --git a/Tests/MIDIKitIOTests/Tests Constants.swift b/Tests/MIDIKitIOTests/Tests Constants.swift index f06082ac82..30f56d46ae 100644 --- a/Tests/MIDIKitIOTests/Tests Constants.swift +++ b/Tests/MIDIKitIOTests/Tests Constants.swift @@ -1,7 +1,7 @@ // // Tests Constants.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Chunk/Header Tests.swift b/Tests/MIDIKitSMFTests/Chunk/Header Tests.swift index f79da597c6..73ca1039fd 100644 --- a/Tests/MIDIKitSMFTests/Chunk/Header Tests.swift +++ b/Tests/MIDIKitSMFTests/Chunk/Header Tests.swift @@ -1,7 +1,7 @@ // // Header Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Chunk/Track Tests.swift b/Tests/MIDIKitSMFTests/Chunk/Track Tests.swift index f86fa18c39..a853dd210a 100644 --- a/Tests/MIDIKitSMFTests/Chunk/Track Tests.swift +++ b/Tests/MIDIKitSMFTests/Chunk/Track Tests.swift @@ -1,7 +1,7 @@ // // Track Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Chunk/UnrecognizedChunk Tests.swift b/Tests/MIDIKitSMFTests/Chunk/UnrecognizedChunk Tests.swift index fa64d95bb9..f02eb8f6ce 100644 --- a/Tests/MIDIKitSMFTests/Chunk/UnrecognizedChunk Tests.swift +++ b/Tests/MIDIKitSMFTests/Chunk/UnrecognizedChunk Tests.swift @@ -1,7 +1,7 @@ // // UnrecognizedChunk Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Event Conversion Tests.swift b/Tests/MIDIKitSMFTests/Event/Event Conversion Tests.swift index ef043a4cd8..ffe67274dd 100644 --- a/Tests/MIDIKitSMFTests/Event/Event Conversion Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Event Conversion Tests.swift @@ -1,7 +1,7 @@ // // Event Conversion Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform @@ -82,7 +82,7 @@ final class Event_Conversion_EventToSMFEvent_Tests: XCTestCase { let smfEvent = event.smfEvent(delta: .ticks(120)) // no equivalent SMF event exists - // (however with the upcoming Standard MIDI File 2.0 spec, this may be implemented in future) + // (with the upcoming Standard MIDI File 2.0 spec, this may be implemented in future) XCTAssertNil(smfEvent) } @@ -98,7 +98,7 @@ final class Event_Conversion_EventToSMFEvent_Tests: XCTestCase { let smfEvent = event.smfEvent(delta: .ticks(120)) // no equivalent SMF event exists - // (however with the upcoming Standard MIDI File 2.0 spec, this may be implemented in future) + // (with the upcoming Standard MIDI File 2.0 spec, this may be implemented in future) XCTAssertNil(smfEvent) } @@ -142,7 +142,7 @@ final class Event_Conversion_EventToSMFEvent_Tests: XCTestCase { let smfEvent = event.smfEvent(delta: .ticks(120)) // no equivalent SMF event exists - // (however with the upcoming Standard MIDI File 2.0 spec, this may be implemented in future) + // (with the upcoming Standard MIDI File 2.0 spec, this may be implemented in future) XCTAssertNil(smfEvent) } @@ -432,7 +432,8 @@ final class Event_Conversion_EventToSMFEvent_Tests: XCTestCase { let smfEvent = event.smfEvent(delta: .ticks(120)) // not an event that can be stored in a MIDI file, only applicable to live MIDI I/O - // (A system reset message byte (0xFF) is reserved in the MIDI file format as the start byte for various MIDI file-specific event types.) + // (A system reset message byte (0xFF) is reserved in the MIDI file format as the start byte + // for various MIDI file-specific event types.) XCTAssertNil(smfEvent) } } diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event CC Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event CC Tests.swift index b970dc6131..fceed0ad68 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event CC Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event CC Tests.swift @@ -1,7 +1,7 @@ // // Event CC Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event ChannelPrefix Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event ChannelPrefix Tests.swift index 7d995b5f1c..eb337e9edf 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event ChannelPrefix Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event ChannelPrefix Tests.swift @@ -1,7 +1,7 @@ // // Event ChannelPrefix Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event KeySignature Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event KeySignature Tests.swift index 41d43aecdf..f828372f77 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event KeySignature Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event KeySignature Tests.swift @@ -1,7 +1,7 @@ // // Event KeySignature Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event Note Off Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event Note Off Tests.swift index 2db9084b05..98cd23189a 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event Note Off Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event Note Off Tests.swift @@ -1,7 +1,7 @@ // // Event Note Off Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event Note On Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event Note On Tests.swift index ba549be41f..f2b8958e17 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event Note On Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event Note On Tests.swift @@ -1,7 +1,7 @@ // // Event Note On Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event Note Pressure Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event Note Pressure Tests.swift index 03c7fa9f5a..6e1088daad 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event Note Pressure Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event Note Pressure Tests.swift @@ -1,7 +1,7 @@ // // Event Note Pressure Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event PitchBend Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event PitchBend Tests.swift index b635bd561c..68dda3df84 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event PitchBend Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event PitchBend Tests.swift @@ -1,7 +1,7 @@ // // Event PitchBend Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event PortPrefix Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event PortPrefix Tests.swift index 041e7d0523..f15c5b5447 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event PortPrefix Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event PortPrefix Tests.swift @@ -1,7 +1,7 @@ // // Event PortPrefix Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event Pressure Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event Pressure Tests.swift index 0f1991833e..0987546581 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event Pressure Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event Pressure Tests.swift @@ -1,7 +1,7 @@ // // Event Pressure Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event ProgramChange Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event ProgramChange Tests.swift index f9cf3365af..021c20f5ba 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event ProgramChange Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event ProgramChange Tests.swift @@ -1,7 +1,7 @@ // // Event ProgramChange Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event SMPTEOffset Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event SMPTEOffset Tests.swift index 0e8782359d..5a5e359230 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event SMPTEOffset Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event SMPTEOffset Tests.swift @@ -1,7 +1,7 @@ // // Event SMPTEOffset Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event SequenceNumber Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event SequenceNumber Tests.swift index ea001a3d73..6d8a1291de 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event SequenceNumber Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event SequenceNumber Tests.swift @@ -1,7 +1,7 @@ // // Event SequenceNumber Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event SequencerSpecific Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event SequencerSpecific Tests.swift index 3503bc8f01..649ce52eb4 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event SequencerSpecific Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event SequencerSpecific Tests.swift @@ -1,7 +1,7 @@ // // Event SequencerSpecific Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event SysEx7 Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event SysEx7 Tests.swift index 0800e76f2d..7da1e4efa2 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event SysEx7 Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event SysEx7 Tests.swift @@ -1,7 +1,7 @@ // // Event SysEx7 Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event Tempo Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event Tempo Tests.swift index 1cc6e16d36..4729e57b39 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event Tempo Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event Tempo Tests.swift @@ -1,7 +1,7 @@ // // Event Tempo Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event Text Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event Text Tests.swift index 985ad1f651..ed736df386 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event Text Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event Text Tests.swift @@ -1,7 +1,7 @@ // // Event Text Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event TimeSignature Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event TimeSignature Tests.swift index 18938f5c3b..bdfe99aa54 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event TimeSignature Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event TimeSignature Tests.swift @@ -1,7 +1,7 @@ // // Event TimeSignature Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event UnrecognizedMeta Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event UnrecognizedMeta Tests.swift index ea086870b5..327e87f142 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event UnrecognizedMeta Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event UnrecognizedMeta Tests.swift @@ -1,7 +1,7 @@ // // Event UnrecognizedMeta Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Event/Events/Event XMFPatchTypePrefix Tests.swift b/Tests/MIDIKitSMFTests/Event/Events/Event XMFPatchTypePrefix Tests.swift index d65bdc5f22..d53fef91b7 100644 --- a/Tests/MIDIKitSMFTests/Event/Events/Event XMFPatchTypePrefix Tests.swift +++ b/Tests/MIDIKitSMFTests/Event/Events/Event XMFPatchTypePrefix Tests.swift @@ -1,7 +1,7 @@ // // Event XMFPatchTypePrefix Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/MIDI File Tests Constants.swift b/Tests/MIDIKitSMFTests/MIDI File Tests Constants.swift index d7c3e819e6..bbb48b3f7f 100644 --- a/Tests/MIDIKitSMFTests/MIDI File Tests Constants.swift +++ b/Tests/MIDIKitSMFTests/MIDI File Tests Constants.swift @@ -1,7 +1,7 @@ // // MIDI File Tests Constants.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // import MIDIKitSMF diff --git a/Tests/MIDIKitSMFTests/MIDI File Utilities Tests.swift b/Tests/MIDIKitSMFTests/MIDI File Utilities Tests.swift index 84e01f8811..7e8e5b04bc 100644 --- a/Tests/MIDIKitSMFTests/MIDI File Utilities Tests.swift +++ b/Tests/MIDIKitSMFTests/MIDI File Utilities Tests.swift @@ -1,7 +1,7 @@ // // MIDI File Utilities Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/MIDI File decode Tests.swift b/Tests/MIDIKitSMFTests/MIDI File decode Tests.swift index 185cba314f..76253b999c 100644 --- a/Tests/MIDIKitSMFTests/MIDI File decode Tests.swift +++ b/Tests/MIDIKitSMFTests/MIDI File decode Tests.swift @@ -1,7 +1,7 @@ // // MIDI File decode Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/MIDI File encode Tests.swift b/Tests/MIDIKitSMFTests/MIDI File encode Tests.swift index 9344587d0c..cbdad5bc5e 100644 --- a/Tests/MIDIKitSMFTests/MIDI File encode Tests.swift +++ b/Tests/MIDIKitSMFTests/MIDI File encode Tests.swift @@ -1,7 +1,7 @@ // // MIDI File encode Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/MIDIKitSMFTests.swift b/Tests/MIDIKitSMFTests/MIDIKitSMFTests.swift index 5c59985011..a6b2eeed83 100644 --- a/Tests/MIDIKitSMFTests/MIDIKitSMFTests.swift +++ b/Tests/MIDIKitSMFTests/MIDIKitSMFTests.swift @@ -1,7 +1,7 @@ // // MIDIKitSMFTests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSMFTests/Types/Timing Tests.swift b/Tests/MIDIKitSMFTests/Types/Timing Tests.swift index b2d3b301d1..dd219087bd 100644 --- a/Tests/MIDIKitSMFTests/Types/Timing Tests.swift +++ b/Tests/MIDIKitSMFTests/Types/Timing Tests.swift @@ -1,7 +1,7 @@ // // Timing Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSyncTests/MIDIKitSyncTests.swift b/Tests/MIDIKitSyncTests/MIDIKitSyncTests.swift index 3589d1dfb1..153e296dd1 100644 --- a/Tests/MIDIKitSyncTests/MIDIKitSyncTests.swift +++ b/Tests/MIDIKitSyncTests/MIDIKitSyncTests.swift @@ -1,7 +1,7 @@ // // MIDIKitSyncTests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSyncTests/MTC/Generator/MTC Encoder Tests.swift b/Tests/MIDIKitSyncTests/MTC/Generator/MTC Encoder Tests.swift index 27f8268773..f03f6ea241 100644 --- a/Tests/MIDIKitSyncTests/MTC/Generator/MTC Encoder Tests.swift +++ b/Tests/MIDIKitSyncTests/MTC/Generator/MTC Encoder Tests.swift @@ -1,7 +1,7 @@ // // MTC Encoder Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform @@ -38,7 +38,8 @@ final class MTC_Generator_Encoder_Tests: XCTestCase { } func testMTC_Encoder_Timecode_NominalRates() { - // perform a spot-check to ensure the .timecode property is returning expected Timecode for nominal (non-scaling) frame rates + // perform a spot-check to ensure the .timecode property is returning + // expected Timecode for nominal (non-scaling) frame rates var mtcEnc: MTCEncoder! @@ -388,7 +389,8 @@ final class MTC_Generator_Encoder_Tests: XCTestCase { // round raw MTC frame number down to an even number, as per MTC spec let originFrame: Int - // (include non-drop rates in switch case even though they won't be traversed, for sake of being exhaustive) + // (include non-drop rates in switch case even though they won't be + // traversed, for sake of being exhaustive) switch $0 { case ._23_976, ._24, ._24_98, ._25, ._29_97, ._29_97_drop, ._30, ._30_drop: // 1x multiplier diff --git a/Tests/MIDIKitSyncTests/MTC/Generator/MTC Generator Tests.swift b/Tests/MIDIKitSyncTests/MTC/Generator/MTC Generator Tests.swift index 8e42cb38f2..bc14b1c922 100644 --- a/Tests/MIDIKitSyncTests/MTC/Generator/MTC Generator Tests.swift +++ b/Tests/MIDIKitSyncTests/MTC/Generator/MTC Generator Tests.swift @@ -1,7 +1,7 @@ // // MTC Generator Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSyncTests/MTC/Integration/MTC Integration Tests.swift b/Tests/MIDIKitSyncTests/MTC/Integration/MTC Integration Tests.swift index 960149ce19..bb70d301d2 100644 --- a/Tests/MIDIKitSyncTests/MTC/Integration/MTC Integration Tests.swift +++ b/Tests/MIDIKitSyncTests/MTC/Integration/MTC Integration Tests.swift @@ -1,7 +1,7 @@ // // MTC Integration Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform @@ -451,7 +451,8 @@ final class MTC_Integration_Integration_Tests: XCTestCase { } func testMTC_Integration_EncoderDecoder_fullFrameBehavior() { - // test expected outcomes regarding Encoder.locate() and transmitting MTC full-frame messages + // test expected outcomes regarding Encoder.locate() and transmitting MTC full-frame + // messages // decoder @@ -543,7 +544,11 @@ final class MTC_Integration_Integration_Tests: XCTestCase { // edge cases // quarter-frame invalidation of last full-frame cache - // edge case: where the Encoder has locateBehavior == .ifDifferent, if the encoder produces quarter-frame messages it should clear its cache of last full-frame message produced so that in the rare case that we locate to the same full-frame message as the last full-frame message sent it succeeds instead of errantly preventing the message + // edge case: where the Encoder has locateBehavior == .ifDifferent, if the encoder produces + // quarter-frame messages it should clear its cache of last full-frame message produced so + // that in the rare case that we locate to the same full-frame message as the last + // full-frame + // message sent it succeeds instead of errantly preventing the message mtcEnc.locate( to: TCC(h: 1, m: 00, s: 00, f: 00).toTimecode(rawValuesAt: ._24), diff --git a/Tests/MIDIKitSyncTests/MTC/MIDISyncKitTests Constants.swift b/Tests/MIDIKitSyncTests/MTC/MIDISyncKitTests Constants.swift index 592669047d..4ea7618208 100644 --- a/Tests/MIDIKitSyncTests/MTC/MIDISyncKitTests Constants.swift +++ b/Tests/MIDIKitSyncTests/MTC/MIDISyncKitTests Constants.swift @@ -1,7 +1,7 @@ // // MIDISyncKitTests Constants.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSyncTests/MTC/MTC Direction Tests.swift b/Tests/MIDIKitSyncTests/MTC/MTC Direction Tests.swift index 32bd0dc992..e07e7c3293 100644 --- a/Tests/MIDIKitSyncTests/MTC/MTC Direction Tests.swift +++ b/Tests/MIDIKitSyncTests/MTC/MTC Direction Tests.swift @@ -1,7 +1,7 @@ // // MTC Direction Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSyncTests/MTC/MTC MTCFrameRate ScaledFrames Tests.swift b/Tests/MIDIKitSyncTests/MTC/MTC MTCFrameRate ScaledFrames Tests.swift index 2f8014800d..18a688f508 100644 --- a/Tests/MIDIKitSyncTests/MTC/MTC MTCFrameRate ScaledFrames Tests.swift +++ b/Tests/MIDIKitSyncTests/MTC/MTC MTCFrameRate ScaledFrames Tests.swift @@ -1,7 +1,7 @@ // // MTC MTCFrameRate ScaledFrames Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSyncTests/MTC/MTC MTCFrameRate Tests.swift b/Tests/MIDIKitSyncTests/MTC/MTC MTCFrameRate Tests.swift index 7ba14edb8b..13f3bae3f2 100644 --- a/Tests/MIDIKitSyncTests/MTC/MTC MTCFrameRate Tests.swift +++ b/Tests/MIDIKitSyncTests/MTC/MTC MTCFrameRate Tests.swift @@ -1,7 +1,7 @@ // // MTC MTCFrameRate Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSyncTests/MTC/MTC MTCFrameRate Translation Tests.swift b/Tests/MIDIKitSyncTests/MTC/MTC MTCFrameRate Translation Tests.swift index e89e94aecb..23bf365910 100644 --- a/Tests/MIDIKitSyncTests/MTC/MTC MTCFrameRate Translation Tests.swift +++ b/Tests/MIDIKitSyncTests/MTC/MTC MTCFrameRate Translation Tests.swift @@ -1,7 +1,7 @@ // // MTC MTCFrameRate Translation Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform @@ -12,9 +12,11 @@ import TimecodeKit final class MTC_MTCFrameRate_Translation_Tests: XCTestCase { func testMTC_MTCFrameRate_derivedFrameRates() { - // these tests may be pedantic, but we'll put them in any way since this acts as our source of truth + // these tests may be pedantic, but we'll put them in any way + // since this acts as our source of truth - // ensure all four MTC frame rate families return the correct matching derived timecode frame rates + // ensure all four MTC frame rate families return the correct + // matching derived timecode frame rates // MTC: 24 diff --git a/Tests/MIDIKitSyncTests/MTC/MTC Utilities Tests.swift b/Tests/MIDIKitSyncTests/MTC/MTC Utilities Tests.swift index 1588b86ed4..af51f27565 100644 --- a/Tests/MIDIKitSyncTests/MTC/MTC Utilities Tests.swift +++ b/Tests/MIDIKitSyncTests/MTC/MTC Utilities Tests.swift @@ -1,7 +1,7 @@ // // MTC Utilities Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSyncTests/MTC/Receiver/MTC Decoder Tests.swift b/Tests/MIDIKitSyncTests/MTC/Receiver/MTC Decoder Tests.swift index 3b1c1d2994..d81632e748 100644 --- a/Tests/MIDIKitSyncTests/MTC/Receiver/MTC Decoder Tests.swift +++ b/Tests/MIDIKitSyncTests/MTC/Receiver/MTC Decoder Tests.swift @@ -1,7 +1,7 @@ // // MTC Decoder Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform @@ -11,6 +11,8 @@ import XCTest import TimecodeKit final class MTC_Receiver_Decoder_Tests: XCTestCase { + // swiftformat:options --maxwidth none + func testMTC_Decoder_Default() { let mtcDec = MTCDecoder() @@ -307,6 +309,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { func testMTC_Decoder_InternalState_QFMessages_25FPS() { // swiftformat:disable wrap + // swiftformat:disable wrapSingleLineComments // 25 fps behaves differently from 24/29.97d/30 MTC SMPTE rates @@ -326,7 +329,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110010)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000010)) // QF 0 MTC 01:00:00:00 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000010)) // QF 0 MTC 01:00:00:00 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -347,7 +350,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110010)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000011)) // QF 0 MTC 01:00:00:01 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000011)) // QF 0 MTC 01:00:00:01 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -368,7 +371,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110010)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00001000)) // QF 0 MTC 01:00:00:22 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00001000)) // QF 0 MTC 01:00:00:22 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -388,7 +391,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110010)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000001)) // QF 0 MTC 01:00:00:24 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000001)) // QF 0 MTC 01:00:00:24 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -428,7 +431,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110010)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000101)) // QF 0 MTC 01:00:01:03 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000101)) // QF 0 MTC 01:00:01:03 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -449,7 +452,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110010)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000111)) // QF 0 MTC 01:00:00:21 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000111)) // QF 0 MTC 01:00:00:21 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -469,7 +472,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110010)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000000)) // QF 0 MTC 01:00:00:23 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000000)) // QF 0 MTC 01:00:00:23 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -509,7 +512,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110010)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000100)) // QF 0 MTC 01:00:01:02 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000100)) // QF 0 MTC 01:00:01:02 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -517,10 +520,12 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { ) // swiftformat:enable wrap + // swiftformat:enable wrapSingleLineComments } func testMTC_Decoder_InternalState_QFMessages_2997DropFPS() { // swiftformat:disable wrap + // swiftformat:disable wrapSingleLineComments // test for edge cases and peculiarities with 29.97 drop fps @@ -539,7 +544,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110100)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000010)) // QF 0 MTC 01:00:00;00 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000010)) // QF 0 MTC 01:00:00;00 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -553,7 +558,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110100)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000100)) // QF 0 MTC 01:00:00;02 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000100)) // QF 0 MTC 01:00:00;02 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -573,7 +578,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110100)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00001100)) // QF 0 MTC 01:00:59;26 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00001100)) // QF 0 MTC 01:00:59;26 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -593,7 +598,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110100)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000010)) // QF 0 MTC 01:00:59;28 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000010)) // QF 0 MTC 01:00:59;28 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -623,7 +628,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00010000)) // QF 1 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00100000)) // QF 2 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00110000)) // QF 3 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01000001)) // QF 4 // sync qf // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01000001)) // QF 4 // sync qf XCTAssertEqual( mtcDec.timecode, @@ -633,7 +638,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110100)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000110)) // QF 0 MTC 01:01:00;04 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000110)) // QF 0 MTC 01:01:00;04 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -655,7 +660,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110100)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00001100)) // QF 0 MTC 01:00:59;26 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00001100)) // QF 0 MTC 01:00:59;26 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -675,7 +680,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01100001)) // QF 6 mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01110100)) // QF 7 - mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000010)) // QF 0 MTC 01:00:59;28 // sync qf + mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b00000010)) // QF 0 MTC 01:00:59;28 - sync qf XCTAssertEqual( mtcDec.timecode, @@ -721,10 +726,12 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { ) // swiftformat:enable wrap + // swiftformat:enable wrapSingleLineComments } func testMTC_Decoder_InternalState_QFMessages_Direction() { // swiftformat:disable wrap + // swiftformat:disable wrapSingleLineComments let mtcDec = MTCDecoder() @@ -772,6 +779,7 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { XCTAssertEqual(mtcDec.direction, .ambiguous) // swiftformat:enable wrap + // swiftformat:enable wrapSingleLineComments } func testMTC_Decoder_Handlers_FullFrameMessage() { @@ -823,6 +831,8 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { } func testMTC_Decoder_Handlers_QFMessages() { + // swiftformat:disable wrapSingleLineComments + // ensure expected callbacks are happening when they should, // and that they carry the data that they should @@ -1254,6 +1264,8 @@ final class MTC_Receiver_Decoder_Tests: XCTestCase { mtcDec.midiIn(event: .timecodeQuarterFrame(dataByte: 0b01010000)) // QF 5 XCTAssertEqual(_direction, .ambiguous) + + // swiftformat:enable wrapSingleLineComments } } diff --git a/Tests/MIDIKitSyncTests/MTC/Receiver/MTC Receiver SyncPolicy Tests.swift b/Tests/MIDIKitSyncTests/MTC/Receiver/MTC Receiver SyncPolicy Tests.swift index db30f06ee0..5e029269b6 100644 --- a/Tests/MIDIKitSyncTests/MTC/Receiver/MTC Receiver SyncPolicy Tests.swift +++ b/Tests/MIDIKitSyncTests/MTC/Receiver/MTC Receiver SyncPolicy Tests.swift @@ -1,7 +1,7 @@ // // MTC Receiver SyncPolicy Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform diff --git a/Tests/MIDIKitSyncTests/MTC/Receiver/MTC Receiver Tests.swift b/Tests/MIDIKitSyncTests/MTC/Receiver/MTC Receiver Tests.swift index da4b0e2fe6..1d19cd6429 100644 --- a/Tests/MIDIKitSyncTests/MTC/Receiver/MTC Receiver Tests.swift +++ b/Tests/MIDIKitSyncTests/MTC/Receiver/MTC Receiver Tests.swift @@ -1,7 +1,7 @@ // // MTC Receiver Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform @@ -87,7 +87,8 @@ final class MTC_Receiver_Receiver_Tests: XCTestCase { func testMTC_Receiver_InternalState_FullFrameMessage() { // test full frame MTC messages and check that properties get updated - // (Receiver.midiIn() is async internally so we need to wait for property updates to occur before reading them) + // (Receiver.midiIn() is async internally so we need to wait for property + // updates to occur before reading them) // init with local frame rate let mtcRec = MTCReceiver(name: "test", initialLocalFrameRate: ._24) @@ -129,9 +130,11 @@ final class MTC_Receiver_Receiver_Tests: XCTestCase { } func testMTC_Receiver_InternalState_FullFrameMessage_IncompatibleFrameRate() { - // test state does not become .incompatibleFrameRate when localFrameRate is present but not compatible with the MTC frame rate being received by the receiver + // test state does not become .incompatibleFrameRate when localFrameRate is present + // but not compatible with the MTC frame rate being received by the receiver - // (Receiver.midiIn() is async internally so we need to wait for property updates to occur before reading them) + // (Receiver.midiIn() is async internally so we need to wait for property + // updates to occur before reading them) // init with local frame rate let mtcRec = MTCReceiver(name: "test", initialLocalFrameRate: ._29_97) @@ -140,7 +143,8 @@ final class MTC_Receiver_Receiver_Tests: XCTestCase { mtcRec.midiIn(event: kMIDIEvent.MTC_FullFrame._01_02_03_04_at_24fps) wait(sec: 0.050) - // state should not change to .incompatibleFrameRate for full frame messages, only quarter frames + // state should not change to .incompatibleFrameRate for full frame messages, only quarter + // frames XCTAssertEqual(mtcRec.state, .idle) // timecode remains unchanged @@ -171,7 +175,8 @@ final class MTC_Receiver_Receiver_Tests: XCTestCase { // test MTC quarter-frame messages and check that properties get updated - // (Receiver.midiIn() is async internally so we need to wait for property updates to occur before reading them) + // (Receiver.midiIn() is async internally so we need to wait for property + // updates to occur before reading them) var isSuccess = false let asyncDoneExp = expectation(description: "Async test completed") @@ -228,7 +233,7 @@ final class MTC_Receiver_Receiver_Tests: XCTestCase { predictedLockTime: preSyncLockTime, lockTimecode: preSyncTimecode ) = mtcRec.state else { - XCTFail("Expected receiver state is preSync, but is a different state.") + XCTFail("Expected preSync receiver state.") asyncDoneExp.fulfill() return } @@ -236,7 +241,8 @@ final class MTC_Receiver_Receiver_Tests: XCTestCase { XCTAssertEqual(preSyncTimecode, lockTimecode) // depending on the system running these tests, this test may be too - // brittle/restrictive and the accuracy may need to be bumped up at some point in the future + // brittle/restrictive and the accuracy may need to be bumped up at some point in the + // future let lhs = (Double(preSyncLockTime.rawValue) / 10e8) + waitTime let rhs = Double(futureTime.rawValue) / 10e8 @@ -304,6 +310,7 @@ final class MTC_Receiver_Receiver_Tests: XCTestCase { func testMTC_Receiver_Handlers_QFMessages() { // swiftformat:disable wrap + // swiftformat:disable wrapSingleLineComments // ensure expected callbacks are happening when they should, // and that they carry the data that they should @@ -520,6 +527,7 @@ final class MTC_Receiver_Receiver_Tests: XCTestCase { XCTAssertEqual(_direction, .ambiguous) // swiftformat:enable wrap + // swiftformat:enable wrapSingleLineComments } } diff --git a/Tests/MIDIKitSyncTests/Stress Tests/Stress Tests.swift b/Tests/MIDIKitSyncTests/Stress Tests/Stress Tests.swift index 5e6fd87142..7a1f0b5a44 100644 --- a/Tests/MIDIKitSyncTests/Stress Tests/Stress Tests.swift +++ b/Tests/MIDIKitSyncTests/Stress Tests/Stress Tests.swift @@ -1,7 +1,7 @@ // // Stress Tests.swift // MIDIKit • https://github.com/orchetect/MIDIKit -// © 2022 Steffan Andrews • Licensed under MIT License +// © 2021-2022 Steffan Andrews • Licensed under MIT License // #if shouldTestCurrentPlatform @@ -56,7 +56,8 @@ final class StressTests: XCTestCase { func testThreadingMTCReceiver() { // MARK: - Receiver - // (Receiver.midiIn() is async internally so we need to wait for property updates to occur before reading them) + // (Receiver.midiIn() is async internally so we need to wait for + // property updates to occur before reading them) // init with local frame rate let mtcRec = MTCReceiver(name: "test", initialLocalFrameRate: ._24)