Tonality

Full module path: melody_features.feature_definitions.tonality.

Also importable via import melody_features as mf (for example mf.pitch_range).

Tonality feature definitions.

infer_key_from_pitches(pitches, algorithm='krumhansl_schmuckler')[source]

Infer the key of a melody using the specified algorithm.

Parameters:
  • pitches (list[int]) – List of MIDI pitch values

  • algorithm (Literal["krumhansl_schmuckler"], optional) – Key-finding algorithm to use. Default is “krumhansl_schmuckler”.

Returns:

(key_name, mode) e.g., (“C”, “major”) or (None, None) if cannot determine

Return type:

tuple[Optional[str], Optional[str]]

Raises:
  • NotImplementedError – If algorithm is not supported

  • Citations

  • --------

  • Krumhansl (1990)

key(melody, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

The key of the melody, either read from the MIDI file or estimated using the specified key finding algorithm, depending on the key estimation strategy.

Parameters:
  • melody (Melody) – A melody-features Melody object

  • key_estimation (str, optional) – Key estimation strategy, default “infer_if_necessary” Can be “always_read_from_file”, “infer_if_necessary”, or “always_infer”

  • key_finding_algorithm (Literal["krumhansl_schmuckler"], optional) – Key-finding algorithm to use when inferring key. Default is “krumhansl_schmuckler”.

Returns:

  • str – The key of the melody, in the format “key name major/minor”

  • Citation

  • ———-

  • Krumhansl (1990)

Return type:

str

Note

This feature is named keyname in MIDI Toolbox.

tonalness(pitches)[source]

The magnitude of the highest correlation with a precomputed key profile. This key profile is established and elaborated on in Krumhansl (1990).

Parameters:

pitches (list[int]) – List of MIDI pitch values

Returns:

  • float – Magnitude of highest key correlation value

  • Citation

  • ——–

  • Krumhansl (1990)

Return type:

float

tonal_clarity(pitches)[source]

The ratio between the top two key correlation values.

Citation

Temperley (2007)

param pitches:

List of MIDI pitch values

type pitches:

list[int]

returns:

Ratio between highest and second highest key correlation values. Returns 0.0 when top/second correlations are unavailable or near-zero.

rtype:

float

Parameters:

pitches (list[int])

Return type:

float

tonal_spike(pitches)[source]

The ratio between the highest key correlation and the sum of all other correlations.

Parameters:

pitches (list[int]) – List of MIDI pitch values

Returns:

Ratio between highest correlation value and sum of all others. Returns 0.0 when top/other correlations are unavailable or near-zero.

Return type:

float

referent(melody, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

Calculate the referent (pitch-class root) of a melody.

Parameters:
  • melody (Melody) – The melody to analyze

  • key_estimation (Literal['always_read_from_file', 'infer_if_necessary', 'always_infer'])

  • key_finding_algorithm (Literal['krumhansl_schmuckler'])

Returns:

Pitch class in semitones above C for the resolved key root; returns -1 when no key can be resolved.

Return type:

int

tonal_tension(melody, ws=1.0, ss='onset', scale_factor=0.09249316305671976, w=array([0.516, 0.315, 0.168]), alpha=0.75, beta=0.75, tonality_vector=None, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

Computes tension ribbons using the tonal tension algorithm. Provides a means of comparing Chew’s spiral array and the tonal tension profiles produced from Herremans and Chew’s tension ribbons. This returns a dictionary containing the cloud diameter, cloud momentum, tensile strain, ordered by onset.

Parameters:
  • melody (Melody) – A melody-features Melody object.

  • ws (float, optional) – Window size in beats. Default is 1.0 beat.

  • ss (str, optional) – Step size in beats or score position for computing the tonal tension features. Default is “onset” (compute at each unique score position).

  • scale_factor (float, optional) – Multiplicative scaling factor. Default uses the distance between C and B#.

  • w (np.ndarray, optional) – Weights for the chords. Default is [0.516, 0.315, 0.168]

  • alpha (float, optional) – Preference for V vs v chord in minor key (0-1). Default is 0.75.

  • beta (float, optional) – Preference for iv vs IV in minor key (0-1). Default is 0.75.

  • tonality_vector (list, optional) – Pre-computed tonality vector (list of (key_name, correlation) tuples). Default is None.

  • key_estimation (Literal["always_read_from_file", "infer_if_necessary", "always_infer"], optional) – Key estimation strategy: “always_read_from_file”, “infer_if_necessary”, or “always_infer”. Default is “infer_if_necessary”.

  • key_finding_algorithm (Literal["krumhansl_schmuckler"], optional) – Key-finding algorithm to use when inferring key. Default is “krumhansl_schmuckler”.

Returns:

  • dict – Dictionary containing tonal tension values keyed by cloud_diameter, cloud_momentum, and tensile_strain, along with onset-aligned index fields from Partitura.

  • Citation

  • ——–

  • Herremans & Chew (2016)

Return type:

dict

mean_cloud_diameter(melody, ws=1.0, ss='onset', scale_factor=0.09249316305671976, w=array([0.516, 0.315, 0.168]), alpha=0.75, beta=0.75, tonality_vector=None, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

Mean cloud diameter from the tonal tension model. Cloud Diameter provides a measure of the maximal tonal distance of the notes in a chord, following the definition in Partitura.

Parameters:
  • melody (Melody) – A melody-features Melody object

  • ws (float, optional) – Window size in beats. Default is 1.0 beat.

  • ss (str, optional) – Step size or score position for computing the tonal tension features. Default is “onset” (compute at each unique score position).

  • scale_factor (float, optional) – Multiplicative scaling factor. Default uses the distance between C and B#.

  • w (np.ndarray, optional) – Weights for the chords. Default is [0.516, 0.315, 0.168].

  • alpha (float, optional) – Preference for V vs v chord in minor key (0-1). Default is 0.75.

  • beta (float, optional) – Preference for iv vs IV in minor key (0-1). Default is 0.75.

  • tonality_vector (list, optional) – Pre-computed tonality vector (list of (key_name, correlation) tuples). Default is None.

  • key_estimation (str, optional) – Key estimation strategy, default “infer_if_necessary”

  • key_finding_algorithm (Literal["krumhansl_schmuckler"], optional) – Key-finding algorithm to use when inferring key. Default is “krumhansl_schmuckler”.

Returns:

  • float – Mean cloud diameter value

  • Citation

  • ——–

  • Herremans & Chew (2016)

Return type:

float

std_cloud_diameter(melody, ws=1.0, ss='onset', scale_factor=0.09249316305671976, w=array([0.516, 0.315, 0.168]), alpha=0.75, beta=0.75, tonality_vector=None, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

Standard deviation of cloud diameter from the tonal tension model. Cloud Diameter provides a measure of the maximal tonal distance of the notes in a chord, following the definition in Partitura.

Parameters:
  • melody (Melody) – A melody-features Melody object

  • ws (float, optional) – Window size in beats. Default is 1.0 beat.

  • ss (str, optional) – Step size or score position for computing the tonal tension features. Default is “onset” (compute at each unique score position).

  • scale_factor (float, optional) – Multiplicative scaling factor. Default uses the distance between C and B#.

  • w (np.ndarray, optional) – Weights for the chords. Default is [0.516, 0.315, 0.168].

  • alpha (float, optional) – Preference for V vs v chord in minor key (0-1). Default is 0.75.

  • beta (float, optional) – Preference for iv vs IV in minor key (0-1). Default is 0.75.

  • tonality_vector (list, optional) – Pre-computed tonality vector (list of (key_name, correlation) tuples). Default is None.

  • key_estimation (str, optional) – Key estimation strategy, default “infer_if_necessary”

  • key_finding_algorithm (Literal["krumhansl_schmuckler"], optional) – Key-finding algorithm to use when inferring key. Default is “krumhansl_schmuckler”.

Returns:

  • float – Standard deviation of cloud diameter values

  • Citation

  • ——–

  • Herremans & Chew (2016)

Return type:

float

mean_cloud_momentum(melody, ws=1.0, ss='onset', scale_factor=0.09249316305671976, w=array([0.516, 0.315, 0.168]), alpha=0.75, beta=0.75, tonality_vector=None, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

Mean cloud momentum from the tonal tension model.

Cloud momentum captures movement of pitch sets in the spiral array space, weighted by note durations, following the definition in Partitura.

Parameters:
  • melody (Melody) – A melody-features Melody object

  • ws (float, optional) – Window size in beats. Default is 1.0 beat.

  • ss (str, optional) – Step size or score position for computing the tonal tension features. Default is “onset” (compute at each unique score position).

  • scale_factor (float, optional) – Multiplicative scaling factor. Default uses the distance between C and B#.

  • w (np.ndarray, optional) – Weights for the chords. Default is [0.516, 0.315, 0.168].

  • alpha (float, optional) – Preference for V vs v chord in minor key (0-1). Default is 0.75.

  • beta (float, optional) – Preference for iv vs IV in minor key (0-1). Default is 0.75.

  • tonality_vector (list, optional) – Pre-computed tonality vector (list of (key_name, correlation) tuples). Default is None.

  • key_estimation (str, optional) – Key estimation strategy, default “infer_if_necessary”

  • key_finding_algorithm (Literal["krumhansl_schmuckler"], optional) – Key-finding algorithm to use when inferring key. Default is “krumhansl_schmuckler”.

Returns:

  • float – Mean cloud momentum value

  • Citation

  • ——–

  • Herremans & Chew (2016)

Return type:

float

std_cloud_momentum(melody, ws=1.0, ss='onset', scale_factor=0.09249316305671976, w=array([0.516, 0.315, 0.168]), alpha=0.75, beta=0.75, tonality_vector=None, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

Standard deviation of cloud momentum from the tonal tension model. Cloud Momentum provides a measure of movement of pitch sets in the spiral array space, weighted by note durations, following the definition in Partitura.

Parameters:
  • melody (Melody) – A melody-features Melody object

  • ws (float, optional) – Window size in beats. Default is 1.0 beat.

  • ss (str, optional) – Step size or score position for computing the tonal tension features. Default is “onset” (compute at each unique score position).

  • scale_factor (float, optional) – Multiplicative scaling factor. Default uses the distance between C and B#.

  • w (np.ndarray, optional) – Weights for the chords. Default is [0.516, 0.315, 0.168].

  • alpha (float, optional) – Preference for V vs v chord in minor key (0-1). Default is 0.75.

  • beta (float, optional) – Preference for iv vs IV in minor key (0-1). Default is 0.75.

  • tonality_vector (list, optional) – Pre-computed tonality vector (list of (key_name, correlation) tuples). Default is None.

  • key_estimation (str, optional) – Key estimation strategy, default “infer_if_necessary”

  • key_finding_algorithm (Literal["krumhansl_schmuckler"], optional) – Key-finding algorithm to use when inferring key. Default is “krumhansl_schmuckler”.

Returns:

  • float – Standard deviation of cloud momentum values

  • Citation

  • ——–

  • Herremans & Chew (2016)

Return type:

float

mean_tensile_strain(melody, ws=1.0, ss='onset', scale_factor=0.09249316305671976, w=array([0.516, 0.315, 0.168]), alpha=0.75, beta=0.75, tonality_vector=None, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

Mean tensile strain from the tonal tension model. Tensile strain provides a measure of the distance between the local and global tonal context, following the definition in Partitura.

Parameters:
  • melody (Melody) – A melody-features Melody object

  • ws (float, optional) – Window size in beats. Default is 1.0 beat.

  • ss (str, optional) – Step size or score position for computing the tonal tension features. Default is “onset” (compute at each unique score position).

  • scale_factor (float, optional) – Multiplicative scaling factor. Default uses the distance between C and B#.

  • w (np.ndarray, optional) – Weights for the chords. Default is [0.516, 0.315, 0.168].

  • alpha (float, optional) – Preference for V vs v chord in minor key (0-1). Default is 0.75.

  • beta (float, optional) – Preference for iv vs IV in minor key (0-1). Default is 0.75.

  • tonality_vector (list, optional) – Pre-computed tonality vector (list of (key_name, correlation) tuples). Default is None.

  • key_estimation (str, optional) – Key estimation strategy, default “infer_if_necessary”

  • key_finding_algorithm (Literal["krumhansl_schmuckler"], optional) – Key-finding algorithm to use when inferring key. Default is “krumhansl_schmuckler”.

Returns:

  • float – Mean tensile strain value

  • Citation

  • ——–

  • Herremans & Chew (2016)

Return type:

float

std_tensile_strain(melody, ws=1.0, ss='onset', scale_factor=0.09249316305671976, w=array([0.516, 0.315, 0.168]), alpha=0.75, beta=0.75, tonality_vector=None, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

Standard deviation of tensile strain from the tonal tension model. Tensile strain provides a measure of the distance between the local and global tonal context, following the definition in Partitura.

Parameters:
  • melody (Melody) – A melody-features Melody object

  • ws (float, optional) – Window size in beats. Default is 1.0 beat.

  • ss (str, optional) – Step size or score position for computing the tonal tension features. Default is “onset” (compute at each unique score position).

  • scale_factor (float, optional) – Multiplicative scaling factor. Default uses the distance between C and B#.

  • w (np.ndarray, optional) – Weights for the chords. Default is [0.516, 0.315, 0.168].

  • alpha (float, optional) – Preference for V vs v chord in minor key (0-1). Default is 0.75.

  • beta (float, optional) – Preference for iv vs IV in minor key (0-1). Default is 0.75.

  • tonality_vector (list, optional) – Pre-computed tonality vector (list of (key_name, correlation) tuples). Default is None.

  • key_estimation (str, optional) – Key estimation strategy, default “infer_if_necessary”

  • key_finding_algorithm (Literal["krumhansl_schmuckler"], optional) – Key-finding algorithm to use when inferring key. Default is “krumhansl_schmuckler”.

Returns:

  • float – Standard deviation of tensile strain values

  • Citation

  • ——–

  • Herremans & Chew (2016)

Return type:

float

tonalness_histogram(pitches)[source]

Equal-width histogram of all 24 Krumhansl-Schmuckler key correlations.

Parameters:

pitches (list[int]) – List of MIDI pitch values

Returns:

  • dict – Bin-range strings mapped to counts (24 correlations, 24 bins).

  • Citation

  • ——–

  • Krumhansl (1990)

Return type:

dict

inscale(melody, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

For each pitch in the melody, returns 1 if the pitch is in the estimated key’s scale, or 0 if it deviates from the scale.

Parameters:
  • melody (Melody) – The melody to analyze

  • key_estimation (Literal['always_read_from_file', 'infer_if_necessary', 'always_infer'])

  • key_finding_algorithm (Literal['krumhansl_schmuckler'])

Returns:

List of 0/1 values indicating if each pitch is in the estimated key’s scale

Return type:

list[int]

proportion_inscale(melody, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

The proportion of notes in the melody that are in the scale of the estimated key.

Parameters:
  • melody (Melody) – The melody to analyze

  • key_estimation (Literal['always_read_from_file', 'infer_if_necessary', 'always_infer'])

  • key_finding_algorithm (Literal['krumhansl_schmuckler'])

Returns:

Proportion of notes in the scale

Return type:

float

longest_monotonic_conjunct_scalar_passage(melody, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

The longest sequence of consecutive notes that fit within the estimated key’s scale that move in the same direction.

Parameters:
  • melody (Melody) – The melody to analyze

  • key_estimation (Literal['always_read_from_file', 'infer_if_necessary', 'always_infer'])

  • key_finding_algorithm (Literal['krumhansl_schmuckler'])

Returns:

Length of the longest monotonic conjunct scalar passage

Return type:

int

longest_conjunct_scalar_passage(melody, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

The longest sequence of consecutive notes that fit within the estimated key’s scale. For example, a melody estimated to be in C major with notes C, D, E, F, G would have a longest conjunct scalar passage of 5.

Parameters:
  • melody (Melody) – The melody to analyze

  • key_estimation (Literal['always_read_from_file', 'infer_if_necessary', 'always_infer'])

  • key_finding_algorithm (Literal['krumhansl_schmuckler'])

Returns:

Length of the longest conjunct scalar passage

Return type:

int

proportion_conjunct_scalar(melody, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

Longest conjunct scalar passage length divided by total note count.

Parameters:
  • melody (Melody) – The melody to analyze

  • key_estimation (Literal['always_read_from_file', 'infer_if_necessary', 'always_infer'])

  • key_finding_algorithm (Literal['krumhansl_schmuckler'])

Returns:

Proportion of conjunct scalar motion

Return type:

float

proportion_scalar(melody, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

Longest monotonic conjunct scalar passage length divided by total notes.

Parameters:
  • melody (Melody) – The melody to analyze

  • key_estimation (Literal['always_read_from_file', 'infer_if_necessary', 'always_infer'])

  • key_finding_algorithm (Literal['krumhansl_schmuckler'])

Returns:

Proportion of scalar motion

Return type:

float

mode(melody, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

Calculate the mode (major/minor) of a melody, either read from the MIDI file or estimated using the specified key finding algorithm.

Parameters:
  • melody (Melody) – The melody to analyze

  • key_estimation (str, optional) – Key estimation strategy, default “infer_if_necessary” Can be “always_read_from_file”, “infer_if_necessary”, or “always_infer”

  • key_finding_algorithm (Literal["krumhansl_schmuckler"], optional) – Key-finding algorithm to use when inferring mode. Default is “krumhansl_schmuckler”.

Returns:

The mode: “major” or “minor”

Return type:

str

get_tonality_features(melody, key_estimation='infer_if_necessary', key_finding_algorithm='krumhansl_schmuckler')[source]

Compute all tonality-based features for a melody.

Parameters:
  • melody (Melody) – The melody to analyze

  • key_estimation (Literal["always_read_from_file", "infer_if_necessary", "always_infer"], optional) – Key estimation strategy. Default is “infer_if_necessary”.

  • key_finding_algorithm (Literal["krumhansl_schmuckler"], optional) – Key-finding algorithm to use when inferring key. Default is “krumhansl_schmuckler”.

Returns:

Dictionary of tonality-based feature values

Return type:

Dict