Skip to content

Commit

Permalink
Merge pull request #111 from orchetect/dev
Browse files Browse the repository at this point in the history
`.send(events:)`: Improved reliability of sending SysEx
  • Loading branch information
orchetect authored Jun 13, 2022
2 parents 4911832 + 2081371 commit e357b2e
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ extension UnsafeMutablePointer where Pointee == MIDIPacketList {
/// Assembles an array of `Byte` arrays into Core MIDI `MIDIPacket`s and wraps them in a `MIDIPacketList`.
///
/// - Note: You must deallocate the pointer when finished with it.
/// - Note: System Exclusive messages must each be packed in a dedicated MIDIPacketList with no other events, otherwise MIDIPacketList may fail.
@inline(__always)
internal init(data: [[MIDI.Byte]]) throws {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,14 @@ extension _MIDIIOSendsMIDIMessagesProtocol {

switch api {
case .legacyCoreMIDI:
try send(rawMessages: events.map { $0.midi1RawBytes })
if events.contains(where: { $0.isSystemExclusive }) {
// System Exclusive events must be the only event in a MIDIPacketList
// so force each event to be sent in its own packet
try events.forEach { try send(event: $0) }
} else {
// combine events into a single MIDIPacketList
try send(rawMessages: events.map { $0.midi1RawBytes })
}

case .newCoreMIDI:
guard #available(macOS 11, iOS 14, macCatalyst 14, tvOS 14, watchOS 7, *) else {
Expand All @@ -172,4 +179,3 @@ extension _MIDIIOSendsMIDIMessagesProtocol {
}

}

6 changes: 4 additions & 2 deletions Tests/MIDIKitTests/Integration Tests/Round Trip Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,10 @@ open class RoundTrip_Tests_Base: XCTestCase {

receivedEvents.reserveCapacity(sourceEvents.count)

for event in sourceEvents {
try output.send(event: event)
// send several events at once to test packing
// multiple packets into a single MIDIPacketList / MIDIEventList
for eventGroup in sourceEvents.split(every: 2) {
try output.send(events: Array(eventGroup))
}

wait(sec: 0.5)
Expand Down
53 changes: 53 additions & 0 deletions Tests/MIDIKitTests/Tests Helpers.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/// ------------------------------------------------------------------------------------
/// ------------------------------------------------------------------------------------
/// Borrowed from [OTCore 1.4.1](https://github.com/orchetect/OTCore) under MIT license.
/// Methods herein are unit tested in OTCore, so no unit tests are necessary in MIDIKit.
/// ------------------------------------------------------------------------------------
/// ------------------------------------------------------------------------------------

#if shouldTestCurrentPlatform

import Foundation

extension Collection {

/// **OTCore:**
/// Splits a `Collection` or `String` into groups of `length` characters, grouping from left-to-right. If `backwards` is true, right-to-left.
@_disfavoredOverload
internal func split(every: Int,
backwards: Bool = false) -> [SubSequence] {

var result: [SubSequence] = []

for i in stride(from: 0, to: count, by: every) {

switch backwards {
case true:
let offsetEndIndex = index(endIndex, offsetBy: -i)
let offsetStartIndex = index(offsetEndIndex,
offsetBy: -every,
limitedBy: startIndex)
?? startIndex

result.insert(self[offsetStartIndex..<offsetEndIndex], at: 0)

case false:
let offsetStartIndex = index(startIndex, offsetBy: i)
let offsetEndIndex = index(offsetStartIndex,
offsetBy: every,
limitedBy: endIndex)
?? endIndex

result.append(self[offsetStartIndex..<offsetEndIndex])

}

}

return result

}

}

#endif

0 comments on commit e357b2e

Please sign in to comment.