├── MIDIEventKit.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcuserdata │ └── Cem.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── project.pbxproj ├── MIDIEventKit.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── Example ├── Example.entitlements ├── AppDelegate.swift ├── Info.plist ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── ViewController.swift └── Base.lproj │ └── Main.storyboard ├── Podfile.lock ├── Source ├── MIDIEventKit.h ├── Info iOS.plist ├── Info Mac.plist ├── MIDIEventKit.strings └── MIDIEventKit.swift ├── Podfile ├── MIDIEventKitTests ├── MIDIEventKitTests.swift └── Info.plist ├── README.md ├── LICENSE ├── .gitignore └── MIDIEventKit.podspec /MIDIEventKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MIDIEventKit.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MIDIEventKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Example.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AudioKit (4.4.0): 3 | - AudioKit/Core (= 4.4.0) 4 | - AudioKit/UI (= 4.4.0) 5 | - AudioKit/Core (4.4.0) 6 | - AudioKit/UI (4.4.0) 7 | 8 | DEPENDENCIES: 9 | - AudioKit 10 | 11 | SPEC REPOS: 12 | https://github.com/cocoapods/specs.git: 13 | - AudioKit 14 | 15 | SPEC CHECKSUMS: 16 | AudioKit: 79c2b23cd00beb656938aa0b81b614391f17eaa3 17 | 18 | PODFILE CHECKSUM: 1bf0ca8f8482b095315e32dddb19fa76eef97afa 19 | 20 | COCOAPODS: 1.6.0.beta.1 21 | -------------------------------------------------------------------------------- /Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Example 4 | // 5 | // Created by Cem Olcay on 8.03.2018. 6 | // Copyright © 2018 cemolcay. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Source/MIDIEventKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // MIDIEventKit.h 3 | // MIDIEventKit 4 | // 5 | // Created by Cem Olcay on 8.03.2018. 6 | // Copyright © 2018 cemolcay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for MIDIEventKit. 12 | FOUNDATION_EXPORT double MIDIEventKitVersionNumber; 13 | 14 | //! Project version string for MIDIEventKit. 15 | FOUNDATION_EXPORT const unsigned char MIDIEventKitVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | swift_version = "4.2" 4 | 5 | target 'Example' do 6 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 7 | use_frameworks! 8 | pod 'AudioKit' 9 | end 10 | 11 | target 'MIDIEventKit iOS' do 12 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 13 | use_frameworks! 14 | end 15 | 16 | target 'MIDIEventKit Mac' do 17 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 18 | use_frameworks! 19 | end 20 | -------------------------------------------------------------------------------- /MIDIEventKitTests/MIDIEventKitTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MIDIEventKitTests.swift 3 | // MIDIEventKitTests 4 | // 5 | // Created by Cem Olcay on 8.03.2018. 6 | // Copyright © 2018 cemolcay. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import CoreMIDI 11 | 12 | class MIDIEventKitTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | } 24 | 25 | extension MIDIEventKitTests { 26 | 27 | } 28 | -------------------------------------------------------------------------------- /MIDIEventKitTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Source/Info iOS.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /MIDIEventKit.xcodeproj/xcuserdata/Cem.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Example.xcscheme 8 | 9 | orderHint 10 | 6 11 | 12 | MIDIEventKit Mac.xcscheme 13 | 14 | orderHint 15 | 5 16 | 17 | MIDIEventKit iOS.xcscheme 18 | 19 | orderHint 20 | 4 21 | 22 | MIDIEventKit.xcscheme 23 | 24 | orderHint 25 | 4 26 | 27 | 28 | SuppressBuildableAutocreation 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MIDIEventKit 2 | === 3 | MIDI data structures for Swift. Send MIDI events in human language. 4 | 5 | 6 | Requirements 7 | ---- 8 | * Swift 4.0+ 9 | * iOS 8.0+ 10 | * macOS 11.0+ 11 | 12 | Install 13 | ---- 14 | ``` 15 | pod 'MIDIEventKit' 16 | ``` 17 | 18 | Usage 19 | ---- 20 | Send or receive `MIDIPacket`s or `MIDIPacketList`s from `CoreMIDI` or [AudioKit](github.com/AudioKit/AudioKit)'s `AKMIDI` easily with MIDIEventKit data structures. 21 | 22 | Documentation 23 | ---- 24 | 25 | You can find documentation on [here](http://cemolcay.github.io/MIDIEventKit). 26 | 27 | App Store 28 | ---- 29 | 30 | This library has battle tested within my apps on App Store. Check them out! 31 | * [ArpBud](https://itunes.apple.com/us/app/arpbud-midi-sequencer-more/id1349342326?mt=8) (iOS, AU) 32 | * [ScaleBud](https://itunes.apple.com/us/app/scalebud-auv3-midi-keyboard/id1409125865?mt=8) (iOS, AUv3) 33 | * [StepBud](https://itunes.apple.com/us/app/stepbud-auv3-midi-sequencer/id1453104408?mt=8) (iOS, AUv3) 34 | -------------------------------------------------------------------------------- /Source/Info Mac.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSHumanReadableCopyright 22 | Copyright © 2018 cemolcay. All rights reserved. 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2016, Cem Olcay 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a 4 | copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | DEALINGS IN THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2018 cemolcay. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Example/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Example 4 | // 5 | // Created by Cem Olcay on 8.03.2018. 6 | // Copyright © 2018 cemolcay. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import AudioKit 11 | 12 | class ViewController: NSViewController, AKMIDIListener { 13 | let midi = AKMIDI() 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | midi.addListener(self) 18 | midi.openInput() 19 | midi.createVirtualOutputPort(name: "MIDIEventKit") 20 | } 21 | 22 | @IBAction func sendMIDI(sender: NSButton) { 23 | let pitch = MIDIEvent( 24 | event: MIDIChannelVoiceEvent.pitchBendChange(bend: 8192, channel: 0), 25 | timestamp: .now) 26 | // midi.sendEvent(AKMIDIEvent(packet: pitch.midiPacket)) 27 | 28 | let mod = MIDIEvent( 29 | event: MIDIChannelVoiceEvent.controllerChange( 30 | event: .modulationWheel(value: 100), 31 | channel: 0), 32 | timestamp: .now) 33 | // midi.sendEvent(AKMIDIEvent(packet: mod.midiPacket)) 34 | 35 | let packetList = [pitch, mod].midiPacketList 36 | for endpoint in midi.endpoints { 37 | MIDISend(midi.virtualInput, endpoint.value, packetList) 38 | } 39 | packetList.deallocate() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/swift,xcode 3 | 4 | ### Swift ### 5 | # Xcode 6 | # 7 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 8 | 9 | ## Build generated 10 | build/ 11 | DerivedData/ 12 | 13 | ## Various settings 14 | *.pbxuser 15 | !default.pbxuser 16 | *.mode1v3 17 | !default.mode1v3 18 | *.mode2v3 19 | !default.mode2v3 20 | *.perspectivev3 21 | !default.perspectivev3 22 | xcuserdata/ 23 | 24 | ## Other 25 | *.moved-aside 26 | *.xcuserstate 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | *.dSYM.zip 32 | *.dSYM 33 | 34 | ## Playgrounds 35 | timeline.xctimeline 36 | playground.xcworkspace 37 | 38 | # Swift Package Manager 39 | # 40 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 41 | # Packages/ 42 | .build/ 43 | 44 | # CocoaPods 45 | # 46 | # We recommend against adding the Pods directory to your .gitignore. However 47 | # you should judge for yourself, the pros and cons are mentioned at: 48 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 49 | # 50 | Pods/ 51 | 52 | # Carthage 53 | # 54 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 55 | Carthage/Checkouts 56 | 57 | Carthage/Build 58 | 59 | # fastlane 60 | # 61 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 62 | # screenshots whenever they are needed. 63 | # For more information about the recommended setup visit: 64 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 65 | 66 | fastlane/report.xml 67 | fastlane/Preview.html 68 | fastlane/screenshots 69 | fastlane/test_output 70 | 71 | 72 | ### Xcode ### 73 | # Xcode 74 | # 75 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 76 | 77 | ## Build generated 78 | 79 | ## Various settings 80 | 81 | ## Other 82 | *.xccheckout 83 | *.xcscmblueprint 84 | 85 | # Docs 86 | docs/ 87 | 88 | # End of https://www.gitignore.io/api/swift,xcode 89 | -------------------------------------------------------------------------------- /Source/MIDIEventKit.strings: -------------------------------------------------------------------------------- 1 | /* 2 | MIDIEventKit.strings 3 | MIDIEventKit 4 | 5 | Created by Cem Olcay on 7.03.2018. 6 | Copyright © 2018 cemolcay. All rights reserved. 7 | */ 8 | 9 | // MIDI System Realtime 10 | 11 | "midi_timingClock" = "Timing Clock"; 12 | "midi_start" = "Start"; 13 | "midi_continue" = "Continue"; 14 | "midi_stop" = "Stop"; 15 | "midi_activeSensing" = "Active Sensing"; 16 | "midi_reset" = "Reset"; 17 | 18 | // MIDI System common 19 | 20 | "midi_systemExclusive" = "System Exclusive"; 21 | "midi_songPositionPointer" = "Song Position Pointer"; 22 | "midi_songSelect" = "Song Select"; 23 | "midi_tuneRequest" = "Tune Request"; 24 | "midi_eox" = "EOX"; 25 | "midi_quarterFrameEvent" = "Quarter Frame"; 26 | 27 | // MIDI Channel Change 28 | 29 | "midi_allSoundOff" = "All Sound Off"; 30 | "midi_resetAllControllers" = "Reset All Controllers"; 31 | "midi_localControl" = "Local Control"; 32 | "midi_allNotesOff" = "All Notes Off"; 33 | "midi_omniModeOff" = "Omni Mode Off"; 34 | "midi_omniModeOn" = "Omni Mode On"; 35 | "midi_monoModeOn" = "Mono Mode On"; 36 | "midi_polyModeOn" = "Poly Mode On"; 37 | 38 | // MIDI Voice Change 39 | 40 | "midi_noteOff" = "Note Off"; 41 | "midi_noteOn" = "Note On"; 42 | "midi_polyphonicAftertouch" = "Polyphonic Aftertouch"; 43 | "midi_channelAftertouch" = "Channel Aftertouch"; 44 | "midi_pitchBendChange" = "Pitch Bend Change"; 45 | 46 | // MIDI CC 47 | 48 | "midi_bankSelect" = "Bank Select"; 49 | "midi_modulationWheel" = "Modulation Wheel"; 50 | "midi_breathController" = "Breath Controller"; 51 | "midi_footController" = "Foot Controller"; 52 | "midi_portamentoTime" = "Portamento Time"; 53 | "midi_dataEntryMSB" = "Data Entry MSB"; 54 | "midi_channelVolume" = "Channel Volume"; 55 | "midi_balance" = "Balance"; 56 | "midi_pan" = "Pan"; 57 | "midi_expressionController" = "Expression Controller"; 58 | "midi_effectControl1" = "Effect Control 1"; 59 | "midi_effectControl2" = "Effect Control 2"; 60 | "midi_generalPurposeController1" = "General Purpose Controller 1"; 61 | "midi_generalPurposeController2" = "General Purpose Controller 2"; 62 | "midi_generalPurposeController3" = "General Purpose Controller 3"; 63 | "midi_generalPurposeController4" = "General Purpose Controller 4"; 64 | "midi_lsbBankSelect" = "LSB Bank Select"; 65 | "midi_lsbModulationWheel" = "LSB Modulation Wheel"; 66 | "midi_lsbBreathController" = "LSB Breath Controller"; 67 | "midi_lsbFootController" = "LSB Foot Controller"; 68 | "midi_lsbPortamentoTime" = "LSB Portamento Time"; 69 | "midi_lsbDataEntryMSB" = "LSB Data Entry MSB"; 70 | "midi_lsbChannelVolume" = "LSB Channel Volume"; 71 | "midi_lsbBalance" = "LSB Balance"; 72 | "midi_lsbPan" = "LSB Pan"; 73 | "midi_lsbExpressionController" = "LSB Expression Controller"; 74 | "midi_lsbEffectControl1" = "LSB Effect Control 1"; 75 | "midi_lsbEffectControl2" = "LSB Effect Control 2"; 76 | "midi_lsbGeneralPurposeController1" = "LSB General Purpose Controller 1"; 77 | "midi_lsbGeneralPurposeController2" = "LSB General Purpose Controller 2"; 78 | "midi_lsbGeneralPurposeController3" = "LSB General Purpose Controller 3"; 79 | "midi_lsbGeneralPurposeController4" = "LSB General Purpose Controller 4"; 80 | "midi_damperPedal" = "Damper Pedal"; 81 | "midi_portamentoOn" = "Portamento On"; 82 | "midi_sostenutoOn" = "Sostenuto On"; 83 | "midi_softPedalOn" = "Soft Pedal On"; 84 | "midi_legatoFootswitch" = "Legato Footswitch"; 85 | "midi_hold2" = "Hold 2"; 86 | "midi_soundVariation" = "Sound Variation"; 87 | "midi_timbreIntesity" = "Timbre Intesity"; 88 | "midi_releaseTime" = "Release Time"; 89 | "midi_attackTime" = "Attack Time"; 90 | "midi_brightness" = "Brightness"; 91 | "midi_decayTime" = "Decay Time"; 92 | "midi_vibratoRate" = "Vibrato Rate"; 93 | "midi_vibratoDepth" = "Vibrato Depth"; 94 | "midi_vibratoDelay" = "Vibrato Delay"; 95 | "midi_defaultUndefined" = "Default Undefined"; 96 | "midi_generalPurposeController5" = "General Purpose Controller5"; 97 | "midi_generalPurposeController6" = "general Purpose Controller6"; 98 | "midi_generalPurposeController7" = "General Purpose Controller7"; 99 | "midi_generalPurposeController8" = "General Purpose Controller8"; 100 | "midi_portamentoControl" = "Portamento Control"; 101 | "midi_highResolutionVelocityPrefix" = "High Resolution Velocity Prefix"; 102 | "midi_reverbSendLevel" = "Reverb Send Level"; 103 | "midi_tremoloDepth" = "Tremolo Depth"; 104 | "midi_chorusSendLevel" = "Chorus Send Level"; 105 | "midi_celesteDepth" = "Celeste Depth"; 106 | "midi_phaserDepth" = "Phaser Depth"; 107 | "midi_dataIncrement" = "Data Increment"; 108 | "midi_dataDecrement" = "Data Decrement"; 109 | "midi_nonRegisteredParameterNumberLSB" = "Non-Registered Parameter Number LSB"; 110 | "midi_nonRegisteredParameterNumberMSB" = "Non-RegisteredParameterNumberMSB"; 111 | "midi_registeredParameterNumberLSB" = "Registered Parameter Number LSB"; 112 | "midi_registeredParameterNumberMSB" = "Registered Parameter Number MSB"; 113 | 114 | "midi_undefined" = "Undefined"; 115 | -------------------------------------------------------------------------------- /MIDIEventKit.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint MIDIEventKit.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "MIDIEventKit" 19 | s.version = "0.0.2" 20 | s.swift_version = "4.2" 21 | s.summary = "MIDI data structures for Swift. Send MIDI events in human language." 22 | 23 | # This description is used to generate tags and improve search results. 24 | # * Think: What does it do? Why did you write it? What is the focus? 25 | # * Try to keep it short, snappy and to the point. 26 | # * Write the description between the DESC delimiters below. 27 | # * Finally, don't worry about the indent, CocoaPods strips it! 28 | s.description = <<-DESC 29 | MIDIEventKit 30 | === 31 | MIDI data structures for Swift. Send MIDI events in human language. 32 | 33 | 34 | Requirements 35 | ---- 36 | * Swift 4.0+ 37 | * iOS 8.0+ 38 | * macOS 10.9+ 39 | 40 | Install 41 | ---- 42 | ``` 43 | pod 'MIDIEventKit' 44 | ``` 45 | 46 | Usage 47 | ---- 48 | Send or receive `MIDIPacket`s or `MIDIPacketList`s from `CoreMIDI` or [AudioKit](github.com/AudioKit/AudioKit)'s `AKMIDI` easily with MIDIEventKit data structures. 49 | DESC 50 | 51 | s.homepage = "https://github.com/cemolcay/MIDIEventKit" 52 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 53 | 54 | 55 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 56 | # 57 | # Licensing your code is important. See http://choosealicense.com for more info. 58 | # CocoaPods will detect a license file if there is a named LICENSE* 59 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 60 | # 61 | 62 | s.license = "MIT" 63 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 64 | 65 | 66 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 67 | # 68 | # Specify the authors of the library, with email addresses. Email addresses 69 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 70 | # accepts just a name if you'd rather not provide an email address. 71 | # 72 | # Specify a social_media_url where others can refer to, for example a twitter 73 | # profile URL. 74 | # 75 | 76 | s.author = { "cemolcay" => "ccemolcay@gmail.com" } 77 | # Or just: s.author = "cemolcay" 78 | # s.authors = { "cemolcay" => "ccemolcay@gmail.com" } 79 | # s.social_media_url = "http://twitter.com/cem_olcay" 80 | 81 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 82 | # 83 | # If this Pod runs only on iOS or OS X, then specify the platform and 84 | # the deployment target. You can optionally include the target after the platform. 85 | # 86 | 87 | # s.platform = :ios 88 | # s.platform = :ios, "8.0" 89 | 90 | # When using multiple platforms 91 | s.ios.deployment_target = "8.0" 92 | s.osx.deployment_target = "10.9" 93 | # s.watchos.deployment_target = "2.0" 94 | # s.tvos.deployment_target = "9.0" 95 | 96 | 97 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 98 | # 99 | # Specify the location from where the source should be retrieved. 100 | # Supports git, hg, bzr, svn and HTTP. 101 | # 102 | 103 | s.source = { :git => "https://github.com/cemolcay/MIDIEventKit.git", :tag => "#{s.version}" } 104 | 105 | 106 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 107 | # 108 | # CocoaPods is smart about how it includes source code. For source files 109 | # giving a folder will include any swift, h, m, mm, c & cpp files. 110 | # For header files it will include any header in the folder. 111 | # Not including the public_header_files will make all headers public. 112 | # 113 | 114 | s.source_files = "Source/MIDIEventKit.swift" 115 | # s.exclude_files = "Classes/Exclude" 116 | 117 | # s.public_header_files = "Classes/**/*.h" 118 | 119 | 120 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 121 | # 122 | # A list of resources included with the Pod. These are copied into the 123 | # target bundle with a build phase script. Anything else will be cleaned. 124 | # You can preserve files from being cleaned, please don't preserve 125 | # non-essential files like tests, examples and documentation. 126 | # 127 | 128 | s.resource = "Source/MIDIEventKit.strings" 129 | # s.resources = "Resources/*.png" 130 | 131 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 132 | 133 | 134 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 135 | # 136 | # Link your library with frameworks, or libraries. Libraries do not include 137 | # the lib prefix of their name. 138 | # 139 | 140 | # s.framework = "SomeFramework" 141 | s.frameworks = "Foundation", "CoreMIDI" 142 | 143 | # s.library = "iconv" 144 | # s.libraries = "iconv", "xml2" 145 | 146 | 147 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 148 | # 149 | # If your library depends on compiler flags you can set them in the xcconfig hash 150 | # where they will only apply to your library. If you depend on other Podspecs 151 | # you can include multiple dependencies to ensure it works. 152 | 153 | s.requires_arc = true 154 | 155 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 156 | # s.dependency "JSONKit", "~> 1.4" 157 | 158 | end 159 | -------------------------------------------------------------------------------- /MIDIEventKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3C27CD968434FE4F018AEFC6 /* Pods_MIDIEventKit_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F4C415C5F92E165807ECFD6 /* Pods_MIDIEventKit_iOS.framework */; }; 11 | 6774B437761D5FE9E890D38E /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D41202A472183AF280DA2C8 /* Pods_Example.framework */; }; 12 | B280797B205168090033D8CA /* MIDIEventKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B280797A205168090033D8CA /* MIDIEventKitTests.swift */; }; 13 | B280797D205168090033D8CA /* MIDIEventKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B280796C205167F70033D8CA /* MIDIEventKit.framework */; }; 14 | B28079892051687C0033D8CA /* MIDIEventKit.h in Headers */ = {isa = PBXBuildFile; fileRef = B28079842051687C0033D8CA /* MIDIEventKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | B280798A2051687C0033D8CA /* MIDIEventKit.h in Headers */ = {isa = PBXBuildFile; fileRef = B28079842051687C0033D8CA /* MIDIEventKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 16 | B280798B2051687C0033D8CA /* MIDIEventKit.strings in Resources */ = {isa = PBXBuildFile; fileRef = B28079852051687C0033D8CA /* MIDIEventKit.strings */; }; 17 | B280798C2051687C0033D8CA /* MIDIEventKit.strings in Resources */ = {isa = PBXBuildFile; fileRef = B28079852051687C0033D8CA /* MIDIEventKit.strings */; }; 18 | B280798D2051687C0033D8CA /* MIDIEventKit.strings in Resources */ = {isa = PBXBuildFile; fileRef = B28079852051687C0033D8CA /* MIDIEventKit.strings */; }; 19 | B28079942051687C0033D8CA /* MIDIEventKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B28079882051687C0033D8CA /* MIDIEventKit.swift */; }; 20 | B28079952051687C0033D8CA /* MIDIEventKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B28079882051687C0033D8CA /* MIDIEventKit.swift */; }; 21 | B28079962051687C0033D8CA /* MIDIEventKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B28079882051687C0033D8CA /* MIDIEventKit.swift */; }; 22 | B280799E205168BE0033D8CA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B280799D205168BE0033D8CA /* AppDelegate.swift */; }; 23 | B28079A0205168BE0033D8CA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B280799F205168BE0033D8CA /* ViewController.swift */; }; 24 | B28079A2205168BE0033D8CA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B28079A1205168BE0033D8CA /* Assets.xcassets */; }; 25 | B28079A5205168BE0033D8CA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B28079A3205168BE0033D8CA /* Main.storyboard */; }; 26 | B28079AC20516B290033D8CA /* CoreMIDI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B28079AB20516B290033D8CA /* CoreMIDI.framework */; }; 27 | B28079AD20516B8D0033D8CA /* MIDIEventKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = B28079882051687C0033D8CA /* MIDIEventKit.swift */; }; 28 | B28079AE20516B900033D8CA /* MIDIEventKit.strings in Resources */ = {isa = PBXBuildFile; fileRef = B28079852051687C0033D8CA /* MIDIEventKit.strings */; }; 29 | D5DFD8B2E77E3A061CFCB1A5 /* Pods_MIDIEventKit_Mac.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 858EF4380B4819866C63B217 /* Pods_MIDIEventKit_Mac.framework */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXContainerItemProxy section */ 33 | B280797E205168090033D8CA /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = B2807929205010B30033D8CA /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = B280796B205167F70033D8CA; 38 | remoteInfo = "MIDIEventKit Mac"; 39 | }; 40 | /* End PBXContainerItemProxy section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 19FF26D21C0824B962ABA6BF /* Pods-MIDIEventKit Mac.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MIDIEventKit Mac.release.xcconfig"; path = "Pods/Target Support Files/Pods-MIDIEventKit Mac/Pods-MIDIEventKit Mac.release.xcconfig"; sourceTree = ""; }; 44 | 232D2816BBD0388804ED3C0C /* Pods-MIDIEventKit iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MIDIEventKit iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-MIDIEventKit iOS/Pods-MIDIEventKit iOS.release.xcconfig"; sourceTree = ""; }; 45 | 2864A751D34FED48A1DE1D74 /* Pods_MIDIEventKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MIDIEventKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 2B2994F511D8ABB2E62810E0 /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = ""; }; 47 | 2F4C415C5F92E165807ECFD6 /* Pods_MIDIEventKit_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MIDIEventKit_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | 4D41202A472183AF280DA2C8 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 722A54B90897D6803A8EAC38 /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = ""; }; 50 | 775140D3856077E9A776235A /* Pods_MIDIEventKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MIDIEventKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 7FBCA92B0E4245B447B87FFD /* Pods-MIDIEventKit Mac.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MIDIEventKit Mac.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MIDIEventKit Mac/Pods-MIDIEventKit Mac.debug.xcconfig"; sourceTree = ""; }; 52 | 858EF4380B4819866C63B217 /* Pods_MIDIEventKit_Mac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MIDIEventKit_Mac.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 8A68D4B5865478FE4D4B27CC /* Pods-MIDIEventKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MIDIEventKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MIDIEventKit/Pods-MIDIEventKit.debug.xcconfig"; sourceTree = ""; }; 54 | B280795F205167E80033D8CA /* MIDIEventKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MIDIEventKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | B280796C205167F70033D8CA /* MIDIEventKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MIDIEventKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | B2807978205168090033D8CA /* MIDIEventKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MIDIEventKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 57 | B280797A205168090033D8CA /* MIDIEventKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MIDIEventKitTests.swift; sourceTree = ""; }; 58 | B280797C205168090033D8CA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 59 | B28079842051687C0033D8CA /* MIDIEventKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIDIEventKit.h; sourceTree = ""; }; 60 | B28079852051687C0033D8CA /* MIDIEventKit.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = MIDIEventKit.strings; sourceTree = ""; }; 61 | B28079862051687C0033D8CA /* Info iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info iOS.plist"; sourceTree = ""; }; 62 | B28079872051687C0033D8CA /* Info Mac.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info Mac.plist"; sourceTree = ""; }; 63 | B28079882051687C0033D8CA /* MIDIEventKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MIDIEventKit.swift; sourceTree = ""; }; 64 | B280799B205168BE0033D8CA /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | B280799D205168BE0033D8CA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 66 | B280799F205168BE0033D8CA /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 67 | B28079A1205168BE0033D8CA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 68 | B28079A4205168BE0033D8CA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 69 | B28079A6205168BE0033D8CA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 70 | B28079A7205168BE0033D8CA /* Example.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Example.entitlements; sourceTree = ""; }; 71 | B28079AB20516B290033D8CA /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/CoreMIDI.framework; sourceTree = DEVELOPER_DIR; }; 72 | BEDE4FE77723D5BFF62AD8B5 /* Pods-MIDIEventKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MIDIEventKit.release.xcconfig"; path = "Pods/Target Support Files/Pods-MIDIEventKit/Pods-MIDIEventKit.release.xcconfig"; sourceTree = ""; }; 73 | CC66C653A2497129D2BAE6FF /* Pods-MIDIEventKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MIDIEventKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MIDIEventKitTests/Pods-MIDIEventKitTests.debug.xcconfig"; sourceTree = ""; }; 74 | ED90A5E01F31F8314E514BDA /* Pods-MIDIEventKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MIDIEventKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-MIDIEventKitTests/Pods-MIDIEventKitTests.release.xcconfig"; sourceTree = ""; }; 75 | F40C8B9623A92EBA39F925C8 /* Pods-MIDIEventKit iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MIDIEventKit iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MIDIEventKit iOS/Pods-MIDIEventKit iOS.debug.xcconfig"; sourceTree = ""; }; 76 | /* End PBXFileReference section */ 77 | 78 | /* Begin PBXFrameworksBuildPhase section */ 79 | B280795B205167E80033D8CA /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | 3C27CD968434FE4F018AEFC6 /* Pods_MIDIEventKit_iOS.framework in Frameworks */, 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | B2807968205167F70033D8CA /* Frameworks */ = { 88 | isa = PBXFrameworksBuildPhase; 89 | buildActionMask = 2147483647; 90 | files = ( 91 | D5DFD8B2E77E3A061CFCB1A5 /* Pods_MIDIEventKit_Mac.framework in Frameworks */, 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | B2807975205168090033D8CA /* Frameworks */ = { 96 | isa = PBXFrameworksBuildPhase; 97 | buildActionMask = 2147483647; 98 | files = ( 99 | B280797D205168090033D8CA /* MIDIEventKit.framework in Frameworks */, 100 | ); 101 | runOnlyForDeploymentPostprocessing = 0; 102 | }; 103 | B2807998205168BE0033D8CA /* Frameworks */ = { 104 | isa = PBXFrameworksBuildPhase; 105 | buildActionMask = 2147483647; 106 | files = ( 107 | B28079AC20516B290033D8CA /* CoreMIDI.framework in Frameworks */, 108 | 6774B437761D5FE9E890D38E /* Pods_Example.framework in Frameworks */, 109 | ); 110 | runOnlyForDeploymentPostprocessing = 0; 111 | }; 112 | /* End PBXFrameworksBuildPhase section */ 113 | 114 | /* Begin PBXGroup section */ 115 | 1FF0F4E81EE0E252533CD33A /* Pods */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | 8A68D4B5865478FE4D4B27CC /* Pods-MIDIEventKit.debug.xcconfig */, 119 | BEDE4FE77723D5BFF62AD8B5 /* Pods-MIDIEventKit.release.xcconfig */, 120 | CC66C653A2497129D2BAE6FF /* Pods-MIDIEventKitTests.debug.xcconfig */, 121 | ED90A5E01F31F8314E514BDA /* Pods-MIDIEventKitTests.release.xcconfig */, 122 | 2B2994F511D8ABB2E62810E0 /* Pods-Example.debug.xcconfig */, 123 | 722A54B90897D6803A8EAC38 /* Pods-Example.release.xcconfig */, 124 | 7FBCA92B0E4245B447B87FFD /* Pods-MIDIEventKit Mac.debug.xcconfig */, 125 | 19FF26D21C0824B962ABA6BF /* Pods-MIDIEventKit Mac.release.xcconfig */, 126 | F40C8B9623A92EBA39F925C8 /* Pods-MIDIEventKit iOS.debug.xcconfig */, 127 | 232D2816BBD0388804ED3C0C /* Pods-MIDIEventKit iOS.release.xcconfig */, 128 | ); 129 | name = Pods; 130 | sourceTree = ""; 131 | }; 132 | B2807928205010B30033D8CA = { 133 | isa = PBXGroup; 134 | children = ( 135 | B28079832051687C0033D8CA /* Source */, 136 | B2807979205168090033D8CA /* MIDIEventKitTests */, 137 | B280799C205168BE0033D8CA /* Example */, 138 | B2807932205010B30033D8CA /* Products */, 139 | 1FF0F4E81EE0E252533CD33A /* Pods */, 140 | C333FE4DFD2D9D20F8EAE7C6 /* Frameworks */, 141 | ); 142 | sourceTree = ""; 143 | }; 144 | B2807932205010B30033D8CA /* Products */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | B280795F205167E80033D8CA /* MIDIEventKit.framework */, 148 | B280796C205167F70033D8CA /* MIDIEventKit.framework */, 149 | B2807978205168090033D8CA /* MIDIEventKitTests.xctest */, 150 | B280799B205168BE0033D8CA /* Example.app */, 151 | ); 152 | name = Products; 153 | sourceTree = ""; 154 | }; 155 | B2807979205168090033D8CA /* MIDIEventKitTests */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | B280797A205168090033D8CA /* MIDIEventKitTests.swift */, 159 | B280797C205168090033D8CA /* Info.plist */, 160 | ); 161 | path = MIDIEventKitTests; 162 | sourceTree = ""; 163 | }; 164 | B28079832051687C0033D8CA /* Source */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | B28079842051687C0033D8CA /* MIDIEventKit.h */, 168 | B28079852051687C0033D8CA /* MIDIEventKit.strings */, 169 | B28079862051687C0033D8CA /* Info iOS.plist */, 170 | B28079872051687C0033D8CA /* Info Mac.plist */, 171 | B28079882051687C0033D8CA /* MIDIEventKit.swift */, 172 | ); 173 | path = Source; 174 | sourceTree = ""; 175 | }; 176 | B280799C205168BE0033D8CA /* Example */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | B280799D205168BE0033D8CA /* AppDelegate.swift */, 180 | B280799F205168BE0033D8CA /* ViewController.swift */, 181 | B28079A1205168BE0033D8CA /* Assets.xcassets */, 182 | B28079A3205168BE0033D8CA /* Main.storyboard */, 183 | B28079A6205168BE0033D8CA /* Info.plist */, 184 | B28079A7205168BE0033D8CA /* Example.entitlements */, 185 | ); 186 | path = Example; 187 | sourceTree = ""; 188 | }; 189 | C333FE4DFD2D9D20F8EAE7C6 /* Frameworks */ = { 190 | isa = PBXGroup; 191 | children = ( 192 | B28079AB20516B290033D8CA /* CoreMIDI.framework */, 193 | 775140D3856077E9A776235A /* Pods_MIDIEventKit.framework */, 194 | 2864A751D34FED48A1DE1D74 /* Pods_MIDIEventKitTests.framework */, 195 | 4D41202A472183AF280DA2C8 /* Pods_Example.framework */, 196 | 858EF4380B4819866C63B217 /* Pods_MIDIEventKit_Mac.framework */, 197 | 2F4C415C5F92E165807ECFD6 /* Pods_MIDIEventKit_iOS.framework */, 198 | ); 199 | name = Frameworks; 200 | sourceTree = ""; 201 | }; 202 | /* End PBXGroup section */ 203 | 204 | /* Begin PBXHeadersBuildPhase section */ 205 | B280795C205167E80033D8CA /* Headers */ = { 206 | isa = PBXHeadersBuildPhase; 207 | buildActionMask = 2147483647; 208 | files = ( 209 | B28079892051687C0033D8CA /* MIDIEventKit.h in Headers */, 210 | ); 211 | runOnlyForDeploymentPostprocessing = 0; 212 | }; 213 | B2807969205167F70033D8CA /* Headers */ = { 214 | isa = PBXHeadersBuildPhase; 215 | buildActionMask = 2147483647; 216 | files = ( 217 | B280798A2051687C0033D8CA /* MIDIEventKit.h in Headers */, 218 | ); 219 | runOnlyForDeploymentPostprocessing = 0; 220 | }; 221 | /* End PBXHeadersBuildPhase section */ 222 | 223 | /* Begin PBXNativeTarget section */ 224 | B280795E205167E80033D8CA /* MIDIEventKit iOS */ = { 225 | isa = PBXNativeTarget; 226 | buildConfigurationList = B2807964205167E80033D8CA /* Build configuration list for PBXNativeTarget "MIDIEventKit iOS" */; 227 | buildPhases = ( 228 | F05D1E6640B11F31B3CFCD37 /* [CP] Check Pods Manifest.lock */, 229 | B280795A205167E80033D8CA /* Sources */, 230 | B280795B205167E80033D8CA /* Frameworks */, 231 | B280795C205167E80033D8CA /* Headers */, 232 | B280795D205167E80033D8CA /* Resources */, 233 | ); 234 | buildRules = ( 235 | ); 236 | dependencies = ( 237 | ); 238 | name = "MIDIEventKit iOS"; 239 | productName = "MIDIEventKit iOS"; 240 | productReference = B280795F205167E80033D8CA /* MIDIEventKit.framework */; 241 | productType = "com.apple.product-type.framework"; 242 | }; 243 | B280796B205167F70033D8CA /* MIDIEventKit Mac */ = { 244 | isa = PBXNativeTarget; 245 | buildConfigurationList = B2807971205167F70033D8CA /* Build configuration list for PBXNativeTarget "MIDIEventKit Mac" */; 246 | buildPhases = ( 247 | 30BCE5DA0EEFF86606049354 /* [CP] Check Pods Manifest.lock */, 248 | B2807967205167F70033D8CA /* Sources */, 249 | B2807968205167F70033D8CA /* Frameworks */, 250 | B2807969205167F70033D8CA /* Headers */, 251 | B280796A205167F70033D8CA /* Resources */, 252 | ); 253 | buildRules = ( 254 | ); 255 | dependencies = ( 256 | ); 257 | name = "MIDIEventKit Mac"; 258 | productName = "MIDIEventKit Mac"; 259 | productReference = B280796C205167F70033D8CA /* MIDIEventKit.framework */; 260 | productType = "com.apple.product-type.framework"; 261 | }; 262 | B2807977205168090033D8CA /* MIDIEventKitTests */ = { 263 | isa = PBXNativeTarget; 264 | buildConfigurationList = B2807980205168090033D8CA /* Build configuration list for PBXNativeTarget "MIDIEventKitTests" */; 265 | buildPhases = ( 266 | B2807974205168090033D8CA /* Sources */, 267 | B2807975205168090033D8CA /* Frameworks */, 268 | B2807976205168090033D8CA /* Resources */, 269 | ); 270 | buildRules = ( 271 | ); 272 | dependencies = ( 273 | B280797F205168090033D8CA /* PBXTargetDependency */, 274 | ); 275 | name = MIDIEventKitTests; 276 | productName = MIDIEventKitTests; 277 | productReference = B2807978205168090033D8CA /* MIDIEventKitTests.xctest */; 278 | productType = "com.apple.product-type.bundle.unit-test"; 279 | }; 280 | B280799A205168BE0033D8CA /* Example */ = { 281 | isa = PBXNativeTarget; 282 | buildConfigurationList = B28079A8205168BE0033D8CA /* Build configuration list for PBXNativeTarget "Example" */; 283 | buildPhases = ( 284 | 8CF6DC63B993F283650ED464 /* [CP] Check Pods Manifest.lock */, 285 | B2807997205168BE0033D8CA /* Sources */, 286 | B2807998205168BE0033D8CA /* Frameworks */, 287 | B2807999205168BE0033D8CA /* Resources */, 288 | 4EF5774E8B845D3201D9B0B8 /* [CP] Embed Pods Frameworks */, 289 | ); 290 | buildRules = ( 291 | ); 292 | dependencies = ( 293 | ); 294 | name = Example; 295 | productName = Example; 296 | productReference = B280799B205168BE0033D8CA /* Example.app */; 297 | productType = "com.apple.product-type.application"; 298 | }; 299 | /* End PBXNativeTarget section */ 300 | 301 | /* Begin PBXProject section */ 302 | B2807929205010B30033D8CA /* Project object */ = { 303 | isa = PBXProject; 304 | attributes = { 305 | LastSwiftUpdateCheck = 0920; 306 | LastUpgradeCheck = 1000; 307 | ORGANIZATIONNAME = cemolcay; 308 | TargetAttributes = { 309 | B280795E205167E80033D8CA = { 310 | CreatedOnToolsVersion = 9.2; 311 | LastSwiftMigration = 1000; 312 | ProvisioningStyle = Automatic; 313 | }; 314 | B280796B205167F70033D8CA = { 315 | CreatedOnToolsVersion = 9.2; 316 | LastSwiftMigration = 1000; 317 | ProvisioningStyle = Automatic; 318 | }; 319 | B2807977205168090033D8CA = { 320 | CreatedOnToolsVersion = 9.2; 321 | LastSwiftMigration = 1000; 322 | ProvisioningStyle = Automatic; 323 | }; 324 | B280799A205168BE0033D8CA = { 325 | CreatedOnToolsVersion = 9.2; 326 | ProvisioningStyle = Automatic; 327 | }; 328 | }; 329 | }; 330 | buildConfigurationList = B280792C205010B30033D8CA /* Build configuration list for PBXProject "MIDIEventKit" */; 331 | compatibilityVersion = "Xcode 8.0"; 332 | developmentRegion = en; 333 | hasScannedForEncodings = 0; 334 | knownRegions = ( 335 | en, 336 | Base, 337 | ); 338 | mainGroup = B2807928205010B30033D8CA; 339 | productRefGroup = B2807932205010B30033D8CA /* Products */; 340 | projectDirPath = ""; 341 | projectRoot = ""; 342 | targets = ( 343 | B280795E205167E80033D8CA /* MIDIEventKit iOS */, 344 | B280796B205167F70033D8CA /* MIDIEventKit Mac */, 345 | B2807977205168090033D8CA /* MIDIEventKitTests */, 346 | B280799A205168BE0033D8CA /* Example */, 347 | ); 348 | }; 349 | /* End PBXProject section */ 350 | 351 | /* Begin PBXResourcesBuildPhase section */ 352 | B280795D205167E80033D8CA /* Resources */ = { 353 | isa = PBXResourcesBuildPhase; 354 | buildActionMask = 2147483647; 355 | files = ( 356 | B280798B2051687C0033D8CA /* MIDIEventKit.strings in Resources */, 357 | ); 358 | runOnlyForDeploymentPostprocessing = 0; 359 | }; 360 | B280796A205167F70033D8CA /* Resources */ = { 361 | isa = PBXResourcesBuildPhase; 362 | buildActionMask = 2147483647; 363 | files = ( 364 | B280798C2051687C0033D8CA /* MIDIEventKit.strings in Resources */, 365 | ); 366 | runOnlyForDeploymentPostprocessing = 0; 367 | }; 368 | B2807976205168090033D8CA /* Resources */ = { 369 | isa = PBXResourcesBuildPhase; 370 | buildActionMask = 2147483647; 371 | files = ( 372 | B280798D2051687C0033D8CA /* MIDIEventKit.strings in Resources */, 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | }; 376 | B2807999205168BE0033D8CA /* Resources */ = { 377 | isa = PBXResourcesBuildPhase; 378 | buildActionMask = 2147483647; 379 | files = ( 380 | B28079AE20516B900033D8CA /* MIDIEventKit.strings in Resources */, 381 | B28079A2205168BE0033D8CA /* Assets.xcassets in Resources */, 382 | B28079A5205168BE0033D8CA /* Main.storyboard in Resources */, 383 | ); 384 | runOnlyForDeploymentPostprocessing = 0; 385 | }; 386 | /* End PBXResourcesBuildPhase section */ 387 | 388 | /* Begin PBXShellScriptBuildPhase section */ 389 | 30BCE5DA0EEFF86606049354 /* [CP] Check Pods Manifest.lock */ = { 390 | isa = PBXShellScriptBuildPhase; 391 | buildActionMask = 2147483647; 392 | files = ( 393 | ); 394 | inputPaths = ( 395 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 396 | "${PODS_ROOT}/Manifest.lock", 397 | ); 398 | name = "[CP] Check Pods Manifest.lock"; 399 | outputPaths = ( 400 | "$(DERIVED_FILE_DIR)/Pods-MIDIEventKit Mac-checkManifestLockResult.txt", 401 | ); 402 | runOnlyForDeploymentPostprocessing = 0; 403 | shellPath = /bin/sh; 404 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 405 | showEnvVarsInLog = 0; 406 | }; 407 | 4EF5774E8B845D3201D9B0B8 /* [CP] Embed Pods Frameworks */ = { 408 | isa = PBXShellScriptBuildPhase; 409 | buildActionMask = 2147483647; 410 | files = ( 411 | ); 412 | inputFileListPaths = ( 413 | ); 414 | inputPaths = ( 415 | "${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks.sh", 416 | "${PODS_ROOT}/AudioKit/macOS/AudioKitUI.framework", 417 | ); 418 | name = "[CP] Embed Pods Frameworks"; 419 | outputFileListPaths = ( 420 | ); 421 | outputPaths = ( 422 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AudioKitUI.framework", 423 | ); 424 | runOnlyForDeploymentPostprocessing = 0; 425 | shellPath = /bin/sh; 426 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks.sh\"\n"; 427 | showEnvVarsInLog = 0; 428 | }; 429 | 8CF6DC63B993F283650ED464 /* [CP] Check Pods Manifest.lock */ = { 430 | isa = PBXShellScriptBuildPhase; 431 | buildActionMask = 2147483647; 432 | files = ( 433 | ); 434 | inputPaths = ( 435 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 436 | "${PODS_ROOT}/Manifest.lock", 437 | ); 438 | name = "[CP] Check Pods Manifest.lock"; 439 | outputPaths = ( 440 | "$(DERIVED_FILE_DIR)/Pods-Example-checkManifestLockResult.txt", 441 | ); 442 | runOnlyForDeploymentPostprocessing = 0; 443 | shellPath = /bin/sh; 444 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 445 | showEnvVarsInLog = 0; 446 | }; 447 | F05D1E6640B11F31B3CFCD37 /* [CP] Check Pods Manifest.lock */ = { 448 | isa = PBXShellScriptBuildPhase; 449 | buildActionMask = 2147483647; 450 | files = ( 451 | ); 452 | inputPaths = ( 453 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 454 | "${PODS_ROOT}/Manifest.lock", 455 | ); 456 | name = "[CP] Check Pods Manifest.lock"; 457 | outputPaths = ( 458 | "$(DERIVED_FILE_DIR)/Pods-MIDIEventKit iOS-checkManifestLockResult.txt", 459 | ); 460 | runOnlyForDeploymentPostprocessing = 0; 461 | shellPath = /bin/sh; 462 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 463 | showEnvVarsInLog = 0; 464 | }; 465 | /* End PBXShellScriptBuildPhase section */ 466 | 467 | /* Begin PBXSourcesBuildPhase section */ 468 | B280795A205167E80033D8CA /* Sources */ = { 469 | isa = PBXSourcesBuildPhase; 470 | buildActionMask = 2147483647; 471 | files = ( 472 | B28079942051687C0033D8CA /* MIDIEventKit.swift in Sources */, 473 | ); 474 | runOnlyForDeploymentPostprocessing = 0; 475 | }; 476 | B2807967205167F70033D8CA /* Sources */ = { 477 | isa = PBXSourcesBuildPhase; 478 | buildActionMask = 2147483647; 479 | files = ( 480 | B28079952051687C0033D8CA /* MIDIEventKit.swift in Sources */, 481 | ); 482 | runOnlyForDeploymentPostprocessing = 0; 483 | }; 484 | B2807974205168090033D8CA /* Sources */ = { 485 | isa = PBXSourcesBuildPhase; 486 | buildActionMask = 2147483647; 487 | files = ( 488 | B28079962051687C0033D8CA /* MIDIEventKit.swift in Sources */, 489 | B280797B205168090033D8CA /* MIDIEventKitTests.swift in Sources */, 490 | ); 491 | runOnlyForDeploymentPostprocessing = 0; 492 | }; 493 | B2807997205168BE0033D8CA /* Sources */ = { 494 | isa = PBXSourcesBuildPhase; 495 | buildActionMask = 2147483647; 496 | files = ( 497 | B28079AD20516B8D0033D8CA /* MIDIEventKit.swift in Sources */, 498 | B28079A0205168BE0033D8CA /* ViewController.swift in Sources */, 499 | B280799E205168BE0033D8CA /* AppDelegate.swift in Sources */, 500 | ); 501 | runOnlyForDeploymentPostprocessing = 0; 502 | }; 503 | /* End PBXSourcesBuildPhase section */ 504 | 505 | /* Begin PBXTargetDependency section */ 506 | B280797F205168090033D8CA /* PBXTargetDependency */ = { 507 | isa = PBXTargetDependency; 508 | target = B280796B205167F70033D8CA /* MIDIEventKit Mac */; 509 | targetProxy = B280797E205168090033D8CA /* PBXContainerItemProxy */; 510 | }; 511 | /* End PBXTargetDependency section */ 512 | 513 | /* Begin PBXVariantGroup section */ 514 | B28079A3205168BE0033D8CA /* Main.storyboard */ = { 515 | isa = PBXVariantGroup; 516 | children = ( 517 | B28079A4205168BE0033D8CA /* Base */, 518 | ); 519 | name = Main.storyboard; 520 | sourceTree = ""; 521 | }; 522 | /* End PBXVariantGroup section */ 523 | 524 | /* Begin XCBuildConfiguration section */ 525 | B2807941205010B30033D8CA /* Debug */ = { 526 | isa = XCBuildConfiguration; 527 | buildSettings = { 528 | ALWAYS_SEARCH_USER_PATHS = NO; 529 | CLANG_ANALYZER_NONNULL = YES; 530 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 531 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 532 | CLANG_CXX_LIBRARY = "libc++"; 533 | CLANG_ENABLE_MODULES = YES; 534 | CLANG_ENABLE_OBJC_ARC = YES; 535 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 536 | CLANG_WARN_BOOL_CONVERSION = YES; 537 | CLANG_WARN_COMMA = YES; 538 | CLANG_WARN_CONSTANT_CONVERSION = YES; 539 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 540 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 541 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 542 | CLANG_WARN_EMPTY_BODY = YES; 543 | CLANG_WARN_ENUM_CONVERSION = YES; 544 | CLANG_WARN_INFINITE_RECURSION = YES; 545 | CLANG_WARN_INT_CONVERSION = YES; 546 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 547 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 548 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 549 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 550 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 551 | CLANG_WARN_STRICT_PROTOTYPES = YES; 552 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 553 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 554 | CLANG_WARN_UNREACHABLE_CODE = YES; 555 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 556 | CODE_SIGN_IDENTITY = "iPhone Developer"; 557 | COPY_PHASE_STRIP = NO; 558 | DEBUG_INFORMATION_FORMAT = dwarf; 559 | ENABLE_STRICT_OBJC_MSGSEND = YES; 560 | ENABLE_TESTABILITY = YES; 561 | GCC_C_LANGUAGE_STANDARD = gnu11; 562 | GCC_DYNAMIC_NO_PIC = NO; 563 | GCC_NO_COMMON_BLOCKS = YES; 564 | GCC_OPTIMIZATION_LEVEL = 0; 565 | GCC_PREPROCESSOR_DEFINITIONS = ( 566 | "DEBUG=1", 567 | "$(inherited)", 568 | ); 569 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 570 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 571 | GCC_WARN_UNDECLARED_SELECTOR = YES; 572 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 573 | GCC_WARN_UNUSED_FUNCTION = YES; 574 | GCC_WARN_UNUSED_VARIABLE = YES; 575 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 576 | MTL_ENABLE_DEBUG_INFO = YES; 577 | ONLY_ACTIVE_ARCH = YES; 578 | SDKROOT = iphoneos; 579 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 580 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 581 | }; 582 | name = Debug; 583 | }; 584 | B2807942205010B30033D8CA /* Release */ = { 585 | isa = XCBuildConfiguration; 586 | buildSettings = { 587 | ALWAYS_SEARCH_USER_PATHS = NO; 588 | CLANG_ANALYZER_NONNULL = YES; 589 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 590 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 591 | CLANG_CXX_LIBRARY = "libc++"; 592 | CLANG_ENABLE_MODULES = YES; 593 | CLANG_ENABLE_OBJC_ARC = YES; 594 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 595 | CLANG_WARN_BOOL_CONVERSION = YES; 596 | CLANG_WARN_COMMA = YES; 597 | CLANG_WARN_CONSTANT_CONVERSION = YES; 598 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 599 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 600 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 601 | CLANG_WARN_EMPTY_BODY = YES; 602 | CLANG_WARN_ENUM_CONVERSION = YES; 603 | CLANG_WARN_INFINITE_RECURSION = YES; 604 | CLANG_WARN_INT_CONVERSION = YES; 605 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 606 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 607 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 608 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 609 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 610 | CLANG_WARN_STRICT_PROTOTYPES = YES; 611 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 612 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 613 | CLANG_WARN_UNREACHABLE_CODE = YES; 614 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 615 | CODE_SIGN_IDENTITY = "iPhone Developer"; 616 | COPY_PHASE_STRIP = NO; 617 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 618 | ENABLE_NS_ASSERTIONS = NO; 619 | ENABLE_STRICT_OBJC_MSGSEND = YES; 620 | GCC_C_LANGUAGE_STANDARD = gnu11; 621 | GCC_NO_COMMON_BLOCKS = YES; 622 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 623 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 624 | GCC_WARN_UNDECLARED_SELECTOR = YES; 625 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 626 | GCC_WARN_UNUSED_FUNCTION = YES; 627 | GCC_WARN_UNUSED_VARIABLE = YES; 628 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 629 | MTL_ENABLE_DEBUG_INFO = NO; 630 | SDKROOT = iphoneos; 631 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 632 | VALIDATE_PRODUCT = YES; 633 | }; 634 | name = Release; 635 | }; 636 | B2807965205167E80033D8CA /* Debug */ = { 637 | isa = XCBuildConfiguration; 638 | baseConfigurationReference = F40C8B9623A92EBA39F925C8 /* Pods-MIDIEventKit iOS.debug.xcconfig */; 639 | buildSettings = { 640 | APPLICATION_EXTENSION_API_ONLY = NO; 641 | CODE_SIGN_IDENTITY = ""; 642 | CODE_SIGN_STYLE = Automatic; 643 | CURRENT_PROJECT_VERSION = 1; 644 | DEFINES_MODULE = YES; 645 | DEVELOPMENT_TEAM = 77Y3N48SNF; 646 | DYLIB_COMPATIBILITY_VERSION = 1; 647 | DYLIB_CURRENT_VERSION = 1; 648 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 649 | INFOPLIST_FILE = "$(SRCROOT)/Source/Info iOS.plist"; 650 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 651 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 652 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 653 | PRODUCT_BUNDLE_IDENTIFIER = "com.cemolcay.MIDIEventKit-iOS"; 654 | PRODUCT_NAME = MIDIEventKit; 655 | SKIP_INSTALL = YES; 656 | SWIFT_VERSION = 4.2; 657 | TARGETED_DEVICE_FAMILY = "1,2"; 658 | VERSIONING_SYSTEM = "apple-generic"; 659 | VERSION_INFO_PREFIX = ""; 660 | }; 661 | name = Debug; 662 | }; 663 | B2807966205167E80033D8CA /* Release */ = { 664 | isa = XCBuildConfiguration; 665 | baseConfigurationReference = 232D2816BBD0388804ED3C0C /* Pods-MIDIEventKit iOS.release.xcconfig */; 666 | buildSettings = { 667 | APPLICATION_EXTENSION_API_ONLY = NO; 668 | CODE_SIGN_IDENTITY = ""; 669 | CODE_SIGN_STYLE = Automatic; 670 | CURRENT_PROJECT_VERSION = 1; 671 | DEFINES_MODULE = YES; 672 | DEVELOPMENT_TEAM = 77Y3N48SNF; 673 | DYLIB_COMPATIBILITY_VERSION = 1; 674 | DYLIB_CURRENT_VERSION = 1; 675 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 676 | INFOPLIST_FILE = "$(SRCROOT)/Source/Info iOS.plist"; 677 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 678 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 679 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 680 | PRODUCT_BUNDLE_IDENTIFIER = "com.cemolcay.MIDIEventKit-iOS"; 681 | PRODUCT_NAME = MIDIEventKit; 682 | SKIP_INSTALL = YES; 683 | SWIFT_VERSION = 4.2; 684 | TARGETED_DEVICE_FAMILY = "1,2"; 685 | VERSIONING_SYSTEM = "apple-generic"; 686 | VERSION_INFO_PREFIX = ""; 687 | }; 688 | name = Release; 689 | }; 690 | B2807972205167F70033D8CA /* Debug */ = { 691 | isa = XCBuildConfiguration; 692 | baseConfigurationReference = 7FBCA92B0E4245B447B87FFD /* Pods-MIDIEventKit Mac.debug.xcconfig */; 693 | buildSettings = { 694 | CODE_SIGN_IDENTITY = ""; 695 | CODE_SIGN_STYLE = Automatic; 696 | COMBINE_HIDPI_IMAGES = YES; 697 | CURRENT_PROJECT_VERSION = 1; 698 | DEFINES_MODULE = YES; 699 | DEVELOPMENT_TEAM = 77Y3N48SNF; 700 | DYLIB_COMPATIBILITY_VERSION = 1; 701 | DYLIB_CURRENT_VERSION = 1; 702 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 703 | FRAMEWORK_VERSION = A; 704 | INFOPLIST_FILE = "$(SRCROOT)/Source/Info Mac.plist"; 705 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 706 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 707 | MACOSX_DEPLOYMENT_TARGET = 10.9; 708 | PRODUCT_BUNDLE_IDENTIFIER = "com.cemolcay.MIDIEventKit-Mac"; 709 | PRODUCT_NAME = MIDIEventKit; 710 | SDKROOT = macosx; 711 | SKIP_INSTALL = YES; 712 | SWIFT_VERSION = 4.2; 713 | VERSIONING_SYSTEM = "apple-generic"; 714 | VERSION_INFO_PREFIX = ""; 715 | }; 716 | name = Debug; 717 | }; 718 | B2807973205167F70033D8CA /* Release */ = { 719 | isa = XCBuildConfiguration; 720 | baseConfigurationReference = 19FF26D21C0824B962ABA6BF /* Pods-MIDIEventKit Mac.release.xcconfig */; 721 | buildSettings = { 722 | CODE_SIGN_IDENTITY = ""; 723 | CODE_SIGN_STYLE = Automatic; 724 | COMBINE_HIDPI_IMAGES = YES; 725 | CURRENT_PROJECT_VERSION = 1; 726 | DEFINES_MODULE = YES; 727 | DEVELOPMENT_TEAM = 77Y3N48SNF; 728 | DYLIB_COMPATIBILITY_VERSION = 1; 729 | DYLIB_CURRENT_VERSION = 1; 730 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 731 | FRAMEWORK_VERSION = A; 732 | INFOPLIST_FILE = "$(SRCROOT)/Source/Info Mac.plist"; 733 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 734 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 735 | MACOSX_DEPLOYMENT_TARGET = 10.9; 736 | PRODUCT_BUNDLE_IDENTIFIER = "com.cemolcay.MIDIEventKit-Mac"; 737 | PRODUCT_NAME = MIDIEventKit; 738 | SDKROOT = macosx; 739 | SKIP_INSTALL = YES; 740 | SWIFT_VERSION = 4.2; 741 | VERSIONING_SYSTEM = "apple-generic"; 742 | VERSION_INFO_PREFIX = ""; 743 | }; 744 | name = Release; 745 | }; 746 | B2807981205168090033D8CA /* Debug */ = { 747 | isa = XCBuildConfiguration; 748 | buildSettings = { 749 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 750 | CODE_SIGN_IDENTITY = "Mac Developer"; 751 | CODE_SIGN_STYLE = Automatic; 752 | COMBINE_HIDPI_IMAGES = YES; 753 | DEVELOPMENT_TEAM = 77Y3N48SNF; 754 | INFOPLIST_FILE = MIDIEventKitTests/Info.plist; 755 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 756 | MACOSX_DEPLOYMENT_TARGET = 10.13; 757 | PRODUCT_BUNDLE_IDENTIFIER = com.cemolcay.MIDIEventKitTests; 758 | PRODUCT_NAME = "$(TARGET_NAME)"; 759 | SDKROOT = macosx; 760 | SWIFT_VERSION = 4.2; 761 | }; 762 | name = Debug; 763 | }; 764 | B2807982205168090033D8CA /* Release */ = { 765 | isa = XCBuildConfiguration; 766 | buildSettings = { 767 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 768 | CODE_SIGN_IDENTITY = "Mac Developer"; 769 | CODE_SIGN_STYLE = Automatic; 770 | COMBINE_HIDPI_IMAGES = YES; 771 | DEVELOPMENT_TEAM = 77Y3N48SNF; 772 | INFOPLIST_FILE = MIDIEventKitTests/Info.plist; 773 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 774 | MACOSX_DEPLOYMENT_TARGET = 10.13; 775 | PRODUCT_BUNDLE_IDENTIFIER = com.cemolcay.MIDIEventKitTests; 776 | PRODUCT_NAME = "$(TARGET_NAME)"; 777 | SDKROOT = macosx; 778 | SWIFT_VERSION = 4.2; 779 | }; 780 | name = Release; 781 | }; 782 | B28079A9205168BE0033D8CA /* Debug */ = { 783 | isa = XCBuildConfiguration; 784 | baseConfigurationReference = 2B2994F511D8ABB2E62810E0 /* Pods-Example.debug.xcconfig */; 785 | buildSettings = { 786 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 787 | CODE_SIGN_ENTITLEMENTS = Example/Example.entitlements; 788 | CODE_SIGN_IDENTITY = "Mac Developer"; 789 | CODE_SIGN_STYLE = Automatic; 790 | COMBINE_HIDPI_IMAGES = YES; 791 | DEVELOPMENT_TEAM = 77Y3N48SNF; 792 | INFOPLIST_FILE = Example/Info.plist; 793 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 794 | MACOSX_DEPLOYMENT_TARGET = 10.11; 795 | PRODUCT_BUNDLE_IDENTIFIER = com.cemolcay.Example; 796 | PRODUCT_NAME = "$(TARGET_NAME)"; 797 | SDKROOT = macosx; 798 | SWIFT_VERSION = 4.0; 799 | }; 800 | name = Debug; 801 | }; 802 | B28079AA205168BE0033D8CA /* Release */ = { 803 | isa = XCBuildConfiguration; 804 | baseConfigurationReference = 722A54B90897D6803A8EAC38 /* Pods-Example.release.xcconfig */; 805 | buildSettings = { 806 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 807 | CODE_SIGN_ENTITLEMENTS = Example/Example.entitlements; 808 | CODE_SIGN_IDENTITY = "Mac Developer"; 809 | CODE_SIGN_STYLE = Automatic; 810 | COMBINE_HIDPI_IMAGES = YES; 811 | DEVELOPMENT_TEAM = 77Y3N48SNF; 812 | INFOPLIST_FILE = Example/Info.plist; 813 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 814 | MACOSX_DEPLOYMENT_TARGET = 10.11; 815 | PRODUCT_BUNDLE_IDENTIFIER = com.cemolcay.Example; 816 | PRODUCT_NAME = "$(TARGET_NAME)"; 817 | SDKROOT = macosx; 818 | SWIFT_VERSION = 4.0; 819 | }; 820 | name = Release; 821 | }; 822 | /* End XCBuildConfiguration section */ 823 | 824 | /* Begin XCConfigurationList section */ 825 | B280792C205010B30033D8CA /* Build configuration list for PBXProject "MIDIEventKit" */ = { 826 | isa = XCConfigurationList; 827 | buildConfigurations = ( 828 | B2807941205010B30033D8CA /* Debug */, 829 | B2807942205010B30033D8CA /* Release */, 830 | ); 831 | defaultConfigurationIsVisible = 0; 832 | defaultConfigurationName = Release; 833 | }; 834 | B2807964205167E80033D8CA /* Build configuration list for PBXNativeTarget "MIDIEventKit iOS" */ = { 835 | isa = XCConfigurationList; 836 | buildConfigurations = ( 837 | B2807965205167E80033D8CA /* Debug */, 838 | B2807966205167E80033D8CA /* Release */, 839 | ); 840 | defaultConfigurationIsVisible = 0; 841 | defaultConfigurationName = Release; 842 | }; 843 | B2807971205167F70033D8CA /* Build configuration list for PBXNativeTarget "MIDIEventKit Mac" */ = { 844 | isa = XCConfigurationList; 845 | buildConfigurations = ( 846 | B2807972205167F70033D8CA /* Debug */, 847 | B2807973205167F70033D8CA /* Release */, 848 | ); 849 | defaultConfigurationIsVisible = 0; 850 | defaultConfigurationName = Release; 851 | }; 852 | B2807980205168090033D8CA /* Build configuration list for PBXNativeTarget "MIDIEventKitTests" */ = { 853 | isa = XCConfigurationList; 854 | buildConfigurations = ( 855 | B2807981205168090033D8CA /* Debug */, 856 | B2807982205168090033D8CA /* Release */, 857 | ); 858 | defaultConfigurationIsVisible = 0; 859 | defaultConfigurationName = Release; 860 | }; 861 | B28079A8205168BE0033D8CA /* Build configuration list for PBXNativeTarget "Example" */ = { 862 | isa = XCConfigurationList; 863 | buildConfigurations = ( 864 | B28079A9205168BE0033D8CA /* Debug */, 865 | B28079AA205168BE0033D8CA /* Release */, 866 | ); 867 | defaultConfigurationIsVisible = 0; 868 | defaultConfigurationName = Release; 869 | }; 870 | /* End XCConfigurationList section */ 871 | }; 872 | rootObject = B2807929205010B30033D8CA /* Project object */; 873 | } 874 | -------------------------------------------------------------------------------- /Source/MIDIEventKit.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MIDIEventKit.swift 3 | // MIDIEventKit 4 | // 5 | // Created by Cem Olcay on 7.03.2018. 6 | // Copyright © 2018 cemolcay. All rights reserved. 7 | // 8 | // Created by the midi.org official specs. 9 | // https://www.midi.org/specifications/item/table-2-expanded-messages-list-status-bytes 10 | // 11 | 12 | import Foundation 13 | import CoreMIDI 14 | 15 | extension Collection where Iterator.Element == MIDIEvent { 16 | /// Creates a `MIDIPacketList` representation from `MIDIEvent` array. 17 | public var midiPacketList: UnsafeMutablePointer { 18 | guard let this = self as? [MIDIEvent] else { fatalError() } 19 | 20 | let packetListPointer = UnsafeMutablePointer.allocate(capacity: this.count) 21 | var packet = MIDIPacketListInit(packetListPointer) 22 | 23 | for midi in this { 24 | packet = MIDIPacketListAdd(packetListPointer, 1024, packet, midi.timestamp.value, midi.event.midiBytes.count, midi.event.midiBytes) 25 | } 26 | 27 | return packetListPointer 28 | 29 | // let packetList = MIDIPacketList(numPackets: UInt32(this.count), packet: packetListPointer.pointee.packet) 30 | // 31 | // packetListPointer.deinitialize() 32 | // packetListPointer.deallocate(capacity: this.count) 33 | // 34 | // return packetList 35 | } 36 | } 37 | 38 | public func ==(lhs: MIDIStatusEvent, rhs: MIDIStatusEvent) -> Bool { 39 | return lhs.statusByte == rhs.statusByte && 40 | lhs.dataBytes == rhs.dataBytes 41 | } 42 | 43 | public protocol MIDIStatusEvent: CustomStringConvertible { 44 | /// Status byte of the midi event. 45 | var statusByte: UInt8 { get } 46 | /// Holds midi event's values within two data packets. 47 | var dataBytes: MIDIEventData { get } 48 | 49 | init?(statusByte: UInt8, dataBytes: MIDIEventData) 50 | } 51 | 52 | extension MIDIStatusEvent { 53 | /// Returns 3 data packets with status and values of the midi event. 54 | public var midiBytes: [UInt8] { 55 | return [statusByte, dataBytes.data1, dataBytes.data2] 56 | } 57 | 58 | public init?(midiPacket: MIDIPacket) { 59 | self.init( 60 | statusByte: midiPacket.data.0, 61 | dataBytes: MIDIEventData( 62 | data1: midiPacket.data.1, 63 | data2: midiPacket.data.2)) 64 | } 65 | } 66 | 67 | public protocol MIDIEventUndefinable { 68 | static var undefinedEventStatusBytes: [UInt8] { get } 69 | } 70 | 71 | /// Timestamp value of the MIDI event message. 72 | public enum MIDIEventTimeStamp: Equatable { 73 | /// Initilize timestamp with a MIDITimeStamp value. 74 | case timestamp(MIDITimeStamp) 75 | /// Timestamp is right now. 76 | case now 77 | /// Future timestamp with a double value in seconds. 78 | case secondsAfterNow(Double) 79 | 80 | /// MIDITimeStamp value for the MIDI message. 81 | public var value: MIDITimeStamp { 82 | switch self { 83 | case .timestamp(let timestamp): 84 | return timestamp 85 | case .now: 86 | return 0 87 | case .secondsAfterNow(let sec): 88 | let now = mach_absolute_time() 89 | let offset = UInt64(sec * 1000000) 90 | return now + offset 91 | } 92 | } 93 | 94 | // MARK: Equatable 95 | 96 | /// Check if two MIDIEventTimeStamp's equal. 97 | /// 98 | /// - Parameters: 99 | /// - lhs: Left hand side of the equation. 100 | /// - rhs: Right hand side of the equation. 101 | /// - Returns: Returns if two timestamps are equal or not. 102 | public static func ==(lhs: MIDIEventTimeStamp, rhs: MIDIEventTimeStamp) -> Bool { 103 | return lhs.value == rhs.value 104 | } 105 | } 106 | 107 | /// Holds two UInt8 MIDI data packets for the event messages. 108 | public struct MIDIEventData: Equatable { 109 | /// First midi data packet. 110 | public var data1: UInt8 111 | /// Second midi data packet. 112 | public var data2: UInt8 113 | 114 | /// Both data packets are empty. 115 | public init() { 116 | data1 = 0 117 | data2 = 0 118 | } 119 | 120 | /// Initilze both data packets with a UInt8 value between 0 - 127. 121 | /// 122 | /// - Parameters: 123 | /// - data1: First data packet value. 124 | /// - data2: Second data packet value. 125 | public init(data1: UInt8, data2: UInt8) { 126 | self.data1 = data1 127 | self.data2 = data2 128 | } 129 | 130 | /// Initilize only first data packet with UInt8 value between 0 - 127. 131 | /// 132 | /// - Parameter data1: First data packet value. 133 | public init(data1: UInt8) { 134 | self.data1 = data1 135 | self.data2 = 0 136 | } 137 | 138 | /// Initilize both packets with a UInt16 value between 0 - 16383. 139 | /// 140 | /// - Parameter data: Both data packets will be created by spliting into two UInt8 data packets by this UInt16 value. 141 | public init(data: UInt16) { 142 | let mask: UInt16 = 0x007F 143 | self.data1 = UInt8(data & mask) // MSB, bit shift right 7 144 | self.data2 = UInt8((data & (mask << 7)) >> 7) // LSB, mask of 127 145 | } 146 | 147 | /// Initilize only first packet with a toggle on/off value. 148 | /// 149 | /// - Parameter on: On/off value of the first data packet. 150 | public init(on: Bool) { 151 | self.data1 = on ? 127 : 0 152 | self.data2 = 0 153 | } 154 | 155 | // MARK: Equatable 156 | 157 | public static func ==(lhs: MIDIEventData, rhs: MIDIEventData) -> Bool { 158 | return lhs.data1 == rhs.data1 && lhs.data2 == rhs.data2 159 | } 160 | } 161 | 162 | /// Create MIDI event messages with MIDIStatusEvent enums for sending or create them from MIDIPacket's for parsing received MIDI message. 163 | public struct MIDIEvent: Equatable { 164 | /// Event type of the MIDI message. 165 | public var event: MIDIStatusEvent 166 | /// Timestamp of the MIDI message. 167 | public var timestamp: MIDIEventTimeStamp 168 | 169 | /// Initilize midi event with `MIDIStatusEvent` enums and a timestamp. 170 | /// 171 | /// - Parameters: 172 | /// - event: Event type of the message. 173 | /// - timestamp: Timestamp of the message. 174 | public init(event: MIDIStatusEvent, timestamp: MIDIEventTimeStamp) { 175 | self.event = event 176 | self.timestamp = timestamp 177 | } 178 | 179 | /// Initilize midi event by parsing received midi packet. 180 | /// 181 | /// - Parameter midiPacket: Received midi packet for parsing into `MIDIEvent` struct. 182 | public init?(midiPacket: MIDIPacket) { 183 | if let channelVoiceEvent = MIDIChannelVoiceEvent(midiPacket: midiPacket) { 184 | self.event = channelVoiceEvent 185 | } else if let systemCommonEvent = MIDISystemCommonEvent(midiPacket: midiPacket) { 186 | self.event = systemCommonEvent 187 | } else if let systemRealTimeEvent = MIDISystemRealTimeEvent(midiPacket: midiPacket) { 188 | self.event = systemRealTimeEvent 189 | } else { 190 | return nil 191 | } 192 | 193 | self.timestamp = .timestamp(midiPacket.timeStamp) 194 | } 195 | 196 | /// MIDI Packet representation for sending event message. 197 | public var midiPacket: MIDIPacket { 198 | var packet = MIDIPacket() 199 | packet.timeStamp = timestamp.value 200 | packet.length = 3 201 | packet.data.0 = event.statusByte 202 | packet.data.1 = event.dataBytes.data1 203 | packet.data.2 = event.dataBytes.data2 204 | return packet 205 | } 206 | 207 | /// Returns a MIDIPacketList packed with itself. 208 | public var midiPacketList: MIDIPacketList { 209 | return MIDIPacketList(numPackets: 1, packet: midiPacket) 210 | } 211 | 212 | // MARK: Equatable 213 | 214 | public static func ==(lhs: MIDIEvent, rhs: MIDIEvent) -> Bool { 215 | return lhs.event == rhs.event && 216 | lhs.timestamp == rhs.timestamp 217 | } 218 | } 219 | 220 | // MARK: - MIDI Channel Voice Events 221 | 222 | public enum MIDIChannelVoiceEvent: MIDIStatusEvent { 223 | case noteOff(note: UInt8, velocity: UInt8, channel: UInt8) // 128 - 143 224 | case noteOn(note: UInt8, velocity: UInt8, channel: UInt8) // 144 - 159 225 | case polyphonicAftertouch(note: UInt8, pressure: UInt8, channel: UInt8) // 160 - 175 226 | case controllerChange(event: MIDIControllerEvent, channel: UInt8) // 176 - 191 227 | case programChange(program: UInt8, channel: UInt8) // 192 - 207 228 | case channelAftertouch(pressure: UInt8, channel: UInt8) // 208 - 223 229 | case pitchBendChange(bend: UInt16, channel: UInt8) // 224 - 239 230 | 231 | // MARK: MIDIStatusEvent 232 | 233 | public var statusByte: UInt8 { 234 | switch self { 235 | case .noteOff(_, _, let channel): return 128 + channel 236 | case .noteOn(_, _, let channel): return 144 + channel 237 | case .polyphonicAftertouch(_, _, let channel): return 160 + channel 238 | case .controllerChange(_, let channel): return 176 + channel 239 | case .programChange(_, let channel): return 192 + channel 240 | case .channelAftertouch(_, let channel): return 208 + channel 241 | case .pitchBendChange(_, let channel): return 224 + channel 242 | } 243 | } 244 | 245 | public var dataBytes: MIDIEventData { 246 | switch self { 247 | case .noteOff(let note, let velocity, _): return MIDIEventData(data1: note, data2: velocity) 248 | case .noteOn(let note, let velocity, _): return MIDIEventData(data1: note, data2: velocity) 249 | case .polyphonicAftertouch(let note, let pressure, _): return MIDIEventData(data1: note, data2: pressure) 250 | case .controllerChange(let event, _): return MIDIEventData(data1: event.statusByte, data2: event.dataBytes.data1) 251 | case .programChange(let program, _): return MIDIEventData(data1: program) 252 | case .channelAftertouch(let pressure, _): return MIDIEventData(data1: pressure) 253 | case .pitchBendChange(let bend, _): return MIDIEventData(data: bend) 254 | } 255 | } 256 | 257 | public init?(statusByte: UInt8, dataBytes: MIDIEventData) { 258 | if statusByte >= 128 && statusByte <= 143 { 259 | let channel = statusByte - 128 260 | self = .noteOff( 261 | note: dataBytes.data1, 262 | velocity: dataBytes.data2, 263 | channel: channel) 264 | } else if statusByte >= 144 && statusByte <= 159 { 265 | let channel = statusByte - 144 266 | self = .noteOn( 267 | note: dataBytes.data1, 268 | velocity: dataBytes.data2, 269 | channel: channel) 270 | } else if statusByte >= 160 && statusByte <= 175 { 271 | let channel = statusByte - 160 272 | self = .polyphonicAftertouch( 273 | note: dataBytes.data1, 274 | pressure: dataBytes.data2, 275 | channel: channel) 276 | } else if statusByte >= 176 && statusByte <= 191, 277 | let event = MIDIControllerEvent(statusByte: statusByte, dataBytes: dataBytes) { 278 | let channel = statusByte - 176 279 | self = .controllerChange( 280 | event: event, 281 | channel: channel) 282 | } else if statusByte >= 192 && statusByte <= 207 { 283 | let channel = statusByte - 192 284 | self = .programChange( 285 | program: dataBytes.data1, 286 | channel: channel) 287 | } else if statusByte >= 208 && statusByte <= 223 { 288 | let channel = statusByte - 208 289 | self = .channelAftertouch( 290 | pressure: dataBytes.data1, 291 | channel: channel) 292 | } else if statusByte >= 224 && statusByte <= 234 { 293 | let channel = statusByte - 224 294 | self = .pitchBendChange( 295 | bend: UInt16((dataBytes.data2 << 8) | dataBytes.data1), 296 | channel: channel) 297 | } else { 298 | return nil 299 | } 300 | } 301 | 302 | // MARK: CustomStringConvertible 303 | 304 | public var description: String { 305 | switch self { 306 | case .noteOff: return NSLocalizedString("midi_noteOff", comment: "") 307 | case .noteOn: return NSLocalizedString("midi_noteOn", comment: "") 308 | case .polyphonicAftertouch: return NSLocalizedString("midi_polyphonicAftertouch", comment: "") 309 | case .controllerChange(let event, _): return event.description 310 | case .programChange(let event, _): return event.description 311 | case .channelAftertouch: return NSLocalizedString("midi_channelAftertouch", comment: "") 312 | case .pitchBendChange: return NSLocalizedString("midi_pitchBendChange", comment: "") 313 | } 314 | } 315 | } 316 | 317 | // MARK: MIDI Controller Events 318 | 319 | public enum MIDIControllerEvent: MIDIStatusEvent, MIDIEventUndefinable { 320 | case bankSelect(value: UInt8) // 0 321 | case modulationWheel(value: UInt8) // 1 322 | case breathController(value: UInt8) // 2 323 | case footController(value: UInt8) // 4 324 | case portamentoTime(value: UInt8) // 5 325 | case dataEntryMSB(value: UInt8) // 6 326 | case channelVolume(value: UInt8) // 7 327 | case balance(value: UInt8) // 8 328 | case pan(value: UInt8) // 10 329 | case expressionController(value: UInt8) // 11 330 | case effectControl1(value: UInt8) // 12 331 | case effectControl2(value: UInt8) // 13 332 | case generalPurposeController1(value: UInt8) // 16 333 | case generalPurposeController2(value: UInt8) // 17 334 | case generalPurposeController3(value: UInt8) // 18 335 | case generalPurposeController4(value: UInt8) // 19 336 | case lsbBankSelect(value: UInt8) // 32 337 | case lsbModulationWheel(value: UInt8) // 33 338 | case lsbBreathController(value: UInt8) // 34 339 | case lsbFootController(value: UInt8) // 38 340 | case lsbPortamentoTime(value: UInt8) // 37 341 | case lsbDataEntryMSB(value: UInt8) // 38 342 | case lsbChannelVolume(value: UInt8) // 39 343 | case lsbBalance(value: UInt8) // 40 344 | case lsbPan(value: UInt8) // 42 345 | case lsbExpressionController(value: UInt8) // 43 346 | case lsbEffectControl1(value: UInt8) // 44 347 | case lsbEffectControl2(value: UInt8) // 45 348 | case lsbGeneralPurposeController1(value: UInt8) // 48 349 | case lsbGeneralPurposeController2(value: UInt8) // 49 350 | case lsbGeneralPurposeController3(value: UInt8) // 50 351 | case lsbGeneralPurposeController4(value: UInt8) // 51 352 | case damperPedal(on: Bool) // 64 353 | case portamentoOn(on: Bool) // 65 354 | case sostenutoOn(on: Bool) // 66 355 | case softPedalOn(on: Bool) // 67 356 | case legatoFootswitch(on: Bool) // 68 357 | case hold2(on: Bool) // 69 358 | case soundVariation(value: UInt8) // 70 359 | case timbreIntesity(value: UInt8) // 71 360 | case releaseTime(value: UInt8) // 72 361 | case attackTime(value: UInt8) // 73 362 | case brightness(value: UInt8) // 74 363 | case decayTime(value: UInt8) // 75 364 | case vibratoRate(value: UInt8) // 76 365 | case vibratoDepth(value: UInt8) // 77 366 | case vibratoDelay(value: UInt8) // 78 367 | case defaultUndefined(value: UInt8) // 79 368 | case generalPurposeController5(value: UInt8) // 80 369 | case generalPurposeController6(value: UInt8) // 81 370 | case generalPurposeController7(value: UInt8) // 82 371 | case generalPurposeController8(value: UInt8) // 83 372 | case portamentoControl(value: UInt8) // 84 373 | case highResolutionVelocityPrefix(value: UInt8) // 88 374 | case reverbSendLevel(value: UInt8) // 91 375 | case tremoloDepth(value: UInt8) // 92 376 | case chorusSendLevel(value: UInt8) // 93 377 | case celesteDepth(value: UInt8) // 94 378 | case phaserDepth(value: UInt8) // 95 379 | case dataIncrement // 96 380 | case dataDecrement // 97 381 | case nonRegisteredParameterNumberLSB(value: UInt8) // 98 382 | case nonRegisteredParameterNumberMSB(value: UInt8) // 99 383 | case registeredParameterNumberLSB(value: UInt8) // 100 384 | case registeredParameterNumberMSB(value: UInt8) // 101 385 | case channelMode(MIDIChannelModeEvent) // 120 - 127 386 | case undefined(status: UInt8, value: UInt8) // 3, 9, 14, 15, 20...31, 35, 21, 46, 47, 52...63, 85, 86, 87, 89, 90, 102...119 387 | 388 | // MARK: MIDIStatusEvent 389 | 390 | public var statusByte: UInt8 { 391 | switch self { 392 | case .bankSelect: return 0 393 | case .modulationWheel: return 1 394 | case .breathController: return 2 395 | case .footController: return 4 396 | case .portamentoTime: return 5 397 | case .dataEntryMSB: return 6 398 | case .channelVolume: return 7 399 | case .balance: return 8 400 | case .pan: return 10 401 | case .expressionController: return 11 402 | case .effectControl1: return 12 403 | case .effectControl2: return 13 404 | case .generalPurposeController1: return 16 405 | case .generalPurposeController2: return 17 406 | case .generalPurposeController3: return 18 407 | case .generalPurposeController4: return 19 408 | case .lsbBankSelect: return 32 409 | case .lsbModulationWheel: return 33 410 | case .lsbBreathController: return 34 411 | case .lsbFootController: return 38 412 | case .lsbPortamentoTime: return 37 413 | case .lsbDataEntryMSB: return 38 414 | case .lsbChannelVolume: return 39 415 | case .lsbBalance: return 40 416 | case .lsbPan: return 42 417 | case .lsbExpressionController: return 43 418 | case .lsbEffectControl1: return 44 419 | case .lsbEffectControl2: return 45 420 | case .lsbGeneralPurposeController1: return 48 421 | case .lsbGeneralPurposeController2: return 49 422 | case .lsbGeneralPurposeController3: return 50 423 | case .lsbGeneralPurposeController4: return 51 424 | case .damperPedal: return 64 425 | case .portamentoOn: return 65 426 | case .sostenutoOn: return 66 427 | case .softPedalOn: return 67 428 | case .legatoFootswitch: return 68 429 | case .hold2: return 69 430 | case .soundVariation: return 70 431 | case .timbreIntesity: return 71 432 | case .releaseTime: return 72 433 | case .attackTime: return 73 434 | case .brightness: return 74 435 | case .decayTime: return 75 436 | case .vibratoRate: return 76 437 | case .vibratoDepth: return 77 438 | case .vibratoDelay: return 78 439 | case .defaultUndefined: return 79 440 | case .generalPurposeController5: return 80 441 | case .generalPurposeController6: return 81 442 | case .generalPurposeController7: return 82 443 | case .generalPurposeController8: return 83 444 | case .portamentoControl: return 84 445 | case .highResolutionVelocityPrefix: return 88 446 | case .reverbSendLevel: return 91 447 | case .tremoloDepth: return 92 448 | case .chorusSendLevel: return 93 449 | case .celesteDepth: return 94 450 | case .phaserDepth: return 95 451 | case .dataIncrement: return 96 452 | case .dataDecrement: return 97 453 | case .nonRegisteredParameterNumberLSB: return 98 454 | case .nonRegisteredParameterNumberMSB: return 99 455 | case .registeredParameterNumberLSB: return 100 456 | case .registeredParameterNumberMSB: return 101 457 | case .channelMode(let mode): return mode.statusByte 458 | case .undefined(let status, _): return status 459 | } 460 | } 461 | 462 | public var dataBytes: MIDIEventData { 463 | switch self { 464 | case .bankSelect(let value): return MIDIEventData(data1: value) 465 | case .modulationWheel(let value): return MIDIEventData(data1: value) 466 | case .breathController(let value): return MIDIEventData(data1: value) 467 | case .footController(let value): return MIDIEventData(data1: value) 468 | case .portamentoTime(let value): return MIDIEventData(data1: value) 469 | case .dataEntryMSB(let value): return MIDIEventData(data1: value) 470 | case .channelVolume(let value): return MIDIEventData(data1: value) 471 | case .balance(let value): return MIDIEventData(data1: value) 472 | case .pan(let value): return MIDIEventData(data1: value) 473 | case .expressionController(let value): return MIDIEventData(data1: value) 474 | case .effectControl1(let value): return MIDIEventData(data1: value) 475 | case .effectControl2(let value): return MIDIEventData(data1: value) 476 | case .generalPurposeController1(let value): return MIDIEventData(data1: value) 477 | case .generalPurposeController2(let value): return MIDIEventData(data1: value) 478 | case .generalPurposeController3(let value): return MIDIEventData(data1: value) 479 | case .generalPurposeController4(let value): return MIDIEventData(data1: value) 480 | case .lsbBankSelect(let value): return MIDIEventData(data1: value) 481 | case .lsbModulationWheel(let value): return MIDIEventData(data1: value) 482 | case .lsbBreathController(let value): return MIDIEventData(data1: value) 483 | case .lsbFootController(let value): return MIDIEventData(data1: value) 484 | case .lsbPortamentoTime(let value): return MIDIEventData(data1: value) 485 | case .lsbDataEntryMSB(let value): return MIDIEventData(data1: value) 486 | case .lsbChannelVolume(let value): return MIDIEventData(data1: value) 487 | case .lsbBalance(let value): return MIDIEventData(data1: value) 488 | case .lsbPan(let value): return MIDIEventData(data1: value) 489 | case .lsbExpressionController(let value): return MIDIEventData(data1: value) 490 | case .lsbEffectControl1(let value): return MIDIEventData(data1: value) 491 | case .lsbEffectControl2(let value): return MIDIEventData(data1: value) 492 | case .lsbGeneralPurposeController1(let value): return MIDIEventData(data1: value) 493 | case .lsbGeneralPurposeController2(let value): return MIDIEventData(data1: value) 494 | case .lsbGeneralPurposeController3(let value): return MIDIEventData(data1: value) 495 | case .lsbGeneralPurposeController4(let value): return MIDIEventData(data1: value) 496 | case .damperPedal(let on): return MIDIEventData(on: on) 497 | case .portamentoOn(let on): return MIDIEventData(on: on) 498 | case .sostenutoOn(let on): return MIDIEventData(on: on) 499 | case .softPedalOn(let on): return MIDIEventData(on: on) 500 | case .legatoFootswitch(let on): return MIDIEventData(on: on) 501 | case .hold2(let on): return MIDIEventData(on: on) 502 | case .soundVariation(let value): return MIDIEventData(data1: value) 503 | case .timbreIntesity(let value): return MIDIEventData(data1: value) 504 | case .releaseTime(let value): return MIDIEventData(data1: value) 505 | case .attackTime(let value): return MIDIEventData(data1: value) 506 | case .brightness(let value): return MIDIEventData(data1: value) 507 | case .decayTime(let value): return MIDIEventData(data1: value) 508 | case .vibratoRate(let value): return MIDIEventData(data1: value) 509 | case .vibratoDepth(let value): return MIDIEventData(data1: value) 510 | case .vibratoDelay(let value): return MIDIEventData(data1: value) 511 | case .defaultUndefined(let value): return MIDIEventData(data1: value) 512 | case .generalPurposeController5(let value): return MIDIEventData(data1: value) 513 | case .generalPurposeController6(let value): return MIDIEventData(data1: value) 514 | case .generalPurposeController7(let value): return MIDIEventData(data1: value) 515 | case .generalPurposeController8(let value): return MIDIEventData(data1: value) 516 | case .portamentoControl(let value): return MIDIEventData(data1: value) 517 | case .highResolutionVelocityPrefix(let value): return MIDIEventData(data1: value) 518 | case .reverbSendLevel(let value): return MIDIEventData(data1: value) 519 | case .tremoloDepth(let value): return MIDIEventData(data1: value) 520 | case .chorusSendLevel(let value): return MIDIEventData(data1: value) 521 | case .celesteDepth(let value): return MIDIEventData(data1: value) 522 | case .phaserDepth(let value): return MIDIEventData(data1: value) 523 | case .dataIncrement: return MIDIEventData() 524 | case .dataDecrement: return MIDIEventData() 525 | case .nonRegisteredParameterNumberLSB(let value): return MIDIEventData(data1: value) 526 | case .nonRegisteredParameterNumberMSB(let value): return MIDIEventData(data1: value) 527 | case .registeredParameterNumberLSB(let value): return MIDIEventData(data1: value) 528 | case .registeredParameterNumberMSB(let value): return MIDIEventData(data1: value) 529 | case .channelMode(let mode): return mode.dataBytes 530 | case .undefined(let status, let value): return MIDIEventData(data1: status, data2: value) 531 | } 532 | } 533 | 534 | public init?(statusByte: UInt8, dataBytes: MIDIEventData) { 535 | switch dataBytes.data1 { 536 | case 0: self = .bankSelect(value: dataBytes.data2) 537 | case 1: self = .modulationWheel(value: dataBytes.data2) 538 | case 2: self = .breathController(value: dataBytes.data2) 539 | case 4: self = .footController(value: dataBytes.data2) 540 | case 5: self = .portamentoTime(value: dataBytes.data2) 541 | case 6: self = .dataEntryMSB(value: dataBytes.data2) 542 | case 7: self = .channelVolume(value: dataBytes.data2) 543 | case 8: self = .balance(value: dataBytes.data2) 544 | case 10: self = .pan(value: dataBytes.data2) 545 | case 11: self = .expressionController(value: dataBytes.data2) 546 | case 12: self = .effectControl1(value: dataBytes.data2) 547 | case 13: self = .effectControl2(value: dataBytes.data2) 548 | case 16: self = .generalPurposeController1(value: dataBytes.data2) 549 | case 17: self = .generalPurposeController2(value: dataBytes.data2) 550 | case 18: self = .generalPurposeController3(value: dataBytes.data2) 551 | case 19: self = .generalPurposeController4(value: dataBytes.data2) 552 | case 32: self = .lsbBankSelect(value: dataBytes.data2) 553 | case 33: self = .lsbModulationWheel(value: dataBytes.data2) 554 | case 34: self = .lsbBreathController(value: dataBytes.data2) 555 | case 36: self = .lsbFootController(value: dataBytes.data2) 556 | case 37: self = .lsbPortamentoTime(value: dataBytes.data2) 557 | case 38: self = .lsbDataEntryMSB(value: dataBytes.data2) 558 | case 39: self = .lsbChannelVolume(value: dataBytes.data2) 559 | case 40: self = .lsbBalance(value: dataBytes.data2) 560 | case 42: self = .lsbPan(value: dataBytes.data2) 561 | case 43: self = .lsbExpressionController(value: dataBytes.data2) 562 | case 44: self = .lsbEffectControl1(value: dataBytes.data2) 563 | case 45: self = .lsbEffectControl2(value: dataBytes.data2) 564 | case 48: self = .lsbGeneralPurposeController1(value: dataBytes.data2) 565 | case 49: self = .lsbGeneralPurposeController2(value: dataBytes.data2) 566 | case 50: self = .lsbGeneralPurposeController3(value: dataBytes.data2) 567 | case 51: self = .lsbGeneralPurposeController4(value: dataBytes.data2) 568 | case 64: self = .damperPedal(on: dataBytes.data2 >= 63) 569 | case 65: self = .portamentoOn(on: dataBytes.data2 >= 63) 570 | case 66: self = .sostenutoOn(on: dataBytes.data2 >= 63) 571 | case 67: self = .softPedalOn(on: dataBytes.data2 >= 63) 572 | case 68: self = .legatoFootswitch(on: dataBytes.data2 >= 63) 573 | case 69: self = .hold2(on: dataBytes.data2 >= 63) 574 | case 70: self = .soundVariation(value: dataBytes.data2) 575 | case 71: self = .timbreIntesity(value: dataBytes.data2) 576 | case 72: self = .releaseTime(value: dataBytes.data2) 577 | case 73: self = .attackTime(value: dataBytes.data2) 578 | case 74: self = .brightness(value: dataBytes.data2) 579 | case 75: self = .decayTime(value: dataBytes.data2) 580 | case 76: self = .vibratoRate(value: dataBytes.data2) 581 | case 77: self = .vibratoDepth(value: dataBytes.data2) 582 | case 78: self = .vibratoDelay(value: dataBytes.data2) 583 | case 79: self = .defaultUndefined(value: dataBytes.data2) 584 | case 80: self = .generalPurposeController5(value: dataBytes.data2) 585 | case 81: self = .generalPurposeController6(value: dataBytes.data2) 586 | case 82: self = .generalPurposeController7(value: dataBytes.data2) 587 | case 83: self = .generalPurposeController8(value: dataBytes.data2) 588 | case 84: self = .portamentoControl(value: dataBytes.data2) 589 | case 88: self = .highResolutionVelocityPrefix(value: dataBytes.data2) 590 | case 91: self = .reverbSendLevel(value: dataBytes.data2) 591 | case 92: self = .tremoloDepth(value: dataBytes.data2) 592 | case 93: self = .chorusSendLevel(value: dataBytes.data2) 593 | case 94: self = .celesteDepth(value: dataBytes.data2) 594 | case 95: self = .phaserDepth(value: dataBytes.data2) 595 | case 96: self = .dataIncrement 596 | case 97: self = .dataDecrement 597 | case 98: self = .nonRegisteredParameterNumberLSB(value: dataBytes.data2) 598 | case 99: self = .nonRegisteredParameterNumberMSB(value: dataBytes.data2) 599 | case 100: self = .registeredParameterNumberLSB(value: dataBytes.data2) 600 | case 101: self = .registeredParameterNumberMSB(value: dataBytes.data2) 601 | default: 602 | if dataBytes.data1 >= 120 && dataBytes.data1 <= 127, 603 | let mode = MIDIChannelModeEvent(statusByte: statusByte, dataBytes: dataBytes) { 604 | self = .channelMode(mode) 605 | } else if MIDIControllerEvent.undefinedEventStatusBytes.contains(dataBytes.data1) { 606 | self = .undefined(status: dataBytes.data1, value: dataBytes.data2) 607 | } else { 608 | return nil 609 | } 610 | } 611 | } 612 | 613 | // MARK: MIDIEventUndefinable 614 | 615 | public static var undefinedEventStatusBytes: [UInt8] { 616 | let bytes: [UInt8] = [3, 9, 14, 15, 35, 21, 46, 47, 85, 86, 87, 89, 90] 617 | return bytes + [UInt8](20...31) + [UInt8](52...63) + [UInt8](102...119) 618 | } 619 | 620 | // MARK: CustomStringConvertible 621 | 622 | public var description: String { 623 | switch self { 624 | case .bankSelect: return NSLocalizedString("midi_bankSelect", comment: "") 625 | case .modulationWheel: return NSLocalizedString("midi_modulationWheel", comment: "") 626 | case .breathController: return NSLocalizedString("midi_breathController", comment: "") 627 | case .footController: return NSLocalizedString("midi_footController", comment: "") 628 | case .portamentoTime: return NSLocalizedString("midi_portamentoTime", comment: "") 629 | case .dataEntryMSB: return NSLocalizedString("midi_dataEntryMSB", comment: "") 630 | case .channelVolume: return NSLocalizedString("midi_channelVolume", comment: "") 631 | case .balance: return NSLocalizedString("midi_balance", comment: "") 632 | case .pan: return NSLocalizedString("midi_pan", comment: "") 633 | case .expressionController: return NSLocalizedString("midi_expressionController", comment: "") 634 | case .effectControl1: return NSLocalizedString("midi_effectControl1", comment: "") 635 | case .effectControl2: return NSLocalizedString("midi_effectControl2", comment: "") 636 | case .generalPurposeController1: return NSLocalizedString("midi_generalPurposeController1", comment: "") 637 | case .generalPurposeController2: return NSLocalizedString("midi_generalPurposeController2", comment: "") 638 | case .generalPurposeController3: return NSLocalizedString("midi_generalPurposeController3", comment: "") 639 | case .generalPurposeController4: return NSLocalizedString("midi_generalPurposeController4", comment: "") 640 | case .lsbBankSelect: return NSLocalizedString("midi_lsbBankSelect", comment: "") 641 | case .lsbModulationWheel: return NSLocalizedString("midi_lsbModulationWheel", comment: "") 642 | case .lsbBreathController: return NSLocalizedString("midi_lsbBreathController", comment: "") 643 | case .lsbFootController: return NSLocalizedString("midi_lsbFootController", comment: "") 644 | case .lsbPortamentoTime: return NSLocalizedString("midi_lsbPortamentoTime", comment: "") 645 | case .lsbDataEntryMSB: return NSLocalizedString("midi_lsbDataEntryMSB", comment: "") 646 | case .lsbChannelVolume: return NSLocalizedString("midi_lsbChannelVolume", comment: "") 647 | case .lsbBalance: return NSLocalizedString("midi_lsbBalance", comment: "") 648 | case .lsbPan: return NSLocalizedString("midi_lsbPan", comment: "") 649 | case .lsbExpressionController: return NSLocalizedString("midi_lsbExpressionController", comment: "") 650 | case .lsbEffectControl1: return NSLocalizedString("midi_lsbEffectControl1", comment: "") 651 | case .lsbEffectControl2: return NSLocalizedString("midi_lsbEffectControl2", comment: "") 652 | case .lsbGeneralPurposeController1: return NSLocalizedString("midi_lsbGeneralPurposeController1", comment: "") 653 | case .lsbGeneralPurposeController2: return NSLocalizedString("midi_lsbGeneralPurposeController2", comment: "") 654 | case .lsbGeneralPurposeController3: return NSLocalizedString("midi_lsbGeneralPurposeController3", comment: "") 655 | case .lsbGeneralPurposeController4: return NSLocalizedString("midi_lsbGeneralPurposeController4", comment: "") 656 | case .damperPedal: return NSLocalizedString("midi_damperPedal", comment: "") 657 | case .portamentoOn: return NSLocalizedString("midi_portamentoOn", comment: "") 658 | case .sostenutoOn: return NSLocalizedString("midi_sostenutoOn", comment: "") 659 | case .softPedalOn: return NSLocalizedString("midi_softPedalOn", comment: "") 660 | case .legatoFootswitch: return NSLocalizedString("midi_legatoFootswitch", comment: "") 661 | case .hold2: return NSLocalizedString("midi_hold2", comment: "") 662 | case .soundVariation: return NSLocalizedString("midi_soundVariation", comment: "") 663 | case .timbreIntesity: return NSLocalizedString("midi_timbreIntesity", comment: "") 664 | case .releaseTime: return NSLocalizedString("midi_releaseTime", comment: "") 665 | case .attackTime: return NSLocalizedString("midi_attackTime", comment: "") 666 | case .brightness: return NSLocalizedString("midi_brightness", comment: "") 667 | case .decayTime: return NSLocalizedString("midi_decayTime", comment: "") 668 | case .vibratoRate: return NSLocalizedString("midi_vibratoRate", comment: "") 669 | case .vibratoDepth: return NSLocalizedString("midi_vibratoDepth", comment: "") 670 | case .vibratoDelay: return NSLocalizedString("midi_vibratoDelay", comment: "") 671 | case .defaultUndefined: return NSLocalizedString("midi_defaultUndefined", comment: "") 672 | case .generalPurposeController5: return NSLocalizedString("midi_generalPurposeController5", comment: "") 673 | case .generalPurposeController6: return NSLocalizedString("midi_generalPurposeController6", comment: "") 674 | case .generalPurposeController7: return NSLocalizedString("midi_generalPurposeController7", comment: "") 675 | case .generalPurposeController8: return NSLocalizedString("midi_generalPurposeController8", comment: "") 676 | case .portamentoControl: return NSLocalizedString("midi_portamentoControl", comment: "") 677 | case .highResolutionVelocityPrefix: return NSLocalizedString("midi_highResolutionVelocityPrefix", comment: "") 678 | case .reverbSendLevel: return NSLocalizedString("midi_reverbSendLevel", comment: "") 679 | case .tremoloDepth: return NSLocalizedString("midi_tremoloDepth", comment: "") 680 | case .chorusSendLevel: return NSLocalizedString("midi_chorusSendLevel", comment: "") 681 | case .celesteDepth: return NSLocalizedString("midi_celesteDepth", comment: "") 682 | case .phaserDepth: return NSLocalizedString("midi_phaserDepth", comment: "") 683 | case .dataIncrement: return NSLocalizedString("midi_dataIncrement", comment: "") 684 | case .dataDecrement: return NSLocalizedString("midi_dataDecrement", comment: "") 685 | case .nonRegisteredParameterNumberLSB: return NSLocalizedString("midi_nonRegisteredParameterNumberLSB", comment: "") 686 | case .nonRegisteredParameterNumberMSB: return NSLocalizedString("midi_nonRegisteredParameterNumberMSB", comment: "") 687 | case .registeredParameterNumberLSB: return NSLocalizedString("midi_registeredParameterNumberLSB", comment: "") 688 | case .registeredParameterNumberMSB: return NSLocalizedString("midi_registeredParameterNumberMSB", comment: "") 689 | case .channelMode(let mode): return mode.description 690 | case .undefined: return NSLocalizedString("midi_undefined", comment: "") 691 | } 692 | } 693 | } 694 | 695 | // MARK: - MIDI Channel Mode Events 696 | 697 | public enum MIDIChannelModeEvent: MIDIStatusEvent { 698 | case allSoundOff // 120 699 | case resetAllControllers // 121 700 | case localControl(on: Bool) // 122 701 | case allNotesOff // 123 702 | case omniModeOff // 124 703 | case omniModeOn // 125 704 | case monoModeOn // 126 705 | case polyModeOn // 127 706 | 707 | // MARK: MIDIStatusEvent 708 | 709 | public var statusByte: UInt8 { 710 | switch self { 711 | case .allSoundOff: return 120 712 | case .resetAllControllers: return 121 713 | case .localControl: return 122 714 | case .allNotesOff: return 123 715 | case .omniModeOff: return 124 716 | case .omniModeOn: return 125 717 | case .monoModeOn: return 126 718 | case .polyModeOn: return 127 719 | } 720 | } 721 | 722 | public var dataBytes: MIDIEventData { 723 | switch self { 724 | case .allSoundOff: return MIDIEventData(data1: statusByte) 725 | case .resetAllControllers: return MIDIEventData(data1: statusByte) 726 | case .localControl(let on): return MIDIEventData(data1: statusByte, data2: on ? 127 : 0) 727 | case .allNotesOff: return MIDIEventData(data1: statusByte) 728 | case .omniModeOff: return MIDIEventData(data1: statusByte) 729 | case .omniModeOn: return MIDIEventData(data1: statusByte) 730 | case .monoModeOn: return MIDIEventData(data1: statusByte) 731 | case .polyModeOn: return MIDIEventData(data1: statusByte) 732 | } 733 | } 734 | 735 | public init?(statusByte: UInt8, dataBytes: MIDIEventData) { 736 | switch dataBytes.data1 { 737 | case 120: self = .allSoundOff 738 | case 121: self = .resetAllControllers 739 | case 122: self = .localControl(on: dataBytes.data2 > 63) 740 | case 123: self = .allNotesOff 741 | case 124: self = .omniModeOff 742 | case 125: self = .omniModeOn 743 | case 126: self = .monoModeOn 744 | case 127: self = .polyModeOn 745 | default: return nil 746 | } 747 | } 748 | 749 | // MARK: CustomStringConvertible 750 | 751 | public var description: String { 752 | switch self { 753 | case .allSoundOff: return NSLocalizedString("midi_allSoundOff", comment: "") 754 | case .resetAllControllers: return NSLocalizedString("midi_resetAllControllers", comment: "") 755 | case .localControl: return NSLocalizedString("midi_localControl", comment: "") 756 | case .allNotesOff: return NSLocalizedString("midi_allNotesOff", comment: "") 757 | case .omniModeOff: return NSLocalizedString("midi_omniModeOff", comment: "") 758 | case .omniModeOn: return NSLocalizedString("midi_omniModeOn", comment: "") 759 | case .monoModeOn: return NSLocalizedString("midi_monoModeOn", comment: "") 760 | case .polyModeOn: return NSLocalizedString("midi_polyModeOn", comment: "") 761 | } 762 | } 763 | } 764 | 765 | // MARK: MIDI Quarter Frame Events 766 | 767 | public enum SMPTERate: UInt8 { 768 | case fps24 = 0x00 769 | case fps25 = 0x01 770 | case fps30 = 0x02 771 | case fps30drop = 0x03 772 | } 773 | 774 | public enum MIDIQuarterFrameEvent: CustomStringConvertible { 775 | case framesLowNibble(UInt8) 776 | case framesHighNibble(UInt8) 777 | case secondsLowNibble(UInt8) 778 | case secondsHighNibble(UInt8) 779 | case minutesLowNibble(UInt8) 780 | case minutesHighNibble(UInt8) 781 | case hoursLowNibble(UInt8) 782 | case hoursHighNibble(nibble: UInt8, rate: SMPTERate) 783 | 784 | public var dataBytes: MIDIEventData { 785 | switch self { 786 | case .framesLowNibble(let nibble): return MIDIEventData(data1: 0x00 + nibble) 787 | case .framesHighNibble(let nibble): return MIDIEventData(data1: 0x10 + nibble) 788 | case .secondsLowNibble(let nibble): return MIDIEventData(data1: 0x20 + nibble) 789 | case .secondsHighNibble(let nibble): return MIDIEventData(data1: 0x30 + nibble) 790 | case .minutesLowNibble(let nibble): return MIDIEventData(data1: 0x40 + nibble) 791 | case .minutesHighNibble(let nibble): return MIDIEventData(data1: 0x50 + nibble) 792 | case .hoursLowNibble(let nibble): return MIDIEventData(data1: 0x60 + nibble) 793 | case .hoursHighNibble(let nibble, let rate): return MIDIEventData(data1: 0x70 + (rate.rawValue + nibble)) 794 | } 795 | } 796 | 797 | public var description: String { 798 | return NSLocalizedString("midi_quarterFrameEvent", comment: "") 799 | } 800 | 801 | public init?(data: MIDIEventData) { 802 | if data.data1 >= 0x00 && data.data1 < 0x10 { 803 | let nibble = data.data1 - 0x00 804 | self = .framesLowNibble(nibble) 805 | } else if data.data1 >= 0x10 && data.data1 < 0x20 { 806 | let nibble = data.data1 - 0x10 807 | self = .framesHighNibble(nibble) 808 | } else if data.data1 >= 0x20 && data.data1 < 0x30 { 809 | let nibble = data.data1 - 0x20 810 | self = .secondsLowNibble(nibble) 811 | } else if data.data1 >= 0x30 && data.data1 < 0x40 { 812 | let nibble = data.data1 - 0x30 813 | self = .secondsHighNibble(nibble) 814 | } else if data.data1 >= 0x40 && data.data1 < 0x50 { 815 | let nibble = data.data1 - 0x40 816 | self = .minutesLowNibble(nibble) 817 | } else if data.data1 >= 0x50 && data.data1 < 0x60 { 818 | let nibble = data.data1 - 0x50 819 | self = .minutesHighNibble(nibble) 820 | } else if data.data1 >= 0x60 && data.data1 < 0x70 { 821 | let nibble = data.data1 - 0x60 822 | self = .hoursLowNibble(nibble) 823 | } else if data.data1 >= 0x70 && data.data1 < 0x80 { 824 | let nibble = data.data1 - 0x70 825 | // FIXME: I don't know how to get both rate and nibble from single byte. 826 | self = .hoursHighNibble(nibble: nibble, rate: .fps24) 827 | } else { 828 | return nil 829 | } 830 | } 831 | } 832 | 833 | // MARK: MIDI System Common Events 834 | 835 | public enum MIDISystemCommonEvent: MIDIStatusEvent, MIDIEventUndefinable { 836 | case systemExclusive(data1: UInt8, data2: UInt8) // 240 837 | case midiTimeCodeQuarterFrame(MIDIQuarterFrameEvent) // 241 838 | case songPositionPointer(pointer: UInt16) // 242 839 | case songSelect(song: UInt8) // 243 840 | case tuneRequest // 246 841 | case eox // 247 842 | case reserved(status: UInt8, data: MIDIEventData) // 245, 244 843 | 844 | // MARK: MIDIStatusEvent 845 | 846 | public var statusByte: UInt8 { 847 | switch self { 848 | case .systemExclusive: return 240 849 | case .midiTimeCodeQuarterFrame: return 241 850 | case .songPositionPointer: return 242 851 | case .songSelect: return 243 852 | case .tuneRequest: return 246 853 | case .eox: return 247 854 | case .reserved(let status, _): return status 855 | } 856 | } 857 | 858 | public var dataBytes: MIDIEventData { 859 | switch self { 860 | case .systemExclusive(let data1, let data2): return MIDIEventData(data1: data1, data2: data2) 861 | case .midiTimeCodeQuarterFrame(let frame): return frame.dataBytes 862 | case .songPositionPointer(let pointer): return MIDIEventData(data: pointer) 863 | case .songSelect(let song): return MIDIEventData(data1: song) 864 | case .tuneRequest: return MIDIEventData() 865 | case .eox: return MIDIEventData() 866 | case .reserved(_, let data): return data 867 | } 868 | } 869 | 870 | public init?(statusByte: UInt8, dataBytes: MIDIEventData) { 871 | switch statusByte { 872 | case 240: self = .systemExclusive(data1: dataBytes.data1, data2: dataBytes.data2) 873 | case 241: 874 | if let event = MIDIQuarterFrameEvent(data: dataBytes) { 875 | self = .midiTimeCodeQuarterFrame(event) 876 | } else { 877 | return nil 878 | } 879 | case 242: self = .songPositionPointer(pointer: UInt16((dataBytes.data2 << 8) | dataBytes.data1)) 880 | case 243: self = .songSelect(song: dataBytes.data1) 881 | case 246: self = .tuneRequest 882 | case 247: self = .eox 883 | default: 884 | if MIDISystemCommonEvent.undefinedEventStatusBytes.contains(statusByte) { 885 | self = .reserved(status: statusByte, data: dataBytes) 886 | } else { 887 | return nil 888 | } 889 | } 890 | } 891 | 892 | // MARK: MIDIEventUndefinable 893 | 894 | public static var undefinedEventStatusBytes: [UInt8] { 895 | return [245, 244] 896 | } 897 | 898 | // MARK: CustomStringConvertible 899 | 900 | public var description: String { 901 | switch self { 902 | case .systemExclusive: return NSLocalizedString("midi_systemExclusive", comment: "") 903 | case .midiTimeCodeQuarterFrame(let qt): return qt.description 904 | case .songPositionPointer: return NSLocalizedString("midi_songPositionPointer", comment: "") 905 | case .songSelect: return NSLocalizedString("midi_songSelect", comment: "") 906 | case .tuneRequest: return NSLocalizedString("midi_tuneRequest", comment: "") 907 | case .eox: return NSLocalizedString("midi_eox", comment: "") 908 | case .reserved: return NSLocalizedString("midi_undefined", comment: "") 909 | } 910 | } 911 | } 912 | 913 | // MARK: MIDI System Real Time Events 914 | 915 | public enum MIDISystemRealTimeEvent: MIDIStatusEvent, MIDIEventUndefinable { 916 | case timingClock // 248 917 | case start // 250 918 | case `continue` // 251 919 | case stop // 252 920 | case activeSensing // 254 921 | case reset // 255 922 | case reserved(status: UInt8, data: MIDIEventData) // 253, 249 923 | 924 | // MARK: MIDIStatusEvent 925 | 926 | public var statusByte: UInt8 { 927 | switch self { 928 | case .timingClock: return 248 929 | case .start: return 250 930 | case .`continue`: return 251 931 | case .stop: return 252 932 | case .activeSensing: return 254 933 | case .reset: return 255 934 | case .reserved(let status, _): return status 935 | } 936 | } 937 | 938 | public var dataBytes: MIDIEventData { 939 | switch self { 940 | case .timingClock: return MIDIEventData() 941 | case .start: return MIDIEventData() 942 | case .`continue`: return MIDIEventData() 943 | case .stop: return MIDIEventData() 944 | case .activeSensing: return MIDIEventData() 945 | case .reset: return MIDIEventData() 946 | case .reserved(_, let data): return data 947 | } 948 | } 949 | 950 | public init?(statusByte: UInt8, dataBytes: MIDIEventData) { 951 | switch statusByte { 952 | case 248: self = .timingClock 953 | case 250: self = .start 954 | case 251: self = .`continue` 955 | case 252: self = .stop 956 | case 254: self = .activeSensing 957 | case 255: self = .reset 958 | default: 959 | if MIDISystemRealTimeEvent.undefinedEventStatusBytes.contains(statusByte) { 960 | self = .reserved(status: statusByte, data: dataBytes) 961 | } else { 962 | return nil 963 | } 964 | } 965 | } 966 | 967 | // MARK: MIDIEventUndefinable 968 | 969 | public static var undefinedEventStatusBytes: [UInt8] { 970 | return [253, 249] 971 | } 972 | 973 | // MARK: CustomStringConvertible 974 | 975 | public var description: String { 976 | switch self { 977 | case .timingClock: return NSLocalizedString("midi_timingClock", comment: "") 978 | case .start: return NSLocalizedString("midi_start", comment: "") 979 | case .`continue`: return NSLocalizedString("midi_continue", comment: "") 980 | case .stop: return NSLocalizedString("midi_stop", comment: "") 981 | case .activeSensing: return NSLocalizedString("midi_activeSensing", comment: "") 982 | case .reset: return NSLocalizedString("midi_reset", comment: "") 983 | case .reserved: return NSLocalizedString("midi_undefined", comment: "") 984 | } 985 | } 986 | } 987 | -------------------------------------------------------------------------------- /Example/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 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 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 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 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | Default 530 | 531 | 532 | 533 | 534 | 535 | 536 | Left to Right 537 | 538 | 539 | 540 | 541 | 542 | 543 | Right to Left 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | Default 555 | 556 | 557 | 558 | 559 | 560 | 561 | Left to Right 562 | 563 | 564 | 565 | 566 | 567 | 568 | Right to Left 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 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 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | --------------------------------------------------------------------------------