Skip to content

Tutorial Three

anstepp edited this page Dec 7, 2020 · 5 revisions

Tutorial Three: A Major Scale, Another Way

In Tutorial Two we built a major scale by hard coding the pitch classes from a C. We concluded by writing a function that would return a list of notes that was a major scale, based on our selected starting pitch.

There are more sophisticated ways of creating series of pitches, namely by using intervals. In this manner, we can create more abstract representations of compositional content, allowing for more complex uses. This is, in essence, the founding principle of Py2MusicXML - prototyping for compositional purposes.

Below is the previous tutorial code, rewritten to instead focus on interval instead of direct pitch classes.

from py2musicxml.notation import Note, Part, Score

duration = 1
octave = 4

note_list = []

major_scale_intervals = [2, 2, 1, 2, 2, 2, 1]

pc = 0

for interval in major_scale_intervals:
    pc += interval
    note_list.append(Note(duration, octave, pc))

time_signature = [(4,4)]

part = Part(note_list, time_signature)

part_list = [part]

score = Score(part_list)

filename = 'diatonic_scale.musicxml'

score.convert_to_xml(filename)

C Major

The big changes from Tutorial Two are the major_scale_intervals and the for loop.

The list major_scale_intervals, instead of containing the pitch classes for a C major scale, instead consist of distances - whole or half steps. In this case, we will be procedurally following these distances by altering the pc variable in the for loop that follows.

The for loop is similar to the loop in Tutorial Two, but instead of simply substituting the values of the major scale pitch classes, we increase the pc variable by the distance of the current value in the major_scale_intervals variable, as seen below.

pc = 0

for interval in major_scale_intervals:
    pc += interval
    note_list.append(Note(duration, octave, pc))

Just as in Tutorial Two, abstracting this loop into a function allows for more variability and use cases.

def create_major_scale(starting_pc):

    duration = 1
    octave = 4

    scale = []

    pc = starting_pc

    major_scale_intervals = [2, 2, 1, 2, 2, 2, 1]

    for interval in major_scale_intervals:
        pc += interval
        scale.append(Note(duration, octave, pc))

    return scale

E-flat Major

Encapsulating the major scale function like this allows for more expansive uses if one continues to abstract what is possible in the function.

def create_scale(starting_pc, intervals):

    duration = 1
    octave = 4

    scale = []

    pc = starting_pc

    for interval in intervals:
        pc += interval
        scale.append(Note(duration, octave, pc))


    return scale

octatonic = [0,1,2,1,2,1,2]
pentatonic = [0,2,2,3,2,3]

octatonic_scale = create_scale(0, octatonic)
pentatonic_scale = create_scale(0, pentatonic)

Octatonic and Pentatonic Scales

Abstraction like this can be used to generate more sophisticated musical structures, such as Sogetto Cavato, as seen in Tutorial Four.

Clone this wiki locally