Audio Output
Shippingstatefulaudio_outputSpeaker-playback sink with live re-trigger guard and monitor mode
Signature
Inputs
signalSignal— left/mono channelsignalRSignal— right channel
Description
Audio Output is a terminal sink that plays its input signal(s) through the operating system's audio device. Wire a mono or left channel into signal and, optionally, a right channel into signalR to drive stereo playback. It has no output ports and produces no data downstream — its effect is purely the physical act of sound rendering.
The node is stateful: it holds a PlaybackGuard recording the signature of the last-played buffer. In LIVE evaluation this re-trigger guard suppresses redundant replays, so identical input on successive ticks does not restart the sound; playback re-arms only when the input signature changes. A live-monitor mode bridges an active capture directly to the output for low-latency hear-through.
Both inputs are optional. An unfed or empty signal is a no-op rather than an error, which lets the node sit in a graph and stay silent until upstream data arrives. Audio samples are treated as dimensionless amplitude in ; physical units and uncertainty ($\sigma$) carried by the incoming Signal are consumed at the boundary and not rendered — only the sample magnitudes reach the DAC.
The node declares no core param_specs. Playback behavior is configured entirely from the Dart node inspector, which supplies rich device controls read at runtime: device_id, volume, sample_rate, loop, normalize, fade_in, and fade_out (camelCase keys are honored).
Mathematics
Examples
Mono tone to the speakers
Feed a signal_generator sine into signal. In LIVE mode the tone plays once; because the buffer signature is unchanged on subsequent ticks, the PlaybackGuard prevents it from stuttering or restarting. Change the frequency and the new signature re-arms playback automatically.
Stereo playback with normalization
Wire the left channel into signal and the right into signalR. Enable normalize in the inspector to rescale peak amplitude to full-scale, and set volume to attenuate:
signal (L) --> audio_output.signal
signalR (R) --> audio_output.signalR
inspector: normalize=true, volume=0.7, fade_in=0.05Applications
- Auditioning synthesized or processed waveforms directly from the graph during DSP prototyping
- Low-latency live monitoring of a `hardware_source` or microphone capture (hear-through)
- Sonification of scientific data — mapping a measured signal to audible amplitude for auditory inspection
- Playback of filtered or reconstructed audio (e.g. after `iir_filter` or `inverse_fft`) for A/B listening tests
Neat
It is a sink with zero output ports, yet it is stateful: the `PlaybackGuard` signature is what makes LIVE re-evaluation idempotent instead of a machine-gun of restarts.
The Rust core exposes no parameters at all — every audio-device control is injected by the Dart inspector and read by key at runtime, so the same node adapts to new controls without a core schema change.
Known issues
Units and uncertainty on the input Signal are discarded at the audio boundary; a signal whose amplitude exceeds $[-1, 1]$ will clip harshly at the DAC unless `normalize` or an upstream `clip` bounds it.
The re-trigger guard keys on the buffer signature, so two acoustically different buffers that hash to the same signature could be suppressed, and continuously varying live input effectively re-arms every tick.