├── .gitignore
├── img
├── window.png
└── quicklook.png
├── qlMIDI
├── .DS_Store
├── Media.xcassets
│ ├── .DS_Store
│ ├── Contents.json
│ ├── Pause.imageset
│ │ ├── Pause@1x.png
│ │ ├── Pause@2x.png
│ │ └── Contents.json
│ ├── Play.imageset
│ │ ├── Play@1x.png
│ │ ├── Play@2x.png
│ │ └── Contents.json
│ ├── previewIcon.imageset
│ │ ├── mac256pt1x.png
│ │ ├── mac512pt1x.png
│ │ ├── mac512pt2x.png
│ │ └── Contents.json
│ └── BacktoPreview.imageset
│ │ ├── BacktoPreview@3x-1.png
│ │ └── Contents.json
├── qlMIDI.entitlements
├── Info.plist
├── PreviewProvider.swift
├── PreviewViewController.swift
└── Base.lproj
│ └── PreviewViewController.xib
├── APPlayMIDI
├── Assets.xcassets
│ ├── Contents.json
│ ├── .DS_Store
│ ├── Pause.imageset
│ │ ├── Pause@1x.png
│ │ ├── Pause@2x.png
│ │ └── Contents.json
│ ├── Play.imageset
│ │ ├── Play@1x.png
│ │ ├── Play@2x.png
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ ├── APPlayMIDI-128.png
│ │ ├── APPlayMIDI-16.png
│ │ ├── APPlayMIDI-256.png
│ │ ├── APPlayMIDI-257.png
│ │ ├── APPlayMIDI-32.png
│ │ ├── APPlayMIDI-33.png
│ │ ├── APPlayMIDI-512.png
│ │ ├── APPlayMIDI-513.png
│ │ ├── APPlayMIDI-64.png
│ │ ├── APPlayMIDI-1024.png
│ │ └── Contents.json
│ └── BacktoPreview.imageset
│ │ ├── BacktoPreview@3x-1.png
│ │ └── Contents.json
├── APPlayMIDI.entitlements
├── WindowController.swift
├── AppDelegate.swift
├── Document.swift
├── Info.plist
├── ViewController.swift
└── Base.lproj
│ └── Main.storyboard
├── APPlayMIDI.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── Ben.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── xcuserdata
│ └── Ben.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── xcshareddata
│ └── xcschemes
│ │ ├── APPlayMIDI.xcscheme
│ │ └── qlMIDI.xcscheme
└── project.pbxproj
├── LICENCE.txt
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | qlMIDI/.DS_Store
3 | APPlayMIDI/.DS_Store
4 | .DS_Store
5 |
--------------------------------------------------------------------------------
/img/window.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/img/window.png
--------------------------------------------------------------------------------
/qlMIDI/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/qlMIDI/.DS_Store
--------------------------------------------------------------------------------
/img/quicklook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/img/quicklook.png
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/qlMIDI/Media.xcassets/.DS_Store
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/.DS_Store
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/Pause.imageset/Pause@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/qlMIDI/Media.xcassets/Pause.imageset/Pause@1x.png
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/Pause.imageset/Pause@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/qlMIDI/Media.xcassets/Pause.imageset/Pause@2x.png
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/Play.imageset/Play@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/qlMIDI/Media.xcassets/Play.imageset/Play@1x.png
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/Play.imageset/Play@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/qlMIDI/Media.xcassets/Play.imageset/Play@2x.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/Pause.imageset/Pause@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/Pause.imageset/Pause@1x.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/Pause.imageset/Pause@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/Pause.imageset/Pause@2x.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/Play.imageset/Play@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/Play.imageset/Play@1x.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/Play.imageset/Play@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/Play.imageset/Play@2x.png
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/previewIcon.imageset/mac256pt1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/qlMIDI/Media.xcassets/previewIcon.imageset/mac256pt1x.png
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/previewIcon.imageset/mac512pt1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/qlMIDI/Media.xcassets/previewIcon.imageset/mac512pt1x.png
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/previewIcon.imageset/mac512pt2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/qlMIDI/Media.xcassets/previewIcon.imageset/mac512pt2x.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-128.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-16.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-256.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-257.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-257.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-32.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-33.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-33.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-512.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-513.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-513.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-64.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/APPlayMIDI-1024.png
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/BacktoPreview.imageset/BacktoPreview@3x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/qlMIDI/Media.xcassets/BacktoPreview.imageset/BacktoPreview@3x-1.png
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/BacktoPreview.imageset/BacktoPreview@3x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI/Assets.xcassets/BacktoPreview.imageset/BacktoPreview@3x-1.png
--------------------------------------------------------------------------------
/APPlayMIDI.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/APPlayMIDI.xcodeproj/xcuserdata/Ben.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/APPlayMIDI.xcodeproj/project.xcworkspace/xcuserdata/Ben.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwiggy/APPlayMIDI/HEAD/APPlayMIDI.xcodeproj/project.xcworkspace/xcuserdata/Ben.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/APPlayMIDI/APPlayMIDI.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.files.user-selected.read-only
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/APPlayMIDI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/BacktoPreview.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "BacktoPreview@3x-1.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/BacktoPreview.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "BacktoPreview@3x-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/Pause.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Pause@1x.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "Pause@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/Play.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Play@1x.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "Play@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/Pause.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Pause@1x.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "Pause@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/Play.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Play@1x.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "Play@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/qlMIDI/Media.xcassets/previewIcon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "mac256pt1x.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "mac512pt1x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "mac512pt2x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/qlMIDI/qlMIDI.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.assets.movies.read-only
8 |
9 | com.apple.security.assets.music.read-only
10 |
11 | com.apple.security.assets.pictures.read-only
12 |
13 | com.apple.security.files.downloads.read-only
14 |
15 | com.apple.security.files.user-selected.read-only
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/APPlayMIDI/WindowController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WindowController.swift
3 | // APPlayMIDI
4 | //
5 | // Created by Ben Byram-Wigfield on 22/10/2019.
6 | // Copyright © 2019 Ben. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | class WindowController: NSWindowController {
12 |
13 | required init?(coder: NSCoder) {
14 | super.init(coder: coder)
15 | shouldCascadeWindows = true
16 | }
17 |
18 | override func windowDidLoad() {
19 | super.windowDidLoad()
20 |
21 | // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/APPlayMIDI/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // APPlayMIDI
4 | //
5 | // Created by Ben on 20/08/2019.
6 | // Copyright © 2019 Ben. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | @NSApplicationMain
12 | class AppDelegate: NSObject, NSApplicationDelegate {
13 |
14 | func applicationShouldOpenUntitledFile(_ sender: NSApplication) -> Bool {
15 | return false
16 | }
17 |
18 | func applicationDidFinishLaunching(_ aNotification: Notification) {
19 | // Insert code here to initialize your application
20 | }
21 |
22 | func applicationWillTerminate(_ aNotification: Notification) {
23 | // Insert code here to tear down your application
24 | }
25 |
26 |
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/qlMIDI/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSExtension
6 |
7 | NSExtensionAttributes
8 |
9 | QLIsDataBasedPreview
10 |
11 | QLSupportedContentTypes
12 |
13 | public.midi-audio
14 |
15 | QLSupportsSearchableItems
16 |
17 |
18 | NSExtensionMainNibFile
19 | PreviewViewController
20 | NSExtensionPointIdentifier
21 | com.apple.quicklook.preview
22 | NSExtensionPrincipalClass
23 | $(PRODUCT_MODULE_NAME).PreviewViewController
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/APPlayMIDI.xcodeproj/xcuserdata/Ben.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | APPlayMIDI.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 | qlMIDI.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 1
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | B5051864230C2C9E0024884E
21 |
22 | primary
23 |
24 |
25 | B53CD76D28738D46002A1C80
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/LICENCE.txt:
--------------------------------------------------------------------------------
1 | The binary and source code of APPlayMIDI.app are made available under the terms of the MIT Licence:
2 |
3 | © 2019 Ben Byram-Wigfield
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/APPlayMIDI/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "APPlayMIDI-16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "APPlayMIDI-33.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "APPlayMIDI-32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "APPlayMIDI-64.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "APPlayMIDI-128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "APPlayMIDI-257.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "APPlayMIDI-256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "APPlayMIDI-513.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "APPlayMIDI-512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "APPlayMIDI-1024.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/APPlayMIDI/Document.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Document.swift
3 | // APPlayMIDI
4 | //
5 | // Created by Ben on 20/08/2019.
6 | // Copyright © 2019 Ben. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 | import AVFoundation
11 | import AppKit
12 |
13 | // Create a PasteboardType for MIDI data
14 | extension NSPasteboard.PasteboardType {
15 | static let typeMidi = NSPasteboard.PasteboardType(rawValue: "public.midi-audio")
16 | }
17 |
18 | class Document: NSDocument {
19 | var theMIDIPlayer: AVMIDIPlayer?
20 | var myData: Data?
21 |
22 | override init() {
23 | super.init()
24 | }
25 |
26 | override class var autosavesInPlace: Bool {
27 | return false
28 | }
29 |
30 | override func makeWindowControllers() {
31 | // Returns the Storyboard that contains your Document window.
32 | let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
33 | let windowController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("Document Window Controller")) as! NSWindowController
34 | self.addWindowController(windowController)
35 | windowController.shouldCascadeWindows = true
36 | }
37 |
38 | @IBAction func copy(_: Any) {
39 | let pboard = NSPasteboard.general
40 | pboard.clearContents()
41 | pboard.setData(myData, forType: .typeMidi)
42 | }
43 |
44 | // override func data(ofType typeName: String) throws -> Data {
45 | // throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
46 | // }
47 |
48 | override func read(from data: Data, ofType typeName: String) throws {
49 | self.theMIDIPlayer = try AVMIDIPlayer.init(data: data, soundBankURL: nil)
50 | self.myData = data
51 | if self.theMIDIPlayer == nil {
52 | throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/qlMIDI/PreviewProvider.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PreviewProvider.swift
3 | // qlMIDI
4 | //
5 | // Created by Ben on 04/07/2022.
6 | // Copyright © 2022 Ben. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 | import Quartz
11 |
12 | class PreviewProvider: QLPreviewProvider, QLPreviewingController {
13 |
14 |
15 | /*
16 | Use a QLPreviewProvider to provide data-based previews.
17 |
18 | To set up your extension as a data-based preview extension:
19 |
20 | - Modify the extension's Info.plist by setting
21 | QLIsDataBasedPreview
22 |
23 |
24 | - Add the supported content types to QLSupportedContentTypes array in the extension's Info.plist.
25 |
26 | - Change the NSExtensionPrincipalClass to this class.
27 | e.g.
28 | NSExtensionPrincipalClass
29 | $(PRODUCT_MODULE_NAME).PreviewProvider
30 |
31 | - Implement providePreview(for:)
32 | */
33 |
34 | func providePreview(for request: QLFilePreviewRequest) async throws -> QLPreviewReply {
35 |
36 | //You can create a QLPreviewReply in several ways, depending on the format of the data you want to return.
37 | //To return Data of a supported content type:
38 |
39 | let contentType = UTType.plainText // replace with your data type
40 |
41 | let reply = QLPreviewReply.init(dataOfContentType: contentType, contentSize: CGSize.init(width: 800, height: 400)) { (replyToUpdate : QLPreviewReply) in
42 |
43 | let data = Data("Hello world".utf8)
44 |
45 | //setting the stringEncoding for text and html data is optional and defaults to String.Encoding.utf8
46 | replyToUpdate.stringEncoding = .utf8
47 |
48 | //initialize your data here
49 |
50 | return data
51 | }
52 |
53 | return reply
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/APPlayMIDI/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDocumentTypes
8 |
9 |
10 | CFBundleTypeExtensions
11 |
12 | [midi]
13 |
14 | CFBundleTypeIconFile
15 |
16 | CFBundleTypeName
17 | MIDI audio
18 | CFBundleTypeOSTypes
19 |
20 | ????
21 |
22 | CFBundleTypeRole
23 | Viewer
24 | LSItemContentTypes
25 |
26 | public.midi-audio
27 |
28 | NSDocumentClass
29 | $(PRODUCT_MODULE_NAME).Document
30 |
31 |
32 | CFBundleExecutable
33 | $(EXECUTABLE_NAME)
34 | CFBundleIconFile
35 |
36 | CFBundleIdentifier
37 | $(PRODUCT_BUNDLE_IDENTIFIER)
38 | CFBundleInfoDictionaryVersion
39 | 6.0
40 | CFBundleName
41 | $(PRODUCT_NAME)
42 | CFBundlePackageType
43 | APPL
44 | CFBundleShortVersionString
45 | $(MARKETING_VERSION)
46 | CFBundleVersion
47 | $(CURRENT_PROJECT_VERSION)
48 | LSApplicationCategoryType
49 | public.app-category.music
50 | LSMinimumSystemVersion
51 | $(MACOSX_DEPLOYMENT_TARGET)
52 | NSHumanReadableCopyright
53 | Copyright © 2019 Ben. All rights reserved.
54 | NSMainStoryboardFile
55 | Main
56 | NSPrincipalClass
57 | NSApplication
58 | UTExportedTypeDeclarations
59 |
60 |
61 | UTTypeDescription
62 | MIDI audio
63 | UTTypeIdentifier
64 | public.midi-audio
65 | UTTypeTagSpecification
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/APPlayMIDI.xcodeproj/xcshareddata/xcschemes/APPlayMIDI.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
44 |
46 |
52 |
53 |
54 |
55 |
61 |
63 |
69 |
70 |
71 |
72 |
74 |
75 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # APPlayMIDI
2 | _A simple MIDI file player for MacOS._
3 |
4 | Ever since 2009, when Apple deprecated the 32-bit QuickTime framework in favour of the newer AVKit, the Mac's flagship media player, QuickTime Player X has refused to play MIDI files. (Despite MIDI file types being associated with the app!)
5 |
6 | The AVKit framework contains a perfectly good player for MIDI files: AVMIDIPlayer, so there's no excuse for not having an app that plays MIDI files. Here's my lightweight implementation.
7 |
8 | 
9 |
10 | Each document window contains a slider that both indicates and sets the current play position, and a 'rewind' button to return to the start of the track. Numerical counters show the play position and total duration.
11 |
12 | The app contains a few other features: it can Copy the MIDI data from a document to the clipboard, so it can be pasted into apps that support pasting MIDI data.
13 |
14 | Known apps that support MIDI pasteboard include: Finale. (Let me know of others.)
15 |
16 | You can also drag the file icon from the titlebar into any app that supports MIDI dragging: e.g. Cubase, Dorico...
17 |
18 | If you like this app, please consider buying me a drink!
19 | https://paypal.me/agroovem
20 |
21 | ### QUICK LOOK! ###
22 |
23 | APPlayMIDI now contains a Quick Look Extension, enabling MIDI files to be played directly in the Finder.
24 |
25 | 
26 |
27 | The Preview panel, or Quick Look pop-up window, will display three objects: Play/pause button, rewind to start, and a progress indicator. Note that you need to press Play to start the preview (to stop files from auto-playing just by being selected in the Finder).
28 |
29 | This feature is still 'a bit beta'; while it works, there are a few interface issues to sort out.
30 |
31 | ### Installation ###
32 | Click on the Releases link above, or here: https://github.com/benwiggy/APPlayMIDI/releases. Download, unzip and move to the /Applications folder. You then need to right click on the app and select "Open". A dialog will come up, telling you that it is from an 'unidentified developer', but there should be an "Open" button.
33 | You may want to make APPlayMIDI the default file for opening MIDI files. Select a MIDI file, then _Get Info_ (File menu or Command I) select "APPlayMIDI", and then click "Change All".
34 |
35 | The source files are included, for anyone who wants to help improve the quality of the code, add functionality, or use them as the basis of a new app.
36 |
37 | ### OS Versions required and supported ###
38 |
39 | v1.10 does need macOS 12, Monterey, for the Quick Look extension to work.
40 | v.1.04 and 05 are Universal Binaries for Intel and Apple Silicon, and so require Big Sur to work.
41 | v1.02 should work on earlier OSes.
42 |
43 | ### Future ###
44 | Some refinement of the Quick Look code, to enable different behaviours for the preview panel and the Quick Look pop-up window, would be nice.
45 |
46 | v.1.14 Added loop feature.
47 | v.1.12 Fixed memory leak and other fixes.
48 | v.1.10 Quick Look support added.
49 | v.1.05 Fixed an issue with a cropped slider in Monterey.
50 | v.1.04 Universal Binary for Intel and ARM Macs.
51 | v.1.02 The app has been code-signed, but apparently that's still not enough to clear MacOS's quarantine.
52 | v.1.01 fixes an issue where document windows did not cascade.
53 |
54 |
--------------------------------------------------------------------------------
/APPlayMIDI.xcodeproj/xcshareddata/xcschemes/qlMIDI.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
6 |
9 |
10 |
16 |
22 |
23 |
24 |
30 |
36 |
37 |
38 |
39 |
40 |
45 |
46 |
47 |
48 |
60 |
62 |
68 |
69 |
70 |
71 |
79 |
81 |
87 |
88 |
89 |
90 |
92 |
93 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/APPlayMIDI/ViewController.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import AVFoundation
3 | import AVKit
4 | import QuickLook
5 |
6 | class ViewController: NSViewController {
7 | var document: Document? {
8 | return self.view.window?.windowController?.document as? Document
9 | }
10 |
11 | var viewMIDIPlayer: AVMIDIPlayer? {
12 | return document?.theMIDIPlayer
13 | }
14 |
15 | var myTimer: Timer?
16 |
17 | @IBOutlet var currentTimeField: NSTextField!
18 | @IBOutlet var theSlider: NSSlider!
19 | @IBOutlet var endTimeField: NSTextField!
20 | @IBOutlet weak var playButton: NSButton!
21 | @IBOutlet weak var loopCheckbox: NSButton! // Outlet for the loop checkbox
22 |
23 | override func viewDidLoad() {
24 | super.viewDidLoad()
25 |
26 | currentTimeField.font = NSFont.monospacedDigitSystemFont(ofSize: 13, weight: .regular)
27 | endTimeField.font = NSFont.monospacedDigitSystemFont(ofSize: 13, weight: .regular)
28 | }
29 |
30 | override func viewDidAppear() {
31 | super.viewDidAppear()
32 | guard let midiPlayer = viewMIDIPlayer else {
33 | print("Error: MIDI Player is not available")
34 | return
35 | }
36 |
37 | theSlider.maxValue = midiPlayer.duration
38 | midiPlayer.prepareToPlay()
39 |
40 | let time = midiPlayer.duration
41 | let timeString = formattedTimeString(time)
42 | endTimeField.stringValue = timeString
43 |
44 | myTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateDisplay), userInfo: nil, repeats: true)
45 | }
46 |
47 | @IBAction func playSwitch(_ sender: NSButton) {
48 | guard let midiPlayer = viewMIDIPlayer else { return }
49 |
50 | if midiPlayer.isPlaying {
51 | midiPlayer.stop()
52 | } else {
53 | midiPlayer.play {
54 | self.completed()
55 | }
56 | }
57 | }
58 |
59 | @IBAction func moveSlider(_ sender: Any) {
60 | guard let midiPlayer = viewMIDIPlayer else { return }
61 |
62 | midiPlayer.stop()
63 | midiPlayer.currentPosition = theSlider.doubleValue
64 | updateDisplay()
65 | playButton.state = .on
66 | midiPlayer.prepareToPlay()
67 | midiPlayer.play {
68 | self.completed()
69 | }
70 | }
71 |
72 | @IBAction func backToStart(_ sender: Any) {
73 | guard let midiPlayer = viewMIDIPlayer else { return }
74 |
75 | midiPlayer.stop()
76 | midiPlayer.currentPosition = 0
77 | playButton.state = .on
78 | midiPlayer.prepareToPlay()
79 | midiPlayer.play {
80 | self.completed()
81 | }
82 | }
83 |
84 | func completed() {
85 | if let midiPlayer = viewMIDIPlayer {
86 | if midiPlayer.currentPosition >= (midiPlayer.duration - 1) {
87 | if self.loopCheckbox.state == .on {
88 | midiPlayer.currentPosition = 0
89 | midiPlayer.prepareToPlay()
90 | midiPlayer.play {
91 | self.completed()
92 | }
93 | } else {
94 | self.playButton.state = .off
95 | }
96 | } else {
97 | self.playButton.state = .off
98 | }
99 | }
100 | }
101 |
102 | @objc func updateDisplay() {
103 | guard let midiPlayer = viewMIDIPlayer else { return }
104 |
105 | if midiPlayer.currentPosition <= midiPlayer.duration {
106 | theSlider.doubleValue = midiPlayer.currentPosition
107 | let timeString = formattedTimeString(midiPlayer.currentPosition)
108 | currentTimeField.stringValue = timeString
109 | }
110 | }
111 |
112 | override func viewDidDisappear() {
113 | super.viewDidDisappear()
114 | document?.theMIDIPlayer = nil
115 | myTimer?.invalidate()
116 | }
117 |
118 | override var representedObject: Any? {
119 | didSet {
120 | // Update the view, if already loaded.
121 | }
122 | }
123 |
124 | private func formattedTimeString(_ time: TimeInterval) -> String {
125 | let hours = Int(floor(time / 3600))
126 | let minutes = Int(floor((time.truncatingRemainder(dividingBy: 3600)) / 60))
127 | let seconds = Int(time) % 60
128 | return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/qlMIDI/PreviewViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PreviewViewController.swift
3 | // qlMIDI
4 | //
5 | // Created by Ben on 04/07/2022.
6 | // Copyright © 2022 Ben. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 | import Quartz
11 | import AVFoundation
12 |
13 | class PreviewViewController: NSViewController, QLPreviewingController {
14 |
15 | override var nibName: NSNib.Name? {
16 | return NSNib.Name("PreviewViewController")
17 | }
18 |
19 | var viewMIDIPlayer: AVMIDIPlayer!
20 |
21 | var myTimer: Timer?
22 |
23 | @IBOutlet weak var quickLookView: NSView!
24 | @IBOutlet weak var finderView: NSView!
25 |
26 | @IBOutlet weak var finderPlayButton: NSButton!
27 | @IBOutlet weak var finderRestartButton: NSButton!
28 | @IBOutlet weak var finderProgressCircle: NSProgressIndicator!
29 |
30 | @IBOutlet weak var totalTimeLabel: NSTextField!
31 | @IBOutlet weak var currentPlaybackTimeLabel: NSTextField!
32 | @IBOutlet weak var filenameLabel: NSTextField!
33 | @IBOutlet weak var playButton: NSButton!
34 | @IBOutlet weak var restartButton: NSButton!
35 | @IBOutlet weak var theSlider: NSProgressIndicator!
36 |
37 | override func loadView() {
38 | super.loadView()
39 | preferredContentSize = CGSize(width: 800, height: 350)
40 |
41 | finderPlayButton.target = self
42 | finderPlayButton.action = #selector(self.playPause)
43 | finderRestartButton.target = self
44 | finderRestartButton.action = #selector(self.restart)
45 |
46 | playButton.target = self
47 | playButton.action = #selector(self.playPause)
48 | restartButton.target = self
49 | restartButton.action = #selector(self.restart)
50 | }
51 |
52 | @objc func playPause() {
53 | guard let midiPlayer = viewMIDIPlayer else { return }
54 | if (midiPlayer.isPlaying) {
55 | midiPlayer.stop()
56 | } else {
57 | midiPlayer.play(self.completed())
58 | }
59 | }
60 |
61 | @objc func restart() {
62 | guard let midiPlayer = viewMIDIPlayer else { return }
63 |
64 | midiPlayer.currentPosition = TimeInterval(0)
65 | playButton.state = NSControl.StateValue.on
66 | finderPlayButton.state = NSControl.StateValue.on
67 | midiPlayer.prepareToPlay()
68 | midiPlayer.play (
69 | self.completed()
70 | )
71 | }
72 |
73 | func completed() -> AVMIDIPlayerCompletionHandler {
74 | return {
75 | self.playButton.state = .off
76 | self.finderPlayButton.state = .off
77 | }
78 | }
79 |
80 | /*
81 | * Implement this method and set QLSupportsSearchableItems to YES in the Info.plist of the extension if you support CoreSpotlight.
82 | *
83 | func preparePreviewOfSearchableItem(identifier: String, queryString: String?, completionHandler handler: @escaping (Error?) -> Void) {
84 | // Perform any setup necessary in order to prepare the view.
85 |
86 | // Call the completion handler so Quick Look knows that the preview is fully loaded.
87 | // Quick Look will display a loading spinner while the completion handler is not called.
88 | handler(nil)
89 | */
90 |
91 | func preparePreviewOfFile(at url: URL, completionHandler handler: @escaping (Error?) -> Void) {
92 | do {
93 | viewMIDIPlayer = try AVMIDIPlayer(contentsOf: url, soundBankURL: nil)
94 | viewMIDIPlayer?.prepareToPlay()
95 | theSlider.maxValue = Double(viewMIDIPlayer?.duration ?? 0.0)
96 |
97 | myTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.updateDisplay), userInfo: nil, repeats: true)
98 |
99 | finderProgressCircle.maxValue = Double(self.viewMIDIPlayer?.duration ?? 0.0)
100 | filenameLabel.stringValue = url.lastPathComponent
101 | filenameLabel.frame.size.width = CGFloat(filenameLabel.stringValue.count * 13)
102 | currentPlaybackTimeLabel.stringValue = "0:00"
103 |
104 | if let time = self.viewMIDIPlayer?.duration {
105 | let minutes = Int(time / 60)
106 | let seconds = Int((time)) % 60
107 | totalTimeLabel.stringValue = String(format: "%01d:%02d", minutes, seconds)
108 | }
109 |
110 | handler(nil) // Call handler with nil to indicate success
111 | } catch {
112 | handler(error) // Call handler with the caught error
113 | }
114 | }
115 |
116 | override func viewDidAppear() {
117 | if let width = self.view.window?.frame.width, width < 600.0 {
118 | //Finder View
119 | self.finderView.isHidden = false
120 | self.quickLookView.isHidden = true
121 | } else {
122 | // QuickLook Window
123 | self.finderView.isHidden = true
124 | self.quickLookView.isHidden = false
125 |
126 | self.viewMIDIPlayer?.play(self.completed())
127 | self.playButton.state = .on
128 | }
129 |
130 | super.viewDidAppear()
131 | }
132 |
133 | override func viewWillDisappear() {
134 | if (viewMIDIPlayer!.isPlaying) {
135 | viewMIDIPlayer!.stop()
136 | }
137 | viewMIDIPlayer = nil
138 | myTimer?.invalidate()
139 | super.viewWillDisappear()
140 | }
141 |
142 | @objc func updateDisplay(){
143 | if viewMIDIPlayer != nil {
144 | if viewMIDIPlayer!.currentPosition <= viewMIDIPlayer!.duration {
145 | theSlider.doubleValue = Double((viewMIDIPlayer!.currentPosition))
146 | if let currentPosition = self.viewMIDIPlayer?.currentPosition {
147 | let minutes = Int(currentPosition / 60)
148 | let seconds = Int((currentPosition)) % 60
149 | currentPlaybackTimeLabel.stringValue = String(format: "%01d:%02d", minutes, seconds)
150 | finderProgressCircle.doubleValue = Double((viewMIDIPlayer!.currentPosition))
151 | }
152 | }
153 | }
154 | }
155 | }
156 |
157 |
--------------------------------------------------------------------------------
/qlMIDI/Base.lproj/PreviewViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
49 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
139 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
--------------------------------------------------------------------------------
/APPlayMIDI.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 55;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | B5051869230C2C9E0024884E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5051868230C2C9E0024884E /* AppDelegate.swift */; };
11 | B505186B230C2C9E0024884E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B505186A230C2C9E0024884E /* ViewController.swift */; };
12 | B505186D230C2C9E0024884E /* Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = B505186C230C2C9E0024884E /* Document.swift */; };
13 | B505186F230C2C9F0024884E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B505186E230C2C9F0024884E /* Assets.xcassets */; };
14 | B5051872230C2C9F0024884E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B5051870230C2C9F0024884E /* Main.storyboard */; };
15 | B53CD76F28738D46002A1C80 /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5C2428F2873209700C0CDB1 /* Quartz.framework */; };
16 | B53CD77228738D46002A1C80 /* PreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CD77128738D46002A1C80 /* PreviewViewController.swift */; };
17 | B53CD77428738D46002A1C80 /* PreviewProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CD77328738D46002A1C80 /* PreviewProvider.swift */; };
18 | B53CD77728738D46002A1C80 /* PreviewViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = B53CD77528738D46002A1C80 /* PreviewViewController.xib */; };
19 | B53CD77C28738D46002A1C80 /* qlMIDI.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = B53CD76E28738D46002A1C80 /* qlMIDI.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
20 | B53CD78128742F29002A1C80 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B53CD78028742F29002A1C80 /* Media.xcassets */; };
21 | B560A51D235F7B71007C9033 /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B560A51C235F7B71007C9033 /* WindowController.swift */; };
22 | /* End PBXBuildFile section */
23 |
24 | /* Begin PBXContainerItemProxy section */
25 | B53CD77A28738D46002A1C80 /* PBXContainerItemProxy */ = {
26 | isa = PBXContainerItemProxy;
27 | containerPortal = B505185D230C2C9E0024884E /* Project object */;
28 | proxyType = 1;
29 | remoteGlobalIDString = B53CD76D28738D46002A1C80;
30 | remoteInfo = qlMIDI;
31 | };
32 | /* End PBXContainerItemProxy section */
33 |
34 | /* Begin PBXCopyFilesBuildPhase section */
35 | B5C2429E2873209700C0CDB1 /* Embed Foundation Extensions */ = {
36 | isa = PBXCopyFilesBuildPhase;
37 | buildActionMask = 2147483647;
38 | dstPath = "";
39 | dstSubfolderSpec = 13;
40 | files = (
41 | B53CD77C28738D46002A1C80 /* qlMIDI.appex in Embed Foundation Extensions */,
42 | );
43 | name = "Embed Foundation Extensions";
44 | runOnlyForDeploymentPostprocessing = 0;
45 | };
46 | /* End PBXCopyFilesBuildPhase section */
47 |
48 | /* Begin PBXFileReference section */
49 | B5051865230C2C9E0024884E /* APPlayMIDI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = APPlayMIDI.app; sourceTree = BUILT_PRODUCTS_DIR; };
50 | B5051868230C2C9E0024884E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
51 | B505186A230C2C9E0024884E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
52 | B505186C230C2C9E0024884E /* Document.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Document.swift; sourceTree = ""; };
53 | B505186E230C2C9F0024884E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
54 | B5051871230C2C9F0024884E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
55 | B5051873230C2C9F0024884E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
56 | B5051874230C2C9F0024884E /* APPlayMIDI.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = APPlayMIDI.entitlements; sourceTree = ""; };
57 | B53CD76E28738D46002A1C80 /* qlMIDI.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = qlMIDI.appex; sourceTree = BUILT_PRODUCTS_DIR; };
58 | B53CD77128738D46002A1C80 /* PreviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewViewController.swift; sourceTree = ""; };
59 | B53CD77328738D46002A1C80 /* PreviewProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewProvider.swift; sourceTree = ""; };
60 | B53CD77628738D46002A1C80 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PreviewViewController.xib; sourceTree = ""; };
61 | B53CD77828738D46002A1C80 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
62 | B53CD77928738D46002A1C80 /* qlMIDI.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = qlMIDI.entitlements; sourceTree = ""; };
63 | B53CD78028742F29002A1C80 /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = ""; };
64 | B560A51C235F7B71007C9033 /* WindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = ""; };
65 | B5C2428F2873209700C0CDB1 /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = System/Library/Frameworks/Quartz.framework; sourceTree = SDKROOT; };
66 | /* End PBXFileReference section */
67 |
68 | /* Begin PBXFrameworksBuildPhase section */
69 | B5051862230C2C9E0024884E /* Frameworks */ = {
70 | isa = PBXFrameworksBuildPhase;
71 | buildActionMask = 2147483647;
72 | files = (
73 | );
74 | runOnlyForDeploymentPostprocessing = 0;
75 | };
76 | B53CD76B28738D46002A1C80 /* Frameworks */ = {
77 | isa = PBXFrameworksBuildPhase;
78 | buildActionMask = 2147483647;
79 | files = (
80 | B53CD76F28738D46002A1C80 /* Quartz.framework in Frameworks */,
81 | );
82 | runOnlyForDeploymentPostprocessing = 0;
83 | };
84 | /* End PBXFrameworksBuildPhase section */
85 |
86 | /* Begin PBXGroup section */
87 | B505185C230C2C9E0024884E = {
88 | isa = PBXGroup;
89 | children = (
90 | B5051867230C2C9E0024884E /* APPlayMIDI */,
91 | B53CD77028738D46002A1C80 /* qlMIDI */,
92 | B5C2428E2873209700C0CDB1 /* Frameworks */,
93 | B5051866230C2C9E0024884E /* Products */,
94 | );
95 | sourceTree = "";
96 | };
97 | B5051866230C2C9E0024884E /* Products */ = {
98 | isa = PBXGroup;
99 | children = (
100 | B5051865230C2C9E0024884E /* APPlayMIDI.app */,
101 | B53CD76E28738D46002A1C80 /* qlMIDI.appex */,
102 | );
103 | name = Products;
104 | sourceTree = "";
105 | };
106 | B5051867230C2C9E0024884E /* APPlayMIDI */ = {
107 | isa = PBXGroup;
108 | children = (
109 | B5051868230C2C9E0024884E /* AppDelegate.swift */,
110 | B505186A230C2C9E0024884E /* ViewController.swift */,
111 | B505186C230C2C9E0024884E /* Document.swift */,
112 | B505186E230C2C9F0024884E /* Assets.xcassets */,
113 | B5051870230C2C9F0024884E /* Main.storyboard */,
114 | B560A51C235F7B71007C9033 /* WindowController.swift */,
115 | B5051873230C2C9F0024884E /* Info.plist */,
116 | B5051874230C2C9F0024884E /* APPlayMIDI.entitlements */,
117 | );
118 | path = APPlayMIDI;
119 | sourceTree = "";
120 | };
121 | B53CD77028738D46002A1C80 /* qlMIDI */ = {
122 | isa = PBXGroup;
123 | children = (
124 | B53CD77128738D46002A1C80 /* PreviewViewController.swift */,
125 | B53CD77328738D46002A1C80 /* PreviewProvider.swift */,
126 | B53CD77528738D46002A1C80 /* PreviewViewController.xib */,
127 | B53CD77828738D46002A1C80 /* Info.plist */,
128 | B53CD77928738D46002A1C80 /* qlMIDI.entitlements */,
129 | B53CD78028742F29002A1C80 /* Media.xcassets */,
130 | );
131 | path = qlMIDI;
132 | sourceTree = "";
133 | };
134 | B5C2428E2873209700C0CDB1 /* Frameworks */ = {
135 | isa = PBXGroup;
136 | children = (
137 | B5C2428F2873209700C0CDB1 /* Quartz.framework */,
138 | );
139 | name = Frameworks;
140 | sourceTree = "";
141 | };
142 | /* End PBXGroup section */
143 |
144 | /* Begin PBXNativeTarget section */
145 | B5051864230C2C9E0024884E /* APPlayMIDI */ = {
146 | isa = PBXNativeTarget;
147 | buildConfigurationList = B5051877230C2C9F0024884E /* Build configuration list for PBXNativeTarget "APPlayMIDI" */;
148 | buildPhases = (
149 | B5051861230C2C9E0024884E /* Sources */,
150 | B5051862230C2C9E0024884E /* Frameworks */,
151 | B5051863230C2C9E0024884E /* Resources */,
152 | B5C2429E2873209700C0CDB1 /* Embed Foundation Extensions */,
153 | );
154 | buildRules = (
155 | );
156 | dependencies = (
157 | B53CD77B28738D46002A1C80 /* PBXTargetDependency */,
158 | );
159 | name = APPlayMIDI;
160 | productName = APPlayMIDI;
161 | productReference = B5051865230C2C9E0024884E /* APPlayMIDI.app */;
162 | productType = "com.apple.product-type.application";
163 | };
164 | B53CD76D28738D46002A1C80 /* qlMIDI */ = {
165 | isa = PBXNativeTarget;
166 | buildConfigurationList = B53CD77D28738D46002A1C80 /* Build configuration list for PBXNativeTarget "qlMIDI" */;
167 | buildPhases = (
168 | B53CD76A28738D46002A1C80 /* Sources */,
169 | B53CD76B28738D46002A1C80 /* Frameworks */,
170 | B53CD76C28738D46002A1C80 /* Resources */,
171 | );
172 | buildRules = (
173 | );
174 | dependencies = (
175 | );
176 | name = qlMIDI;
177 | productName = qlMIDI;
178 | productReference = B53CD76E28738D46002A1C80 /* qlMIDI.appex */;
179 | productType = "com.apple.product-type.app-extension";
180 | };
181 | /* End PBXNativeTarget section */
182 |
183 | /* Begin PBXProject section */
184 | B505185D230C2C9E0024884E /* Project object */ = {
185 | isa = PBXProject;
186 | attributes = {
187 | BuildIndependentTargetsInParallel = YES;
188 | KnownAssetTags = (
189 | New,
190 | );
191 | LastSwiftUpdateCheck = 1330;
192 | LastUpgradeCheck = 1500;
193 | ORGANIZATIONNAME = Ben;
194 | TargetAttributes = {
195 | B5051864230C2C9E0024884E = {
196 | CreatedOnToolsVersion = 10.3;
197 | };
198 | B53CD76D28738D46002A1C80 = {
199 | CreatedOnToolsVersion = 13.3.1;
200 | };
201 | };
202 | };
203 | buildConfigurationList = B5051860230C2C9E0024884E /* Build configuration list for PBXProject "APPlayMIDI" */;
204 | compatibilityVersion = "Xcode 13.0";
205 | developmentRegion = en;
206 | hasScannedForEncodings = 0;
207 | knownRegions = (
208 | en,
209 | Base,
210 | );
211 | mainGroup = B505185C230C2C9E0024884E;
212 | productRefGroup = B5051866230C2C9E0024884E /* Products */;
213 | projectDirPath = "";
214 | projectRoot = "";
215 | targets = (
216 | B5051864230C2C9E0024884E /* APPlayMIDI */,
217 | B53CD76D28738D46002A1C80 /* qlMIDI */,
218 | );
219 | };
220 | /* End PBXProject section */
221 |
222 | /* Begin PBXResourcesBuildPhase section */
223 | B5051863230C2C9E0024884E /* Resources */ = {
224 | isa = PBXResourcesBuildPhase;
225 | buildActionMask = 2147483647;
226 | files = (
227 | B505186F230C2C9F0024884E /* Assets.xcassets in Resources */,
228 | B5051872230C2C9F0024884E /* Main.storyboard in Resources */,
229 | );
230 | runOnlyForDeploymentPostprocessing = 0;
231 | };
232 | B53CD76C28738D46002A1C80 /* Resources */ = {
233 | isa = PBXResourcesBuildPhase;
234 | buildActionMask = 2147483647;
235 | files = (
236 | B53CD78128742F29002A1C80 /* Media.xcassets in Resources */,
237 | B53CD77728738D46002A1C80 /* PreviewViewController.xib in Resources */,
238 | );
239 | runOnlyForDeploymentPostprocessing = 0;
240 | };
241 | /* End PBXResourcesBuildPhase section */
242 |
243 | /* Begin PBXSourcesBuildPhase section */
244 | B5051861230C2C9E0024884E /* Sources */ = {
245 | isa = PBXSourcesBuildPhase;
246 | buildActionMask = 2147483647;
247 | files = (
248 | B505186B230C2C9E0024884E /* ViewController.swift in Sources */,
249 | B560A51D235F7B71007C9033 /* WindowController.swift in Sources */,
250 | B5051869230C2C9E0024884E /* AppDelegate.swift in Sources */,
251 | B505186D230C2C9E0024884E /* Document.swift in Sources */,
252 | );
253 | runOnlyForDeploymentPostprocessing = 0;
254 | };
255 | B53CD76A28738D46002A1C80 /* Sources */ = {
256 | isa = PBXSourcesBuildPhase;
257 | buildActionMask = 2147483647;
258 | files = (
259 | B53CD77228738D46002A1C80 /* PreviewViewController.swift in Sources */,
260 | B53CD77428738D46002A1C80 /* PreviewProvider.swift in Sources */,
261 | );
262 | runOnlyForDeploymentPostprocessing = 0;
263 | };
264 | /* End PBXSourcesBuildPhase section */
265 |
266 | /* Begin PBXTargetDependency section */
267 | B53CD77B28738D46002A1C80 /* PBXTargetDependency */ = {
268 | isa = PBXTargetDependency;
269 | target = B53CD76D28738D46002A1C80 /* qlMIDI */;
270 | targetProxy = B53CD77A28738D46002A1C80 /* PBXContainerItemProxy */;
271 | };
272 | /* End PBXTargetDependency section */
273 |
274 | /* Begin PBXVariantGroup section */
275 | B5051870230C2C9F0024884E /* Main.storyboard */ = {
276 | isa = PBXVariantGroup;
277 | children = (
278 | B5051871230C2C9F0024884E /* Base */,
279 | );
280 | name = Main.storyboard;
281 | sourceTree = "";
282 | };
283 | B53CD77528738D46002A1C80 /* PreviewViewController.xib */ = {
284 | isa = PBXVariantGroup;
285 | children = (
286 | B53CD77628738D46002A1C80 /* Base */,
287 | );
288 | name = PreviewViewController.xib;
289 | sourceTree = "";
290 | };
291 | /* End PBXVariantGroup section */
292 |
293 | /* Begin XCBuildConfiguration section */
294 | B5051875230C2C9F0024884E /* Debug */ = {
295 | isa = XCBuildConfiguration;
296 | buildSettings = {
297 | ALWAYS_SEARCH_USER_PATHS = NO;
298 | CLANG_ANALYZER_NONNULL = YES;
299 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
300 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
301 | CLANG_CXX_LIBRARY = "libc++";
302 | CLANG_ENABLE_MODULES = YES;
303 | CLANG_ENABLE_OBJC_ARC = YES;
304 | CLANG_ENABLE_OBJC_WEAK = YES;
305 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
306 | CLANG_WARN_BOOL_CONVERSION = YES;
307 | CLANG_WARN_COMMA = YES;
308 | CLANG_WARN_CONSTANT_CONVERSION = YES;
309 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
310 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
311 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
312 | CLANG_WARN_EMPTY_BODY = YES;
313 | CLANG_WARN_ENUM_CONVERSION = YES;
314 | CLANG_WARN_INFINITE_RECURSION = YES;
315 | CLANG_WARN_INT_CONVERSION = YES;
316 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
317 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
318 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
319 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
320 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
321 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
322 | CLANG_WARN_STRICT_PROTOTYPES = YES;
323 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
324 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
325 | CLANG_WARN_UNREACHABLE_CODE = YES;
326 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
327 | CODE_SIGN_IDENTITY = "-";
328 | COPY_PHASE_STRIP = NO;
329 | DEAD_CODE_STRIPPING = YES;
330 | DEBUG_INFORMATION_FORMAT = dwarf;
331 | ENABLE_STRICT_OBJC_MSGSEND = YES;
332 | ENABLE_TESTABILITY = YES;
333 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
334 | GCC_C_LANGUAGE_STANDARD = gnu11;
335 | GCC_DYNAMIC_NO_PIC = NO;
336 | GCC_NO_COMMON_BLOCKS = YES;
337 | GCC_OPTIMIZATION_LEVEL = 0;
338 | GCC_PREPROCESSOR_DEFINITIONS = (
339 | "DEBUG=1",
340 | "$(inherited)",
341 | );
342 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
343 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
344 | GCC_WARN_UNDECLARED_SELECTOR = YES;
345 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
346 | GCC_WARN_UNUSED_FUNCTION = YES;
347 | GCC_WARN_UNUSED_VARIABLE = YES;
348 | MACOSX_DEPLOYMENT_TARGET = 11.5;
349 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
350 | MTL_FAST_MATH = YES;
351 | ONLY_ACTIVE_ARCH = NO;
352 | SDKROOT = macosx;
353 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
354 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
355 | };
356 | name = Debug;
357 | };
358 | B5051876230C2C9F0024884E /* Release */ = {
359 | isa = XCBuildConfiguration;
360 | buildSettings = {
361 | ALWAYS_SEARCH_USER_PATHS = NO;
362 | CLANG_ANALYZER_NONNULL = YES;
363 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
364 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
365 | CLANG_CXX_LIBRARY = "libc++";
366 | CLANG_ENABLE_MODULES = YES;
367 | CLANG_ENABLE_OBJC_ARC = YES;
368 | CLANG_ENABLE_OBJC_WEAK = YES;
369 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
370 | CLANG_WARN_BOOL_CONVERSION = YES;
371 | CLANG_WARN_COMMA = YES;
372 | CLANG_WARN_CONSTANT_CONVERSION = YES;
373 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
374 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
375 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
376 | CLANG_WARN_EMPTY_BODY = YES;
377 | CLANG_WARN_ENUM_CONVERSION = YES;
378 | CLANG_WARN_INFINITE_RECURSION = YES;
379 | CLANG_WARN_INT_CONVERSION = YES;
380 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
381 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
382 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
383 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
384 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
385 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
386 | CLANG_WARN_STRICT_PROTOTYPES = YES;
387 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
388 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
389 | CLANG_WARN_UNREACHABLE_CODE = YES;
390 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
391 | CODE_SIGN_IDENTITY = "-";
392 | COPY_PHASE_STRIP = NO;
393 | DEAD_CODE_STRIPPING = YES;
394 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
395 | ENABLE_NS_ASSERTIONS = NO;
396 | ENABLE_STRICT_OBJC_MSGSEND = YES;
397 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
398 | GCC_C_LANGUAGE_STANDARD = gnu11;
399 | GCC_NO_COMMON_BLOCKS = YES;
400 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
401 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
402 | GCC_WARN_UNDECLARED_SELECTOR = YES;
403 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
404 | GCC_WARN_UNUSED_FUNCTION = YES;
405 | GCC_WARN_UNUSED_VARIABLE = YES;
406 | MACOSX_DEPLOYMENT_TARGET = 11.5;
407 | MTL_ENABLE_DEBUG_INFO = NO;
408 | MTL_FAST_MATH = YES;
409 | ONLY_ACTIVE_ARCH = NO;
410 | SDKROOT = macosx;
411 | SWIFT_COMPILATION_MODE = wholemodule;
412 | SWIFT_OPTIMIZATION_LEVEL = "-O";
413 | };
414 | name = Release;
415 | };
416 | B5051878230C2C9F0024884E /* Debug */ = {
417 | isa = XCBuildConfiguration;
418 | buildSettings = {
419 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
420 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
421 | CODE_SIGN_ENTITLEMENTS = APPlayMIDI/APPlayMIDI.entitlements;
422 | CODE_SIGN_IDENTITY = "-";
423 | CODE_SIGN_STYLE = Automatic;
424 | COMBINE_HIDPI_IMAGES = YES;
425 | CURRENT_PROJECT_VERSION = 80;
426 | DEAD_CODE_STRIPPING = YES;
427 | DEVELOPMENT_TEAM = "";
428 | ENABLE_HARDENED_RUNTIME = YES;
429 | INFOPLIST_FILE = APPlayMIDI/Info.plist;
430 | INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.music";
431 | LD_RUNPATH_SEARCH_PATHS = (
432 | "$(inherited)",
433 | "@executable_path/../Frameworks",
434 | );
435 | MACOSX_DEPLOYMENT_TARGET = 11.5;
436 | MARKETING_VERSION = 1.14;
437 | PRODUCT_BUNDLE_IDENTIFIER = bensoft.APPlayMIDI;
438 | PRODUCT_NAME = "$(TARGET_NAME)";
439 | SWIFT_VERSION = 5.0;
440 | };
441 | name = Debug;
442 | };
443 | B5051879230C2C9F0024884E /* Release */ = {
444 | isa = XCBuildConfiguration;
445 | buildSettings = {
446 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
447 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
448 | CODE_SIGN_ENTITLEMENTS = APPlayMIDI/APPlayMIDI.entitlements;
449 | CODE_SIGN_IDENTITY = "-";
450 | CODE_SIGN_STYLE = Automatic;
451 | COMBINE_HIDPI_IMAGES = YES;
452 | CURRENT_PROJECT_VERSION = 80;
453 | DEAD_CODE_STRIPPING = YES;
454 | DEVELOPMENT_TEAM = "";
455 | ENABLE_HARDENED_RUNTIME = YES;
456 | INFOPLIST_FILE = APPlayMIDI/Info.plist;
457 | INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.music";
458 | LD_RUNPATH_SEARCH_PATHS = (
459 | "$(inherited)",
460 | "@executable_path/../Frameworks",
461 | );
462 | MACOSX_DEPLOYMENT_TARGET = 11.5;
463 | MARKETING_VERSION = 1.14;
464 | PRODUCT_BUNDLE_IDENTIFIER = bensoft.APPlayMIDI;
465 | PRODUCT_NAME = "$(TARGET_NAME)";
466 | SWIFT_VERSION = 5.0;
467 | };
468 | name = Release;
469 | };
470 | B53CD77E28738D46002A1C80 /* Debug */ = {
471 | isa = XCBuildConfiguration;
472 | buildSettings = {
473 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
474 | CODE_SIGN_ENTITLEMENTS = qlMIDI/qlMIDI.entitlements;
475 | CODE_SIGN_IDENTITY = "-";
476 | CODE_SIGN_STYLE = Automatic;
477 | CURRENT_PROJECT_VERSION = 80;
478 | DEAD_CODE_STRIPPING = YES;
479 | DEVELOPMENT_TEAM = "";
480 | ENABLE_HARDENED_RUNTIME = YES;
481 | GENERATE_INFOPLIST_FILE = YES;
482 | INFOPLIST_FILE = qlMIDI/Info.plist;
483 | INFOPLIST_KEY_CFBundleDisplayName = qlMIDI;
484 | INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 Ben. All rights reserved.";
485 | LD_RUNPATH_SEARCH_PATHS = (
486 | "$(inherited)",
487 | "@executable_path/../Frameworks",
488 | "@executable_path/../../../../Frameworks",
489 | );
490 | MACOSX_DEPLOYMENT_TARGET = 12.0;
491 | MARKETING_VERSION = 1.12;
492 | ONLY_ACTIVE_ARCH = NO;
493 | PRODUCT_BUNDLE_IDENTIFIER = bensoft.APPlayMIDI.qlMIDI;
494 | PRODUCT_NAME = "$(TARGET_NAME)";
495 | SKIP_INSTALL = YES;
496 | SWIFT_EMIT_LOC_STRINGS = YES;
497 | SWIFT_VERSION = 5.0;
498 | };
499 | name = Debug;
500 | };
501 | B53CD77F28738D46002A1C80 /* Release */ = {
502 | isa = XCBuildConfiguration;
503 | buildSettings = {
504 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
505 | CODE_SIGN_ENTITLEMENTS = qlMIDI/qlMIDI.entitlements;
506 | CODE_SIGN_IDENTITY = "-";
507 | CODE_SIGN_STYLE = Automatic;
508 | CURRENT_PROJECT_VERSION = 80;
509 | DEAD_CODE_STRIPPING = YES;
510 | DEVELOPMENT_TEAM = "";
511 | ENABLE_HARDENED_RUNTIME = YES;
512 | GENERATE_INFOPLIST_FILE = YES;
513 | INFOPLIST_FILE = qlMIDI/Info.plist;
514 | INFOPLIST_KEY_CFBundleDisplayName = qlMIDI;
515 | INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 Ben. All rights reserved.";
516 | LD_RUNPATH_SEARCH_PATHS = (
517 | "$(inherited)",
518 | "@executable_path/../Frameworks",
519 | "@executable_path/../../../../Frameworks",
520 | );
521 | MACOSX_DEPLOYMENT_TARGET = 12.0;
522 | MARKETING_VERSION = 1.12;
523 | ONLY_ACTIVE_ARCH = NO;
524 | PRODUCT_BUNDLE_IDENTIFIER = bensoft.APPlayMIDI.qlMIDI;
525 | PRODUCT_NAME = "$(TARGET_NAME)";
526 | SKIP_INSTALL = YES;
527 | SWIFT_EMIT_LOC_STRINGS = YES;
528 | SWIFT_VERSION = 5.0;
529 | };
530 | name = Release;
531 | };
532 | /* End XCBuildConfiguration section */
533 |
534 | /* Begin XCConfigurationList section */
535 | B5051860230C2C9E0024884E /* Build configuration list for PBXProject "APPlayMIDI" */ = {
536 | isa = XCConfigurationList;
537 | buildConfigurations = (
538 | B5051875230C2C9F0024884E /* Debug */,
539 | B5051876230C2C9F0024884E /* Release */,
540 | );
541 | defaultConfigurationIsVisible = 0;
542 | defaultConfigurationName = Release;
543 | };
544 | B5051877230C2C9F0024884E /* Build configuration list for PBXNativeTarget "APPlayMIDI" */ = {
545 | isa = XCConfigurationList;
546 | buildConfigurations = (
547 | B5051878230C2C9F0024884E /* Debug */,
548 | B5051879230C2C9F0024884E /* Release */,
549 | );
550 | defaultConfigurationIsVisible = 0;
551 | defaultConfigurationName = Release;
552 | };
553 | B53CD77D28738D46002A1C80 /* Build configuration list for PBXNativeTarget "qlMIDI" */ = {
554 | isa = XCConfigurationList;
555 | buildConfigurations = (
556 | B53CD77E28738D46002A1C80 /* Debug */,
557 | B53CD77F28738D46002A1C80 /* Release */,
558 | );
559 | defaultConfigurationIsVisible = 0;
560 | defaultConfigurationName = Release;
561 | };
562 | /* End XCConfigurationList section */
563 | };
564 | rootObject = B505185D230C2C9E0024884E /* Project object */;
565 | }
566 |
--------------------------------------------------------------------------------
/APPlayMIDI/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
--------------------------------------------------------------------------------