Package: dissonant
This package implements various models of perceptual chord dissonance.
Given a musical chord composed of individual tones, each composed of
partials, a dissonance model provides a score that estimate how
dissonant (harsh) does it sound to human listener.It contains implementation of several models of dissoance with
corrections of errors found in the formulas in the papers. See below.Installationpip install dissonantWhydissonant? PyPI packagedissonancewas already taken.UsageDissonance of a C major chord with harmonic tones in 12-TET tuning with
base 440 Hz using the Sethares1993 model:from dissonant import harmonic_tone, dissonance, pitch_to_freq
freqs, amps = harmonic_tone(pitch_to_freq([0, 4, 7, 12]), n_partials=10)
d = dissonance(freqs, amps, model='sethares1993')Dissonance curve of a sliding interval of two harmonic tones: seenotebooks/dissonance_curve.ipynb.Papers1965, Plomp, Levelt - Tonal Consonance and Critical
Bandwidth1979, Hutchinson, Knopoff - The significance of the acoustic
component of consonance in Western triad1993, Sethares - Local Consonance and the Relationship Between
Timbre and
Scalehttp://sethares.engr.wisc.edu/papers/consance.html2000, Vassilakis - Auditory roughness estimation of complex
spectraPDF is not public, only HTML2001, Vassilakis - Perceptual and Physical Properties of Amplitude
Fluctuation and their Musical
Significance- PhD thesis2002, Cook - Tone of Voice and
Mind- book2004, Sethares - Tuning Timbre Spectrum
Scale- book2005, Vassilakis - Auditory Roughness as Means of Musical
Expression2006, Benson - David Benson Music: A Mathematical
Offering(book
page)2006, Cook, Fujisawa - The Psychophysics of Harmony Perception:
Harmony is a Three-Tone
Phenomenon2009, Cook - Harmony Perception: Harmoniousness Is More Than the Sum
of Interval
Consonance2010, Vassilakis, Kendall - Psychoacoustic and congitive aspects of
auditory roughness - definitions, models and
applications2013, Dillon - Calculating the Dissonance of a Chord according to
Helmholtz theoryExtra2001, McKinney et al. - Neural correlates of musical dissonance in
the inferior
colliculus2007, Vassilakis - SRA: A Web-based Research Tool for Spectral and
Roughness Analysis of Sound
Signalshttp://musicalgorithms.ewu.edu/algorithms/Roughness.htmlhttp://musicalgorithms.ewu.edu/learnmoresra/moremodel.htmlKameoka, A. & Kuriyagawa, M. (1969a). Consonance theory, part I:
Consonance of dyads. Journal of the Acoustical Society of America,
Vol. 45, No. 6, pp. 1451-1459.Kameoka, A. & Kuriyagawa, M. (1969b). Consonance theory, part II:
Consonance of complex tones and its computation method. Journal of
the Acoustical Society of America, Vol. 45, No. 6, pp. 1460-1469.Mashinter, Keith. (1995). Discrepancies in Theories of Sensory
Dissonance arising from the Models of Kameoka & Kuriyagawa, and
Hutchinson & Knopoff. Undergraduate thesis submitted for the double
honours degrees in Applied Mathematics and Music, University of
Waterloo.Phil Keenan ([@ingthrumath](https://twitter.com/ingthrumath))http://meandering-through-mathematics.blogspot.com/2015/03/consonance-and-dissonance-in-music.htmlhttp://meandering-through-mathematics.blogspot.com/2016/06/experimenting-with-sounds-consonance.htmlOther resourceshttps://en.wikipedia.org/wiki/Consonance_and_dissonancehttp://www.res.kutc.kansai-u.ac.jp/~cook/http://www.res.kutc.kansai-u.ac.jp/~cook/05%20harmony.htmlhttp://www.res.kutc.kansai-u.ac.jp/~cook/Harmony.cN. D. Cook, T. Fujisawa and K. Takami. This program is an
improved version of the algorithm reported in Tone of Voice and
Mind (Benjamins, Amsterdam, 2002). It calculates the
dissonance, tension, instability and modality of chords
containing 2-5 tones and assuming the presence of 1-5 upper
partials.video:CogMIR 2013 - Norman D Cook - Visual Display of the
Acoustical Properties of
Harmonyhttp://sethares.engr.wisc.edu/consemi.html#anchor149613http://sethares.engr.wisc.edu/forrestjava/html/TuningAndTimbre.htmlhttp://sethares.engr.wisc.edu/comprog.html- MATLAB, C++, Lisphttps://gist.github.com/endolith/3066664http://www.davideverotta.com/A_folders/Theory/m_dissonance.htmlhttp://www.music-cog.ohio-state.edu/Music829B/diss.htmlModelsThere are several acoustic models of dissonance. They may work on
different data and provide several various metrics. All of them are
based on some perceptual experiments.Input signals:two plain sinusoidal tonestwo harmonic tones - integer multiples of the base frequencychord (two or more) of harmonic tonessignals with continuous spectrumPlompLevelt1965They measured the perceived dissonance of pairs of sinusoidal tones and
of complex tones with 6 harmonics. They provide only experimental data,
not a parametric model.Sethares1993First, he explicitly parameterizes the data of PlompLevelt1965 (for a
pair of sinusoids and for any number of complex tones) with constants
found by fitting the curve to the data.Dissonanced(x)for the differencexbetween a pair of
frequencies. This ignores the absolute frequencies.d(x) = exp(-a * x) - exp(-b * x)
Constants:
a = 3.5
b = 5.75Dissonance for a pair of frequencies(f_1, f_2)(for f_1 < f_2) and
their amplitudes(a_1, a_2). This takes into account the absolute
frequencies.d_maxis just the maximum of d(x).d_pair(f_1, f_2, a_1, a_2) =
  s = d_max / (s_1 * f_1 + s_2)
  x = s * (f_2 - f_1)
  a_1 * a_2 * (exp(-a * x) - exp(-b * x))

Constants:
a = 3.5
b = 5.75
d_max = 0.24
s_1 = 0.0207 # 0.021 in the paper
s_2 = 18.96 # 19 in the paperExpressed in terms ofd(x):d_pair(f_1, f_2, a_1, a_2) = a_1 * a_2 * d((f_2 - f_1) * d_max / (s_1 * f_1 + s_2))Model of dissonance of a single complex tone (containing various
partials) is just the sum of dissonances for all pairs of partials. In
case the partials are integer multiples of a base frequency we can call
tone “harmonic”, otherwise just a general “timbre”.freqs = (f_1, f_2, ... f_n)
amps = (a_1, a_2, ... a_n)
d_complex(freqs, amps) = 0.5 * sum([d(f_i, f_j, a_i, a_j) for i in range(n) for j in range(n)])

or equally:

d_complex(freqs, amps) = sum([
  d(freqs[i], freqs[j], amps[i], amps[j])
  for i in range(n)
  for j in range(n)
  if i < j])Then we can model dissonance of a pair of complex tones (timbres).
Basically it’s still a sum of dissonances of all pairs of partials. We
can however expressfreqs_2 = alpha * freqs_1and plotd_complex()for fixedfreqs_1and varyingalphato get a
“dissonance curve”.Note that this model can be used to model dissonance of intervals of
complex tones, as well as chords (any number of tones).Note the constantss_1,s_2are defined in the paper with low
precision. Better precision is provided in the code by Mr. Sethares:http://sethares.engr.wisc.edu/comprog.html.Questions?Why we just sum the dissonance and not compute mean? Which aggregation
operation makes more sense?Vassilakis2001There’s a modification to thed_pair()function which should make it
depend more reliably on “SPL” and “AF-degree”, in particular put more
accent on the relative amplitudes of interfering sinusoids rather than
on thir absolute amplitudes.Defined in Eq.(6.23) on page 197 (219 in the PDF).a_2 should be >= a_1
d_pair(f_1, f_2, a_1, a_2) =
  (a_1 * a_2) ^ 0.1 * 0.5 *
  ((2 * a_2) / (a_1 + a_2)) ^ 3.11 *
  (exp(-a * s * (f_2 - f_1)) - exp(-b * s * (f_2 - f_1)))

Where:
spl = a_1 * a_2
af_degree = (2 * a_2) / (a_1 + a_2)
a = 3.5
b = 5.75
d_max = 0.24
s_1 = 0.0207
s_2 = 18.96

It can be expressed in terms of d(x):

d_pair(f_1, f_2, a_1, a_2) =
  spl = a_1 * a_2
  af_degree = (2 * a_2) / (a_1 + a_2)
  s = d_max / (s_1 * f_1 + s_2)
  x = s * (f_2 - f_1)
  spl ^ 0.1 * 0.5 * af_degree ^ 3.11 * d(x)In comparison in the Sethares1993 model it is:d_pair(f_1, f_2, a_1, a_2) =
  spl = a_1 * a_2
  s = d_max / (s_1 * f_1 + s_2)
  x = (f_2 - f_1) * x
  spl * d(x)Note that in order to handle the case if a_1 < a_2 we could define:af_degree(a_1, a_2) = (2 * min(a_1, a_2)) / (a_1 + a_2)Looking at Vassilakis2010 this is exactly what they do, extending
Vassilakis2001, otherwise the model is the same.Extending this to a set of complex tones is the same as in Sethares1993
- just aggregated_pair()for all pairs via a sum.Note there’s an additional0.5factor in the Vassilakis2001 model
compared to Sethares1993. IMHO the meaning is to compensate for pairs of
partials being summed twice. In order to make the models comparable we
should remove this term and take only pairs of partials only once in all
models.Cook2002Dissonance model (Cook2002, Appendix 2, page 276 and on, eg. A2-1):Original - wrong:
d_pair(x, a_1, a_2) =
  mu_a = (a_1 + a_2) / 2
  mu_a * (exp(-a * x) - exp(-b * x))

Fixed:
  d_pair(x, a_1, a_2) =
    mu_a = (a_1 + a_2) / 2
    mu_a * c * (exp(-a * x) - exp(-b * x))

Where:
mu_a ... mean amplitude, within [0.0; 1.0]
x ... interval between the frequencies (in semitones)
a = 1.2
b = 4.0
c = 3.5351 = 1 / (np.exp(-1.2) - np.exp(-4))Parameters were “chosen to give a maximal dissonance value at roughly
one quartertone, a dissonance of 1.00 at an interval of one semitone,
and smaller values for larger intervals”.The constantsaandbare quite different than in the
Sethares1993 model. Also the amplitudes are aggregated by mean, instead
of product or minimum. The constantcis missing in the paper but
needs to be on the place as in the formula above.Cook2006Other metrics: dissonance, tension, modality, tonal instability. Based
on three tones, not just an interval of two.Dissonance model (Cook2006, eq. 3).Note that in the article it’s actually defined in a wrong way: - there’s
one more minus sign when applyingbeta_1,beta_2- logarithm
should be of base 2 -log2(f_2 / f_1)needs to be multiplied by 12
to get the 12-TET semitone interval - there should be bracket, not floor
around the difference of exponentials (probably a printing error)Note: for the sake of readability we replace here original greeknuwithv.Original - wrong:
d_pair(f_1, f_2, a_1, a_2) =
  x = log(f_2 / f_1)
  v = a_1 * a_2
  v * beta_3 *
  floor(
    exp(-beta_1 * x ^ gamma) -
    exp(-beta_2 * x ^ gamma))

Fixed:
d_pair(f_1, f_2, a_1, a_2) =
  x = 12 * log2(f_2 / f_1)
  v = a_1 * a_2
  v * beta_3 *
  (exp(beta_1 * x ^ gamma) -
   exp(beta_2 * x ^ gamma))

Constants:
beta_1 = -0.8 # "interval of maximal dissonance"
beta_2 = -1.6 # "steepness of the fall from maximal dissonance"
beta_3 = 4.0
gamma = 1.25Total dissonance of a chords is the sum of dissonances of all pairs of
partials.Cook2009Simplified version of Cook2006. Still the definition is wrong (see
above).There’s no gamma exponent.Original - wrong:
d_pair(f_1, f_2, a_1, a_2) =
  x = log(f_2 / f_1)
  v = a_1 * a_2
  v * beta_3 *
  (exp(-beta_1 * x) -
   exp(-beta_2 * x))

Fixed:
d_pair(f_1, f_2, a_1, a_2) =
  x = 12 * log2(f_2 / f_1)
  v = a_1 * a_2
  v * beta_3 *
  (exp(beta_1 * x) -
   exp(beta_2 * x))

Constants:
beta_1 = -0.8 # "interval of maximal dissonance"
beta_2 = -1.6 # "steepness of the fall from maximal dissonance"
beta_3 = 4.0Tension of a triad (not implemented yet):tension(f_1, f_2, f_3) =
  x = log(f_2 / f_1)
  y = log(f_3 / f_2)
  v = a_1 * a_2 * a_3
  v * exp(-((y - x) / alpha)^2)

alpha = ~0.6