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

HARMONY MODES

Compare diatonic harmony, contrary motion, and species counterpoint with the same input. Mode implementations are available in /src/harmony/modes.

◆ ◇ ◆ ◇ ◆MODE SELECTOR

DIATONIC FOURTHS

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

COMPARE MODES WITH THE SAME INPUT

COUNTERPOINT DEMO

◆ ◇ ◆ ◇ ◆VOICE LEADING
VOICE CONFIGURATION

VOICE-LEADING STYLES AND REGISTERS

PALESTRINA

16th-century strict species

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