SSTIM stimulus interoperability and anti-aliasing

The optional music.stimulation.sstim_io module exports SSTIM 0.19.0 RDF descriptions that can be consumed back into MUSIC. Its portable semantic layer uses StimulusSpecification, StimulationSignal, StimulusChannel and SignalRendering, with declared mechanism, carrier, duration, frequency extent, and physical/perceptual presence.

The original five deterministic generators are supported here: binaural_beats, monaural_beats, isochronic_tones, amplitude_modulation and frequency_modulation. The library’s exact numeric arguments, including duty cycle and depth, are stored in a separate MUSIC extension namespace so that portable SSTIM terms are not falsely presented as an executable program. A third-party renderer understands the SSTIM triples, but must also understand these engine hints to reproduce MUSIC output sample-for-sample.

Install

pip install 'music[sstim,antialias]'

Create, validate and render an SSTIM description:

from music.stimulation.sstim_io import (
    to_sstim_graph, render_sstim, validate_sstim,
)

graph = to_sstim_graph(
    "binaural_beats",
    parameters={"carrier_freq": 200, "beat_freq": 10},
    duration=30,
    sample_rate=48000,
    base="https://your-institution.example/stimuli/run-001/",
)
report = validate_sstim(graph, version="0.19.0")
if not report.ok:
    raise ValueError(str(report))
graph.serialize("stimulus.ttl", format="turtle")
audio = render_sstim(graph)

This creates a stimulus specification, not a session execution record, a claim of effectiveness, or a statement that the listener actually received the audio. Use SSTIM’s own sstim.Session for executions with a clock and playback events.

If you import a Turtle description from another author, the engine will refuse an unknown generator, unexpected types, conflicting carrier/method assertions, or a non-portable rate. The input’s music-impl:generator is a closed enumeration, not an import path; parsing does not load remote URLs. It only renders a bounded subset, not arbitrary SSTIM graphs.

Anti-alias changing modulation and gates

music.bandlimited_note already removes out-of-band harmonics in static-pitch periodic waveforms. For glissandi, FM, abrupt pulses or nonlinear post-processing, filtering a low-rate WAV is too late: the aliasing already folded into the audible band. Render at a higher rate before those operations, then low-pass and decimate:

import music

sound = music.render_oversampled(
    music.isochronic_tones, sample_rate=48000,
    duration=5, factor=4, carrier_freq=12000,
    pulse_rate=100, duty_cycle=0.5,
)

The routine calls the original generator at 192 kHz and returns audio at 48 kHz, using SciPy’s polyphase resampling and Kaiser filtering. It accepts mono or channels-first audio, guarantees the output sample count, and does not normalize gain. The original generator still behaves exactly as before, with no changed defaults.

Important limits:

  • Oversampling is not an anti-alias guarantee for an arbitrarily fast FM or a waveform whose source was already sampled with folded energy.

  • Sharp pulse edges are deliberately rounded by low-pass filtering. A truly instantaneous edge necessarily contains unbounded harmonics.

  • Larger factors cost RAM and CPU, and convolution introduces short transient behavior at the boundaries. Benchmark against a higher-rate reference signal in the application’s frequency range.

  • For real-time applications, do not interpret this offline, array-based implementation as a low-latency streaming renderer.

Reproduce the DSP comparison:

python -m pytest tests/test_oversampling.py -q

The test compares direct 48 kHz rendering and 4x oversampled rendering against a 16x high-rate reference on a gated 15 kHz carrier. The criterion is a reduction in sample-domain reference error, not merely a better-looking spectrogram or an unqualified perceptual claim.

These capabilities are independent. render_sstim(..., oversampling_factor=4) combines them, but the SSTIM graph itself does not claim that its carrier was rendered alias-free.

For stochastic noise, geometric motion and multi-phase programs, see Advanced SSTIM exchange and spectral synthesis.