So I’ve talked about classes representing the ideas of note and interval. This post I’ll cover Voices.ScaleClass, Voices.Scale and Voices.KeySignature.

A scale is an interesting interplay between notes and intervals within an octave. As an example, the notes C D E F G A B constitute the C major scale. But it is the set of intervals between these notes (the sum of which is an octave) which defines the essence of what it is to be a major scale. Specifically, these intervals are: maj2 maj2 min2 maj2 maj2 maj2 min2. Typically the intervals are summed cumulatively with the initial perfect unison and the final perfect octave assumed, so: maj2 maj3 per4 per5 maj6 maj7. That set of intervals, measured out above a tonic note, locates and names the notes of any major scale.

Although a scale can be viewed as a series of notes or as a series of intervals, it’s practical to see the notes as the scale and the intervals as the scale class. So a scale can be defined as a sequence of notes, chosen out of the possible notes in the octave, and beginning on a tonic. And a scale class can be defined as the class of scales between whose notes appears the same sequence of intervals. As I’ve said, that sequence of intervals sums to an octave no matter what the scale class.

So, let’s look at a C# class representing scale class. Greatly simplified, Voices.ScaleClass looks like:

public class ScaleClass

{

static ScaleClass()

{

_majorScale = new ScaleClass("Major", "2 3 4 5 6 7");

_dorianMode = new ScaleClass("Dorian Mode", "2 b3 4 5 6 b7");

...

_bluesScale = new ScaleClass("Blues Scale", "b3 4 b5 5 b7");

}

public static ScaleClass MajorScale { get { return _majorScale; } } static ScaleClass _majorScale;

public static ScaleClass IonianMode { get { return _majorScale; } }

public static ScaleClass DorianMode { get { return _dorianMode; } } static ScaleClass _dorianMode;

...

public static ScaleClass BluesScale { get { return _bluesScale; } } static ScaleClass _bluesScale;

internal ScaleClass(string longName, string intervalsString)

{

_longName = longName;

_intervalsString = intervalsString;

}

internal string _longName;

internal string _intervalsString;

}

The only real value this class provides is a place to store the _intervalsString field. This field contains a string representation of the sequence of intervals which give the scale class its identity. These intervals have the format of an optional sharp or flat symbol followed by a digital interval quantity. Alternatively they can be the solfeggio symbols: do, di, ra, re, ..., te, ti.

The class Voices.Scale has a constructor with the signature:

public Scale(ScaleClass scaleClass, Note tonic)

What this constructor is interested in is the tonic note and the _intervalsString from scaleClass. It String.Splits intervalsString into a string[] the elements of which it then takes in turn and obtains an Interval from by means of the following method on Voices.Interval:

internal static Interval Interval.LookUp(string abbreviation)

The constructor proceeds to add each resulting Interval in turn to the tonic Note, thus obtaining the degrees of the scale. It’s a little more complicated than than because Voices.Scale is actually composed of a doubly-linked cyclic list of Voices.ScaleTone.

So, of the list nodes (i.e. the tones) in a Scale, those which are ScaleDiatones are the ones corresponding to the tonic note and the notes reached by adding the intervals of the scale class to it. All the rest are plain old ScaleTones.

In order to support enumeration, Voices.Scale implements IEnumerable and its implementation of IEnumerable.GetEnumerator simply returns a new instance of the Voices.ScaleToneEnumerator class. As is typical, ScaleToneEnumerator Resets its Current state to ‘one before the first element’ which in this case is the tone at the 11-o’clock position. It implements MoveNext by moving to ScaleTone.Sharp until the 11-o’clock position is reached again.

The last class I’ll talk about in this post is KeySignature. A key signature is a pattern of sharp or flat symbols written at the beginning of a musical staff to indicate which degrees of the scale are not natural. Strictly speaking, distinct key signatures exist only for fifteen major scales. Minor scales and the remaining modes re-use the key signatures of their relative major scale. I omitted this detail above for the sake of clarity, but one of the arguments to the ScaleClass constructor is a value from the ScaleClass.Mode enumeration, which looks like this:

public enum Mode

{

Major = 0,

Dorian = 6,

Phrygian = 5,

Lydian = 4,

Mixolydian = 3,

Minor = 2,

Locrian = 1

}

There is a field for each mode. The value given to each field represents the degree of the corresponding mode on which the mode’s relative major begins. For example, you may know that the major mode begins on the minor mode’s third degree. This is why Minor has the value 2 (where 0 means first). The constructor of the class Voices.Scale reads n, the integer value of its ScaleClass’s Mode, and then finds the nth degree of the scale being constructed. This way it identifies the major scale on which the scale is based and it is that scale which donates its key signature.

The important parts of the KeySignature class are:

public Note[] Accidentals

{

get

{

return _accidentals;

}

}

internal Note[] _accidentals;

public bool Sharps

{

get { return _sharps; }

}

internal bool _sharps = true;

The Accidentals property returns an array of Notes in key signature order, and the Sharps property tells us whether the accidentals are sharps or flats.