Pitch
This page details the Pitch
class and all its methods.
Creating Pitches
Section titled “Creating Pitches”There are three main ways to create Pitch
vectors from scratch. Using the class constructor, using the static method Pitch.fromChroma
, or using static methods on a parse class to parse a Pitch
from a string format like SPN or LilyPond.
Class Constructor
Section titled “Class Constructor”constructor(w: number, h: number);
Internally a pitch is defined as some number of whole steps and some number of half steps from (the lowest MIDI note). You can directly initialise a Pitch
like so:
let p = new Pitch(25, 10); // coordinates for C4
p.w; // 25p.h; // 10
fromChroma
Section titled “fromChroma”static fromChroma(chroma: number, octave: number): Pitch;
This method allows you to initialise a Pitch
from its “chroma”, the signed distance of a note from C in perfect 5ths, and its octave using SPN numbering:
let p = Pitch.fromChroma(0, 4);
p.w; // 25p.h; // 10
Common Queries
Section titled “Common Queries”The following methods extract information from a Pitch
vector.
get midi(): number;
The standard MIDI number of a Pitch
. Throws an error if outside of the MIDI range of to :
let p = SPN.toPitch("C4");p.midi; // 60
p = SPN.toPitch("C-1");p.midi; // 0
p = SPN.toPitch("G9");p.midi; // 127
p = SPN.toPitch("A-2");p.midi; // Error: Outside of standard MIDI range: -3
p = SPN.toPitch("A9");p.midi; // Error: Outside of standard MIDI range: 129
chroma
Section titled “chroma”get chroma(): number;
The signed distance of a Pitch
from C in perfect fifths.
let p = SPN.toPitch("D3");p.chroma; // 2, because C G D => 0 1 2
p = SPN.toPitch("Eb5");p.chroma; // -3, because Eb Bb F C => -3 -2 -1 0
get pc7(): number;
The 0-indexed 7-tone pitch class of a Pitch
. Equivalent to a numerical representation of its letter name, where C is 0:
let p = SPN.toPitch("C4");p.pc7; // 0
p = SPN.toPitch("F4");p.pc7; // 3
get pc12(): number;
The 12-tone pitch class of a note. C is 0.
let p = SPN.toPitch("C4");p.pc12; // 0
p = SPN.toPitch("E4");p.pc12; // 4
p = SPN.toPitch("Fb4");p.pc12; // also 4, due to enharmonicity in 12TET
letter
Section titled “letter”get letter(): string;
The letter component of a Pitch
vector’s standard name.
let p = SPN.toPitch("E4");p.letter; // "E"
accidental
Section titled “accidental”get accidental(): number;
The accidental component of a Pitch
vector’s standard name, expressed as a signed integer.
- 0 means natural.
- +1 means sharp.
- -1 means flat.
- +2 means double-sharp.
- -2 means double-flat.
- etc. for any arbitrary accidental.
let p = SPN.toPitch("Fx");p.accidental; // 2
p = SPN.toPitch("Eb");p.accidental; // -1
p = SPN.toPitch("Abbb");p.accidental; // -3
octave
Section titled “octave”get octave(): number;
The octave number of a Pitch
(in SPN numbering).
let p = SPN.toPitch("F4");p.octave; // 4
stepsTo
Section titled “stepsTo”stepsTo(p: Pitch): number;
Returns the (signed) number of diatonic steps separating a Pitch
from another passed-in Pitch
.
let p = SPN.toPitch("C4");let q = SPN.toPitch("F#4");
p.stepsTo(q); // 3
q = SPN.toPitch("Ab3");p.stepsTo(q); // -2
isEqual
Section titled “isEqual”isEqual(p: Pitch): boolean;
Returns true if and only if the passed in Pitch
vector and the current vector are identical. Note that this does not mean “are enharmonically equivalent in 12TET”, or “have the same pitch chroma”: they must literally hold the same coordinates.
let p = SPN.toPitch("C4");let q = SPN.toPitch("C5");
p.isEqual(q); // false
q = SPN.toPitch("B3");p.isEqual(q); // false
q = SPN.toPitch("C4");p.isEqual(q); // true
isEnharmonic
Section titled “isEnharmonic”isEnharmonic(p: Pitch, edo?: number): boolean;
Returns true if the passed in Pitch
is enharmonic to the current Pitch
in the passed in EDO tuning. If no second argument is passed this method defaults to 12TET. Notes will still register as enharmonic if they are in different octaves.
let p = SPN.toPitch("C#4");let q = SPN.toPitch("Db4");
p.isEnharmonic(q); // true (in 12TET)p.isEnharmonic(q, 31); // false (in 31EDO)
p = SPN.toPitch("Gbb4");q = SPN.toPitch("Ex4");
p.isEnharmonic(q); // false (in 12TET)p.isEnharmonic(q, 31); // true (in 31EDO)
degreeIn
Section titled “degreeIn”degreeIn(context: TonalContext): number;
Returns the scale degree number (0-indexed, such that the tonic degree is 0) represented by the Pitch
in the passed-in TonalContext
:
let context = TonalContext.fromStrings("C", "major");
let p = SPN.toPitch("C4");p.degreeIn(context); // 0
p = SPN.toPitch("D4");p.degreeIn(context); // 1
p = SPN.toPitch("D#4");p.degreeIn(context); // still 1 (just an altered variant)
alterationIn
Section titled “alterationIn”alterationIn(context: TonalContext): number;
Returns the alteration represented by the Pitch
in the passed-in TonalContext
.
- 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")p.alterationIn(context); // 0, Bb is diatonic in D minor
p = SPN.toPitch("B4")p.alterationIn(context); // 1, B is raised in D minor
p = SPN.toPitch("Bbb4")p.alterationIn(context); // -2, Bbb is too flat for this context
Transformations
Section titled “Transformations”The following methods produce a new vector from the current Pitch
. None of them mutate the original object.
intervalTo
Section titled “intervalTo”intervalTo(p: Pitch): Interval;
Returns the Interval
from the current Pitch to another passed-in vector. Often a more convenient way to access Interval.between
let p = SPN.toPitch("C4");let q = SPN.toPitch("E4");
let m = p.intervalTo(q); // m now holds a major third Intervallet n = Interval.between(p, q); // equivalent
transposeReal
Section titled “transposeReal”transposeReal(m: Interval): Pitch;
Transposes the underlying Pitch
by the passed in Interval vector. Returns the transposed Pitch
as a new vector:
let p = SPN.toPitch("C4");let q = SPN.toPitch("E4");let m = Interval.fromName("M3");
p = p.transposeReal(m);p.isEqual(q); // true
invert
Section titled “invert”invert(axis: Axis): Pitch;
Invert a Pitch
about the passed in Axis
. An Axis
is created from two Pitches
that will be mapped to each other by the inversion across it. Returns the inverted Pitch as a new vector.
let axis = Axis.fromSPN("C4", "G4");let p = SPN.toPitch("Db4");
p = p.invert(axis); // p now points to F#4
snapTo
Section titled “snapTo”snapTo(context: TonalContext): Pitch;
Snaps a Pitch
vector to the diatonic position for that letter-name in
the passed-in TonalContext
. Returns the result as a new Pitch
:
let context = TonalContext.fromStrings("C", "major");let p = SPN.toPitch("F#4");
p = p.snapTo(context); // p now points to F4
transposeDiatonic
Section titled “transposeDiatonic”transposeDiatonic(steps: number, context: TonalContext): Pitch;
Transposes a Pitch
by a generic interval, snapping to diatonic values.
- Interval measured in steps, such that 0 is a unison.
let context = TonalContext.fromStrings("C", "major");let p = SPN.toPitch("F#4");
p = p.transposeDiatonic(4, context); // p now points to C5
Ranges
Section titled “Ranges”range.diatonic
Section titled “range.diatonic”diatonic(from: Pitch, to: Pitch, context: TonalContext): Generator<Pitch, void, unknown>;
Generates a diatonic range of Pitch
vectors between the two boundary Pitch
es passed-in, within the specified TonalContext
let context = TonalContext.fromStrings("C", "major");let p = SPN.toPitch("C4");let q = SPN.toPitch("E5");
Pitch.range.diatonic(p, q, context).forEach(r => console.log(SPN.fromPitch(r)));// C4 D4 E4 F4 G4 A4 B4 C5 D5 E5
range.chromatic
Section titled “range.chromatic”chromatic(from: Pitch, to: Pitch, context: TonalContext): Generator<Pitch, void, unknown>;
Generates a chromatic range of Pitch
vectors between the two boundary Pitch
es passed-in, within the specified TonalContext
. Essentially any all pitches between the boundaries that could occur diatonically or chromatically in a given tonal context.
let context = TonalContext.fromStrings("C", "major");let p = SPN.toPitch("C4");let q = SPN.toPitch("E5");
Pitch.range.chromatic(p, q, context).forEach(r => console.log(SPN.fromPitch(r)));// C4 Db4 C#4 D4 Eb4 D#4 E4 F4 Gb4 F#4 G4 Ab4 G#4 A4 Bb4 A#4 B4 C5 Db5 C#5 D5 Eb5 D#5 E5