Sustained Rhythm
ci / checks (push) Successful in 47m43s

This commit is contained in:
khodowany
2026-09-30 02:18:31 -05:00
parent 8a23fa0fc2
commit 923b7f14e2
826 changed files with 57641 additions and 35 deletions
+21 -7
View File
@@ -173,6 +173,16 @@ def normalize_beams(events: list[dict]) -> None:
if not event.get('beams'):
event.pop('beams', None)
def written_durations(length: fractions.Fraction):
while length:
written = generator.model.written_for(length)
duration = length
if 'ratio' in written and length.denominator & (length.denominator - 1) == 0:
duration = next((size for size in generator.model.TYPE_LENGTHS.values() if size < length), length)
written = generator.model.written_for(duration)
yield duration, written
length -= duration
def realize(measure: dict, bar: generator.rhythm.Bar, previous: dict | None, *, lane: str = '') -> list[dict]:
item = context(measure, previous)
length = generator.model.fraction(measure['duration'])
@@ -186,23 +196,27 @@ def realize(measure: dict, bar: generator.rhythm.Bar, previous: dict | None, *,
if continuation:
chord = None
sounding_end = end
if chord and lane == 'electric':
sounding_end = min(end, start + 1)
for change in measure['harmonies']:
time = generator.model.fraction(change['onset'])
if chord and start < time < sounding_end and not same_chord(chord, active_chord(measure, time, previous)):
sounding_end = time
written = {'type': source.written_type, 'dots': source.dots} if end - start == source.duration and sounding_end == end else None
event = generator.model.make_event(f'{measure["id"]}-rhythm-{lane}-{len(events)}', start, sounding_end - start, 'note' if chord else 'rest', written=written)
unchanged = end - start == source.duration and sounding_end == end
duration = sounding_end - start
written = {'type': source.written_type, 'dots': source.dots} if unchanged else generator.model.written_for(duration)
if not unchanged and (lane == 'electric' or not chord):
duration, written = next(written_durations(duration))
event = generator.model.make_event(f'{measure["id"]}-rhythm-{lane}-{len(events)}', start, duration, 'note' if chord else 'rest', written=written)
if chord:
event['_harmony'] = chord
if lane:
event.update(_guitar_profile='electric' if lane == 'electric' else 'acoustic', _guitar_lane=lane)
if source.beams and written and chord:
if source.beams and unchanged and chord:
event['beams'] = [{'level': level, 'type': kind} for level, kind in source.beams]
events.append(event)
if sounding_end < end:
events.append(generator.model.make_event(f'{measure["id"]}-rhythm-{lane}-{len(events)}', sounding_end, end - sounding_end, 'rest'))
cursor = start + duration
for duration, written in written_durations(end - cursor):
events.append(generator.model.make_event(f'{measure["id"]}-rhythm-{lane}-{len(events)}', cursor, duration, 'rest', written=written))
cursor += duration
normalize_beams(events)
return events