Scales, diatonic¶
Scale literals¶
Use string input to “write” a scale directly:
>>> voice = abjad.Voice("a'4 b' cs'' d'' e'' fs'' gs'' a''", name="Example_Voice")
>>> staff = abjad.Staff([voice], name="Example_Staff")
>>> note = abjad.select.note(staff, 0)
>>> key_signature = abjad.KeySignature(
... abjad.NamedPitchClass("a"), abjad.Mode("major")
... )
>>> abjad.attach(key_signature, note)
>>> abjad.show(staff)
A function to generate one octave of a scale¶
Use a list of intervals to model the structure of any scale. Here’s the interval structure of C major, G major, D major and every other scale in the major mode:
>>> intervals = "M2 M2 m2 M2 M2 M2 m2".split()
>>> intervals = [abjad.NamedInterval(_) for _ in intervals]
This function makes one octave of any scale:
>>> def make_scale(tonic, intervals):
... pitches = []
... pitch = abjad.NamedPitch(tonic)
... pitches.append(pitch)
... for interval in intervals:
... pitch = pitch + interval
... pitches.append(pitch)
... return pitches
...
Here’s one octave of a major scale, rooted on C:
>>> make_scale("c'", intervals)
[NamedPitch("c'"), NamedPitch("d'"), NamedPitch("e'"), NamedPitch("f'"), NamedPitch("g'"), NamedPitch("a'"), NamedPitch("b'"), NamedPitch("c''")]
Here’s one octave of a natural minor scale, rooted on C:
>>> intervals = "M2 m2 M2 M2 m2 M2 M2".split()
>>> intervals = [abjad.NamedInterval(_) for _ in intervals]
>>> make_scale("c'", intervals)
[NamedPitch("c'"), NamedPitch("d'"), NamedPitch("ef'"), NamedPitch("f'"), NamedPitch("g'"), NamedPitch("af'"), NamedPitch("bf'"), NamedPitch("c''")]
Here’s one octave of a Dorian scale, rooted on C:
>>> intervals = "M2 m2 M2 M2 M2 m2 M2".split()
>>> intervals = [abjad.NamedInterval(_) for _ in intervals]
>>> make_scale("c'", intervals)
[NamedPitch("c'"), NamedPitch("d'"), NamedPitch("ef'"), NamedPitch("f'"), NamedPitch("g'"), NamedPitch("a'"), NamedPitch("bf'"), NamedPitch("c''")]
Illustrating one scale at a time¶
Change pitches to notes like this:
>>> intervals = "M2 M2 m2 M2 M2 M2 m2".split()
>>> intervals = [abjad.NamedInterval(_) for _ in intervals]
>>> pitches = make_scale("a'", intervals)
>>> notes = [abjad.Note(_, (1, 4)) for _ in pitches]
>>> voice = abjad.Voice(notes, name="Example_Voice")
>>> staff = abjad.Staff([voice], name="Example_Staff")
>>> note = abjad.select.note(staff, 0)
>>> key_signature = abjad.KeySignature(
... abjad.NamedPitchClass("a"), abjad.Mode("major")
... )
>>> abjad.attach(key_signature, note)
>>> abjad.show(staff)
Reverse scale direction like this:
>>> notes = [abjad.Note(_, (1, 4)) for _ in reversed(pitches)]
>>> voice = abjad.Voice(notes, name="Example_Voice")
>>> staff = abjad.Staff([voice], name="Example_Staff")
>>> note = abjad.select.note(staff, 0)
>>> key_signature = abjad.KeySignature(
... abjad.NamedPitchClass("a"), abjad.Mode("major")
... )
>>> abjad.attach(key_signature, note)
>>> abjad.show(staff)
Join ascending and descending segments like this:
>>> notes = [abjad.Note(_, (1, 4)) for _ in pitches]
>>> descending = [abjad.Note(_, (1, 4)) for _ in reversed(pitches)]
>>> descending = descending[1:]
>>> notes.extend(descending)
>>> voice = abjad.Voice(notes, name="Example_Voice")
>>> staff = abjad.Staff([voice], name="Example_Staff")
>>> note = abjad.select.note(staff, 0)
>>> key_signature = abjad.KeySignature(
... abjad.NamedPitchClass("a"), abjad.Mode("major")
... )
>>> abjad.attach(key_signature, note)
>>> abjad.show(staff)
A function to enumerate many scales¶
This dictionary changes mode to intervals:
>>> mode_to_intervals = {
... "major": "M2 M2 m2 M2 M2 M2 m2",
... "minor": "M2 m2 M2 M2 m2 M2 M2",
... "dorian": "M2 m2 M2 M2 M2 m2 M2",
... }
This function enumerates scales in any mode:
>>> def make_score(tonics, mode_name):
... voice = abjad.Voice(name="Example_Voice")
... staff = abjad.Staff([voice], name="Example_Staff")
... score = abjad.Score([staff], name="Score")
... intervals = mode_to_intervals[mode_name]
... intervals = intervals.split()
... intervals = [abjad.NamedInterval(_) for _ in intervals]
... for tonic in tonics:
... pitch_class = abjad.NamedPitchClass(tonic)
... mode = abjad.Mode(mode_name)
... key_signature = abjad.KeySignature(pitch_class, mode)
... pitches = []
... ascending = make_scale(tonic, intervals)
... pitches.extend(ascending)
... descending = make_scale(tonic, intervals)
... descending = list(reversed(descending))[1:]
... pitches.extend(descending)
... notes = [abjad.Note(_, (1, 4)) for _ in pitches]
... name = notes[0].written_pitch.get_name(locale="us")
... name = name[:-1]
... string = rf'\markup {{ "{name} {mode_name}" }}'
... markup = abjad.Markup(string)
... abjad.attach(markup, notes[0], direction=abjad.UP)
... bar_line = abjad.BarLine("||")
... abjad.attach(bar_line, notes[-1])
... string = r"\markup \transparent A"
... strut = abjad.Markup(string)
... bundle = abjad.bundle(strut, r"- \tweak staff-padding 8")
... abjad.attach(bundle, notes[-1], direction=abjad.UP)
... voice.extend(notes)
... time_signature = abjad.TimeSignature((15, 4))
... abjad.attach(time_signature, voice[0])
... return score
...
This LilyPond code styles output:
>>> preamble = r"""#(set-global-staff-size 14)
...
... \layout {
... \context {
... \Score
... \override BarNumber.stencil = ##f
... \override TextScript.staff-padding = 3
... \override TimeSignature.stencil = ##f
... }
... indent = 0
... }
... """
Twelve major scales¶
>>> string = "C4 G4 D4 A4 E4 B4 F4 Bb4 Eb4 Ab4 Db4 Gb4"
>>> tonics = string.split()
>>> score = make_score(tonics, "major")
>>> lilypond_file = abjad.LilyPondFile([preamble, score])
>>> abjad.show(lilypond_file)
Twelve minor scales¶
>>> string = "C4 G4 D4 A4 E4 B4 F4 Bb4 Eb4 Ab4 Db4 Gb4"
>>> tonics = string.split()
>>> score = make_score(tonics, "minor")
>>> lilypond_file = abjad.LilyPondFile([preamble, score])
>>> abjad.show(lilypond_file)
Twelve Dorian scales¶
>>> string = "C4 G4 D4 A4 E4 B4 F4 Bb4 Eb4 Ab4 Db4 Gb4"
>>> tonics = string.split()
>>> score = make_score(tonics, "dorian")
>>> lilypond_file = abjad.LilyPondFile([preamble, score])
>>> abjad.show(lilypond_file)