Root finding
ParncuttRootAnalysis
¶
ParncuttRootAnalysis(
chord: Union[List[int], Chord, PitchCollection],
root_support_weights: Union[str, Dict[int, float]] = "v2",
exponent: float = 0.5,
)
Parncutt's (1988) model for finding the root of a chord.
Author: Peter Harrison
Parameters:
-
chord(Union[List[int], Chord, PitchCollection]) –The chord to analyze. Can be represented as: A list of MIDI pitches representing a chord, A Chord object, or A PitchCollection object.
-
root_support_weights(Union[str, Dict[int, float]], default:'v2') –Identifies the root support weights to use. "v1" uses the original weights from Parncutt (1988), "v2" uses the updated weights from Parncutt (2006), by default "v2".
-
exponent(float, default:0.5) –Exponent to be used when computing root ambiguities, by default 0.5.
Attributes:
-
pc_set(set) –The chord's pitch class set.
-
root(int) –The pitch class of the derived chord root.
-
root_ambiguity(float) –A measure of how ambiguous the root is.
-
root_strengths(List[float]) –Root support values for each pitch class.
-
root_support_weights(Union[str, Dict[int, float]]) –Identifies the root support weights to use. "v1" uses the original weights from Parncutt (1988), "v2" uses the updated weights from Parncutt (2006), by default "v2".
-
exponent(float) –Exponent to be used when computing root ambiguities, by default 0.5.
Examples:
>>> # Major triad
>>> analysis = ParncuttRootAnalysis([60, 64, 67]) # C major triad
>>> analysis.root
0
>>> analysis.root_ambiguity
1.9
>>> # Minor triad
>>> analysis = ParncuttRootAnalysis([60, 63, 67]) # C minor triad
>>> analysis.root
0
>>> analysis.root_ambiguity
2.1
>>> # Dominant seventh
>>> analysis = ParncuttRootAnalysis([60, 64, 67, 70]) # C7
>>> analysis.root
0
>>> analysis.root_ambiguity
2.1
>>> # Diminished triad (more ambiguous)
>>> analysis = ParncuttRootAnalysis([60, 63, 66]) # C diminished
>>> analysis.root
0
>>> analysis.root_ambiguity
2.5
>>> # Using original Parncutt (1988) weights
>>> analysis = ParncuttRootAnalysis([60, 64, 67, 70], root_support_weights="v1")
>>> analysis.root
0
>>> analysis.root_ambiguity
2.1
>>> # Using a Chord object as the input
>>> from amads.core.basics import Chord, Note
>>> chord = Chord(Note(pitch=60), # C4
... Note(pitch=64), # E4
... Note(pitch=67)) # G4
>>> analysis = ParncuttRootAnalysis(chord)
>>> analysis.root
0
>>> # Using a PitchCollection object as the input
>>> from amads.core.pitch import Pitch, PitchCollection
>>> pitch_collection = PitchCollection([Pitch(x) for x in ["D4", "F4", "A4"]])
>>> analysis = ParncuttRootAnalysis(pitch_collection)
>>> analysis.root
2
See as_distribution() method for plotting root support weights.
References
[1] Parncutt, R. (1988). Revision of Terhardt's psychoacoustical model of the root(s) of a musical chord. Music Perception, 6(1), 65–93. https://doi.org/10.2307/40285416
[2] Parncutt, R. (2006). Commentary on Cook & Fujisawa's "The Psychophysics of Harmony Perception: Harmony is a Three-Tone Phenomenon." Empirical Musicology Review, 1(4), 204–209.
Source code in amads/harmony/root_finding/parncutt.py
118 119 120 121 122 123 124 125 126 127 128 129 130 131 | |
Functions¶
load_chord
staticmethod
¶
load_chord(
chord: Union[List[int], Chord, PitchCollection],
) -> tuple[set[int], set[int]]
Normalize the chord argument into pitch and pitch-class sets.
Accepts a list of MIDI numbers, a Chord, or a PitchCollection and returns a set of MIDI pitches along with its pitch-class set. Raises on unknown types, empty chords, or undefined pitches.
Source code in amads/harmony/root_finding/parncutt.py
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | |
load_root_support_weights
¶
load_root_support_weights(
root_support_weights: Union[str, Dict[int, float]],
) -> Dict[int, float]
Resolve the root-support weight table.
Accepts a version key ("v1" or "v2") or a custom mapping of interval->weight values. Raises ValueError for unknown versions.
Source code in amads/harmony/root_finding/parncutt.py
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | |
get_root_ambiguity
¶
get_root_ambiguity() -> float
Measure ambiguity as the normalized sum of root strengths.
Source code in amads/harmony/root_finding/parncutt.py
192 193 194 195 196 197 | |
as_distribution
¶
as_distribution() -> Distribution
Convert root support weights to a (plot-able) Distribution
Returns:
-
Distribution–containing (12) root support weights
Examples:
>>> analysis = ParncuttRootAnalysis([0, 4, 7])
>>> import matplotlib.pyplot as plt
>>> fig = analysis.as_distribution().plot(show=False)
>>> # plt.show() # in an interactive session, this will display the plot
>>> plt.close(fig) # in a non-interactive session, this is needed to close the plot
Source code in amads/harmony/root_finding/parncutt.py
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | |