maialib 1.10.2__cp311-cp311-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- maialib/__init__.py +4 -0
- maialib/maiacore/Release/__init__.pyi +3 -0
- maialib/maiacore/Release/maiacore.cp311-win_amd64.pyd +0 -0
- maialib/maiacore/Release/maiacore.pyi +1414 -0
- maialib/maiacore/__init__.py +4 -0
- maialib/maiacore/__init__.pyi +24 -0
- maialib/maiapy/__init__.py +3 -0
- maialib/maiapy/__init__.pyi +3 -0
- maialib/maiapy/other.py +148 -0
- maialib/maiapy/other.pyi +79 -0
- maialib/maiapy/plots.py +806 -0
- maialib/maiapy/plots.pyi +103 -0
- maialib/maiapy/sethares_dissonance.py +481 -0
- maialib/maiapy/sethares_dissonance.pyi +128 -0
- maialib/setup.py +61 -0
- maialib/xml-scores-examples/Bach_Cello_Suite_1.mxl +0 -0
- maialib/xml-scores-examples/Beethoven_Symphony_5_mov_1.xml +170525 -0
- maialib/xml-scores-examples/Chopin_Fantasie_Impromptu.mxl +0 -0
- maialib/xml-scores-examples/Dvorak_Symphony_9_mov_4.mxl +0 -0
- maialib/xml-scores-examples/Mahler_Symphony_8_Finale.mxl +0 -0
- maialib/xml-scores-examples/Mozart_Requiem_Introitus.mxl +0 -0
- maialib/xml-scores-examples/Strauss_Also_Sprach_Zarathustra.mxl +0 -0
- maialib-1.10.2.dist-info/METADATA +822 -0
- maialib-1.10.2.dist-info/RECORD +27 -0
- maialib-1.10.2.dist-info/WHEEL +5 -0
- maialib-1.10.2.dist-info/licenses/LICENSE.txt +674 -0
- maialib-1.10.2.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
import plotly
|
|
3
|
+
import plotly.graph_objects as go
|
|
4
|
+
from maialib import maiacore as mc
|
|
5
|
+
from typing import Callable
|
|
6
|
+
|
|
7
|
+
def plotSetharesDissonanceCurve(fundamentalFreq: float = 440, numPartials: int = 6, ratioLowLimit: float = 1.0, ratioHighLimit: float = 2.3, ratioStepIncrement: float = 0.001, amplCallback: Callable[[list[float]], list[float]] | None = None, partialsDecayExpRate: float = 0.88) -> tuple[go.Figure, pd.DataFrame]:
|
|
8
|
+
"""
|
|
9
|
+
Generate and return the sensory dissonance curve (Sethares) for a harmonic spectrum.
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
fundamentalFreq : float, default=440
|
|
14
|
+
Base frequency (f₀) in Hz on which the partials are built.
|
|
15
|
+
|
|
16
|
+
numPartials : int, default=6
|
|
17
|
+
Number of harmonics (partials) to include.
|
|
18
|
+
|
|
19
|
+
ratioLowLimit : float, default=1.0
|
|
20
|
+
Lower bound of the frequency ratio axis (intervals).
|
|
21
|
+
|
|
22
|
+
ratioHighLimit : float, default=2.3
|
|
23
|
+
Upper bound of the frequency ratio axis.
|
|
24
|
+
|
|
25
|
+
ratioStepIncrement : float, default=0.001
|
|
26
|
+
Step size between successive frequency ratios in the dissonance curve.
|
|
27
|
+
|
|
28
|
+
amplCallback : Optional[Callable[[List[float]], List[float]]], default=None
|
|
29
|
+
Optional function that receives a list of partial frequencies and returns
|
|
30
|
+
corresponding amplitudes. If None, amplitudes decay exponentially by
|
|
31
|
+
`partialsDecayExpRate`.
|
|
32
|
+
|
|
33
|
+
partialsDecayExpRate : float, default=0.88
|
|
34
|
+
Exponential decay rate for harmonics when `amplCallback` is None:
|
|
35
|
+
amplitude_i = (partialsDecayExpRate)**i.
|
|
36
|
+
|
|
37
|
+
Returns
|
|
38
|
+
-------
|
|
39
|
+
fig : go.Figure
|
|
40
|
+
Plotly figure of the sensory dissonance curve with a log-scaled frequency ratio
|
|
41
|
+
axis. Includes vertical lines for musically notable intervals (e.g., 3/2, 5/4).
|
|
42
|
+
|
|
43
|
+
df : pandas.DataFrame
|
|
44
|
+
DataFrame with columns:
|
|
45
|
+
- 'ratio': frequency ratio values
|
|
46
|
+
- 'dissonance': sensory dissonance computed for each ratio
|
|
47
|
+
- 'freqs': frequency pair vectors used for calculation
|
|
48
|
+
- 'amps': amplitude pair vectors used in calculation
|
|
49
|
+
|
|
50
|
+
Behavior
|
|
51
|
+
--------
|
|
52
|
+
1. Constructs frequency vector `freqs` with integer multiples of `fundamentalFreq`.
|
|
53
|
+
2. Computes amplitude vector `amps` via `amplCallback`, or using exponential decay.
|
|
54
|
+
3. Validates matching lengths for `freqs` and `amps`, raising ValueError if mismatched.
|
|
55
|
+
4. Constructs a `ratios` array from `ratioLowLimit` to `ratioHighLimit`.
|
|
56
|
+
5. For each ratio r:
|
|
57
|
+
- Concatenates `freqs` with r × `freqs`; likewise for amplitudes.
|
|
58
|
+
- Applies `_dissmeasure` to compute sensory dissonance, frequency pairs, and amplitude pairs.
|
|
59
|
+
6. Builds a Plotly figure plotting dissonance vs. ratio and overlays lines at common musical intervals.
|
|
60
|
+
7. Returns the figure and a pandas DataFrame for further analysis.
|
|
61
|
+
|
|
62
|
+
Exceptions
|
|
63
|
+
----------
|
|
64
|
+
ValueError:
|
|
65
|
+
Raised if the output of `amplCallback` (if provided) does not match `numPartials` in length.
|
|
66
|
+
"""
|
|
67
|
+
def plotScoreSetharesDissonance(score: mc.Score, plotType: str = 'line', lineShape: str = 'linear', numPartialsPerNote: int = 6, useMinModel: bool = True, partialsDecayExpRate: float = 0.88, amplCallback: Callable[[list[float]], list[float]] | None = None, dissCallback: Callable[[list[float]], float] | None = None, **kwargs) -> tuple[go.Figure, pd.DataFrame]:
|
|
68
|
+
'''Plot 2D line graph of the Sethares Dissonance over time
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
score (maialib.Score): A maialib Score object loaded with a valid MusicXML file
|
|
72
|
+
plotType (str): Can be \'line\' or \'scatter\'
|
|
73
|
+
lineShape (str): Can be \'linear\' or \'spline\'
|
|
74
|
+
numPartialsPerNote (int): Amount of spectral partials for each note
|
|
75
|
+
useMinModel (bool): Sethares dissonance values can be computed using the \'minimal amplitude\' model
|
|
76
|
+
or the \'product amplitudes\' model. The \'min\' model is a more recent approach
|
|
77
|
+
partialsDecayExpRate (float): Partials decay exponential rate (default: 0.88)
|
|
78
|
+
amplCallback: Custom user function callback to generate the amplitude of each spectrum partial
|
|
79
|
+
dissCallback: Custom user function callback to receive all paired partial dissonances and computes
|
|
80
|
+
a single total dissonance value output
|
|
81
|
+
Kwargs:
|
|
82
|
+
measureStart (int): Start measure to plot
|
|
83
|
+
measureEnd (int): End measure to plot
|
|
84
|
+
numPoints (int): Number of interpolated points
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
A list: [Plotly Figure, The plot data as a Pandas Dataframe]
|
|
88
|
+
|
|
89
|
+
Raises:
|
|
90
|
+
RuntimeError, KeyError
|
|
91
|
+
|
|
92
|
+
Examples of use:
|
|
93
|
+
|
|
94
|
+
>>> myScore = ml.Score("/path/to/score.xml")
|
|
95
|
+
>>> ml.plotScoreSetharesDissonance(myScore)
|
|
96
|
+
>>> ml.plotScoreSetharesDissonance(myScore, numPoints=15)
|
|
97
|
+
>>> ml.plotScoreSetharesDissonance(myScore, measureStart=10, measureEnd=20)
|
|
98
|
+
'''
|
|
99
|
+
def plotChordDyadsSetharesDissonanceHeatmap(chord: mc.Chord, numPartialsPerNote: int = 6, useMinModel: bool = True, amplCallback: Callable[[list[float]], list[float]] | None = None, partialsDecayExpRate: float = 0.88, dissonanceThreshold: float = 0.1, dissonanceDecimalPoint: int = 2, showValues: bool = False, valuesDecimalPlaces: int = 2) -> tuple[plotly.graph_objs._figure.Figure, pd.DataFrame]:
|
|
100
|
+
'''Plot chord dyads Sethares dissonance heatmap
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
chord (maialib.Chord): A maialib Chord
|
|
104
|
+
|
|
105
|
+
Kwargs:
|
|
106
|
+
numPartialsPerNote (int): Amount of spectral partials for each note
|
|
107
|
+
useMinModel (bool): Sethares dissonance values can be computed using the \'minimal amplitude\' model
|
|
108
|
+
or the \'product amplitudes\' model. The \'min\' model is a more recent approach
|
|
109
|
+
amplCallback: Custom user function callback to generate the amplitude of each spectrum partial
|
|
110
|
+
partialsDecayExpRate (float): Partials decay exponential rate (default: 0.88)
|
|
111
|
+
dissonanceThreshold (float): Dissonance threshold to skip small dissonance values
|
|
112
|
+
dissonanceDecimalPoint (int): Round chord dissonance value in the plot title
|
|
113
|
+
showValues (bool): If True, show numerical values inside heatmap cells
|
|
114
|
+
valuesDecimalPlaces (int): Number of decimal places to display in cell values
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
A list: [Plotly Figure, The plot data as a Pandas Dataframe]
|
|
118
|
+
|
|
119
|
+
Raises:
|
|
120
|
+
RuntimeError, KeyError
|
|
121
|
+
|
|
122
|
+
Examples of use:
|
|
123
|
+
|
|
124
|
+
>>> import maialib as ml
|
|
125
|
+
>>> myChord = ml.Chord(["C3", "E3", "G3"])
|
|
126
|
+
>>> fig, df = plotChordDyadsSetharesDissonanceHeatmap(myChord)
|
|
127
|
+
>>> fig.show()
|
|
128
|
+
'''
|
maialib/setup.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
5
|
+
long_description = fh.read()
|
|
6
|
+
|
|
7
|
+
with open("LICENSE.txt", "r", encoding="utf-8") as fh:
|
|
8
|
+
license_txt = fh.read()
|
|
9
|
+
|
|
10
|
+
# Lê a versão do arquivo VERSION
|
|
11
|
+
version_path = Path(__file__).parent.parent / "VERSION"
|
|
12
|
+
version = version_path.read_text().strip()
|
|
13
|
+
|
|
14
|
+
setup(
|
|
15
|
+
name="maialib",
|
|
16
|
+
version=version + "-dev",
|
|
17
|
+
author="Nycholas Maia",
|
|
18
|
+
author_email="nyckmaia@gmail.com",
|
|
19
|
+
description="A C++/Python library to manipulate music data",
|
|
20
|
+
long_description=long_description,
|
|
21
|
+
long_description_content_type="text/markdown",
|
|
22
|
+
license="GNU General Public License v3 or later (GPLv3+)",
|
|
23
|
+
url="https://github.com/nyckmaia/maialib",
|
|
24
|
+
project_urls={
|
|
25
|
+
"Bug Tracker": "https://github.com/nyckmaia/maialib/issues",
|
|
26
|
+
},
|
|
27
|
+
keywords=["music", "score", "sheet music", "analysis"],
|
|
28
|
+
packages=find_packages(),
|
|
29
|
+
package_data={
|
|
30
|
+
"": [
|
|
31
|
+
"*.so",
|
|
32
|
+
"*.pyd",
|
|
33
|
+
"__init__.pyi",
|
|
34
|
+
"maiacore/__init__.pyi",
|
|
35
|
+
"py.typed",
|
|
36
|
+
"*.pyi",
|
|
37
|
+
"**/*.pyi",
|
|
38
|
+
"xml-scores-examples/Bach_Cello_Suite_1.mxl",
|
|
39
|
+
"xml-scores-examples/Beethoven_Symphony_5_mov_1.xml",
|
|
40
|
+
"xml-scores-examples/Chopin_Fantasie_Impromptu.mxl",
|
|
41
|
+
"xml-scores-examples/Dvorak_Symphony_9_mov_4.mxl",
|
|
42
|
+
"xml-scores-examples/Mahler_Symphony_8_Finale.mxl",
|
|
43
|
+
"xml-scores-examples/Mozart_Requiem_Introitus.mxl",
|
|
44
|
+
"xml-scores-examples/Strauss_Also_Sprach_Zarathustra.mxl",
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
include_package_data=True,
|
|
48
|
+
py_modules=["maiacore", "maiapy"],
|
|
49
|
+
classifiers=[
|
|
50
|
+
"Development Status :: 3 - Alpha",
|
|
51
|
+
"Programming Language :: Python :: 3",
|
|
52
|
+
"Programming Language :: C++",
|
|
53
|
+
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
|
|
54
|
+
"Operating System :: OS Independent",
|
|
55
|
+
"Intended Audience :: Science/Research",
|
|
56
|
+
"Natural Language :: English",
|
|
57
|
+
"Topic :: Software Development :: Libraries",
|
|
58
|
+
],
|
|
59
|
+
python_requires=">=3.8.0",
|
|
60
|
+
zip_safe=False,
|
|
61
|
+
)
|
|
Binary file
|