{ "info": { "author": "Bohumir Zamecnik", "author_email": "bohumir.zamecnik@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Operating System :: MacOS :: MacOS X", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", "Topic :: Multimedia :: Sound/Audio :: Analysis" ], "description": "Chord dissonance models\n=======================\n\nThis package implements various models of perceptual chord dissonance.\nGiven a musical chord composed of individual tones, each composed of\npartials, a dissonance model provides a score that estimate how\ndissonant (harsh) does it sound to human listener.\n\nIt contains implementation of several models of dissoance with\ncorrections of errors found in the formulas in the papers. See below.\n\nInstallation\n------------\n\n::\n\n pip install dissonant\n\nWhy ``dissonant``? PyPI package ``dissonance`` was already taken.\n\nUsage\n-----\n\nDissonance of a C major chord with harmonic tones in 12-TET tuning with\nbase 440 Hz using the Sethares1993 model:\n\n::\n\n from dissonant import harmonic_tone, dissonance, pitch_to_freq\n freqs, amps = harmonic_tone(pitch_to_freq([0, 4, 7, 12]), n_partials=10)\n d = dissonance(freqs, amps, model='sethares1993')\n\nDissonance curve of a sliding interval of two harmonic tones: see\n`notebooks/dissonance_curve.ipynb `__.\n\nPapers\n------\n\n- `1965, Plomp, Levelt - Tonal Consonance and Critical\n Bandwidth `__\n- 1979, Hutchinson, Knopoff - The significance of the acoustic\n component of consonance in Western triad\n- `1993, Sethares - Local Consonance and the Relationship Between\n Timbre and\n Scale `__\n\n - http://sethares.engr.wisc.edu/papers/consance.html\n\n- `2000, Vassilakis - Auditory roughness estimation of complex\n spectra `__\n\n - PDF is not public, only HTML\n\n- `2001, Vassilakis - Perceptual and Physical Properties of Amplitude\n Fluctuation and their Musical\n Significance `__\n - PhD thesis\n- `2002, Cook - Tone of Voice and\n Mind `__\n - book\n- `2004, Sethares - Tuning Timbre Spectrum\n Scale `__ - book\n- `2005, Vassilakis - Auditory Roughness as Means of Musical\n Expression `__\n- `2006, Benson - David Benson Music: A Mathematical\n Offering `__\n (`book\n page `__)\n- `2006, Cook, Fujisawa - The Psychophysics of Harmony Perception:\n Harmony is a Three-Tone\n Phenomenon `__\n- `2009, Cook - Harmony Perception: Harmoniousness Is More Than the Sum\n of Interval\n Consonance `__\n- `2010, Vassilakis, Kendall - Psychoacoustic and congitive aspects of\n auditory roughness - definitions, models and\n applications `__\n- `2013, Dillon - Calculating the Dissonance of a Chord according to\n Helmholtz theory `__\n\nExtra\n~~~~~\n\n- `2001, McKinney et al. - Neural correlates of musical dissonance in\n the inferior\n colliculus `__\n- `2007, Vassilakis - SRA: A Web-based Research Tool for Spectral and\n Roughness Analysis of Sound\n Signals `__\n\n - http://musicalgorithms.ewu.edu/algorithms/Roughness.html\n - http://musicalgorithms.ewu.edu/learnmoresra/moremodel.html\n\n- Kameoka, A. & Kuriyagawa, M. (1969a). Consonance theory, part I:\n Consonance of dyads. Journal of the Acoustical Society of America,\n Vol. 45, No.\u00a06, pp.\u00a01451-1459.\n- Kameoka, A. & Kuriyagawa, M. (1969b). Consonance theory, part II:\n Consonance of complex tones and its computation method. Journal of\n the Acoustical Society of America, Vol. 45, No.\u00a06, pp.\u00a01460-1469.\n- Mashinter, Keith. (1995). Discrepancies in Theories of Sensory\n Dissonance arising from the Models of Kameoka & Kuriyagawa, and\n Hutchinson & Knopoff. Undergraduate thesis submitted for the double\n honours degrees in Applied Mathematics and Music, University of\n Waterloo.\n- Phil Keenan ([@ingthrumath](https://twitter.com/ingthrumath))\n\n - http://meandering-through-mathematics.blogspot.com/2015/03/consonance-and-dissonance-in-music.html\n - http://meandering-through-mathematics.blogspot.com/2016/06/experimenting-with-sounds-consonance.html\n\nOther resources\n---------------\n\n- https://en.wikipedia.org/wiki/Consonance_and_dissonance\n- http://www.res.kutc.kansai-u.ac.jp/~cook/\n\n - http://www.res.kutc.kansai-u.ac.jp/~cook/05%20harmony.html\n - http://www.res.kutc.kansai-u.ac.jp/~cook/Harmony.c\n\n - N. D. Cook, T. Fujisawa and K. Takami. This program is an\n improved version of the algorithm reported in Tone of Voice and\n Mind (Benjamins, Amsterdam, 2002). It calculates the\n dissonance, tension, instability and modality of chords\n containing 2-5 tones and assuming the presence of 1-5 upper\n partials.\n - video: `CogMIR 2013 - Norman D Cook - Visual Display of the\n Acoustical Properties of\n Harmony `__\n\n- http://sethares.engr.wisc.edu/consemi.html#anchor149613\n- http://sethares.engr.wisc.edu/forrestjava/html/TuningAndTimbre.html\n- http://sethares.engr.wisc.edu/comprog.html - MATLAB, C++, Lisp\n- https://gist.github.com/endolith/3066664\n- http://www.davideverotta.com/A_folders/Theory/m_dissonance.html\n- http://www.music-cog.ohio-state.edu/Music829B/diss.html\n\nModels\n------\n\nThere are several acoustic models of dissonance. They may work on\ndifferent data and provide several various metrics. All of them are\nbased on some perceptual experiments.\n\nInput signals:\n\n- two plain sinusoidal tones\n- two harmonic tones - integer multiples of the base frequency\n- chord (two or more) of harmonic tones\n- signals with continuous spectrum\n\nPlompLevelt1965\n~~~~~~~~~~~~~~~\n\nThey measured the perceived dissonance of pairs of sinusoidal tones and\nof complex tones with 6 harmonics. They provide only experimental data,\nnot a parametric model.\n\nSethares1993\n~~~~~~~~~~~~\n\nFirst, he explicitly parameterizes the data of PlompLevelt1965 (for a\npair of sinusoids and for any number of complex tones) with constants\nfound by fitting the curve to the data.\n\nDissonance ``d(x)`` for the difference ``x`` between a pair of\nfrequencies. This ignores the absolute frequencies.\n\n::\n\n d(x) = exp(-a * x) - exp(-b * x)\n Constants:\n a = 3.5\n b = 5.75\n\nDissonance for a pair of frequencies ``(f_1, f_2)`` (for f_1 < f_2) and\ntheir amplitudes ``(a_1, a_2)``. This takes into account the absolute\nfrequencies. ``d_max`` is just the maximum of d(x).\n\n::\n\n d_pair(f_1, f_2, a_1, a_2) =\n s = d_max / (s_1 * f_1 + s_2)\n x = s * (f_2 - f_1)\n a_1 * a_2 * (exp(-a * x) - exp(-b * x))\n\n Constants:\n a = 3.5\n b = 5.75\n d_max = 0.24\n s_1 = 0.0207 # 0.021 in the paper\n s_2 = 18.96 # 19 in the paper\n\nExpressed in terms of ``d(x)``:\n\n::\n\n 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))\n\nModel of dissonance of a single complex tone (containing various\npartials) is just the sum of dissonances for all pairs of partials. In\ncase the partials are integer multiples of a base frequency we can call\ntone \u201charmonic\u201d, otherwise just a general \u201ctimbre\u201d.\n\n::\n\n freqs = (f_1, f_2, ... f_n)\n amps = (a_1, a_2, ... a_n)\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)])\n\n or equally:\n\n d_complex(freqs, amps) = sum([\n d(freqs[i], freqs[j], amps[i], amps[j])\n for i in range(n)\n for j in range(n)\n if i < j])\n\nThen we can model dissonance of a pair of complex tones (timbres).\nBasically it\u2019s still a sum of dissonances of all pairs of partials. We\ncan however express ``freqs_2 = alpha * freqs_1`` and plot\n``d_complex()`` for fixed ``freqs_1`` and varying ``alpha`` to get a\n\u201cdissonance curve\u201d.\n\nNote that this model can be used to model dissonance of intervals of\ncomplex tones, as well as chords (any number of tones).\n\nNote the constants ``s_1``, ``s_2`` are defined in the paper with low\nprecision. Better precision is provided in the code by Mr.\u00a0Sethares:\nhttp://sethares.engr.wisc.edu/comprog.html.\n\nQuestions?\n^^^^^^^^^^\n\nWhy we just sum the dissonance and not compute mean? Which aggregation\noperation makes more sense?\n\nVassilakis2001\n~~~~~~~~~~~~~~\n\nThere\u2019s a modification to the ``d_pair()`` function which should make it\ndepend more reliably on \u201cSPL\u201d and \u201cAF-degree\u201d, in particular put more\naccent on the relative amplitudes of interfering sinusoids rather than\non thir absolute amplitudes.\n\nDefined in Eq.(6.23) on page 197 (219 in the PDF).\n\n::\n\n a_2 should be >= a_1\n d_pair(f_1, f_2, a_1, a_2) =\n (a_1 * a_2) ^ 0.1 * 0.5 *\n ((2 * a_2) / (a_1 + a_2)) ^ 3.11 *\n (exp(-a * s * (f_2 - f_1)) - exp(-b * s * (f_2 - f_1)))\n\n Where:\n spl = a_1 * a_2\n af_degree = (2 * a_2) / (a_1 + a_2)\n a = 3.5\n b = 5.75\n d_max = 0.24\n s_1 = 0.0207\n s_2 = 18.96\n\n It can be expressed in terms of d(x):\n\n d_pair(f_1, f_2, a_1, a_2) =\n spl = a_1 * a_2\n af_degree = (2 * a_2) / (a_1 + a_2)\n s = d_max / (s_1 * f_1 + s_2)\n x = s * (f_2 - f_1)\n spl ^ 0.1 * 0.5 * af_degree ^ 3.11 * d(x)\n\nIn comparison in the Sethares1993 model it is:\n\n::\n\n d_pair(f_1, f_2, a_1, a_2) =\n spl = a_1 * a_2\n s = d_max / (s_1 * f_1 + s_2)\n x = (f_2 - f_1) * x\n spl * d(x)\n\nNote that in order to handle the case if a_1 < a_2 we could define:\n\n::\n\n af_degree(a_1, a_2) = (2 * min(a_1, a_2)) / (a_1 + a_2)\n\nLooking at Vassilakis2010 this is exactly what they do, extending\nVassilakis2001, otherwise the model is the same.\n\nExtending this to a set of complex tones is the same as in Sethares1993\n- just aggregate ``d_pair()`` for all pairs via a sum.\n\nNote there\u2019s an additional ``0.5`` factor in the Vassilakis2001 model\ncompared to Sethares1993. IMHO the meaning is to compensate for pairs of\npartials being summed twice. In order to make the models comparable we\nshould remove this term and take only pairs of partials only once in all\nmodels.\n\nCook2002\n~~~~~~~~\n\nDissonance model (Cook2002, Appendix 2, page 276 and on, eg. A2-1):\n\n::\n\n Original - wrong:\n d_pair(x, a_1, a_2) =\n mu_a = (a_1 + a_2) / 2\n mu_a * (exp(-a * x) - exp(-b * x))\n\n Fixed:\n d_pair(x, a_1, a_2) =\n mu_a = (a_1 + a_2) / 2\n mu_a * c * (exp(-a * x) - exp(-b * x))\n\n Where:\n mu_a ... mean amplitude, within [0.0; 1.0]\n x ... interval between the frequencies (in semitones)\n a = 1.2\n b = 4.0\n c = 3.5351 = 1 / (np.exp(-1.2) - np.exp(-4))\n\nParameters were \u201cchosen to give a maximal dissonance value at roughly\none quartertone, a dissonance of 1.00 at an interval of one semitone,\nand smaller values for larger intervals\u201d.\n\nThe constants ``a`` and ``b`` are quite different than in the\nSethares1993 model. Also the amplitudes are aggregated by mean, instead\nof product or minimum. The constant ``c`` is missing in the paper but\nneeds to be on the place as in the formula above.\n\nCook2006\n~~~~~~~~\n\nOther metrics: dissonance, tension, modality, tonal instability. Based\non three tones, not just an interval of two.\n\nDissonance model (Cook2006, eq. 3).\n\nNote that in the article it\u2019s actually defined in a wrong way: - there\u2019s\none more minus sign when applying ``beta_1``, ``beta_2`` - logarithm\nshould be of base 2 - ``log2(f_2 / f_1)`` needs to be multiplied by 12\nto get the 12-TET semitone interval - there should be bracket, not floor\naround the difference of exponentials (probably a printing error)\n\nNote: for the sake of readability we replace here original greek ``nu``\nwith ``v``.\n\n::\n\n Original - wrong:\n d_pair(f_1, f_2, a_1, a_2) =\n x = log(f_2 / f_1)\n v = a_1 * a_2\n v * beta_3 *\n floor(\n exp(-beta_1 * x ^ gamma) -\n exp(-beta_2 * x ^ gamma))\n\n Fixed:\n d_pair(f_1, f_2, a_1, a_2) =\n x = 12 * log2(f_2 / f_1)\n v = a_1 * a_2\n v * beta_3 *\n (exp(beta_1 * x ^ gamma) -\n exp(beta_2 * x ^ gamma))\n\n Constants:\n beta_1 = -0.8 # \"interval of maximal dissonance\"\n beta_2 = -1.6 # \"steepness of the fall from maximal dissonance\"\n beta_3 = 4.0\n gamma = 1.25\n\nTotal dissonance of a chords is the sum of dissonances of all pairs of\npartials.\n\nCook2009\n~~~~~~~~\n\nSimplified version of Cook2006. Still the definition is wrong (see\nabove).\n\nThere\u2019s no gamma exponent.\n\n::\n\n Original - wrong:\n d_pair(f_1, f_2, a_1, a_2) =\n x = log(f_2 / f_1)\n v = a_1 * a_2\n v * beta_3 *\n (exp(-beta_1 * x) -\n exp(-beta_2 * x))\n\n Fixed:\n d_pair(f_1, f_2, a_1, a_2) =\n x = 12 * log2(f_2 / f_1)\n v = a_1 * a_2\n v * beta_3 *\n (exp(beta_1 * x) -\n exp(beta_2 * x))\n\n Constants:\n beta_1 = -0.8 # \"interval of maximal dissonance\"\n beta_2 = -1.6 # \"steepness of the fall from maximal dissonance\"\n beta_3 = 4.0\n\nTension of a triad (not implemented yet):\n\n::\n\n tension(f_1, f_2, f_3) =\n x = log(f_2 / f_1)\n y = log(f_3 / f_2)\n v = a_1 * a_2 * a_3\n v * exp(-((y - x) / alpha)^2)\n\n alpha = ~0.6\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/bzamecnik/dissonant", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "dissonant", "package_url": "https://pypi.org/project/dissonant/", "platform": "", "project_url": "https://pypi.org/project/dissonant/", "project_urls": { "Homepage": "https://github.com/bzamecnik/dissonant" }, "release_url": "https://pypi.org/project/dissonant/0.1.1/", "requires_dist": [ "numpy" ], "requires_python": "", "summary": "Musical chord dissonance models", "version": "0.1.1" }, "last_serial": 3729049, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "0ebe670c59768e1f7e4da6fdd44778f0", "sha256": "0070cd009ec78ac72c7741c49fad3f4c6c1f12d860d4ae9e15f8a739edc082c0" }, "downloads": -1, "filename": "dissonant-0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "0ebe670c59768e1f7e4da6fdd44778f0", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 12161, "upload_time": "2018-04-03T10:09:29", "url": "https://files.pythonhosted.org/packages/b8/8d/015b6c51698024e690b3637559a5eb906a08afe054dfb2c5686ce0aa72cf/dissonant-0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "815abbecf6fa91c99f709d705e4a631c", "sha256": "8bd4b3f9fc31a2680651d9e90cae0e0d056929686908a0f0fb974bbb641441e8" }, "downloads": -1, "filename": "dissonant-0.1.tar.gz", "has_sig": false, "md5_digest": "815abbecf6fa91c99f709d705e4a631c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7997, "upload_time": "2018-04-03T10:09:15", "url": "https://files.pythonhosted.org/packages/2c/4e/17fa22caa713f0d2ff7a2e8d8a62139ca4efb68d2261a1f3c849d6efb7b2/dissonant-0.1.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "367bb78ad2a940abe6496225a9ad1a2d", "sha256": "e815cf882c519eb07875c7129ec8fd78b0d0e52add5c019b391285d12e03382e" }, "downloads": -1, "filename": "dissonant-0.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "367bb78ad2a940abe6496225a9ad1a2d", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 15405, "upload_time": "2018-04-03T10:21:51", "url": "https://files.pythonhosted.org/packages/af/93/52409808732e7157456bdf193478a797a55c42e02425ffc48a72549e3c3f/dissonant-0.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ec262a3e9fe1a858fe48b7c32a9fe252", "sha256": "216747bd0599fabd767b6b439c5532c0461712373dfbf44e707fbdf12fe7f935" }, "downloads": -1, "filename": "dissonant-0.1.1.tar.gz", "has_sig": false, "md5_digest": "ec262a3e9fe1a858fe48b7c32a9fe252", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10089, "upload_time": "2018-04-03T10:21:53", "url": "https://files.pythonhosted.org/packages/a9/d4/f7b44ffa7a4c66188320074af28a7e2cf952bbb9e372124265197913e967/dissonant-0.1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "367bb78ad2a940abe6496225a9ad1a2d", "sha256": "e815cf882c519eb07875c7129ec8fd78b0d0e52add5c019b391285d12e03382e" }, "downloads": -1, "filename": "dissonant-0.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "367bb78ad2a940abe6496225a9ad1a2d", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 15405, "upload_time": "2018-04-03T10:21:51", "url": "https://files.pythonhosted.org/packages/af/93/52409808732e7157456bdf193478a797a55c42e02425ffc48a72549e3c3f/dissonant-0.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ec262a3e9fe1a858fe48b7c32a9fe252", "sha256": "216747bd0599fabd767b6b439c5532c0461712373dfbf44e707fbdf12fe7f935" }, "downloads": -1, "filename": "dissonant-0.1.1.tar.gz", "has_sig": false, "md5_digest": "ec262a3e9fe1a858fe48b7c32a9fe252", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10089, "upload_time": "2018-04-03T10:21:53", "url": "https://files.pythonhosted.org/packages/a9/d4/f7b44ffa7a4c66188320074af28a7e2cf952bbb9e372124265197913e967/dissonant-0.1.1.tar.gz" } ] }