OPM.js documentationOnline demos

Generated from Markdown source. Edit the source, not this HTML.

Sound design workflow #

Example 12 (checkout-only) is a browser FM designer built only on the public API (OPM, playNote, updateNote). It is a demo helper, not part of the engine. Start it over HTTPS or localhost, click Start, then hold a note (button or Space) and edit while it sounds. Begin at a low device volume: host gain defaults to 0.15 and is capped at 0.3.

What you can edit #

AreaControls
TopologyAlgorithm 0–7 with a live signal graph (arrows run from modulator to recipient; carriers reach the output), operator-1 feedback 0–7, modulation index
OperatorsRatio, level, detune, waveform, noise hold rate (20–20000 Hz) and four-stage ADSR for each operator
LFORate, AM depth, PM cents, waveform, delay, note/global sync, phase, and a 0–1 AM and PM target weight per operator (the selective-LFO fields)
EnvelopesA dB-versus-time plot of each operator for a chosen gate length. It evaluates the engine's own envelopeAt, so segments that are straight in dB are exponential in amplitude, and −96 dB is the engine floor.
Starting pointsEvery bundled recipe, with its provenance, intended register, velocity range and host trim shown beside it
AudioDSP profile (eco / standard / high), note, velocity, host gain

Live edits versus retriggers #

A held note is edited natively where the engine has a live control, and retriggered otherwise:

EditBehavior while a note is held
Operator ratiooperatorRatios ramp (20 ms)
Any ADSR stageoperatorADSR, re-anchored at the current dB level
Feedbackfeedback ramp (20 ms)
LFO rate, AM depth, PM depthlfoRate, amDepth, pmDepth ramp
Algorithm, selective target weights, level, detune, operator/LFO waveform, noise rate, delay/sync/phase, modulation indexThe note is released and retriggered, because these are fixed when a note is admitted
NameNo audio change

The envelope plot shows a fresh note. Key-rate scaling, pitch envelopes, velocity and the LFO can alter an actual note, and a live ADSR edit starts from the sounding level, so the plot is a guide rather than an oscilloscope.

Patch JSON #

The page exports and imports one canonical version 7 patch (at most 16 KiB). Import uses the strict single-voice path: unknown fields, accessors, non-finite numbers and out-of-range values are rejected visibly, and legacy versions 1–6 are normalized to version 7. The exported file can be passed straight to opm.playNote({ voice: patch, note: 60 }) or loaded with opm.loadVoice(name, patch). Nothing is uploaded; use the bank tools for many voices at once.

Choose noise for an unpitched deterministic held-noise oscillator; noise rate is ignored for periodic shapes. Ratio/fixed-Hz/live pitch controls do not pitch noise, but envelopes, levels, velocity, key scaling and AM still apply. Noise can modulate or act as a carrier on any operator, an OPM.js extension rather than a hardware-fidelity claim. Square/saw/noise are not alias-free despite per-voice oversampling. The recipe selector automatically includes original noise-snare, noise-hihat and explosion starting points; see oscillator formulas.

Designing with selective LFO #

By default the LFO touches every operator. Set pmTargets / amTargets to confine it:

tide_keys, ember_bass and orbit_pad in the voice quality guide are worked examples, and the audition page (checkout-only) can A/B them against other recipes with a held ratio/feedback/ADSR control phrase.

Limits #

The designer previews one note at a time on the main OPM instance of the page. It does not predict polyphonic loudness; leave headroom when chords are played (see the suggested polyphony and trim in the usage table). No listening judgment is built in.