A stage of OSC-1. It works the same on its own page as it does in the chain — same parameters, same paths.
Oscillator
Two tone generators and the interval between them.
Audio and MIDI
Browser session
Audio is stopped.
Input · MIDI keyboard
Your keyboard is a keyboard. Middle row plays the white notes, top row the black ones. Z and X change octave. Keys are ignored while you are typing in a field.
Oscillator
The source stage: two oscillators with independent wave, octave, detune and level. Everything downstream is shaping what this makes, so it is the first thing worth understanding.
Parameters
Oscillator 1
Oscillator 2
These knobs move the module's published schema, but the preview engine only renders OSC Mini, FX Mini and the OSC-1 chain — so they won't change what you hear yet.
Output · Audio signal
The signal leaving Oscillator, tapped after the output stage. It's a picture of what your speakers are getting.
About
The source stage: two oscillators with independent wave, octave, detune and level. Everything downstream is shaping what this makes, so it is the first thing worth understanding.
Take it into your DAW.
Same DSP as this page. The plugin isn't a rebuild — it's the identical kernel from the identical TypeScript source, compiled native instead of to WASM.
Free forever, no account, and playing it in the browser will never ask you for one. VST3 and standalone today; AU and CLAP are on the roadmap.
Every knob, and what it actually does.
Generated from the module's parameter schema — the same source as the web UI, the worklet transport and the VST3 parameter table, so it cannot drift.
| Param | Range | Default | Units | What it does | Automatable |
|---|---|---|---|---|---|
| Oscillator 1 | |||||
Osc 1 Waveoscillator.osc1Type | sine · square · sawtooth · triangle | sawtooth | — | Waveform for the first oscillator. Sawtooth has every harmonic and is the usual starting point; sine has none, so a filter has nothing to remove. | Yes (stepped) |
Osc 1 Leveloscillator.osc1Level | 0 … 1 | 0.7 | — | Level of the first oscillator into the mix. | Yes |
Osc 1 Octaveoscillator.osc1Octave | -3 … 3 | 0 | oct | Transposes oscillator 1 in whole octaves. | Yes (stepped) |
Osc 1 Detuneoscillator.osc1Detune | -100 … 100 | 0 | ct | Fine pitch offset in cents, one semitone either way. | Yes |
| Oscillator 2 | |||||
Osc 2 Waveoscillator.osc2Type | sine · square · sawtooth · triangle | square | — | Waveform for the second oscillator. | Yes (stepped) |
Osc 2 Leveloscillator.osc2Level | 0 … 1 | 0.3 | — | Level of the second oscillator. Keep it under oscillator 1 and it thickens; match them and it becomes a chord of two. | Yes |
Osc 2 Octaveoscillator.osc2Octave | -3 … 3 | 0 | oct | Transposes oscillator 2 in whole octaves. Down one is the classic sub. | Yes (stepped) |
Osc 2 Detuneoscillator.osc2Detune | -100 … 100 | 7 | ct | Fine pitch offset for oscillator 2. Seven cents is the default because a small mismatch is what makes two oscillators sound like more than two. | Yes |
Parameter paths (filter.cutoff) are what you'll see in your DAW's automation list and in the SDK. Same names everywhere.
How it works.
Two oscillators run at the note frequency, each offset by its own octave and detune, and sum into the stage output at their respective levels. There is no unison stack and no phase reset - two voices, honestly counted.
The detune default of seven cents is not arbitrary. Two perfectly-tuned oscillators sum into one louder oscillator; a few cents of mismatch produces a slow beat between them, and that beat is most of what people mean when they say a synth sounds fat.
It's yours to read and to fork.
Research preview
npx codex clone oscillator
npm run devThe codex CLI name is proposed, not shipped. That command gives you this module's DSP, schema, presets and UI as a local project — change a number, hear it immediately.