Skip to content

Commit 7626c54

Browse files
committed
Merge branch 'develop' into sequencer-thread-safety
2 parents f0b7a1a + 9b28711 commit 7626c54

File tree

10 files changed

+74
-23
lines changed

10 files changed

+74
-23
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
Try to make sure your changes conform to the [Swift API Design Guidelines](https://swift.org/documentation/api-design-guidelines/). If you have 40 minutes you'd like to have well-spent, watch [Modern Swift API Design](https://developer.apple.com/videos/play/wwdc2019/415/) from WWDC 2019.
44

5-
Ready to send us a pull request? Please make sure your request is based on the a `develop` branch of the repository since `main` should only hold stable releases.
5+
Ready to send us a pull request? Please make sure your request is based on the `develop` branch of the repository since `main` should only hold stable releases.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
</div>
1313

14-
This extension to AudioKit contains all of the AudioKit features that rely on C/C++ DSP.
14+
This extension to AudioKit contains all of the AudioKit features that rely on C/C++ DSP.
1515

1616
## Documentation
1717

Sources/AudioKitEX/Sequencing/Sequence.swift

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,9 @@ extension Array where Element == SequenceEvent {
4040
return self.sorted(by: { (event1:SequenceEvent, event2:SequenceEvent) -> Bool in
4141
let event1Beat = event1.beat
4242
let event2Beat = event2.beat
43-
let simultaneous = (event1Beat == event2Beat) && (event1.data1 == event2.data1)
44-
if isNoteOn(event1.status) && isNoteOff(event2.status) && simultaneous {
45-
return false
46-
}
47-
if isNoteOff(event1.status) && isNoteOn(event2.status) && simultaneous {
48-
return true
43+
if event1Beat == event2Beat {
44+
if isNoteOn(event1.status) && isNoteOff(event2.status) { return false }
45+
if isNoteOff(event1.status) && isNoteOn(event2.status) { return true }
4946
}
5047
return event1Beat < event2Beat
5148
})
@@ -64,7 +61,7 @@ extension Array where Element == SequenceEvent {
6461
public struct NoteEventSequence: Equatable {
6562
/// Array of sequence notes
6663
public var notes: [SequenceNote]
67-
/// Array of sequenc events
64+
/// Array of sequence events
6865
public var events: [SequenceEvent]
6966

7067
/// Initialize with notes and events
@@ -115,7 +112,7 @@ public struct NoteEventSequence: Equatable {
115112
notes.removeAll { $0.noteOn.beat == position }
116113
}
117114

118-
/// Remove all occurences of a certain MIDI Note nUmber
115+
/// Remove all occurrences of a certain MIDI Note nUmber
119116
/// - Parameter noteNumber: Note to remove
120117
public mutating func removeAllInstancesOf(noteNumber: MIDINoteNumber) {
121118
notes.removeAll { $0.noteOn.data1 == noteNumber }

Sources/AudioKitEX/Sequencing/Sequencer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ open class Sequencer {
173173
stop()
174174
}
175175

176-
/// Retrived a track for a given node
176+
/// Retrieved a track for a given node
177177
/// - Parameter node: Node you want to access the tack for
178178
/// - Returns: Track associated with the given node
179179
public func getTrackFor(node: Node) -> SequencerTrack? {

Sources/AudioKitEX/Sequencing/SequencerTrack.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ open class SequencerTrack {
7272
akSequencerEngineStopPlayingNotes(engine)
7373
}
7474

75-
/// Set the current position to the start ofthe track
75+
/// Set the current position to the start of the track
7676
public func rewind() {
7777
seek(to: 0)
7878
}

Sources/CAudioKitEX/Nodes/CallbackInstrumentDSP.mm

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,26 @@
1313
// MARK: Member Functions
1414

1515
RingBuffer<AUMIDIEvent> midiBuffer;
16-
NSTimer* timer;
16+
dispatch_source_t timer;
1717

1818
CallbackInstrumentDSP() {
1919
// Hopefully this polling interval is ok.
20-
timer = [NSTimer timerWithTimeInterval:0.01
21-
repeats:true
22-
block:^(NSTimer * _Nonnull timer) {
20+
static dispatch_once_t onceToken;
21+
static dispatch_queue_t timerQueue;
22+
dispatch_once(&onceToken, ^{
23+
timerQueue = dispatch_queue_create("audio.kit.timer.queue", DISPATCH_QUEUE_CONCURRENT);
24+
});
25+
timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, timerQueue);
26+
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC, 0);
27+
dispatch_source_set_event_handler(timer, ^{
2328
consumer();
24-
}];
25-
NSRunLoop *runner = [NSRunLoop currentRunLoop];
26-
[runner addTimer:timer forMode: NSDefaultRunLoopMode];
29+
});
30+
dispatch_resume(timer);
2731
}
2832

2933
~CallbackInstrumentDSP() {
30-
[timer invalidate];
34+
dispatch_source_cancel(timer);
35+
timer = nil;
3136
}
3237

3338
void process(FrameRange range) override {

Sources/CAudioKitEX/include/CAudioKit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ FOUNDATION_EXPORT const unsigned char AudioKitVersionString[];
2929
#import "ParameterRamper.h"
3030
#import "ParameterAutomation.h"
3131

32-
// Swift/ObjC/C/C++ Inter-operability
32+
// Swift/ObjC/C/C++ Interoperability
3333
#import "Interop.h"
3434

3535
CF_EXTERN_C_BEGIN

Sources/CAudioKitEX/include/DebugDSP.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
extern "C" {
1010
#endif
1111

12-
/// Activate or deactive DSP kernel debugging.
12+
/// Activate or deactivate DSP kernel debugging.
1313
void DebugDSPSetActive(bool active);
1414

1515
/// Update the hash at the selected slot with a new value.

Sources/CAudioKitEX/include/ParameterRamper.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#import <atomic>
1717

1818
class ParameterRamper {
19-
float clampLow, clampHigh;
2019
std::atomic<float> _uiValue{0};
2120
float _goal;
2221
float inverseSlope;

Tests/AudioKitEXTests/SequenceTests.swift

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,55 @@ class NoteEventSequenceTests: XCTestCase {
5252
XCTAssertEqual(seq.notes[1].noteOn.data1, 62)
5353
}
5454

55+
func testNoteOffAlwaysBeforeNoteOnInBeatTimeOrdered() {
56+
let noteOn = SequenceEvent(status: noteOnByte, data1: 60, data2: 0, beat: 0)
57+
let noteOff = SequenceEvent(status: noteOffByte, data1: 60, data2: 0, beat: 0)
58+
let otherNoteOn = SequenceEvent(status: noteOnByte, data1: 61, data2: 0, beat: 0)
59+
60+
let sequences = [
61+
[noteOn, noteOff, otherNoteOn],
62+
[noteOn, otherNoteOn, noteOff],
63+
[noteOff, noteOn , otherNoteOn],
64+
[noteOff, otherNoteOn, noteOn],
65+
[otherNoteOn, noteOn, noteOff],
66+
[otherNoteOn, noteOff, noteOn]
67+
]
68+
69+
for sequence in sequences {
70+
let ordered = sequence.beatTimeOrdered()
71+
XCTAssertLessThan(ordered.firstIndex(of: noteOff)!, ordered.firstIndex(of: noteOn)!)
72+
}
73+
}
74+
75+
func testEarlierNoteBeforeInBeatTimeOrderedForSameNoteSameStatus() {
76+
let earlier = SequenceEvent(status: noteOnByte, data1: 60, data2: 0, beat: 0)
77+
let later = SequenceEvent(status: noteOnByte, data1: 60, data2: 0, beat: 1)
78+
79+
let sequences = [
80+
[earlier, later],
81+
[later, earlier],
82+
]
83+
84+
for sequence in sequences {
85+
let ordered = sequence.beatTimeOrdered()
86+
XCTAssertLessThan(ordered.firstIndex(of: earlier)!, ordered.firstIndex(of: later)!)
87+
}
88+
}
89+
90+
func testEarlierNoteBeforeInBeatTimeOrderedForSameNoteDifferentStatus() {
91+
let earlier = SequenceEvent(status: noteOnByte, data1: 60, data2: 0, beat: 0)
92+
let later = SequenceEvent(status: noteOffByte, data1: 60, data2: 0, beat: 1)
93+
94+
let sequences = [
95+
[earlier, later],
96+
[later, earlier],
97+
]
98+
99+
for sequence in sequences {
100+
let ordered = sequence.beatTimeOrdered()
101+
XCTAssertLessThan(ordered.firstIndex(of: earlier)!, ordered.firstIndex(of: later)!)
102+
}
103+
}
104+
55105
}
56106
#endif

0 commit comments

Comments
 (0)