diff --git a/Source/MIKMIDINoteEvent.h b/Source/MIKMIDINoteEvent.h index 19e28d04..d43fd0a3 100644 --- a/Source/MIKMIDINoteEvent.h +++ b/Source/MIKMIDINoteEvent.h @@ -73,7 +73,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) Float32 duration; /** - * The time stamp at the end of the notes duration. + * The time stamp at the end of the notes duration. This is simply the event's timeStamp + duration. */ @property (nonatomic, readonly) MusicTimeStamp endTimeStamp; diff --git a/Source/MIKMIDISequencer.m b/Source/MIKMIDISequencer.m index b69b5b0f..42fa1c73 100644 --- a/Source/MIKMIDISequencer.m +++ b/Source/MIKMIDISequencer.m @@ -340,7 +340,20 @@ - (void)processSequenceStartingFromMIDITimeStamp:(MIDITimeStamp)fromMIDITimeStam NSArray *tracksToPlay = soloTracks.count != 0 ? soloTracks : nonMutedTracks; for (MIKMIDITrack *track in tracksToPlay) { - NSArray *events = [track eventsFromTimeStamp:MAX(fromMusicTimeStamp - playbackOffset, 0) toTimeStamp:toMusicTimeStamp - playbackOffset]; + MusicTimeStamp startTimeStamp = MAX(fromMusicTimeStamp - playbackOffset - track.offset, 0); + MusicTimeStamp endTimeStamp = toMusicTimeStamp - playbackOffset - track.offset; + NSArray *events = [track eventsFromTimeStamp:startTimeStamp toTimeStamp:endTimeStamp]; + if (track.offset != 0) { + // Shift events by offset + NSMutableArray *shiftedEvents = [NSMutableArray array]; + for (MIKMIDIEvent *event in events) { + MIKMutableMIDIEvent *shiftedEvent = [event mutableCopy]; + shiftedEvent.timeStamp += track.offset; + [shiftedEvents addObject:shiftedEvent]; + } + events = shiftedEvents; + } + id destination = events.count ? [self commandSchedulerForTrack:track] : nil; // only get the destination if there's events so we don't create a destination endpoint if not needed for (MIKMIDIEvent *event in events) { NSNumber *timeStampKey = @(event.timeStamp + playbackOffset);