maialib 1.9.3__cp38-cp38-musllinux_1_2_x86_64.whl → 1.9.5__cp38-cp38-musllinux_1_2_x86_64.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.
Potentially problematic release.
This version of maialib might be problematic. Click here for more details.
- maialib/maiacore/maiacore.cpython-38-x86_64-linux-gnu.so +0 -0
- maialib/maiacore/maiacore.pyi +5 -5
- maialib/maiapy/sethares_dissonance.py +117 -27
- maialib/maiapy/sethares_dissonance.pyi +63 -6
- maialib/xml-scores-examples/Beethoven_Symphony_5_mov_1.xml +38647 -40319
- {maialib-1.9.3.dist-info → maialib-1.9.5.dist-info}/METADATA +23 -15
- {maialib-1.9.3.dist-info → maialib-1.9.5.dist-info}/RECORD +17 -17
- {maialib-1.9.3.dist-info → maialib-1.9.5.dist-info}/LICENSE.txt +0 -0
- {maialib-1.9.3.dist-info → maialib-1.9.5.dist-info}/WHEEL +0 -0
- {maialib-1.9.3.dist-info → maialib-1.9.5.dist-info}/top_level.txt +0 -0
|
Binary file
|
maialib/maiacore/maiacore.pyi
CHANGED
|
@@ -93,7 +93,7 @@ class Chord:
|
|
|
93
93
|
@typing.overload
|
|
94
94
|
def getHarmonicDensity(self, lowerBoundPitch: str = '', higherBoundPitch: str = '') -> float:
|
|
95
95
|
...
|
|
96
|
-
def getHarmonicSpectrum(self, numPartialsPerNote: int = 6, amplCallback: typing.Callable[[list[float]], list[float]] = None) -> tuple[list[float], list[float]]:
|
|
96
|
+
def getHarmonicSpectrum(self, numPartialsPerNote: int = 6, amplCallback: typing.Callable[[list[float]], list[float]] = None, partialsDecayExpRate: float = 0.8799999952316284) -> tuple[list[float], list[float]]:
|
|
97
97
|
...
|
|
98
98
|
def getIntervals(self, firstNoteAsReference: bool = False) -> list[Interval]:
|
|
99
99
|
...
|
|
@@ -139,9 +139,9 @@ class Chord:
|
|
|
139
139
|
...
|
|
140
140
|
def getRoot(self) -> Note:
|
|
141
141
|
...
|
|
142
|
-
def getSetharesDissonance(self, numPartialsPerNote: int = 6, useMinModel: bool = True, amplCallback: typing.Callable[[list[float]], list[float]] = None, dissCallback: typing.Callable[[list[float]], float] = None) -> float:
|
|
142
|
+
def getSetharesDissonance(self, numPartialsPerNote: int = 6, useMinModel: bool = True, amplCallback: typing.Callable[[list[float]], list[float]] = None, partialsDecayExpRate: float = 0.8799999952316284, dissCallback: typing.Callable[[list[float]], float] = None) -> float:
|
|
143
143
|
...
|
|
144
|
-
def getSetharesDyadsDataFrame(self, numPartialsPerNote: int = 6, useMinModel: bool = True, amplCallback: typing.Callable[[list[float]], list[float]] = None) -> typing.Any:
|
|
144
|
+
def getSetharesDyadsDataFrame(self, numPartialsPerNote: int = 6, useMinModel: bool = True, amplCallback: typing.Callable[[list[float]], list[float]] = None, partialsDecayExpRate: float = 0.8799999952316284) -> typing.Any:
|
|
145
145
|
...
|
|
146
146
|
def getStackDataFrame(self, enharmonyNotes: bool = False) -> typing.Any:
|
|
147
147
|
...
|
|
@@ -946,7 +946,7 @@ class Note:
|
|
|
946
946
|
...
|
|
947
947
|
def getFrequency(self, equalTemperament: bool = True, freqA4: float = 440.0) -> float:
|
|
948
948
|
...
|
|
949
|
-
def getHarmonicSpectrum(self, numPartials: int = 6, amplCallback: typing.Callable[[list[float]], list[float]] = None) -> tuple[list[float], list[float]]:
|
|
949
|
+
def getHarmonicSpectrum(self, numPartials: int = 6, amplCallback: typing.Callable[[list[float]], list[float]] = None, partialsDecayExpRate: float = 0.8799999952316284) -> tuple[list[float], list[float]]:
|
|
950
950
|
...
|
|
951
951
|
def getLongType(self) -> str:
|
|
952
952
|
...
|
|
@@ -1411,4 +1411,4 @@ C: ClefSign # value = <ClefSign.C: 2>
|
|
|
1411
1411
|
F: ClefSign # value = <ClefSign.F: 1>
|
|
1412
1412
|
G: ClefSign # value = <ClefSign.G: 0>
|
|
1413
1413
|
P: ClefSign # value = <ClefSign.P: 3>
|
|
1414
|
-
__version__: str = '"1.9.
|
|
1414
|
+
__version__: str = '"1.9.5"'
|
|
@@ -67,16 +67,69 @@ def _dissmeasure(fvec: List[float], amp: List[float], model: str = 'min') -> flo
|
|
|
67
67
|
return D, fr_pairs, am_pairs
|
|
68
68
|
|
|
69
69
|
|
|
70
|
-
def plotSetharesDissonanceCurve(fundamentalFreq: float = 440, numPartials: int = 6, ratioLowLimit: float = 1.0, ratioHighLimit: float = 2.3, ratioStepIncrement: float = 0.001, amplCallback: Optional[Callable[[List[float]], List[float]]] = None) -> Tuple[go.Figure, pd.DataFrame]:
|
|
70
|
+
def plotSetharesDissonanceCurve(fundamentalFreq: float = 440, numPartials: int = 6, ratioLowLimit: float = 1.0, ratioHighLimit: float = 2.3, ratioStepIncrement: float = 0.001, amplCallback: Optional[Callable[[List[float]], List[float]]] = None, partialsDecayExpRate: float = 0.88) -> Tuple[go.Figure, pd.DataFrame]:
|
|
71
71
|
"""
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
Generate and return the sensory dissonance curve (Sethares) for a harmonic spectrum.
|
|
73
|
+
|
|
74
|
+
Parameters
|
|
75
|
+
----------
|
|
76
|
+
fundamentalFreq : float, default=440
|
|
77
|
+
Base frequency (f₀) in Hz on which the partials are built.
|
|
78
|
+
|
|
79
|
+
numPartials : int, default=6
|
|
80
|
+
Number of harmonics (partials) to include.
|
|
81
|
+
|
|
82
|
+
ratioLowLimit : float, default=1.0
|
|
83
|
+
Lower bound of the frequency ratio axis (intervals).
|
|
84
|
+
|
|
85
|
+
ratioHighLimit : float, default=2.3
|
|
86
|
+
Upper bound of the frequency ratio axis.
|
|
87
|
+
|
|
88
|
+
ratioStepIncrement : float, default=0.001
|
|
89
|
+
Step size between successive frequency ratios in the dissonance curve.
|
|
90
|
+
|
|
91
|
+
amplCallback : Optional[Callable[[List[float]], List[float]]], default=None
|
|
92
|
+
Optional function that receives a list of partial frequencies and returns
|
|
93
|
+
corresponding amplitudes. If None, amplitudes decay exponentially by
|
|
94
|
+
`partialsDecayExpRate`.
|
|
95
|
+
|
|
96
|
+
partialsDecayExpRate : float, default=0.88
|
|
97
|
+
Exponential decay rate for harmonics when `amplCallback` is None:
|
|
98
|
+
amplitude_i = (partialsDecayExpRate)**i.
|
|
99
|
+
|
|
100
|
+
Returns
|
|
101
|
+
-------
|
|
102
|
+
fig : go.Figure
|
|
103
|
+
Plotly figure of the sensory dissonance curve with a log-scaled frequency ratio
|
|
104
|
+
axis. Includes vertical lines for musically notable intervals (e.g., 3/2, 5/4).
|
|
105
|
+
|
|
106
|
+
df : pandas.DataFrame
|
|
107
|
+
DataFrame with columns:
|
|
108
|
+
- 'ratio': frequency ratio values
|
|
109
|
+
- 'dissonance': sensory dissonance computed for each ratio
|
|
110
|
+
- 'freqs': frequency pair vectors used for calculation
|
|
111
|
+
- 'amps': amplitude pair vectors used in calculation
|
|
112
|
+
|
|
113
|
+
Behavior
|
|
114
|
+
--------
|
|
115
|
+
1. Constructs frequency vector `freqs` with integer multiples of `fundamentalFreq`.
|
|
116
|
+
2. Computes amplitude vector `amps` via `amplCallback`, or using exponential decay.
|
|
117
|
+
3. Validates matching lengths for `freqs` and `amps`, raising ValueError if mismatched.
|
|
118
|
+
4. Constructs a `ratios` array from `ratioLowLimit` to `ratioHighLimit`.
|
|
119
|
+
5. For each ratio r:
|
|
120
|
+
- Concatenates `freqs` with r × `freqs`; likewise for amplitudes.
|
|
121
|
+
- Applies `_dissmeasure` to compute sensory dissonance, frequency pairs, and amplitude pairs.
|
|
122
|
+
6. Builds a Plotly figure plotting dissonance vs. ratio and overlays lines at common musical intervals.
|
|
123
|
+
7. Returns the figure and a pandas DataFrame for further analysis.
|
|
124
|
+
|
|
125
|
+
Exceptions
|
|
126
|
+
----------
|
|
127
|
+
ValueError:
|
|
128
|
+
Raised if the output of `amplCallback` (if provided) does not match `numPartials` in length.
|
|
76
129
|
"""
|
|
77
130
|
freqs = fundamentalFreq * np.array(list(range(1, numPartials+1)))
|
|
78
|
-
amps =
|
|
79
|
-
|
|
131
|
+
amps = partialsDecayExpRate**np.array(list(range(0, numPartials))
|
|
132
|
+
) if amplCallback == None else amplCallback(freqs)
|
|
80
133
|
|
|
81
134
|
if len(freqs) != len(amps):
|
|
82
135
|
raise ValueError(
|
|
@@ -190,6 +243,7 @@ def _setharesDissonanceDataFrameInterpolation(df: pd.DataFrame, interpolatePoint
|
|
|
190
243
|
|
|
191
244
|
|
|
192
245
|
def plotScoreSetharesDissonance(score: mc.Score, plotType='line', lineShape='linear', numPartialsPerNote: int = 6, useMinModel: bool = True,
|
|
246
|
+
partialsDecayExpRate: float = 0.88,
|
|
193
247
|
amplCallback: Optional[Callable[[
|
|
194
248
|
List[float]], List[float]]] = None,
|
|
195
249
|
dissCallback: Optional[Callable[[List[float]], float]] = None, **kwargs) -> Tuple[go.Figure, pd.DataFrame]:
|
|
@@ -202,6 +256,7 @@ def plotScoreSetharesDissonance(score: mc.Score, plotType='line', lineShape='lin
|
|
|
202
256
|
numPartialsPerNote (int): Amount of spectral partials for each note
|
|
203
257
|
useMinModel (bool): Sethares dissonance values can be computed using the 'minimal amplitude' model
|
|
204
258
|
or the 'product amplitudes' model. The 'min' model is a more recent approach
|
|
259
|
+
partialsDecayExpRate (float): Partials decay exponential rate (default: 0.88)
|
|
205
260
|
amplCallback: Custom user function callback to generate the amplitude of each spectrum partial
|
|
206
261
|
dissCallback: Custom user function callback to receive all paired partial dissonances and computes
|
|
207
262
|
a single total dissonance value output
|
|
@@ -233,7 +288,7 @@ def plotScoreSetharesDissonance(score: mc.Score, plotType='line', lineShape='lin
|
|
|
233
288
|
df = score.getChordsDataFrame(kwargs)
|
|
234
289
|
|
|
235
290
|
df["dissonance"] = df.apply(lambda row: row.chord.getSetharesDissonance(
|
|
236
|
-
numPartialsPerNote, useMinModel, amplCallback, dissCallback), axis=1)
|
|
291
|
+
numPartialsPerNote, useMinModel, amplCallback, partialsDecayExpRate, dissCallback), axis=1)
|
|
237
292
|
df["chordNotes"] = df.apply(lambda row: ', '.join(
|
|
238
293
|
[str(x.getPitch()) for x in row.chord.getNotes()]), axis=1)
|
|
239
294
|
df["chordSize"] = df.apply(lambda row: row.chord.size(), axis=1)
|
|
@@ -282,7 +337,8 @@ def plotScoreSetharesDissonance(score: mc.Score, plotType='line', lineShape='lin
|
|
|
282
337
|
|
|
283
338
|
|
|
284
339
|
def plotChordDyadsSetharesDissonanceHeatmap(chord: mc.Chord, numPartialsPerNote: int = 6, useMinModel: bool = True, amplCallback: Optional[Callable[[
|
|
285
|
-
|
|
340
|
+
List[float]], List[float]]] = None, partialsDecayExpRate: float = 0.88, dissonanceThreshold: float = 0.1, dissonanceDecimalPoint: int = 2, showValues: bool = False,
|
|
341
|
+
valuesDecimalPlaces: int = 2) -> Tuple[plotly.graph_objs._figure.Figure, pd.DataFrame]:
|
|
286
342
|
"""Plot chord dyads Sethares dissonance heatmap
|
|
287
343
|
|
|
288
344
|
Args:
|
|
@@ -293,8 +349,11 @@ def plotChordDyadsSetharesDissonanceHeatmap(chord: mc.Chord, numPartialsPerNote:
|
|
|
293
349
|
useMinModel (bool): Sethares dissonance values can be computed using the 'minimal amplitude' model
|
|
294
350
|
or the 'product amplitudes' model. The 'min' model is a more recent approach
|
|
295
351
|
amplCallback: Custom user function callback to generate the amplitude of each spectrum partial
|
|
352
|
+
partialsDecayExpRate (float): Partials decay exponential rate (default: 0.88)
|
|
296
353
|
dissonanceThreshold (float): Dissonance threshold to skip small dissonance values
|
|
297
354
|
dissonanceDecimalPoint (int): Round chord dissonance value in the plot title
|
|
355
|
+
showValues (bool): If True, show numerical values inside heatmap cells
|
|
356
|
+
valuesDecimalPlaces (int): Number of decimal places to display in cell values
|
|
298
357
|
|
|
299
358
|
Returns:
|
|
300
359
|
A list: [Plotly Figure, The plot data as a Pandas Dataframe]
|
|
@@ -310,33 +369,64 @@ def plotChordDyadsSetharesDissonanceHeatmap(chord: mc.Chord, numPartialsPerNote:
|
|
|
310
369
|
>>> fig.show()
|
|
311
370
|
"""
|
|
312
371
|
df = chord.getSetharesDyadsDataFrame(
|
|
313
|
-
numPartialsPerNote=numPartialsPerNote, useMinModel=useMinModel, amplCallback=amplCallback)
|
|
372
|
+
numPartialsPerNote=numPartialsPerNote, useMinModel=useMinModel, amplCallback=amplCallback, partialsDecayExpRate=partialsDecayExpRate)
|
|
314
373
|
dfFiltered = df[df.dissonance > dissonanceThreshold]
|
|
315
374
|
|
|
316
|
-
# Pivot
|
|
375
|
+
# Pivot para matriz (targetFreq como linhas, baseFreq como colunas)
|
|
317
376
|
matrix_df = dfFiltered.pivot(
|
|
318
|
-
index='targetFreq', columns='baseFreq', values='dissonance'
|
|
377
|
+
index='targetFreq', columns='baseFreq', values='dissonance'
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
# Reordena linhas e colunas para consistência
|
|
381
|
+
matrix_df = matrix_df.reindex(
|
|
382
|
+
index=sorted(matrix_df.index),
|
|
383
|
+
columns=sorted(matrix_df.columns)
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
# Índices para o heatmap uniforme
|
|
387
|
+
x_ticks = list(range(len(matrix_df.columns)))
|
|
388
|
+
y_ticks = list(range(len(matrix_df.index)))
|
|
319
389
|
|
|
320
|
-
#
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
y="Target Frequency (Hz)", color="Dissonance"),
|
|
324
|
-
color_continuous_scale='Inferno')
|
|
390
|
+
# Labels reais (frequências)
|
|
391
|
+
x_labels = [round(v, 0) for v in matrix_df.columns]
|
|
392
|
+
y_labels = [round(v, 0) for v in matrix_df.index]
|
|
325
393
|
|
|
326
|
-
#
|
|
327
|
-
|
|
328
|
-
|
|
394
|
+
# Formatação do texto (caso showValues=True)
|
|
395
|
+
if showValues:
|
|
396
|
+
text_format = f".{valuesDecimalPlaces}f"
|
|
397
|
+
else:
|
|
398
|
+
text_format = False
|
|
399
|
+
|
|
400
|
+
# Criar heatmap com quadrados iguais
|
|
401
|
+
fig = px.imshow(
|
|
402
|
+
matrix_df.values,
|
|
403
|
+
labels=dict(x="Base Frequency (Hz)",
|
|
404
|
+
y="Target Frequency (Hz)", color="Dissonance"),
|
|
405
|
+
color_continuous_scale="Inferno",
|
|
406
|
+
origin="lower", # força o eixo Y a começar por baixo
|
|
407
|
+
text_auto=text_format
|
|
408
|
+
)
|
|
329
409
|
|
|
330
|
-
|
|
331
|
-
|
|
410
|
+
# Ajusta ticks para mostrar frequências reais
|
|
411
|
+
fig.update_xaxes(
|
|
412
|
+
tickmode="array",
|
|
413
|
+
tickvals=x_ticks,
|
|
414
|
+
ticktext=x_labels
|
|
415
|
+
)
|
|
416
|
+
fig.update_yaxes(
|
|
417
|
+
tickmode="array",
|
|
418
|
+
tickvals=y_ticks,
|
|
419
|
+
ticktext=y_labels,
|
|
420
|
+
)
|
|
332
421
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
fig.update_yaxes(type='linear', tickvals=y_ticks,
|
|
336
|
-
ticktext=roundedYTicksValues, autorange=True)
|
|
422
|
+
# Mantém os quadrados sempre iguais
|
|
423
|
+
fig.update_yaxes(scaleanchor="x", scaleratio=1)
|
|
337
424
|
|
|
425
|
+
# Título
|
|
338
426
|
roundedDissonanceValue = round(df.dissonance.sum(), dissonanceDecimalPoint)
|
|
339
427
|
fig.update_layout(
|
|
340
|
-
title=f'<b>Chord Dyads Sethares Dissonance Heatmap</b><br><i>Chord Dissonance={
|
|
428
|
+
title=f'<b>Chord Dyads Sethares Dissonance Heatmap</b><br><i>Chord Dissonance={roundedDissonanceValue}</i>',
|
|
429
|
+
title_x=0.5
|
|
430
|
+
)
|
|
341
431
|
|
|
342
432
|
return fig, dfFiltered
|
|
@@ -4,14 +4,67 @@ import plotly.graph_objects as go
|
|
|
4
4
|
from maialib import maiacore as mc
|
|
5
5
|
from typing import Callable
|
|
6
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) -> tuple[go.Figure, pd.DataFrame]:
|
|
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
8
|
"""
|
|
9
|
-
|
|
9
|
+
Generate and return the sensory dissonance curve (Sethares) for a harmonic spectrum.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
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.
|
|
13
66
|
"""
|
|
14
|
-
def plotScoreSetharesDissonance(score: mc.Score, plotType: str = 'line', lineShape: str = 'linear', numPartialsPerNote: int = 6, useMinModel: bool = True, amplCallback: Callable[[list[float]], list[float]] | None = None, dissCallback: Callable[[list[float]], float] | None = None, **kwargs) -> tuple[go.Figure, pd.DataFrame]:
|
|
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]:
|
|
15
68
|
'''Plot 2D line graph of the Sethares Dissonance over time
|
|
16
69
|
|
|
17
70
|
Args:
|
|
@@ -21,6 +74,7 @@ def plotScoreSetharesDissonance(score: mc.Score, plotType: str = 'line', lineSha
|
|
|
21
74
|
numPartialsPerNote (int): Amount of spectral partials for each note
|
|
22
75
|
useMinModel (bool): Sethares dissonance values can be computed using the \'minimal amplitude\' model
|
|
23
76
|
or the \'product amplitudes\' model. The \'min\' model is a more recent approach
|
|
77
|
+
partialsDecayExpRate (float): Partials decay exponential rate (default: 0.88)
|
|
24
78
|
amplCallback: Custom user function callback to generate the amplitude of each spectrum partial
|
|
25
79
|
dissCallback: Custom user function callback to receive all paired partial dissonances and computes
|
|
26
80
|
a single total dissonance value output
|
|
@@ -42,7 +96,7 @@ def plotScoreSetharesDissonance(score: mc.Score, plotType: str = 'line', lineSha
|
|
|
42
96
|
>>> ml.plotScoreSetharesDissonance(myScore, numPoints=15)
|
|
43
97
|
>>> ml.plotScoreSetharesDissonance(myScore, measureStart=10, measureEnd=20)
|
|
44
98
|
'''
|
|
45
|
-
def plotChordDyadsSetharesDissonanceHeatmap(chord: mc.Chord, numPartialsPerNote: int = 6, useMinModel: bool = True, amplCallback: Callable[[list[float]], list[float]] | None = None, dissonanceThreshold: float = 0.1, dissonanceDecimalPoint: int = 2) -> tuple[plotly.graph_objs._figure.Figure, pd.DataFrame]:
|
|
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]:
|
|
46
100
|
'''Plot chord dyads Sethares dissonance heatmap
|
|
47
101
|
|
|
48
102
|
Args:
|
|
@@ -53,8 +107,11 @@ def plotChordDyadsSetharesDissonanceHeatmap(chord: mc.Chord, numPartialsPerNote:
|
|
|
53
107
|
useMinModel (bool): Sethares dissonance values can be computed using the \'minimal amplitude\' model
|
|
54
108
|
or the \'product amplitudes\' model. The \'min\' model is a more recent approach
|
|
55
109
|
amplCallback: Custom user function callback to generate the amplitude of each spectrum partial
|
|
110
|
+
partialsDecayExpRate (float): Partials decay exponential rate (default: 0.88)
|
|
56
111
|
dissonanceThreshold (float): Dissonance threshold to skip small dissonance values
|
|
57
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
|
|
58
115
|
|
|
59
116
|
Returns:
|
|
60
117
|
A list: [Plotly Figure, The plot data as a Pandas Dataframe]
|