def makeRowScore(data: Optional = None, write: bool = False, title: Optional[str] = 'Rows_in_the_Repertoire'): """ Makes a score setting out any number of rows in musical notation, annotated with labelled pitch classes and work metadata (title, composer etc). Note: unlike the rest of this repository, this requires an external music21: library """ from music21 import bar, expressions, layout, metadata, meter, serial, stream score = stream.Score() part = stream.Part() part.insert(0, meter.TimeSignature('12/4')) # Not essential count = 1 if not data: jsonPath = os.path.join('.', 'Repertoire_Anthology', 'rows_in_the_repertoire.json') with open(jsonPath) as jsonFile: data = json.load(jsonFile) for d in data: # dict entry = data[d] m = stream.Measure(number=count) count += 1 row = serial.pcToToneRow(entry['P0']) for x in row.notes: x.stemDirection = 'none' x.lyric = x.pitch.pitchClass m.insert(x.offset, x) text = f"{entry['Composer']}: {entry['Work']}, {entry['Year']}" # ", {entry['P0']}" m.insert(0, expressions.TextExpression(text)) part.append(m) score.append(part) # Layout for thisMeasure in score.parts[0].getElementsByClass('Measure'): thisMeasure.insert(bar.Barline(type='final', location='right')) thisMeasure.insert(layout.SystemLayout(isNew=True)) # Metadata score.insert(0, metadata.Metadata()) score.metadata.composer = 'Various composers and analysts, compiled by Mark Gotham' score.metadata.title = title if write: w = os.path.join('.', 'Repertoire_Anthology', title + '.mxl') score.write(fmt='mxl', fp=w) else: return score
def generate_cycle_pairs_for_all_string_sets(root_scale, tonic, pair_type, voicing=Voicing.Closed): cycle_pairs = [] for strings in iteration_function(voicing): string_set = (GuitarRange.get_string(strings[0]), GuitarRange.get_string(strings[1]), GuitarRange.get_string(strings[2])) tonic_triad = generate_tonic_triad(root_scale, tonic, string_set, voicing) cycle_pair = generate_cycle_pair(root_scale, tonic_triad, pair_type, string_set, voicing) # populate all the metadata to make the titling and everything automatic cycle_pair.metadata = metadata.Metadata() cycle_pair.metadata.title = "Cycle " + pair_type + " Progression in " + root_scale.name + "\nString Set: " + \ str(string_set[0].number.value) + "-" + str(string_set[1].number.value) + "-" + \ str(string_set[2].number.value) + "; " + Voicing.to_string(voicing) + " Triads" cycle_pair.metadata.composer = "Graham Smith" cycle_pair.metadata.date = "2020" # add system breaks at the end each measure to make it one measure per line cycle_pair.definesExplicitSystemBreaks = True for s in cycle_pair.getElementsByClass(stream.Stream): measures = s.getElementsByClass(stream.Measure) for m in measures: m.append(layout.SystemLayout(isNew=True)) cycle_pair.definesExplicitSystemBreaks = True # add notation to make the score easier to read cycle_pair[1][0][1].lyric = "First cycle starts" cycle_pair[2][0][0].lyric = "Second cycle starts" # add an ending measure to make the line breaks and formatting a bit cleaner/more consistent m = stream.Measure() last_chord_as_list = list(tonic_triad.pitches) check_note_ranges_and_transpose(last_chord_as_list, string_set) last_chord = chord.Chord(last_chord_as_list) last_chord.duration = duration.Duration(4.0) m.append(last_chord) r = note.Rest() r.duration = duration.Duration(2.0) m.append(r) cycle_pair[2].append(m) ensure_unique_chords(cycle_pair) # cycle_pair.show() cycle_pairs.append(cycle_pair) return cycle_pairs
def testDynamicsPositionB(self): import random from music21 import stream, note, layout s = stream.Stream() for i in range(6): m = stream.Measure(number=i + 1) m.append(layout.SystemLayout(isNew=True)) m.append(note.Rest(type='whole')) s.append(m) for m in s.getElementsByClass('Measure'): offsets = [x * .25 for x in range(16)] random.shuffle(offsets) offsets = offsets[:4] for o in offsets: d = Dynamic('mf') d.positionVertical = 20 m.insert(o, d)
def testDynamicsPositionB(self): import random from music21 import stream from music21 import note from music21 import layout s = stream.Stream() for i in range(6): m = stream.Measure(number=i + 1) m.append(layout.SystemLayout(isNew=True)) m.append(note.Rest(type='whole')) s.append(m) stream_iterator = s.getElementsByClass(stream.Measure) for m in stream_iterator: offsets = [x * 0.25 for x in range(16)] random.shuffle(offsets) offsets = offsets[:4] for o in offsets: d = Dynamic('mf') d.style.absoluteY = 20 m.insert(o, d)