Inputs#

Input dataclasses for biotuner.harmonic_geometry.

HarmonicInput is the unified per-frame harmonic descriptor consumed by every geometry-producing function. HarmonicSequence is a time-resolved list of HarmonicInput frames, used for animation / morphing pipelines and naturally paired with the output of biotuner.transitional_harmony or biotuner.harmonic_sequence.

class HarmonicInput(ratios: ~typing.List[~fractions.Fraction | float] | None = None, peaks: ~typing.List[float] | None = None, amplitudes: ~typing.List[float] | None = None, phases: ~typing.List[float] | None = None, damping: ~typing.List[float] | None = None, base_freq: float = 1.0, equave: float = 2.0, metadata: ~typing.Dict[str, ~typing.Any] = <factory>)[source]#

Bases: object

Unified harmonic input.

At least one of ratios or peaks must be provided. All list-typed optional fields, if given, must have lengths matching the number of components (len(ratios) or len(peaks)).

Parameters:
  • ratios (list of Fraction or float, optional) – Frequency ratios. Coerced to Fraction when a rational approximation within DEFAULT_MAX_DENOMINATOR exists.

  • peaks (list of float, optional) – Peak frequencies in Hz.

  • amplitudes (list of float, optional) – Linear (not dB) amplitudes per component. Defaults to uniform.

  • phases (list of float, optional) – Phase per component, in radians. Defaults to zeros.

  • damping (list of float, optional) – Decay rate (1/s) per component. Defaults to zeros.

  • base_freq (float, default=1.0) – Reference frequency in Hz. Used when ratios are given without peaks to recover absolute frequencies.

  • equave (float, default=2.0) – Equave width: 2.0 for octaves, 3.0 for tritaves, etc. Must be greater than 1.

  • metadata (dict) – Free-form annotations preserved across constructors and validation.

Notes

Validation is invoked by __post_init__(); constructing an inconsistent HarmonicInput raises ValueError.

ratios: List[Fraction | float] | None = None#
peaks: List[float] | None = None#
amplitudes: List[float] | None = None#
phases: List[float] | None = None#
damping: List[float] | None = None#
base_freq: float = 1.0#
equave: float = 2.0#
metadata: Dict[str, Any]#
n_components() int[source]#

Return the number of harmonic components.

Resolved from ratios first, then peaks. At least one of the two is guaranteed to be present after validate().

to_peaks() ndarray[source]#

Return absolute peak frequencies in Hz as a 1-D float64 array.

If peaks is set, those values are returned directly. Otherwise peaks are reconstructed as base_freq * ratios.

to_ratios() List[Fraction | float][source]#

Return ratios.

If ratios is set, those values are returned. Otherwise ratios are derived as peaks / base_freq and coerced to Fraction.

normalized_amplitudes() ndarray[source]#

Return amplitudes scaled to sum to 1.

If amplitudes is None, returns a uniform distribution over the components.

validate() None[source]#

Raise ValueError if the input is internally inconsistent.

Checked invariants:

  • at least one of ratios / peaks is given,

  • equave > 1 and base_freq > 0,

  • all list-typed fields have matching lengths,

  • all amplitudes are non-negative,

  • all peaks are positive,

  • if both ratios and peaks are given, they agree up to base_freq within a small relative tolerance.

classmethod from_ratios(ratios: Iterable[Fraction | int | float | tuple], base_freq: float = 1.0, amplitudes: Sequence[float] | None = None, phases: Sequence[float] | None = None, damping: Sequence[float] | None = None, equave: float = 2.0, metadata: Dict[str, Any] | None = None) HarmonicInput[source]#

Build from a sequence of ratios.

classmethod from_peaks(peaks: Iterable[float], base_freq: float | None = None, amplitudes: Sequence[float] | None = None, phases: Sequence[float] | None = None, damping: Sequence[float] | None = None, equave: float = 2.0, metadata: Dict[str, Any] | None = None) HarmonicInput[source]#

Build from a sequence of peak frequencies in Hz.

If base_freq is None it is set to the smallest peak so that the implied ratio of the lowest component is exactly 1.

classmethod from_biotuner(bt: Any, equave: float = 2.0) HarmonicInput[source]#

Build from a fitted compute_biotuner (a.k.a. BiotunerObject) instance.

Pulls peaks (required), amps, and peaks_ratios when available. Phase / damping are not currently exposed by biotuner and are left at their defaults.

Parameters:
  • bt (compute_biotuner) – A biotuner object on which peaks_extraction has been called.

  • equave (float, default=2.0)

Raises:
  • AttributeError – If bt lacks a peaks attribute.

  • ValueError – If bt.peaks is empty.

class HarmonicSequence(frames: List[HarmonicInput], times: ndarray | None = None)[source]#

Bases: object

Time-resolved sequence of HarmonicInput frames.

Pairs naturally with the output of biotuner.transitional_harmony and biotuner.harmonic_sequence: each window’s peaks become a frame here, and downstream geometry functions can be applied frame-by-frame via transformations.geometry_sequence.

Parameters:
  • frames (list of HarmonicInput) – At least one frame is required.

  • times (ndarray, optional) – Time of each frame in seconds. If None, frames are assumed to be uniformly spaced at unit intervals.

frames: List[HarmonicInput]#
times: ndarray | None = None#
n_frames() int[source]#

Number of frames in the sequence.

at(t: float) HarmonicInput[source]#

Return the frame nearest to time t.

interpolate(t: float, mode: str = 'log') HarmonicInput[source]#

Return a HarmonicInput interpolated to time t.

Currently supports two-frame interpolation between the bracketing frames. mode selects the space in which ratios / peaks are blended:

  • 'log' (default) — logarithmic, musically correct,

  • 'linear' — straight linear interpolation,

  • 'nearest' — return the nearest frame (no blending).

Frames must have equal n_components; if they do not, this raises ValueError. Richer interpolation (mismatched component counts, phase wrapping, etc.) is the job of transformations.interpolate_input in Phase 6.

classmethod from_biotuner_list(bt_list: Sequence[Any], times: Sequence[float] | None = None, equave: float = 2.0) HarmonicSequence[source]#

Build from a sequence of fitted compute_biotuner objects.

Each biotuner object becomes one frame. Objects with no peaks are skipped; if every object is empty, ValueError is raised.

Parameters:
  • bt_list (sequence of compute_biotuner) – Fitted biotuner objects (peaks_extraction already called).

  • times (sequence of float, optional) – One time per kept frame. If None, frames are uniformly spaced. If provided, must match the number of non-empty biotuner objects.

  • equave (float, default=2.0)

classmethod from_biotuner_group(btg: Any, times: Sequence[float] | None = None, equave: float = 2.0) HarmonicSequence[source]#

Build from a biotuner.biotuner_group.BiotunerGroup instance.

Uses btg.objects (the per-series compute_biotuner instances). BiotunerGroup must have been constructed with store_objects=True (the default).

Parameters:
  • btg (BiotunerGroup) – A group whose compute_peaks has been run.

  • times (sequence of float, optional) – One time per non-empty frame; see from_biotuner_list().

  • equave (float, default=2.0)

Raises:

AttributeError – If btg has no objects attribute, or it is None (e.g. store_objects=False was used).