Skip to content

TonalContext

A TonalContext provides a context against which to evaluate the position and behaviour of notes “in” a key or mode. It exposes the following public fields:

tonic: {
letter: string;
accidental: number;
chroma: number;
};
mode: number;
constructor(chroma: number, mode: number);

You can create a TonalContext directly via the class constructor function, from the pitch chroma of its tonic degree, and a “mode number” using the following table:

Lydian0
Ionian1
Mixolydian2
Dorian3
Aeolian4
Phrygian5
Locrian6
let context = new TonalContext(2, 1); // D major
let p = SPN.toPitch("F4");
p.snapTo(context); // F#4;
static fromStrings(tonic: string, mode: string): TonalContext;

The more intuitive way to initialise a TonalContext. Takes the name of the tonic pitch class and the name of the mode as strings. Can be “major” or “minor”, or a traditional modal name like “dorian” or “ionian”. Case-insensitive.

let context = TonalContext.fromStrings("G", "minor");
let p = SPN.toPitch("B4");
p.snapTo(context); // Bb4

Most of TonalContext’s methods are usually more conveniently accessed from the Pitch vectors they act on rather than the class itself, but are available nonetheless. TonalContext.degreeChroma is only available as a method directly on a TonalContext instance, however.

degreeNumber(p: Pitch): number;

Returns the scale degree (0-indexed, such that the tonic is 0) of the passed in Pitch vector in the current TonalContext.

let context = TonalContext.fromStrings("C", "major");
let p = SPN.toPitch("C4");
context.degreeNumber(p); // 0
p = SPN.toPitch("D4");
context.degreeNumber(p); // 1
p = SPN.toPitch("D#4");
context.degreeNumber(p); // still 1 (just an altered variant)
degreeAlteration(p: Pitch): number;

Returns the scale degree alteration represented by a Pitch in the current TonalContext, e.g. C# is a raised note in the key of C major.

  • 0 represents a diatonic degree.
  • +1 and -1 represent raised and lowered degrees respectively.
  • +2 and -2 represent degrees too sharp or too flat to belong in a given TonalContext.
let context = TonalContext.fromStrings("G", "minor");
let p = SPN.toPitch("Bb4")
context.degreeAlteration(p); // 0, Bb is diatonic in D minor
p = SPN.toPitch("B4")
context.degreeAlteration(p); // 1, B is raised in D minor
p = SPN.toPitch("Bbb4")
context.degreeAlteration(p); // -2, Bbb is too flat for this context
degreeChroma(degree: number): number;

Returns the chroma of the diatonic version of the degree number passed in (0-indexed, so the tonic is 0).

let context = TonalContext.fromStrings("G", "minor");
context.degreeChroma(0); // 1, the chroma of G
context.degreeChroma(1); // 3, the chroma of A
context.degreeChroma(2); // -2, the chroma of Bb
context.degreeChroma(3); // 0, the chroma of C
snapDiatonic(p: Pitch): Pitch;

Snaps the passed-in Pitch vector to the diatonic position for that letter-name in the current TonalContext. Returns the result as a new Pitch:

let context = TonalContext.fromStrings("C", "major");
let p = SPN.toPitch("F#4");
p = context.snapDiatonic(p); // p now points to F4