let harmony = Engine.new(Palestrina);
fn detect_pitch(buf) -> Note
const MAX_VOICES: usize = 4;
voice_leading.reject_parallels()
struct GuitarInput { onset }
engine.harmonize(note, scale)
fn detect_pitch(
  buf: &[f32]
) -> Option<Note>
let voices =
  counterpoint::
    generate(line, mode);
if interval == Fifth
  && motion == Parallel
  { reject() }
#[inline(always)]
fn onset(
  frame: &Frame
) -> bool
block_size: 128
sample_rate: 48_000
latency_ms: 7.2
// Palestrina
// counterpoint
// rules.rs
CONTRAPUNK WEEKEND JAM·WK 01·Koji Kondo· STARTS IN 2DAYS→ /jam
THE ENGINE · RUST · WASM · CLAP

ONE RUST CORE.
THREE SURFACES.

The same solver runs in the desktop app, the browser, and hosts CLAP plugins inside itself. No AI. No network. Just the code in /src/harmony.

◆ ◇ ◆ ◇ ◆ PITCH DETECTION
MCLEOD + SINGLE-CYCLE

2.7MS TO KNOW WHAT YOU PLAYED

128-sample buffer at 48kHz. Autocorrelation with the McLeod variant picks the period; single-cycle refinement locks the pitch.

BUFFER128 samples2.7ms @ 48kHz
ALGORITHMMcLeod + single-cycle refineF0 + confidence
ONSETspectral flux + RMS gatere-attack detection
TOTALpluck → MIDI-out< 10ms on M-series
◆ ◇ ◆ ◇ ◆ VOICE-LEADING SOLVER
FOUR STYLE PRESETS · STRUCT-LEVEL WEIGHTS

THE RULES, AS NUMBERS

Contrapunk's solver is a cartesian-product enumerator over legal voices, pruned by hard rules, scored by a weighted sum. Swap presets to change the aesthetic.

STYLE_RULES::PALESTRINA

PALESTRINA

16th-century strict species

Hard reject parallel 5ths
Hard reject parallel 8ves
Max leap (semitones)5 (P4)
Stepwise bonus+60
Common-tone bonus+45
Leap penalty / semitone−15
Voice-cross penalty−150
Spread preference−4 (tight)
Contrary motion bonus+40
LIVE · CLICK A FRET
E2A2D3G3B3E4357912
◆ ◇ ◆ ◇ ◆ VOICE REGISTERS
SATB · FIXED MIDI RANGES

WHERE EACH VOICE LIVES

Every candidate note is clamped to its voice's register before scoring. Centering bias picks the opening chord.

SOPRANOC4–C6
ALTOG3–E5
TENORC3–A4
BASSE2–E4
MIDI 36 — 84 · CENTER MARK = FIRST-CHORD PREFERENCE
◆ ◇ ◆ ◇ ◆ PLUGIN HOST
CLAP · clack-host

HOST YOUR OWN INSTRUMENT

The app links clack-host, a safe Rust wrapper over the CLAP ABI. Load a .clap synth; Contrapunk routes the generated MIDI straight into it and mixes the audio out.

CLAP PLUGIN HOST · clack-host
SLOT 01 · INSTRUMENT
VITAL.clap
wavetable · 2 in · 2 out
HARMONY
→ MIDI →
PLUGIN
→ AUDIO →
OUT
CLAP ABI · SAFE WRAPPER · GUI, LOG, AUDIO-PORTS, NOTE-PORTSROUTING HARMONY → INSTRUMENT
◆ ◇ ◆ ◇ ◆ THE STACK
CORE
Rust · no_std-friendly
/src/harmony, /src/dsp
DESKTOP
Tauri v2
native window · plugin host
BROWSER
WASM · Web Audio API
same core · no install
MIDI
midir · virtual ports
route into any DAW
AUDIO
cpal · CoreAudio/ASIO
lock-free ring buffers
PLUGINS
clack-host · CLAP
GUI, log, audio + note ports
GET CONTRAPUNK

THREE WAYS IN.
ALL FREE.

Browser at app.contrapunk.com. macOS DMG from GitHub Releases. Build from source with cargo tauri dev.