Chroma

Chromagram: CQT magnitudes folded onto pitch classes and peak-normalized per frame, the standard representation for chord and key analysis. Rows are ordered C, C#, D, … for the default twelve classes.
specux.chroma(x, *, sr, hop_length=512, n_chroma=12, bins_per_octave=36, n_octaves=7, fmin=None, tuning=0.0, backend="auto")import numpy as np
import specux
x = np.random.randn(4 * 22050).astype(np.float32)C = specux.chroma(x, sr=22050)C.shape # (12, 173) = (..., n_chroma, n_frames)import torch
import specux
xt = torch.randn(8, 4 * 22050, device="cuda", requires_grad=True)C = specux.chroma(xt, sr=22050)C.sum().backward()import cupy
import specux
xc = cupy.random.standard_normal((8, 4 * 22050), dtype=cupy.float32)C = specux.chroma(xc, sr=22050)Parameters
sr: sample rate in Hz.hop_length: frame advance; divisibility as in the CQT.n_chroma: pitch classes per octave; must dividebins_per_octave.bins_per_octave: CQT bin density under the fold (default 36, three bins per semitone).n_octaves: octave span of the underlying CQT (default 7, C1 up).fmin: lowest CQT frequency;Nonemeans C1, which puts pitch class 0 on C.tuning: bin offset in fractions of a bin.backend:"auto","cuda","cpu", or"metal".
The per-frame peak normalizer is treated as a constant in the backward pass, so gradients flow through the folded magnitudes but not through the normalization itself.
The configured form
specux.Chroma holds the parameters; to_dict() round-trips the
configuration. The torch Module for training pipelines is
specux.transforms.Chroma.
t = specux.Chroma(sr=22050, n_chroma=12)C = t(x) # (..., n_chroma, n_frames)assert specux.Chroma(**t.to_dict()) == t