music.render_oversampled

music.render_oversampled(renderer, *, duration=2.0, sample_rate=44100, number_of_samples=0, factor=4, **parameters)[source]

Render at a higher sampling rate, low-pass, then downsample.

The renderer must accept number_of_samples and sample_rate, as music.note_with_fm, music.note_with_glissando, and music.isochronic_tones do. It must return samples with time on the last axis, either mono (N,) or channels-first (C, N).

Parameters:
renderercallable()

A sound generator. It is called once at the oversampled rate. Supply nonlinear operations inside it, before decimation.

durationfloat

Output duration in seconds, used when number_of_samples=0.

sample_rateint

Requested output sampling rate in Hz.

number_of_samplesint

Exact output sample count, overriding duration when nonzero.

factorint

Oversampling multiplier, an integer from 2 to 16.

**parameters

Passed to renderer unchanged, except the sample count and rate.

Returns:
ndarray

Mono or channels-first float64 samples, at exactly the requested count. No peak normalization is applied: preserve output levels.

Raises:
ValueError

On invalid sizes, non-finite samples, or wrong renderer shape.

ImportError

If SciPy is missing. Install with pip install ‘music[antialias]’.

Parameters:
  • renderer (Callable[[...], ArrayLike])

  • duration (float)

  • sample_rate (int)

  • number_of_samples (int)

  • factor (int)

  • parameters (Any)

Return type:

NDArray[float64]

Notes

Uses scipy.signal.resample_poly and a Kaiser-window low-pass filter. Filtering smooths intentional hard edges; alias suppression and an infinitely sharp pulse are incompatible at finite sample rate. Always benchmark audio quality and CPU/memory costs for your use case.

Examples

>>> from music import isochronic_tones
>>> signal = render_oversampled(
...     isochronic_tones, sample_rate=48000, duration=.02,
...     carrier_freq=12000, pulse_rate=100)
>>> signal.shape
(960,)