-
-
Save josiah-wolf-oberholtzer/1f26b219deff23eb7b779c56f3c047af to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from abjad import * | |
def compute_prime_form(pitch_class_set): | |
rotations = pitch_class_set_to_rotations(pitch_class_set) | |
intervals, pitch_class_set = sorted(rotations.items())[0] | |
inverted_pitch_class_set = [12 - _ for _ in pitch_class_set] | |
inverted_rotations = pitch_class_set_to_rotations(inverted_pitch_class_set) | |
inverted_intervals, inverted_pitch_class_set = sorted( | |
inverted_rotations.items())[0] | |
candidates = { | |
intervals: pitch_class_set, | |
inverted_intervals: inverted_pitch_class_set, | |
} | |
_, prime_form = sorted(candidates.items())[0] | |
return prime_form | |
def pitch_class_set_to_rotations(pitch_class_set): | |
pitch_class_set = sorted(int(_) for _ in pitch_class_set) | |
rotations = {} | |
for _ in range(len(pitch_class_set)): | |
pitch_class_set = sequencetools.rotate_sequence( | |
pitch_class_set, -1) | |
#print('A', pitch_class_set) | |
if pitch_class_set[-1] < pitch_class_set[0]: | |
pitch_class_set[-1] += 12 | |
#print('B', pitch_class_set) | |
intervals = [] | |
for j in range(1, len(pitch_class_set)): | |
intervals.append(pitch_class_set[j] - pitch_class_set[0]) | |
transposed = tuple(_ - pitch_class_set[0] for _ in pitch_class_set) | |
rotations[tuple(intervals)] = tuple(transposed) | |
return rotations | |
def pedaling_to_pedal_markup(pedaling): | |
mapping = {0: '-', -1: '^', 1: 'v'} | |
parts = [mapping[x] for x in pedaling] | |
parts.insert(3, '|') | |
scheme = schemetools.Scheme(''.join(parts), force_quotes=True) | |
return Markup(markuptools.MarkupCommand('harp-pedal', scheme), Down) | |
def pedaling_to_scale(pedaling): | |
pitches = pitchtools.PitchSegment("d' c' b' e' f' g' a'") | |
pairs = sorted(zip(pitches, pedaling)) | |
print('PAIRS:', pairs) | |
pitches = [] | |
for pitch, alteration in pairs: | |
pitches.append(pitch.apply_accidental(alteration)) | |
return pitchtools.PitchSegment(pitches) | |
def make_duplicate_pitch_color_map(scale): | |
index = 0 | |
colors = ['red', 'blue', 'green', 'magenta'] | |
vector = pitchtools.PitchClassVector(scale, pitchtools.NumberedPitchClass) | |
mapping = {} | |
for pitch_class, count in vector.items(): | |
if 1 == count: | |
continue | |
if pitch_class in mapping: | |
continue | |
mapping[pitch_class] = colors[index] | |
index += 1 | |
return mapping | |
def prime_form_to_prime_form_markup(prime_form): | |
pitch_classes = ', '.join(str(int(pc)) for pc in sorted(prime_form)) | |
markup = Markup(pitch_classes, Down).sans().fontsize(-4).bracket() | |
return markup | |
def make_markup(pedaling, prime_form): | |
pedal_markup = pedaling_to_pedal_markup(pedaling) | |
prime_form_markup = prime_form_to_prime_form_markup(prime_form) | |
markup = Markup.center_column([pedal_markup, prime_form_markup], Down) | |
return markup | |
def pedaling_to_measure_and_prime_form(pedaling): | |
scale = pedaling_to_scale(pedaling) | |
pitch_class_set = pitchtools.PitchClassSet( | |
scale, | |
item_class=pitchtools.NumberedPitchClass, | |
) | |
prime_form = compute_prime_form(pitch_class_set) | |
notes = scoretools.make_leaves(scale, [(1, 8)]) | |
measure = Measure((4, 4), notes) | |
mapping = make_duplicate_pitch_color_map(scale) | |
for note in notes: | |
numbered_pitch_class = pitchtools.NumberedPitchClass(note) | |
if numbered_pitch_class not in mapping: | |
continue | |
color = mapping[numbered_pitch_class] | |
color = schemetools.Scheme(['x11-color', "'{}".format(color)]) | |
override(note).note_head.color = color | |
measure.append(Skip((1, 8))) | |
markup = make_markup(pedaling, prime_form) | |
attach(markup, measure[3]) | |
return measure, prime_form | |
def make_staff(): | |
prime_forms_to_measures = {} | |
pedalings = sequencetools.yield_outer_product_of_sequences([[0, 1, -1]] * 7) | |
counter = 0 | |
for pedaling in pedalings: | |
measure, prime_form = pedaling_to_measure_and_prime_form( | |
pedaling) | |
measures = prime_forms_to_measures.setdefault(prime_form, []) | |
measures.append(measure) | |
counter += 1 | |
#if counter == 20: | |
# break | |
staff = Staff() | |
comparator = lambda item: (len(item[0]), item[0]) | |
for prime_form, measures in sorted( | |
prime_forms_to_measures.items(), | |
key=comparator, | |
): | |
for measure in measures: | |
staff.append(measure) | |
return staff | |
def make_lilypond_file(staff): | |
override(staff).stem.transparent = True | |
override(staff).beam.transparent = True | |
override(staff).bar_line.transparent = True | |
override(staff).time_signature.stencil = False | |
override(staff).bar_number.stencil = False | |
override(staff).text_script.parent_alignment_X = Center | |
override(staff).text_script.self_alignment_X = Center | |
lilypond_file = lilypondfiletools.LilyPondFile.new(staff) | |
lilypond_file.paper_block.indent = 0 | |
lilypond_file.paper_block.short_indent = 0 | |
return lilypond_file | |
if __name__ == '__main__': | |
staff = make_staff() | |
lilypond_file = make_lilypond_file(staff) | |
show(lilypond_file) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment