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
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

DIATONIC FOURTHS

+3 scale degrees above melody
Chromatic fallback when out of key
Open / quartal sound
Stateless
LIVE · CLICK A FRET
E2A2D3G3B3E43579121517192124
◆ ◇ ◆ ◇ ◆ PRACTICE
PLAY WITH IT

SAME MELODY. DIFFERENT MODE.

PLAY ONE NOTE. HEAR COUNTERPOINT.

◆ ◇ ◆ ◇ ◆ VOICE LEADING
ORTHOGONAL TO MODE

HARMONY MODES PICK PITCHES. STYLE RULES PICK VOICINGS.

PALESTRINA

16th-century strict species

MotionMostly stepwise
VoicingTight
Common tonesHeld when possible
Contrary motionEncouraged
LIVE · CLICK A FRET
E2A2D3G3B3E43579121517192124