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.
@@ -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
+ )