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
SEVEN HARMONY MODES · ONE ENGINE

PICK A RULE.

From diatonic thirds to strict species counterpoint. Each mode is one function in /src/harmony/modes.

◆ ◇ ◆ ◇ ◆ PICK A MODE
PARALLEL 3RDS · HarmonyMode::DIATONICTHIRDS

DIATONIC THIRDS

+2 scale degrees above melody
Stays in key (snaps via harmonize_smart)
Handles out-of-key via modal interchange
Stateless
LIVE · CLICK A FRET
E2A2D3G3B3E4357912
◆ ◇ ◆ ◇ ◆ PRACTICE
PLAY WITH IT

SAME MELODY. DIFFERENT MODE.

LIVE · CLICK A KEY

PLAY ONE NOTE. HEAR COUNTERPOINT.

◆ ◇ ◆ ◇ ◆ VOICE LEADING
ORTHOGONAL TO MODE

HARMONY MODES PICK PITCHES. STYLE RULES PICK VOICINGS.

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