-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathMIDIPacket+SequenceType.swift
56 lines (46 loc) · 1.49 KB
/
MIDIPacket+SequenceType.swift
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
import CoreMIDI
/** The returned generator will enumerate each value of the provided tuple. */
func generatorForTuple(tuple: Any) -> AnyGenerator<Any> {
let children = Mirror(reflecting: tuple).children
return anyGenerator(children.generate().lazy.map { $0.value }.generate())
}
/**
Allows a MIDIPacket to be iterated through with a for statement.
Example usage:
let packet: MIDIPacket
for message in packet {
// message is a Message
}
*/
extension MIDIPacket: SequenceType {
public func generate() -> AnyGenerator<Event> {
let generator = generatorForTuple(self.data)
var index: UInt16 = 0
return anyGenerator {
if index >= self.length {
return nil
}
func pop() -> UInt8 {
assert(index < self.length)
index++
return generator.next() as! UInt8
}
let status = pop()
if Message.isStatusByte(status) {
var data1: UInt8 = 0
var data2: UInt8 = 0
switch Message.statusMessage(status) {
case .NoteOff: data1 = pop(); data2 = pop();
case .NoteOn: data1 = pop(); data2 = pop();
case .Aftertouch: data1 = pop(); data2 = pop();
case .ControlChange: data1 = pop(); data2 = pop();
case .ProgramChange: data1 = pop()
case .ChannelPressure:data1 = pop()
case .PitchBend: data1 = pop(); data2 = pop();
}
return Event(timeStamp: self.timeStamp, status: status, data1: data1, data2: data2)
}
return nil
}
}
}