Generation

This commit is contained in:
khodowany
2026-09-26 10:12:51 -05:00
parent 9fd5abd075
commit 1d5f3a9372
20 changed files with 681 additions and 155 deletions
+11 -3
View File
@@ -73,12 +73,20 @@ def validate_source(document: dict, *, practice: bool = False) -> None:
if practice and len(voices) > 1:
raise ValueError('practice requires one monophonic voice')
def build_measure(source: dict, identifier: str, role: str, part: str, previous: dict | None, label: str = '', rhythm: generator.rhythm.Bar | None = None) -> dict:
def build_measure(source: dict, identifier: str, role: str, part: str, previous: dict | None, label: str = '', rhythm: generator.rhythm.Bar | tuple[generator.rhythm.Bar, generator.rhythm.Bar] | None = None, *, melody_octave: bool = False) -> dict:
voices = generator.score.copy_source_voices(source, strip_lyrics=role == 'melody') if role in ('vocal', 'melody') else None
notes = [n for v in voices for n in v['notes']] if voices else generator.accompaniment.realize(source, rhythm, previous) if rhythm is not None else generated_voice(source, role, previous)
if role == 'accompaniment' and part == 'acoustic':
voices = [{'id': lane, 'notes': generator.accompaniment.realize(source, bar, previous, lane=lane)} for lane, bar in zip(('upper', 'bass'), (rhythm[1], rhythm[0]))]
for voice in voices:
for note in voice['notes']:
note.update(voice=voice['id'], stem='down' if voice['id'] == 'bass' else 'up')
notes = [n for v in voices for n in v['notes']] if voices else generator.accompaniment.realize(source, rhythm, previous, lane='electric') if rhythm is not None else generated_voice(source, role, previous)
if role in ('melody', 'vocal'):
for note in notes:
note['pitches'] = [generator.pitch.shift_pitch(p, 7, 12) for p in note['pitches']]
octaves = 2 if melody_octave and role == 'melody' else 1
note['pitches'] = [generator.pitch.shift_pitch(p, 7 * octaves, 12 * octaves) for p in note['pitches']]
if role == 'melody':
note['_melody'] = True
result = generator.score.make_measure(identifier, source, [] if voices else notes, section_label=label)
if voices:
result['voices'] = voices