Inputs#
Backward-compatible re-export of the HarmonicInput descriptor.
HarmonicInput originally lived in this submodule because
biotuner.harmonic_geometry was its only consumer. As of the
cross-module HarmonicInput promotion, the canonical home is
biotuner.harmonic_input at the top level — so unrelated modules
(harmonic_timbre, the engine backend, exporters) can consume the
descriptor without pulling in geometry as a transitive dependency.
This file remains so that the ~24 internal call sites and any external
code still doing from biotuner.harmonic_geometry.inputs import
HarmonicInput keep working unchanged. New code should prefer:
from biotuner.harmonic_input import HarmonicInput, HarmonicSequence
- 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>, linewidths: ~typing.List[float] | None = None, freqs: ~typing.List[float] | None = None, psd: ~typing.List[float] | None = None, spectrum_method: str | None = None, aperiodic_exponent: float | None = None, spectral_flatness: float | None = None, ratios_source: str = 'peaks', ratios_alternates: ~typing.Dict[str, ~typing.List[float]] = <factory>)[source]#
Bases:
objectUnified harmonic input.
At least one of
ratiosorpeaksmust be provided. All list-typed optional fields, if given, must have lengths matching the number of components (len(ratios)orlen(peaks)).- Parameters:
ratios (list of Fraction or float, optional) – Frequency ratios. Coerced to
Fractionwhen a rational approximation withinDEFAULT_MAX_DENOMINATORexists.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
ratiosare given withoutpeaksto recover absolute frequencies.equave (float, default=2.0) – Equave width:
2.0for octaves,3.0for 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 inconsistentHarmonicInputraisesValueError.- 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]#
- linewidths: List[float] | None = None#
- freqs: List[float] | None = None#
- psd: List[float] | None = None#
- spectrum_method: str | None = None#
- aperiodic_exponent: float | None = None#
- spectral_flatness: float | None = None#
- ratios_source: str = 'peaks'#
- ratios_alternates: Dict[str, List[float]]#
- n_components() int[source]#
Return the number of harmonic components.
Resolved from
ratiosfirst, thenpeaks. At least one of the two is guaranteed to be present aftervalidate().
- to_peaks() ndarray[source]#
Return absolute peak frequencies in Hz as a 1-D
float64array.If
peaksis set, those values are returned directly. Otherwise peaks are reconstructed asbase_freq * ratios.
- to_ratios() List[Fraction | float][source]#
Return ratios.
If
ratiosis set, those values are returned. Otherwise ratios are derived aspeaks / base_freqand coerced toFraction.
- normalized_amplitudes() ndarray[source]#
Return amplitudes scaled to sum to 1.
If
amplitudesisNone, returns a uniform distribution over the components.
- validate() None[source]#
Raise
ValueErrorif the input is internally inconsistent.Checked invariants:
at least one of
ratios/peaksis given,equave > 1andbase_freq > 0,all list-typed fields have matching lengths,
all amplitudes are non-negative,
all peaks are positive,
if both
ratiosandpeaksare given, they agree up tobase_freqwithin 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_freqisNoneit 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, *, scale_priority: Sequence[str] | None = None, include_alternates: bool = True, include_spectrum: bool = True, include_fooof: bool = True) HarmonicInput[source]#
Build from a fitted
compute_biotunerinstance.Two selection modes for the canonical
ratios:Legacy mode (
scale_priorityisNone, the default) — reproduces the historical behaviour exactly: pullspeaks(required),ampswhen length-aligned, and usespeaks_ratiosas the canonical ratios when it’s 1:1 aligned with peaks.ratios_sourceis set to"peaks"andratios_alternatesis left empty so existing callers see no schema change.Scale-priority mode (
scale_priorityprovided) — walks the priority list in order (using the canonical names fromSCALE_KEYS), picks the first non-empty scale asratios, records its label inratios_source. Wheninclude_alternates=True(default), every other non-empty scale found onbtis stored inratios_alternatesunder the same canonical name. Amplitudes / linewidths are populated only if their lengths align with the chosen scale.
Tier-A spectral context is populated regardless of mode:
freqs/psd/spectrum_method(wheninclude_spectrum)aperiodic_exponent/linewidths(wheninclude_fooof)spectral_flatness(always, if available)
- Parameters:
bt (compute_biotuner) – A fitted biotuner object on which
peaks_extractionhas been called.equave (float, default=2.0)
scale_priority (sequence of str, optional) – Ordered preference for
ratios. Values must come fromSCALE_KEYS. Unknown keys raiseValueError.include_alternates (bool, default=True) – In scale-priority mode, populate
ratios_alternateswith every other non-empty scale found onbt. Ignored in legacy mode.include_spectrum (bool, default=True) – Copy
bt.freqs/bt.psd/bt.spectrum_methodif available.include_fooof (bool, default=True) – Copy
bt.aperiodic_exponentand a length-alignedbt.linewidthif available.
- Raises:
AttributeError – If
btlacks apeaksattribute.ValueError – If
bt.peaksis empty, orscale_prioritycontains an unknown key.
- class HarmonicSequence(frames: List[HarmonicInput], times: ndarray | None = None)[source]#
Bases:
objectTime-resolved sequence of
HarmonicInputframes.Pairs naturally with the output of
biotuner.transitional_harmonyandbiotuner.harmonic_sequence: each window’s peaks become a frame here, and downstream geometry functions can be applied frame-by-frame viatransformations.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#
- at(t: float) HarmonicInput[source]#
Return the frame nearest to time
t.
- interpolate(t: float, mode: str = 'log') HarmonicInput[source]#
Return a
HarmonicInputinterpolated to timet.Currently supports two-frame interpolation between the bracketing frames.
modeselects 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 raisesValueError. Richer interpolation (mismatched component counts, phase wrapping, etc.) is the job oftransformations.interpolate_inputin 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_biotunerobjects.Each biotuner object becomes one frame. Objects with no peaks are skipped; if every object is empty,
ValueErroris raised.- Parameters:
bt_list (sequence of compute_biotuner) – Fitted biotuner objects (
peaks_extractionalready 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.BiotunerGroupinstance.Uses
btg.objects(the per-seriescompute_biotunerinstances).BiotunerGroupmust have been constructed withstore_objects=True(the default).- Parameters:
btg (BiotunerGroup) – A group whose
compute_peakshas 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
btghas noobjectsattribute, or it isNone(e.g.store_objects=Falsewas used).