"""
SegmentMaker with supporting classes and functions.
"""
import datetime
import itertools
import os
import abjad
import baca
import quicktions
from . import consort
from .commands import HandlerCommand, RhythmCommand
from .sequence import flatten
[docs]class NoteheadBracketMaker:
r"""
Writes tuplet brackets with inserted note head.
.. container:: example
>>> tuplet = abjad.Tuplet((3, 2), "cs'8 d'8")
>>> tuplet_2 = abjad.Tuplet((2, 3), components=[abjad.Note(0, (3, 8)), tuplet])
>>> staff = abjad.Staff()
>>> staff.append(tuplet_2)
>>> staff.extend([abjad.Note("c'4"), abjad.Note("cs'8"), abjad.Note("d'8")])
>>> new_brackets = evans.NoteheadBracketMaker()
>>> new_brackets(staff)
>>> score = abjad.Score([staff])
>>> moment = "#(ly:make-moment 1 25)"
>>> abjad.setting(score).proportional_notation_duration = moment
>>> file = abjad.LilyPondFile(
... items=[score],
... includes=["abjad.ily"],
... global_staff_size=16,
... )
...
>>> abjad.show(file) # doctest: +SKIP
.. docs::
>>> print(abjad.lilypond(staff))
\new Staff
{
\tweak TupletNumber.text #(tuplet-number::append-note-wrapper(tuplet-number::non-default-tuplet-fraction-text 3 2) "4")
\times 2/3 {
c'4.
\tweak text #tuplet-number::calc-fraction-text
\tweak TupletNumber.text #(tuplet-number::append-note-wrapper(tuplet-number::non-default-tuplet-fraction-text 2 3) "8")
\times 3/2 {
cs'8
d'8
}
}
c'4
cs'8
d'8
}
"""
[docs] def __call__(self, selections):
return self._transform_brackets(selections)
[docs] def __str__(self):
return abjad.storage(self)
[docs] def __repr__(self):
return abjad.storage(self)
def _assemble_notehead(self, head_dur):
pair = head_dur.pair
dot_parts = []
while 1 < pair[0]:
dot_part = (1, pair[1])
dot_parts.append(dot_part)
head_dur -= abjad.Duration(dot_part)
pair = head_dur.pair
duration_string = f"{pair[1]}"
for _ in dot_parts:
duration_string += "."
return duration_string
def _transform_brackets(self, selections):
for tuplet in abjad.select(selections).components(abjad.Tuplet):
for rest_group in abjad.select(tuplet).rests().group_by_contiguity():
abjad.mutate.fuse(rest_group)
inner_durs = []
for _ in tuplet[:]:
if isinstance(_, abjad.Tuplet):
inner_durs.append(_.multiplied_duration)
else:
inner_durs.append(_.written_duration)
tuplet_dur = sum(inner_durs)
imp_num, imp_den = tuplet.implied_prolation.pair
head_dur = tuplet_dur / imp_den
dur_string = self._assemble_notehead(head_dur)
abjad.tweak(
tuplet
).TupletNumber.text = f'#(tuplet-number::append-note-wrapper(tuplet-number::non-default-tuplet-fraction-text {imp_den} {imp_num}) "{dur_string}")'
[docs]class SegmentMaker:
beaming = False
def __init__(
self,
abbreviations=None,
add_final_grand_pause=True,
barline="||",
beam_pattern="runs",
beam_rests=False,
clef_handlers=None,
colophon=None,
commands=None,
current_directory=None,
cutaway=True,
fermata="scripts.ushortfermata",
instruments=None,
names=None,
name_staves=True,
mm_rests=True,
page_break_counts=None,
rehearsal_mark=None,
score_includes=None,
score_template=None,
segment_name=None,
tempo=((1, 4), 90),
time_signatures=None,
tuplet_bracket_noteheads=True,
):
self.abbreviations = abbreviations
self.add_final_grand_pause = add_final_grand_pause
self.barline = barline
self.beam_pattern = beam_pattern
SegmentMaker.beaming = beam_rests
self.clef_handlers = clef_handlers
self.colophon = colophon
self.commands = commands
self.current_directory = current_directory
self.cutaway = cutaway
self.fermata = fermata
self.instruments = instruments
self.names = names
self.name_staves = name_staves
self.mm_rests = mm_rests
self.page_break_counts = page_break_counts
self.rehearsal_mark = rehearsal_mark
self.score_includes = score_includes
self.score_template = score_template
self.segment_name = segment_name
self.tempo = tempo
self.time_signatures = time_signatures
self.tuplet_bracket_noteheads = tuplet_bracket_noteheads
[docs] def __str__(self):
return abjad.storage(self)
[docs] def __repr__(self):
return abjad.storage(self)
def _add_attachments(self):
print("Adding attachments ...")
if self.colophon is not None:
last_voice = abjad.select(self.score_template).components(abjad.Voice)[
-1
] #
colophon_leaf = abjad.select(last_voice).leaves()[-2] #
abjad.attach(self.colophon, colophon_leaf)
if self.abbreviations is not None:
abbreviations = []
abb = self.abbreviations
mark_abbreviations = [
abjad.Markup(fr"\markup {{ \hcenter-in #12 {_} }}", literal=True)
for _ in abb
]
for x in mark_abbreviations:
abbreviations.append(abjad.MarginMarkup(markup=x))
else:
abbreviations = [_ for _ in range(len(self.instruments))]
if self.names is not None:
names = []
nm = self.names
mark_names = [
abjad.Markup(fr"\markup {{ \hcenter-in #14 {_} }}", literal=True)
for _ in nm
]
for x in mark_names:
names.append(abjad.StartMarkup(markup=x))
else:
names = [_ for _ in range(len(self.instruments))]
metro = abjad.MetronomeMark(self.tempo[0], self.tempo[1])
# metro = abjad.MetronomeMark(custom_markup=metro.make_tempo_equation_markup())#remove if broken
if self.tempo is not None:
for staff in abjad.iterate(
self.score_template["Global Context"]
).components(abjad.Staff):
leaf1 = abjad.select(staff).leaves()[0]
abjad.attach(metro, leaf1)
markup2 = abjad.RehearsalMark(
markup=abjad.Markup(
fr"\markup \bold {{ {self.rehearsal_mark} }}", literal=True
)
)
if self.rehearsal_mark is not None:
for staff in abjad.iterate(
self.score_template["Global Context"]
).components(abjad.Staff):
leaf1 = abjad.select(staff).leaves()[0]
abjad.attach(markup2, leaf1)
bar_line = abjad.BarLine(self.barline)
if self.barline is not None:
for voice in abjad.iterate(self.score_template["Staff Group"]).components(
abjad.Staff # was Voice
):
if self.barline == "|.":
last_leaf = abjad.select(voice).leaves()[-1]
abjad.attach(bar_line, last_leaf)
else:
last_leaf = abjad.select(voice).leaves()[-3]
abjad.attach(bar_line, last_leaf)
if self.clef_handlers is None:
self.clef_handlers = [
None
for _ in abjad.select(self.score_template["Staff Group"]).components(
abjad.Staff
)
]
for abbrev, name, inst, handler, voice in zip(
abbreviations,
names,
self.instruments,
self.clef_handlers,
abjad.select(self.score_template["Staff Group"]).components(
abjad.Staff
), # was Voice
):
first_leaf = abjad.select(voice).leaves()[0]
if self.name_staves is True:
if not isinstance(abbrev, int):
abjad.attach(
abbrev,
first_leaf,
tag=abjad.Tag("applying staff names and clefs"),
)
if not isinstance(name, int):
abjad.attach(
name,
first_leaf,
tag=abjad.Tag("applying staff names and clefs"),
)
abjad.attach(
inst, first_leaf, tag=abjad.Tag("applying staff names and clefs")
)
# abjad.iterpitches.transpose_from_sounding_pitch(voice)
if handler is not None:
handler(voice)
def _add_ending_skips(self):
print("Adding ending skips ...")
last_skip = abjad.select(self.score_template["Global Context"]).leaves()[-1]
override_command = abjad.LilyPondLiteral(
r"\once \override Score.TimeSignature.stencil = ##f", format_slot="before"
)
abjad.attach(
override_command, last_skip, tag=abjad.Tag("applying ending skips")
)
for voice in abjad.select(self.score_template["Staff Group"]).components(
abjad.Voice
):
container = abjad.Container()
sig = self.time_signatures[-1]
leaf_duration = sig.duration / 2
rest_leaf = abjad.Rest(1, multiplier=(leaf_duration))
mult_rest_leaf = abjad.MultimeasureRest(1, multiplier=(leaf_duration))
container.append(rest_leaf)
container.append(mult_rest_leaf)
markup = abjad.Markup(
rf"""\markup \center-align \musicglyph #"{self.fermata}" """,
direction=abjad.Up,
literal=True,
)
start_command = abjad.LilyPondLiteral(
r"\stopStaff \once \override Staff.StaffSymbol.line-count = #0 \startStaff",
format_slot="before",
)
stop_command = abjad.LilyPondLiteral(
r"\stopStaff \startStaff", format_slot="after"
)
rest_literal = abjad.LilyPondLiteral(
r"\once \override Rest.color = #white", "before"
)
mult_rest_literal = abjad.LilyPondLiteral(
r"\once \override MultiMeasureRest.color = #white", "before"
)
penultimate_rest = container[0]
final_rest = container[-1]
abjad.attach(markup, final_rest, tag=abjad.Tag("applying ending skips"))
abjad.attach(
start_command, penultimate_rest, tag=abjad.Tag("applying ending skips")
)
if self.barline == "|.":
stop_command = abjad.LilyPondLiteral(r"\stopStaff", format_slot="after")
abjad.attach(
stop_command, final_rest, tag=abjad.Tag("applying ending skips")
)
else:
abjad.attach(
stop_command, final_rest, tag=abjad.Tag("applying ending skips")
)
abjad.attach(
rest_literal, penultimate_rest, tag=abjad.Tag("applying ending skips")
)
abjad.attach(
mult_rest_literal, final_rest, tag=abjad.Tag("applying ending skips")
)
voice.append(container[:])
[docs] def beam_score(target):
global_skips = [_ for _ in abjad.select(target["Global Context"]).leaves()]
sigs = []
for skip in global_skips:
for indicator in abjad.get.indicators(skip):
if isinstance(indicator, abjad.TimeSignature):
sigs.append(indicator)
print("Beaming meter ...")
for voice in abjad.iterate(target["Staff Group"]).components(abjad.Voice):
for i, shard in enumerate(abjad.mutate.split(voice[:], sigs)):
met = abjad.Meter(sigs[i].pair)
inventories = [
x
for x in enumerate(
abjad.Meter(sigs[i].pair).depthwise_offset_inventory
)
]
if sigs[i].denominator == 4:
beam_meter(
components=shard[:],
meter=met,
offset_depth=inventories[-1][0],
include_rests=SegmentMaker.beaming,
# include_rests=False,
)
else:
beam_meter(
components=shard[:],
meter=met,
offset_depth=inventories[-2][0],
include_rests=SegmentMaker.beaming,
# include_rests=False,
)
for trem in abjad.select(target).components(abjad.TremoloContainer):
if abjad.StartBeam() in abjad.get.indicators(trem[0]):
abjad.detach(abjad.StartBeam(), trem[0])
if abjad.StopBeam() in abjad.get.indicators(trem[-1]):
abjad.detach(abjad.StopBeam(), trem[-1])
def _break_pages(self):
print("Breaking pages ...")
if self.page_break_counts is not None:
lit = abjad.LilyPondLiteral(r"\pageBreak", format_slot="absolute_after")
result = abjad.select(self.score_template["Global Context"]).components(
abjad.Skip
)
result = result.partition_by_counts(
self.page_break_counts, cyclic=True, overhang=False
)
for item in result:
abjad.attach(lit, item[-1])
def _cache_persistent_info(self):
print("Caching persistent info ...")
info = abjad.OrderedDict()
for i, voice in enumerate(
abjad.select(self.score_template["Staff Group"]).components(
abjad.Staff
) # was Voice
):
penultimate_rest = abjad.select(voice).leaves()[-2]
persistent_attachments = abjad.get.indicators(penultimate_rest)
info[f"Voice {i + 1}"] = persistent_attachments
with open(f"{self.current_directory}/.persistent.py", "w") as fp:
info_format = abjad.storage(info)
string = f"import abjad\ninfo = {info_format}"
fp.writelines(string)
def _call_commands(self):
if self.commands is None:
return
print("Calling commands ...")
self.commands = flatten(self.commands)
for group_type, group in itertools.groupby(self.commands, lambda _: type(_)):
if group_type == RhythmCommand:
rhythm_group = [_ for _ in group]
self._make_containers(rhythm_group)
elif group_type == HandlerCommand:
handler_group = [_ for _ in group]
self.call_handlers(handler_group)
elif group_type == str:
for s in group:
if s == "skips":
self._add_ending_skips()
else:
for command in group:
command(self.score_template)
[docs] def call_handlers(self, commands): # bypasses grace notes?
print("Calling handlers ...")
handler_to_value = abjad.OrderedDict()
voice_names = sorted(set(_.voice_name for _ in commands))
command_groups = []
for handler_type, command_group in itertools.groupby(
commands, lambda _: type(_.handler)
):
group = [_ for _ in command_group]
command_groups.append(group)
for group in command_groups:
voice_collections = abjad.OrderedDict()
global_collection = consort.LogicalTieCollection()
for tie in abjad.select(
self.score_template["Global Context"]
).logical_ties():
global_collection.insert(tie)
voice_collections["Global Context"] = global_collection
for voice in abjad.select(self.score_template).components(abjad.Voice):
collection = consort.LogicalTieCollection()
for tie in abjad.select(voice).logical_ties():
collection.insert(tie)
voice_collections[voice.name] = collection
for v_name in voice_names:
voice_command_list = [
command for command in group if command.voice_name == v_name
]
voice_command_list.sort(key=lambda _: _.timespan)
for command in voice_command_list:
voice_tie_collection = voice_collections[command.voice_name]
target_timespan = command.timespan
selection = abjad.Selection(
[
_
for _ in voice_tie_collection.find_logical_ties_starting_during_timespan(
target_timespan
)
]
)
if not selection:
continue
handler = command.handler
handler(selection)
handler_to_value[handler.name] = handler.state()
with open(f"{self.current_directory}/.handlers.py", "w") as fp:
handler_to_value_format = abjad.storage(handler_to_value)
string = f"import abjad\nhandler_to_value = {handler_to_value_format}"
fp.writelines(string)
def _extract_parts(self):
print("Extracting parts ...")
for count, staff in enumerate(
abjad.iterate(self.score_template["Staff Group"]).components(abjad.Staff)
):
t = rf"\tag #'voice{count + 1}"
literal = abjad.LilyPondLiteral(t, format_slot="before")
container = abjad.Container()
abjad.attach(literal, container)
abjad.mutate.wrap(staff, container)
for count, group in enumerate(
abjad.iterate(self.score_template["Staff Group"]).components(
abjad.StaffGroup
)
):
t = rf"\tag #'group{count + 1}"
literal = abjad.LilyPondLiteral(t, format_slot="before")
container = abjad.Container()
abjad.attach(literal, container)
abjad.mutate.wrap(group, container)
def _make_global_context(self):
print("Making global context ...")
for time_signature in self.time_signatures:
skip = abjad.Skip(1, multiplier=(time_signature))
abjad.attach(time_signature, skip, tag=abjad.Tag("scaling time signatures"))
self.score_template["Global Context"].append(skip)
def _make_containers(self, commands):
print("Making containers ...")
def make_container(handler, durations):
selections = handler(durations)
container = abjad.Container([])
container.extend(selections)
return container
voice_names = sorted(set(_.voice_name for _ in commands))
handler_to_value = abjad.OrderedDict()
for voice_name in voice_names:
voice_commands = [_ for _ in commands if _.voice_name == voice_name]
voice_commands.sort(key=lambda _: _.timespan)
for handler, grouper in itertools.groupby(
voice_commands, key=lambda _: _.handler
):
durations = [command.timespan.duration for command in grouper]
container = make_container(handler, durations)
voice = self.score_template[voice_name]
voice.append(container[:])
handler_to_value[handler.name] = handler.return_state()
with open(f"{self.current_directory}/.rhythm.py", "w") as fp:
handler_to_value_format = abjad.storage(handler_to_value)
string = f"import abjad\nhandler_to_value = {handler_to_value_format}"
fp.writelines(string)
def _make_mm_rests(self):
print("Making MM rests ...")
for voice in abjad.iterate(self.score_template["Staff Group"]).components(
abjad.Staff # was Voice
):
leaves = abjad.select(voice).leaves(grace=False)
shards = abjad.mutate.split(leaves, self.time_signatures)
for shard in shards[:-1]:
if not all(isinstance(leaf, abjad.Rest) for leaf in shard):
continue
indicators = abjad.get.indicators(shard[0])
multiplier = abjad.get.duration(shard) / 2
invisible_rest = abjad.Rest(1, multiplier=(multiplier))
rest_literal = abjad.LilyPondLiteral(
r"\once \override Rest.transparent = ##t", "before"
)
abjad.attach(
rest_literal, invisible_rest, tag=abjad.Tag("applying invisibility")
)
for indicator in indicators:
abjad.attach(
indicator, invisible_rest, tag=abjad.Tag("applying indicators")
)
multimeasure_rest = abjad.MultimeasureRest(1, multiplier=(multiplier))
start_command = abjad.LilyPondLiteral(
r"\stopStaff \once \override Staff.StaffSymbol.line-count = #1 \startStaff",
format_slot="before",
)
stop_command = abjad.LilyPondLiteral(
r"\stopStaff \startStaff", format_slot="after"
)
if self.cutaway is True:
abjad.attach(
start_command, invisible_rest, tag=abjad.Tag("applying cutaway")
)
abjad.attach(
stop_command,
multimeasure_rest,
tag=abjad.Tag("applying cutaway"),
)
both_rests = [invisible_rest, multimeasure_rest]
abjad.mutate.replace(shard, both_rests[:])
else:
both_rests = [invisible_rest, multimeasure_rest]
abjad.mutate.replace(shard, both_rests[:])
def _remove_final_grand_pause(self):
if self.add_final_grand_pause is True:
return
print("Removing final grand pause ...")
for staff in abjad.select(self.score_template["Global Context"]).components(
abjad.Staff
):
grand_pause = abjad.mutate.split(staff[:], self.time_signatures)[-1]
for _ in grand_pause:
staff.remove(_)
for voice in abjad.select(self.score_template["Staff Group"]).components(
abjad.Voice
):
grand_pause = abjad.mutate.split(voice[:], self.time_signatures)[-1]
for _ in grand_pause:
voice.remove(_)
def _render_file(self):
print("Rendering file ...")
abjad.SegmentMaker.comment_measure_numbers(self.score_template)
score_block = abjad.Block(name="score")
score_block.items.append(self.score_template)
score_file = abjad.LilyPondFile(
items=[score_block], includes=self.score_includes
)
for leaf in abjad.iterate(self.score_template).leaves():
literal = abjad.LilyPondLiteral("", "absolute_before")
abjad.attach(literal, leaf, tag=None)
for container in abjad.iterate(self.score_template).components(abjad.Container):
if hasattr(container, "_main_leaf"):
literal = abjad.LilyPondLiteral("", "absolute_after")
abjad.attach(literal, container, tag=None)
else:
literal = abjad.LilyPondLiteral("", "absolute_before")
abjad.attach(literal, container, tag=None)
literal = abjad.LilyPondLiteral("", "closing")
abjad.attach(literal, container, tag=None)
directory = self.current_directory
pdf_path = baca.Path(f"{directory}/illustration.pdf")
if pdf_path.exists():
pdf_path.unlink()
print(f"Persisting {pdf_path.trim()} ...")
result = abjad.persist.as_pdf(
score_file,
pdf_path,
# align_tags=79,
)
success = result[3]
if success is False:
print("LilyPond failed!")
if pdf_path.exists():
print(f"Opening {pdf_path.trim()} ...")
os.system(f"open {pdf_path}")
with open(f"{directory}/illustration.ly") as pointer_1:
score_lines = pointer_1.readlines()
build_path = self.current_directory.parent.with_name("build")
build_path /= "score"
lines = score_lines[7:-1] # was 15:-1
with open(f"{build_path}/{self.segment_name}.ly", "w") as fp:
fp.writelines(lines)
[docs] def rewrite_meter(target):
print("Rewriting meter ...")
global_skips = [_ for _ in abjad.select(target["Global Context"]).leaves()]
sigs = []
for skip in global_skips:
for indicator in abjad.get.indicators(skip):
if isinstance(indicator, abjad.TimeSignature):
sigs.append(indicator)
for voice in abjad.select(target["Staff Group"]).components(abjad.Voice):
voice_dur = abjad.get.duration(voice)
time_signatures = sigs[:-1]
durations = [_.duration for _ in time_signatures]
sig_dur = sum(durations)
assert voice_dur == sig_dur, (voice_dur, sig_dur)
shards = abjad.mutate.split(voice[:], durations)
for i, shard in enumerate(shards):
time_signature = sigs[i]
inventories = [
x
for x in enumerate(
abjad.Meter(time_signature.pair).depthwise_offset_inventory
)
]
if time_signature.denominator == 4:
abjad.Meter.rewrite_meter(
shard,
time_signature,
boundary_depth=inventories[-1][0],
rewrite_tuplets=False,
)
else:
abjad.Meter.rewrite_meter(
shard,
time_signature,
boundary_depth=inventories[-2][0],
rewrite_tuplets=False,
)
def _write_optimization_log(self):
print("Writing optimization log ...\n")
times = [self.pre_handlers_time + self.handlers_time + self.post_handlers_time]
segment_time = sum(times)
with open(f"{self.current_directory}/.optimization", "a") as fp:
segment_time = f"Segment runtime: {segment_time} "
segment_time += abjad.String("second").pluralize(segment_time)
pre_handlers_time = f" Pre-handlers runtime: {self.pre_handlers_time} "
pre_handlers_time += abjad.String("second").pluralize(
self.pre_handlers_time
)
handlers_time = f" Handlers runtime: {self.handlers_time} "
handlers_time += abjad.String("second").pluralize(self.handlers_time)
post_handlers_time = f" Post-handlers runtime: {self.post_handlers_time} "
post_handlers_time += abjad.String("second").pluralize(
self.post_handlers_time
)
lines = []
lines.append("")
lines.append("")
lines.append(f"{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
lines.append(segment_time)
lines.append(pre_handlers_time)
lines.append(handlers_time)
lines.append(post_handlers_time)
string = "\n".join(lines)
fp.write(string)
## EXPERIMENTAL
def _extract_voice_info(self, score):
score_pitches = []
score_durations = []
for voice in abjad.select(score).components(abjad.Voice):
pitches = []
durations = []
for tie in abjad.select(voice).logical_ties():
dur = abjad.get.duration(tie)
durations.append(str(dur))
if isinstance(tie[0], abjad.Rest):
sub_pitches = ["Rest()"]
else:
if abjad.get.annotation(tie[0], "ratio"):
sub_pitches = [abjad.get.annotation(tie[0], "ratio")]
else:
sub_pitches = [p.hertz for p in abjad.get.pitches(tie[0])]
if 1 < len(sub_pitches):
pitches.append([str(s) for s in sub_pitches])
elif 0 == len(sub_pitches):
pitches.append("Rest()")
else:
pitches.append(str(sub_pitches[0]))
score_pitches.append(pitches)
score_durations.append(durations)
return [_ for _ in zip(score_pitches, score_durations)]
def _make_sc_file(self):
info = self._extract_voice_info(self.score_template)
lines = "s.boot;\ns.quit;\n\n("
for i, voice in enumerate(info):
lines += f"\n\t// voice {i + 1}\n\t\tPbind(\n\t\t\t\\freq, Pseq(\n"
lines += "\t\t\t\t[\n"
for chord in voice[0]:
lines += "\t\t\t\t\t[\n"
if isinstance(chord, list):
for _ in chord:
if _ == "Rest()":
lines += f"\t\t\t\t\t\t{_},\n"
else:
if _[0] == "[":
lines += f"\t\t\t\t\t\t{_[2:-2]},\n"
else:
lines += f"\t\t\t\t\t\t{_},\n"
else:
if chord == "Rest()":
lines += f"\t\t\t\t\t\t{chord},\n"
else:
if chord[0] == "[":
lines += f"\t\t\t\t\t\t{chord[2:-2]},\n"
else:
lines += f"\t\t\t\t\t\t{chord},\n"
lines += "\t\t\t\t\t],\n"
lines += "\t\t\t\t],\n"
lines += "\t\t\t),\n"
lines += "\t\t\t\\dur, Pseq(\n\t\t\t\t[\n"
for dur in voice[1]:
lines += f"\t\t\t\t\t{quicktions.Fraction(dur) * 4} * {quicktions.Fraction(60, self.tempo[-1])},\n"
lines += "\t\t\t\t]\n"
lines += "\t\t\t,1),\n"
lines += "\t\t\t\\legato, 1,\n\t\t).play;"
lines += ")"
with open(
f'{self.current_directory}/voice_to_sc_{str(datetime.datetime.now()).replace(" ", "-").replace(":", "-").replace(".", "-")}.scd',
"w",
) as fp:
fp.writelines(lines)
[docs] def build_segment(self):
with abjad.Timer() as timer:
self._make_global_context()
self.pre_handlers_time = int(timer.elapsed_time)
with abjad.Timer() as timer:
self._call_commands()
self.handlers_time = int(timer.elapsed_time)
with abjad.Timer() as timer:
if self.mm_rests:
self._make_mm_rests()
self._add_attachments()
self._cache_persistent_info()
self._remove_final_grand_pause()
self._extract_parts()
self._break_pages()
self._render_file()
self.post_handlers_time = int(timer.elapsed_time)
self._write_optimization_log()
[docs]def beam_meter(components, meter, offset_depth, include_rests=True):
r"""
.. container:: example
>>> pre_tuplet_notes = abjad.Staff("c'8 c'8 c'8")
>>> tuplet = abjad.Tuplet((2, 3), "c'8 r8 c'8")
>>> post_tuplet_notes = abjad.Staff("c'8 c'8 c'8")
>>> staff = abjad.Staff()
>>> for _ in [pre_tuplet_notes[:], tuplet, post_tuplet_notes[:]]:
... staff.append(_)
...
>>> evans.beam_meter(components=staff[:], meter=abjad.Meter((4, 4)), offset_depth=1)
>>> score = abjad.Score([staff])
>>> moment = "#(ly:make-moment 1 25)"
>>> abjad.setting(score).proportional_notation_duration = moment
>>> file = abjad.LilyPondFile(
... items=[score],
... includes=["abjad.ily"],
... global_staff_size=16,
... )
...
>>> abjad.show(file) # doctest: +SKIP
.. docs::
>>> print(abjad.lilypond(staff))
\new Staff
{
\override Staff.Stem.stemlet-length = 0.75
c'8
[
\revert Staff.Stem.stemlet-length
c'8
]
c'8
\times 2/3 {
\override Staff.Stem.stemlet-length = 0.75
c'8
[
r8
\revert Staff.Stem.stemlet-length
c'8
]
}
c'8
\override Staff.Stem.stemlet-length = 0.75
c'8
[
\revert Staff.Stem.stemlet-length
c'8
]
}
"""
offsets = meter.depthwise_offset_inventory[offset_depth]
offset_pairs = []
for i, _ in enumerate(offsets[:-1]):
offset_pair = [offsets[i], offsets[i + 1]]
offset_pairs.append(offset_pair)
initial_offset = abjad.get.timespan(components[0]).start_offset
for i, pair in enumerate(offset_pairs):
for i_, item in enumerate(pair):
offset_pairs[i][i_] = item + initial_offset
offset_timespans = [
abjad.Timespan(start_offset=pair[0], stop_offset=pair[1])
for pair in offset_pairs
]
tup_list = [tup for tup in abjad.select(components).components(abjad.Tuplet)]
for t in tup_list:
if isinstance(abjad.get.parentage(t).components[1], abjad.Tuplet) is False:
abjad.beam(
t[:],
beam_rests=include_rests,
stemlet_length=0.75,
beam_lone_notes=False,
selector=abjad.select().leaves(grace=False),
)
else:
continue
non_tup_list = []
for leaf in abjad.select(components).leaves():
if isinstance(abjad.get.parentage(leaf).components[1], abjad.Tuplet) is False:
non_tup_list.append(leaf)
beamed_groups = []
for i in enumerate(offset_timespans):
beamed_groups.append([])
for i, span in enumerate(offset_timespans):
for group in (
abjad.select(non_tup_list[:])
.leaves()
.group_by(
predicate=lambda x: abjad.get.timespan(x).happens_during_timespan(span)
)
):
if abjad.get.timespan(group).happens_during_timespan(span) is True:
beamed_groups[i].append(group[:])
for subgroup in beamed_groups:
subgrouper = abjad.select(subgroup).group_by_contiguity()
for beam_group in subgrouper:
# if not all(isinstance(leaf, abjad.Rest) for leaf in beam_group)
abjad.beam(
beam_group[:],
beam_rests=include_rests,
stemlet_length=0.75,
beam_lone_notes=False,
selector=abjad.select().leaves(grace=False),
)
[docs]def annotate_leaves(score, prototype=abjad.Leaf):
for voice in abjad.select(score).components(abjad.Voice):
if prototype is not None:
abjad.Label(voice).with_indices(prototype=prototype)
else:
abjad.Label(voice).with_indices()