Skip to content

Instantly share code, notes, and snippets.

@josiah-wolf-oberholtzer
Forked from jefftrevino/harpChart.py
Last active August 1, 2016 19:20
Show Gist options
  • Save josiah-wolf-oberholtzer/1f26b219deff23eb7b779c56f3c047af to your computer and use it in GitHub Desktop.
Save josiah-wolf-oberholtzer/1f26b219deff23eb7b779c56f3c047af to your computer and use it in GitHub Desktop.
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