maialib 1.9.4__cp310-cp310-musllinux_1_2_i686.whl → 1.9.5__cp310-cp310-musllinux_1_2_i686.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.

@@ -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.4"'
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
- Compute the Sethares Dissonance Curve of a given base frequency
73
-
74
- Return
75
- A tuple that contains a Plotly figure, and the pair 'ratios' and 'dissonance' lists
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 = 0.88**np.array(list(range(0, numPartials))
79
- ) if amplCallback == None else amplCallback(freqs)
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,7 @@ 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
- List[float]], List[float]]] = None, dissonanceThreshold: float = 0.1, dissonanceDecimalPoint: int = 2, showValues: bool = False,
340
+ List[float]], List[float]]] = None, partialsDecayExpRate: float = 0.88, dissonanceThreshold: float = 0.1, dissonanceDecimalPoint: int = 2, showValues: bool = False,
286
341
  valuesDecimalPlaces: int = 2) -> Tuple[plotly.graph_objs._figure.Figure, pd.DataFrame]:
287
342
  """Plot chord dyads Sethares dissonance heatmap
288
343
 
@@ -294,6 +349,7 @@ def plotChordDyadsSetharesDissonanceHeatmap(chord: mc.Chord, numPartialsPerNote:
294
349
  useMinModel (bool): Sethares dissonance values can be computed using the 'minimal amplitude' model
295
350
  or the 'product amplitudes' model. The 'min' model is a more recent approach
296
351
  amplCallback: Custom user function callback to generate the amplitude of each spectrum partial
352
+ partialsDecayExpRate (float): Partials decay exponential rate (default: 0.88)
297
353
  dissonanceThreshold (float): Dissonance threshold to skip small dissonance values
298
354
  dissonanceDecimalPoint (int): Round chord dissonance value in the plot title
299
355
  showValues (bool): If True, show numerical values inside heatmap cells
@@ -313,7 +369,7 @@ def plotChordDyadsSetharesDissonanceHeatmap(chord: mc.Chord, numPartialsPerNote:
313
369
  >>> fig.show()
314
370
  """
315
371
  df = chord.getSetharesDyadsDataFrame(
316
- numPartialsPerNote=numPartialsPerNote, useMinModel=useMinModel, amplCallback=amplCallback)
372
+ numPartialsPerNote=numPartialsPerNote, useMinModel=useMinModel, amplCallback=amplCallback, partialsDecayExpRate=partialsDecayExpRate)
317
373
  dfFiltered = df[df.dissonance > dissonanceThreshold]
318
374
 
319
375
  # Pivot para matriz (targetFreq como linhas, baseFreq como colunas)
@@ -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
- Compute the Sethares Dissonance Curve of a given base frequency
9
+ Generate and return the sensory dissonance curve (Sethares) for a harmonic spectrum.
10
10
 
11
- Return
12
- A tuple that contains a Plotly figure, and the pair 'ratios' and 'dissonance' lists
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, showValues: bool = False, valuesDecimalPlaces: 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,6 +107,7 @@ 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
58
113
  showValues (bool): If True, show numerical values inside heatmap cells