Skip to content

Commit 91cdd95

Browse files
author
Simon Holliday
committed
- Fix potential rounding errors mapping to pulses
1 parent 06853c9 commit 91cdd95

2 files changed

Lines changed: 14 additions & 1 deletion

File tree

subsequence/pattern_builder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def grid (self) -> int:
152152
def _has_pitch_at_beat (self, pitch: typing.Union[int, str], beat: float) -> bool:
153153
"""Helper to check if a pitch is already sounding at a specific beat."""
154154
midi_pitch = self._resolve_pitch(pitch)
155-
pulse = int(beat * subsequence.constants.MIDI_QUARTER_NOTE + 0.5)
155+
pulse = int(beat * subsequence.constants.MIDI_QUARTER_NOTE)
156156
if pulse in self._pattern.steps:
157157
return any(n.pitch == midi_pitch for n in self._pattern.steps[pulse].notes)
158158
return False

tests/test_pattern_builder.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4746,3 +4746,16 @@ def test_velocity_ramp_uses_grid ():
47464746
_, builder = _make_builder(default_grid=8, length=8)
47474747
result = builder.velocity_ramp(50, 100)
47484748
assert len(result) == 8
4749+
4750+
4751+
def test_no_overlap_rounding_edge_case ():
4752+
"""_has_pitch_at_beat must use the same int() truncation as add_note_beats.
4753+
At a beat where beat*PPQ == N+0.5, int() gives N but int()+0.5 rounds to N+1,
4754+
so the lookup would miss the placed note and no_overlap=True would fail."""
4755+
_, builder = _make_builder(default_grid=16, length=4)
4756+
# 11.5/480 * 480 == 11.5 → int() truncates to 11, int(+0.5) rounds to 12
4757+
beat = 11.5 / subsequence.constants.MIDI_QUARTER_NOTE
4758+
# Place a note at the edge-case beat position via add_note_beats
4759+
builder._pattern.add_note_beats(beat, 60, 100, 0.25)
4760+
# _has_pitch_at_beat must find it (would return False under the old + 0.5 rounding)
4761+
assert builder._has_pitch_at_beat(60, beat), "_has_pitch_at_beat missed a note placed at the same beat (rounding mismatch)"

0 commit comments

Comments
 (0)