OSC Mini
A compact subtractive synth for learning the signal path.
A tonewheel organ with nine drawbars and no attack stage.
Engine preview
Not built for macOS, Windows or Linux
A tonewheel organ is not an additive synthesiser, and building it as one gets the sound wrong in ways you can hear on the first chord. There is exactly one generator, a shaft carrying 91 toothed wheels turning past magnetic pickups, and every key on every drawbar is a switch that taps some wheel on that shaft. This module is built that way round, and the consequences come out on their own.
The first is shared wheels. Play a C with the 4' drawbar out and the C above it with the 8' out, and there is one oscillator behind both, in one phase at one amplitude. They cannot beat and the sum is not twice as loud. That is why this instrument's big chords stay legible where a stack of per-note sine banks turns to mud.
The second is that there is no attack. The wheels never start and never stop, so a key produces no onset of its own, the only transient in the instrument is the contact closing, which is the key click. Turn the click to zero here and notes simply appear, which sounds synthetic because it is; the click is not dirt on the sound, it is the sound's only edge.
The third is foldback, and it is the one an approximation usually skips. Nine drawbars span four octaves of harmonics above the played note, the manual spans five, and the generator has seven and a half, so at both ends a drawbar asks for a wheel that does not exist and the instrument wires it to the same pitch class an octave nearer the middle. The top octave therefore stops getting brighter as you play up it, and the bottom octave has no true sub-bass because the 16' bar has folded up into unison with the 8'. Both are famous parts of how the instrument feels under the hands, and neither is something anyone would add on purpose.
One genuine interlock is modelled and is worth knowing about before it surprises you: switching percussion on takes the 1' drawbar out of circuit, because the percussion one-shot borrows that busbar's contacts. That is true of the hardware and is not defeatable there either, it is why organists treat percussion and the 1' bar as alternatives.
This is a preview instrument. The DSP is hand-written Web Audio in the website's stand-in engine, good enough to hear foldback bite at the top of the keyboard and the horn reach speed before the drum does, but it is not a compiled kernel and it is not covered by any parity claim.
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.
| Format | Result | Download |
|---|---|---|
| Browser package (JS) | Not built by this module's lane this module has no release.json; its packager lane records no browser program rows | Not built for the browser |
| Browser package (WASM) | Not built by this module's lane this module has no release.json; its packager lane records no browser program rows | Not built for the browser |
| VST3 | Not built — the native export is blocked native-export.json records nativeEligibility "blocked" | Not built for macOS, Windows or Linux |
| Audio Unit | Not built — the native export is blocked native-export.json records nativeEligibility "blocked" | Not built for macOS |
| CLAP | Not built — the native export is blocked native-export.json records nativeEligibility "blocked" | Not built for macOS, Windows or Linux |
| Standalone app | Not built — the native export is blocked native-export.json records nativeEligibility "blocked" | Not built for macOS, Windows or Linux |
Parity
No lane recorded an artifact; there is no parity evidence.
Start from a named sound, then adjust the instrument to make it yours.
Migration fallback: approximated from parameter groups, not a runtime wiring diagram.
The generator is 79 sine oscillators, one per wheel from 13 to 91, started when the instrument is mounted and never stopped. Wheels 1 to 12 exist on the real shaft but drive the pedal division only, so no manual tap can reach them, which is exactly what makes the 16' drawbar fold up in the bottom octave rather than reaching for a wheel that is not wired to the manual. A key is nine GainNodes, one per drawbar, each connecting its wheel to that drawbar's busbar; it creates no oscillators, which is why polyphony here costs almost nothing and why two keys wanting the same pitch get one wheel between them.
Foldback is one rule applied at every tap. The wheel a key wants is its own wheel number plus the drawbar's semitone offset; if that lands above 91 it comes down an octave until it fits, and if it lands below 13 it goes up. Worked over the 61-key manual this reproduces the published table exactly: the 16' bar folds for the bottom twelve keys, the 8', 5⅓' and 4' bars never fold at all, and the treble folds begin at different keys per bar, the last key for 2⅔', the top six for 2', ten for 1⅗', thirteen for 1⅓' and eighteen for 1'. The wheel pitches are equal-tempered at A440; the real generator's gear ratios differ from that by a fraction of a cent, which is not what makes the instrument sound like itself, so the gear table is deliberately not modelled.
A drawbar is a slider on a resistance ladder with nine taps about 3 dB apart, so position 8 is unity and position 1 is 21 dB down. Position 0 is not one more step down: it is the bar out of circuit and therefore exactly silent, which is why a registration digit of 0 means the harmonic is absent rather than quiet. Percussion borrows the 1' busbar's contacts, so switching it on takes that bar out of circuit, modelled here because a bar that goes silent with no explanation looks like a bug.
The scanner is two web-fx primitives rather than one bespoke effect, because the hardware is one mechanism read two ways: the vibrato line box's delayed output alone is pitch modulation, and summed back against the dry signal it is beating. That is precisely the difference between the vibrato primitive (100% wet) and the chorus primitive (a fixed dry sum), so V1-V3 and C1-C3 are six depth settings across the two, at the fixed 6.9 Hz the scanner motor turns at. Both are built once and only their send gains move, so throwing the switch mid-phrase crossfades rather than rebuilding the graph.
The rotary cabinet is a crossover at 800 Hz feeding two independently turning radiators, and each rotor does three things at once to whatever it radiates: the source approaches and recedes (Doppler, so pitch), it points at and away from the microphones (amplitude), and it sweeps across the stereo pair (position). Those are the vibrato, tremolo and auto-panner primitives, three per rotor, all driven from one rate. The horn swings hardest in position and level because it is directional; the drum mostly just moves.
Speed changes are ramped rather than switched, and the two rotors ramp differently: the light horn reaches tremolo in about a second and coasts down slower, while the heavy drum takes two to three. That asymmetry is the whole gesture, the recognisable part of a rotary is the deceleration into chorale, not either steady state. The ramp is driven by a timer at twenty writes a second rather than by an AudioParam schedule, because the values that have to move are LFO frequencies inside effect primitives and a primitive owns its own parameters; reaching past its setParam to schedule on its oscillator would be exactly the reach into an effect the fx contract exists to prevent.
Gain staging leans on the amplifier rather than on headroom arithmetic. Nine drawbars at full across a ten-note chord is a sum well past unity, and scaling every tap down to fit that worst case would make ordinary playing inaudible. Instead the preamp's soft-clip curve is never fully linear, its asymptote is bounded for any nonzero drive, and the stage's makeup gain is the reciprocal of that ceiling, so the output cannot exceed full scale at any setting and turning the drive up gets louder and dirtier together rather than only dirtier.