Skip to main content
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
OPEN SOURCE · GITHUB · DISCORD

PROJECT COMMUNITY

Inspect the public work, ask a question, report a reproducible bug, or contribute a focused pull request.

01 · SOURCE

Inspect the engine

Read the Rust harmony engine, open issues, and review every merged change in public.

Browse the repository ↗
02 · DISCUSS

Join the conversation

Ask setup questions, compare musical workflows, and share reproducible feedback with other users.

Join Discord ↗
03 · CONTRIBUTE

Change the project

Report a bug or propose a focused pull request. The contribution guide explains the review path.

Read the guide ↗
◆ ◇ ◆ ◇ ◆RECENT COMMITS
  1. de71d36refactor(dsp): remove textbook Rust exercises (#197)Vibhav Bobade · 7d ago
  2. af83873feat(dsp): add Chapter 3 studio exercises (#195)Vibhav Bobade · 7d ago
  3. decf23afeat(dsp): add cumulative wavetable learning exercises (#192)Vibhav Bobade · 7d ago
  4. f16ee0efix(ui): keep scale keys piano-coloredVibhav Bobade · 8d ago
  5. c557bb5fix(harmony): apply spread changes to next notesVibhav Bobade · 8d ago
  6. 7134554fix(harmony): keep spread voicings in keyVibhav Bobade · 8d ago
  7. 4dfb985fix(routing): preserve input owners on stale harmony releaseVibhav Bobade · 8d ago
  8. 60335c4feat(determinism): add reset and close lifecycle gapsVibhav Bobade · 8d ago
  9. 66eb9f5chore(wasm): refresh bindings after rebaseVibhav Bobade · 8d ago
  10. f73a224refactor(harmony): keep held-owner replay explicitVibhav Bobade · 8d ago
  11. 85335fbfix(determinism): canonicalize performance lifecycleVibhav Bobade · 8d ago
  12. 992e776test(determinism): define end-to-end replay contractsVibhav Bobade · 8d ago
  13. f76ea67feat(routing): add all-to-synth overrideVibhav Bobade · 8d ago
  14. 1e41593fix(ui): address synth mixer review feedbackVibhav Bobade · 10d ago
  15. e715573fix(ui): keep inactive voice routes visibleVibhav Bobade · 10d ago
  16. c9996d8fix(ui): keep Elixir as the single synth mixerVibhav Bobade · 11d ago
  17. b56f051chore(deps): bump clap from 4.6.4 to 4.6.6 in the rust-minor-patch groupdependabot[bot] · 9d ago
  18. 9c38712fix(ui): anchor expression roll to bottom keyboardVibhav Bobade · 12d ago
  19. 87a13dcfix(presets): make cpk persistence safe and reloadableVibhav Bobade · 13d ago
  20. 8a2b0cafix(presets): resolve AppData path resolution and remount PresetManager UIPrashant Singh · 16d ago
AVAILABLE FORMATS

BROWSER, DESKTOP,
OR SOURCE.

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