Skip to content

Pitch

This page details all the functions that create, transform or query Pitch vectors.

Pitch vectors can be initialised directly:

Pitch p = { 25, 10 }; // initialised to middle C

It’s often more convenient, however, to be able to create a new Pitch from existing vectors, or to assign them values by parsing strings in accepted formats.

Pitch pitch_from_chroma(int chroma, int octave);

Creates a Pitch vector from a specified chroma (signed distance from C in 5ths) and octave (following SPN numbering).

These functions query commonly required information from Pitch vectors.

int pitch_chroma(Pitch p);

Returns the number of perfect fifths (signed) separating a Pitch from C. Abstracts octave information away.

int pitch_letter(Pitch p);

Returns the offset of a Pitch’s letter from ‘A’ / ‘a’. It’s up to you to add ‘A’ or ‘a’ to the result to get an actual character though!

int pitch_accidental(Pitch p);

Returns a Pitch’s accidental as an offset from \natural, so:

\sharp\sharp2
\sharp1
\natural0
\flat-1
\flat\flat-2

etc. for triple sharps/flats and beyond.

int pitch_octave(Pitch p);

Returns the SPN octave number of a Pitch. Middle C is 4.

int pitch_midi(Pitch p);

Returns the standard MIDI value for a given Pitch.

int pitch_pc12(Pitch p);

Returns the 12-tone pitch class number of a Pitch (C is 0).

static inline int steps_between(Pitch p, Pitch q);

Returns the (signed) number of diatonic steps between two pitches. Calculated as qpq - p.

bool pitches_equal(Pitch p, Pitch q);

Predicate function that checks whether two Pitch vectors are equal.

bool pitches_enharmonic(Pitch m, Pitch n, int edo);

Predicate function that checks whether two Pitch vectors are enharmonics in a given EDO tuning system. The third parameter ‘edo’ is for passing in the tuning system to check against. So for example:

Pitch p, q;
pitch_from_spn("C#4", &p);
pitch_from_spn("Db4", &q);
pitches_enharmonic(p, q, 12); // true; C# and Db are enharmonic in 12tet
pitches_enharmonic(p, q, 31); // false; C# and Db are not enharmonic in 31tet
pitch_from_spn("Gbb4", &p);
pitch_from_spn("Ex4", &q);
pitches_enharmonic(p, q, 31); // true; Gbb and Ex are enharmonic in 31tet
pitches_enharmonic(p, q, 12); // false; Gbb and Ex are not enharmonic in 12tet
Pitch pitch_highest(Pitch arr[], int len, TuningMap T);

This function takes a Pitch[] array and a TuningMap, and returns the highest Pitch in the array. Uses the passed-in TuningMap to decide which Pitch is “higher” than the others.

char *names[10] = {"B#3", "C4", "D4", "D#4", "Eb4",
"E4", "F4", "Ex4", "F#4", "Gb4"};
Pitch arr[10];
for (int i = 0; i < 10; i++) {
pitch_from_spn(names[i], arr + i);
}
TuningMap T = tuning_map_from_edo(12, (Pitch){29, 11}, 440);
Pitch highest = pitch_highest(arr, 10, T); // highest now holds Gb4
Pitch pitch_lowest(Pitch arr[], int len, TuningMap T);

This function takes a Pitch[] array and a TuningMap, and returns the lowest Pitch in the array. Uses the passed-in TuningMap to decide which Pitch is “lower” than the others.

char *names[10] = {"B#3", "C4", "D4", "D#4", "Eb4",
"E4", "F4", "Ex4", "F#4", "Gb4"};
Pitch arr[10];
for (int i = 0; i < 10; i++) {
pitch_from_spn(names[i], arr + i);
}
TuningMap T = tuning_map_from_edo(12, (Pitch){29, 11}, 440);
Pitch lowest = pitch_lowest(arr, 10, T); // lowest now holds B#3
Pitch pitch_nearest(Pitch p, Pitch arr[], int len, TuningMap T);

This function takes a Pitch, a Pitch[] array and a TuningMap, and returns the closest Pitch in the array to the Pitch passed via the first argument. Uses the passed-in TuningMap to decide which Pitch is “closer” than the others.

char *names[10] = {"B#3", "C4", "D4", "D#4", "Eb4",
"E4", "F4", "Ex4", "F#4", "Gb4"};
Pitch arr[10];
for (int i = 0; i < 10; i++) {
pitch_from_spn(names[i], arr + i);
}
Pitch target;
pitch_from_spn("Gbb4", &target);
TuningMap T = tuning_map_from_edo(12, (Pitch){29, 11}, 440);
Pitch nearest = pitch_nearest(target, arr, 10, T); // nearest now holds F4
T = tuning_map_from_edo(31, reference, 440);
nearest = pitch_nearest(target, arr, 10, T); // nearest now holds Ex4
Pitch transpose_real(Pitch p, Interval m);

This function takes a Pitch and an Interval, and returns a new Pitch formed by their sum.

MirrorAxis axis_create(Pitch p, Pitch q);

Creates a MirrorAxis about which to invert a Pitch by adding two Pitch vectors together. To be used in conjunction with pitch_invert.

Pitch pitch_invert(Pitch p, MirrorAxis a);

Invert a Pitch about a passed in MirrorAxis, returning a new Pitch (the result of subtracting p from a). Inversion is real, not diatonic.

StandardPitch pitch_to_standard(Pitch p);

Converts from Meantonal’s standard Pitch representation to the StandardPitch representation. Useful as a preliminary step to rendering standard notation.

Pitch pitch_from_standard(StandardPitch p);

Converts from the StandardPitch type back to a regular Pitch vector. Conversion in this direction is generally less used, but the StandardPitch might represent a convenient parsing target to then extract Pitch vectors from if you are working with a notation format Meantonal’s parse functions don’t cover.