
Gamelan
Modelled bronze instruments with flexible tuning.
Engine preview
VST3
About
A gamelan is not a piano with a different sample set. Its bars and gongs are inharmonic, the partials sit at ratios like 2.3 and 3.6 rather than 2 and 3, and its scales have five or seven notes to the octave, tuned by the smith rather than by a table. Both facts are structural, and an instrument that ignores either one ends up sounding like a bell patch. This module takes them as the starting point.
The sound is modal synthesis: each note is a short mallet strike convolved with a synthesised impulse response built from that instrument family's measured partial ratios, pitch-scaled to the note being played. Nothing is sampled. Changing the instrument rebuilds the partial set, which is why Gong Ageng and Peking are not the same sound transposed, they have different numbers of partials at different ratios with different decay profiles.
Tuning is part of the instrument, not a global setting somewhere else. In Scale maps every input to the nearest root-relative slendro or pelog bar, while 12-TET leaves all chromatic notes available. The panel shows both the selected root and where each key lands.
This is a preview instrument. The DSP is hand-written Web Audio in the website's stand-in engine, good enough to play and to hear the microtuning clearly, but not a compiled kernel and not covered by any parity claim.
System requirements.
The downloadable Gamelan release supports the hosts and systems listed below.
- VST3macOS · arm64
Works in Ableton Live, Reaper, Cubase, Studio One, Bitwig and FL Studio.
Build evidence
Every row below is a recorded build row or the recorded absence of one. Nothing here is inferred from what this module is meant to support.
- Module
- music.codex.gamelan v0.0.0
- Built at
- Closure hash
- 38eaf365fbc8…
- Toolchain
- scriptc 64acce1ae3b8…
- moduleToolchainDist c621ffab721d…
- pluginShellKitRuntime bca003784692…
- faceShellGeneration 8533207ab81f…
- uiPreservation cd28dbd7e3d6…
- packagerVersion 3
| Format | Result | Download |
|---|---|---|
| Browser package (JS) | Builtweb bundle sha256 ab521a39d01d… · 644 KB | Built, but no downloadable archive was recorded. |
| Browser package (WASM) | Builtweb bundle sha256 1ec8d5448882… · 2.0 MB | Built, but no downloadable archive was recorded. |
| VST3 | Builtdarwin-arm64Steinberg validator + VST3 host render: passed bundle sha256 73ebfc15a1ac… · 2.2 MB | CodexGamelan-vst3-darwin-arm64.zip archive sha256 2a53991af3eb… · 2.2 MB · darwin-arm64 |
| Audio Unit | Not built no recorded artifact row for au; native-lane-report.json is absent or records no au row for this module | Not built for macOS |
| CLAP | Not built no recorded artifact row for clap; native-lane-report.json is absent or records no clap row for this module | Not built for macOS, Windows or Linux |
| Standalone app | Not built no recorded artifact row for standalone; native-lane-report.json is absent or records no standalone row for this module | Not built for macOS, Windows or Linux |
Parity
browser-js = browser-wasm = vst3 qualified against their own recorded digests. Not recorded: au, clap, standalone.
Presets
Start from a named sound, then adjust the instrument to make it yours.
Signal graph.
ExperimentalMigration fallback: approximated from parameter groups, not a runtime wiring diagram.
How it works.
Each note is an exciter driving a resonator: a two-to-twelve millisecond filtered noise burst with a leading click, convolved with an impulse response synthesised for that exact note. The IR is a bank of exponentially-decaying sinusoids placed at the instrument's measured partial ratios, 1, 2.3, 3.6, 5.25, 7.1, 9.35 for a bar metallophone, 1, 1.52, 2.33, 2.9, 3.98 for a hanging gong, pitch-scaled from the fundamental the ratios were measured at. Convolving the strike with those modes is what excites them, which is why Hardness changes the balance of partials and not just the brightness: a wider excitation spectrum reaches further up the inharmonic series.
Ombak is modelled where it actually happens. Paired gamelan instruments are tuned a few Hz apart so their combination beats, so the renderer places each mode at f minus half the ombak rate in the left channel and f plus half in the right. The beating you hear is genuine interference between two detuned partials, not an amplitude modulation applied afterwards, which is also why it survives being played polyphonically instead of all the voices pulsing in lockstep.
Strike position is in the impulse response, not on top of it. Every mode of a bar or a plate has a standing-wave shape, and how strongly a strike excites that mode is how far the surface moves at the point you hit, so each mode's amplitude is multiplied by its shape at the strike position before the IR is rendered. A bar's modes alternate symmetric and antisymmetric about its centre, so a centre strike wakes modes 1, 3 and 5 and leaves 2 and 4 at the floor; a gong's alternate between nodal circles and nodal diameters, so the boss gives you the fundamental and the rim gives you the shimmer. Nothing is weighted to exactly zero, because a real mallet has width and never lands on a mathematical point. Size scales the same bank three ways at once: it lengthens the decay, slows the ombak, and bends the partial ratios toward or away from harmonic about the fundamental, which stays put, so a bigger instrument is a different instrument rather than a transposition.
Velocity is the one place the preview and the compiled kernel do different arithmetic, and it is worth saying which. The kernel tilts each mode individually per strike. A convolver cannot: the impulse response is shared across velocities by construction, and rebuilding a three-second stereo IR per keystroke is not something a main thread can do. So the same physics is applied one stage earlier, in the exciter, a soft hit has a longer contact time and therefore a narrower excitation spectrum, which is exactly what the Hardness control already moves, so velocity is coupled into it through Vel Tone. Level follows velocity squared on both paths. The result is audibly the same gesture and is not the same computation, which is the honest summary of this whole module.
Rendering an IR is a few hundred thousand sine evaluations, so they are cached by instrument, note frequency and every timbre parameter that feeds the renderer. Play a scale and the cache fills note by note; move Damping or Ombak and the whole cache is dropped, because those parameters change the samples themselves rather than how they are played back. Voices are capped at eight with oldest-first stealing, and every voice's nodes are freed on a hard seven-second tail cap with a short fade, Gong Ageng's impulse response is six seconds long and convolution adds that to the note, so without the cap a few gongs would pile up convolvers indefinitely.
Tuning runs before any of that. A MIDI note goes through the shared tuning library, which returns either a frequency or null; null means the key is unmapped in the current scale and the voice is never created. Slendro maps five degrees onto C, D, E, G and A, pelog seven onto C, C#, D, E, F, G and A, and everything else is silent. Custom mode is equal temperament with a cents offset per pitch class, which is the practical way to dial in a specific gamelan's tuning by ear.
Goes well with.
Pluck
A physical string model, rendered per note.
OSC Mini
A compact subtractive synth for learning the signal path.
Space Mini
Convolution reverb: eight synthesized spaces, twenty-five real cabinets.






