diff --git a/Examples/MIDISystemInfo/MIDISystemInfo.xcodeproj/project.pbxproj b/Examples/MIDISystemInfo/MIDISystemInfo.xcodeproj/project.pbxproj index f161a69b05..5030d09117 100644 --- a/Examples/MIDISystemInfo/MIDISystemInfo.xcodeproj/project.pbxproj +++ b/Examples/MIDISystemInfo/MIDISystemInfo.xcodeproj/project.pbxproj @@ -9,21 +9,20 @@ /* Begin PBXBuildFile section */ E205B44425E86AA7001A07D1 /* WebKitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E205B44325E86AA7001A07D1 /* WebKitView.swift */; }; E230C4A325AE7B31005DCB55 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E230C4A225AE7B31005DCB55 /* AppDelegate.swift */; }; - E230C4A525AE7B31005DCB55 /* ContentViewCatalina.swift in Sources */ = {isa = PBXBuildFile; fileRef = E230C4A425AE7B31005DCB55 /* ContentViewCatalina.swift */; }; + E230C4A525AE7B31005DCB55 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E230C4A425AE7B31005DCB55 /* ContentView.swift */; }; E230C4AD25AE7B33005DCB55 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E230C4AB25AE7B33005DCB55 /* Main.storyboard */; }; E24D200525BE75A90095BDE5 /* OTCore in Frameworks */ = {isa = PBXBuildFile; productRef = E24D200425BE75A90095BDE5 /* OTCore */; }; E24D200B25BE75D90095BDE5 /* MIDIKit in Frameworks */ = {isa = PBXBuildFile; productRef = E24D200A25BE75D90095BDE5 /* MIDIKit */; }; E26B849C25EDA4F400080052 /* DetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E26B849B25EDA4F400080052 /* DetailsView.swift */; }; E293070425E90D750011904C /* HostingWindowKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = E293070325E90D750011904C /* HostingWindowKey.swift */; }; E2AC6C7B25EDF96C008A4558 /* ContentViewManual.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2AC6C7A25EDF96C008A4558 /* ContentViewManual.swift */; }; - E2FFD48325EDAF8700396632 /* ContentViewBigSur.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2FFD48225EDAF8700396632 /* ContentViewBigSur.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ E205B44325E86AA7001A07D1 /* WebKitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebKitView.swift; sourceTree = ""; }; E230C49F25AE7B31005DCB55 /* MIDISystemInfo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MIDISystemInfo.app; sourceTree = BUILT_PRODUCTS_DIR; }; E230C4A225AE7B31005DCB55 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - E230C4A425AE7B31005DCB55 /* ContentViewCatalina.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentViewCatalina.swift; sourceTree = ""; }; + E230C4A425AE7B31005DCB55 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; E230C4AC25AE7B33005DCB55 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; E230C4AE25AE7B33005DCB55 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; E230C4AF25AE7B33005DCB55 /* MIDISystemInfo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MIDISystemInfo.entitlements; sourceTree = ""; }; @@ -31,7 +30,6 @@ E293070325E90D750011904C /* HostingWindowKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HostingWindowKey.swift; sourceTree = ""; }; E2AC6C7A25EDF96C008A4558 /* ContentViewManual.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentViewManual.swift; sourceTree = ""; }; E2BE8483268BCA570034F62C /* MIDIKit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = MIDIKit; path = ../..; sourceTree = ""; }; - E2FFD48225EDAF8700396632 /* ContentViewBigSur.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentViewBigSur.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -82,9 +80,8 @@ E2AC6C7925EDF8FF008A4558 /* ContentView */ = { isa = PBXGroup; children = ( - E230C4A425AE7B31005DCB55 /* ContentViewCatalina.swift */, + E230C4A425AE7B31005DCB55 /* ContentView.swift */, E2AC6C7A25EDF96C008A4558 /* ContentViewManual.swift */, - E2FFD48225EDAF8700396632 /* ContentViewBigSur.swift */, ); path = ContentView; sourceTree = ""; @@ -165,9 +162,8 @@ buildActionMask = 2147483647; files = ( E205B44425E86AA7001A07D1 /* WebKitView.swift in Sources */, - E2FFD48325EDAF8700396632 /* ContentViewBigSur.swift in Sources */, E26B849C25EDA4F400080052 /* DetailsView.swift in Sources */, - E230C4A525AE7B31005DCB55 /* ContentViewCatalina.swift in Sources */, + E230C4A525AE7B31005DCB55 /* ContentView.swift in Sources */, E293070425E90D750011904C /* HostingWindowKey.swift in Sources */, E230C4A325AE7B31005DCB55 /* AppDelegate.swift in Sources */, E2AC6C7B25EDF96C008A4558 /* ContentViewManual.swift in Sources */, diff --git a/Examples/MIDISystemInfo/MIDISystemInfo/AppDelegate.swift b/Examples/MIDISystemInfo/MIDISystemInfo/AppDelegate.swift index de039c8b56..9efeb8a3c5 100644 --- a/Examples/MIDISystemInfo/MIDISystemInfo/AppDelegate.swift +++ b/Examples/MIDISystemInfo/MIDISystemInfo/AppDelegate.swift @@ -23,61 +23,47 @@ class AppDelegate: NSObject, NSApplicationDelegate { defaultSubsystem: Globals.bundle.bundleID, useEmoji: .all) + // set up midi manager + + midiManager = { + let newManager = + MIDI.IO.Manager(clientName: "MIDISystemInfo", + model: "TestApp", + manufacturer: "Orchetect") + do { + Log.debug("Starting MIDI manager client") + try newManager.start() + } catch { + Log.default(error) + } + + return newManager + }() + // Create the window and set the content view. window = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 950, height: 850), styleMask: [.titled, .miniaturizable, .resizable], - backing: .buffered, defer: false) - - // Create the SwiftUI view that provides the window contents. - window.isReleasedWhenClosed = false - - window.center() - window.setFrameAutosaveName("Main Window") - - window.contentView = { - if #available(macOS 11.0, *) { - - // for Big Sur, demonstrate using @StateObject to hold the MIDI.IO.Manager in a subordinate scope and not in AppDelegate - window.title = "MIDIKit Test Harness (Big Sur)" - return NSHostingView( - rootView: ContentViewBigSur() - .environment(\.hostingWindow, { [weak window] in window }) - ) - - } else { - - // for Catalina, since @StateObject is not available for use, demonstrate storing the MIDI.IO.Manager instance in AppDelegate and passing it by reference into ContentView's weak @ObservedObject storage. - midiManager = { - let newManager = - MIDI.IO.Manager(clientName: "MIDISystemInfo", - model: "TestApp", - manufacturer: "Orchetect") - do { - Log.debug("Starting MIDI manager client") - try newManager.start() - } catch { - Log.default(error) - } - - return newManager - }() - - window.title = "MIDIKit Test Harness (Catalina)" - return NSHostingView( - rootView: ContentViewCatalina(midiManager: midiManager!) - .environment(\.hostingWindow, { [weak window] in window }) - ) - - } - }() - - window.makeKeyAndOrderFront(nil) - - } - - func applicationWillTerminate(_ aNotification: Notification) { - // Insert code here to tear down your application - } + backing: .buffered, defer: false) + + // Create the SwiftUI view that provides the window contents. + window.isReleasedWhenClosed = false + + window.center() + window.setFrameAutosaveName("Main Window") + + window.title = "MIDIKit Test Harness (Catalina)" + window.contentView = NSHostingView( + rootView: ContentViewCatalina(midiManager: midiManager!) + .environment(\.hostingWindow, { [weak window] in window }) + ) + + window.makeKeyAndOrderFront(nil) + + } + + func applicationWillTerminate(_ aNotification: Notification) { + // Insert code here to tear down your application + } } diff --git a/Examples/MIDISystemInfo/MIDISystemInfo/ContentView/ContentViewCatalina.swift b/Examples/MIDISystemInfo/MIDISystemInfo/ContentView/ContentView.swift similarity index 100% rename from Examples/MIDISystemInfo/MIDISystemInfo/ContentView/ContentViewCatalina.swift rename to Examples/MIDISystemInfo/MIDISystemInfo/ContentView/ContentView.swift diff --git a/Examples/MIDISystemInfo/MIDISystemInfo/ContentView/ContentViewBigSur.swift b/Examples/MIDISystemInfo/MIDISystemInfo/ContentView/ContentViewBigSur.swift deleted file mode 100644 index 9979b09f36..0000000000 --- a/Examples/MIDISystemInfo/MIDISystemInfo/ContentView/ContentViewBigSur.swift +++ /dev/null @@ -1,107 +0,0 @@ -// -// ContentViewBigSur.swift -// MIDISystemInfo -// MIDIKit • https://github.com/orchetect/MIDIKit -// - -import SwiftUI -import MIDIKit -import OTCore - -@available(macOS 11.0, *) -struct ContentViewBigSur: View { - - @StateObject var midiManager: MIDI.IO.Manager = { - let newManager = - MIDI.IO.Manager(clientName: "MIDISystemInfo", - model: "TestApp", - manufacturer: "Orchetect") - do { - Log.debug("Starting MIDI manager client") - try newManager.start() - } catch { - Log.default(error) - } - - return newManager - }() - - var body: some View { - - NavigationView { - - List { - - Section(header: Text("MIDI Devices")) { - - ForEach(midiManager.devices.devices.sortedByName()) { item in - Group { - if let nsImg = item.getImageAsNSImage { - Image(nsImage: nsImg) - .resizable() - } else { - Text("🎹") - } - } - .frame(width: 18, height: 18, alignment: .center) - - Text("\(item.name)") - } - - } - - Section(header: Text("MIDI Outputs")) { - - ForEach(midiManager.endpoints.outputs.sortedByName()) { item in - Group { - if let nsImg = item.getImageAsNSImage { - Image(nsImage: nsImg) - .resizable() - } else { - Text("🎵") - } - } - .frame(width: 18, height: 18, alignment: .center) - - Text("\(item.name)") - } - - } - - Section(header: Text("MIDI Inputs")) { - - ForEach(midiManager.endpoints.inputs.sortedByName()) { item in - Group { - if let nsImg = item.getImageAsNSImage { - Image(nsImage: nsImg) - .resizable() - } else { - Text("🎵") - } - } - .frame(width: 18, height: 18, alignment: .center) - - Text("\(item.name)") - } - - } - - } - .frame(width: 300) - - EmptyDetailsView() - - } - .navigationViewStyle(DoubleColumnNavigationViewStyle()) - .frame(maxWidth: .infinity, maxHeight: .infinity) - - } - -} - -@available(macOS 11.0, *) -struct ContentViewBigSur_Previews: PreviewProvider { - static var previews: some View { - ContentViewBigSur() - } -} diff --git a/Examples/MIDISystemInfo/MIDISystemInfo/ContentView/ContentViewManual.swift b/Examples/MIDISystemInfo/MIDISystemInfo/ContentView/ContentViewManual.swift index 72f90e8f4b..9738852c4c 100644 --- a/Examples/MIDISystemInfo/MIDISystemInfo/ContentView/ContentViewManual.swift +++ b/Examples/MIDISystemInfo/MIDISystemInfo/ContentView/ContentViewManual.swift @@ -34,9 +34,12 @@ struct ContentViewManual: View { ZStack { } .onAppear { - // onAppear has the potential to trigger more than once during the lifecycle of the view, so it's not best practise to put setup code here - // however it won't have any dire consequences if this onAppear block runs more than once, and - // we don't care too much that this setup code may happen lazily while the rest of the view loads + // onAppear has the potential to trigger more than once + // during the lifecycle of the view, so it's not best + // practise to put setup code here. however it won't have + // any dire consequences if this onAppear block runs more + // than once, and we don't care too much that this setup + // code may happen lazily while the rest of the view loads // set up MIDI manager notifications callback handler // so we can be notified when MIDI endpoints in the system change, @@ -76,7 +79,7 @@ struct ContentViewManual: View { } - Section(header: Text("MIDI Outputs")) { + Section(header: Text("MIDI Output Endpoints")) { ForEach(outputs.sortedByName()) { item in NavigationLink(destination: DetailsView(endpoint: item)) { @@ -96,7 +99,7 @@ struct ContentViewManual: View { } - Section(header: Text("MIDI Inputs")) { + Section(header: Text("MIDI Input Endpoints")) { ForEach(inputs.sortedByName()) { item in NavigationLink(destination: DetailsView(endpoint: item)) { diff --git a/Sources/MIDIKit/Packet/Packet UniversalPacketData.swift b/Sources/MIDIKit/Packet/Packet UniversalPacketData.swift index 7f23f5afb0..87a690867d 100644 --- a/Sources/MIDIKit/Packet/Packet UniversalPacketData.swift +++ b/Sources/MIDIKit/Packet/Packet UniversalPacketData.swift @@ -19,15 +19,21 @@ extension MIDI.Packet { /// Flat array of raw bytes @inline(__always) public var bytes: [MIDI.Byte] { - #warning("> this is dumb?") var bytes: [MIDI.Byte] = [] bytes.reserveCapacity(4 * words.count) - words.forEach { - bytes.append(MIDI.Byte($0 & 0xFF000000) >> (6*4)) - bytes.append(MIDI.Byte($0 & 0x00FF0000) >> (4*4)) - bytes.append(MIDI.Byte($0 & 0x0000FF00) >> (2*4)) - bytes.append(MIDI.Byte($0 & 0x000000FF)) + + words.forEach { word in + let byte1 = MIDI.Byte((word & 0xFF000000) >> 24) + let byte2 = MIDI.Byte((word & 0x00FF0000) >> 16) + let byte3 = MIDI.Byte((word & 0x0000FF00) >> 8) + let byte4 = MIDI.Byte(word & 0x000000FF) + + bytes.append(byte1) + bytes.append(byte2) + bytes.append(byte3) + bytes.append(byte4) } + return bytes }