Skip to content
librazPublic

About

Pure-TypeScript, zero-dependency music theory engine: harmonic analysis, chord detection, chord and scale vocabulary, voicing and counterpoint, reharmonization, and seeded part generation over MIDI note events.

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

libcantus

CI npm PyPI codecov License C++ TypeScript Platform docs

Music theory for MIDI note events: recover the harmony from notes, and write new parts against that same reading.

One specification, a pure TypeScript reference implementation and a C++17 core under it, reachable from C++, WebAssembly, Node, Python and the command line. Every surface gives the same results and the same errors, and the surfaces over the core give the same floating-point bits on every platform.

Documentation · Getting started · Packages and surfaces

From note events to parts, and back

What's inside

  • Harmony from notes. Chord and key detection, Roman numerals, cadences, modulation, form. Analysis
  • Parts against the harmony. Progressions, bass, counter-melody, drums, motifs, seeded and reproducible. Generation
  • Theory vocabulary. Notes, intervals, scales, chords, voicing, part-writing and counterpoint checks. Harmony
  • Playability. Instrument profiles, transposition and range checks. Instruments
  • Evidence in answers. Each reading carries its rationale and the readings it turned down; an undecidable question comes back null.

Surfaces

Surface Package Page
TypeScript (reference) @libraz/libcantus ts/
C++ CMake package cantus C++ core
WebAssembly @libraz/libcantus-wasm bindings/wasm/
Node native @libraz/libcantus-node (built from source) bindings/node/
Python libcantus bindings/python/
Command line cantus Command line

The TypeScript package is synchronous, dependency-free and tree-shakeable. The other surfaces call the C++ core and differ from it only in small, documented ways (C++ core and surface differences).

Installation and quick start

Each example reads the chord of C, E and G.

TypeScript, Node.js 22 or later:

yarn add @libraz/libcantus
import { detectChordBest } from '@libraz/libcantus';

detectChordBest([60, 64, 67]); // { rootPc: 0, quality: 'maj', intervals: [0, 4, 7] }

WebAssembly, ESM only; the same API and types:

yarn add @libraz/libcantus-wasm
import { detectChordBest } from '@libraz/libcantus-wasm';

detectChordBest([60, 64, 67]);

Code that imports @libraz/libcantus can switch to it without edits, through a package-manager or bundler alias: see Switching between pure TypeScript and WebAssembly.

Node native, from a checkout (make build-node):

import { detectChordBest } from '@libraz/libcantus-node';

detectChordBest([60, 64, 67]);

Python, 3.10 or later:

pip install libcantus
import libcantus

libcantus.detect_chord_best([60, 64, 67])

Command line, a release asset from GitHub:

cantus detectChordBest '[[60, 64, 67]]'

C++, CMake 3.24 and a C++17 compiler:

include(FetchContent)
FetchContent_Declare(cantus GIT_REPOSITORY https://github.com/libraz/libcantus.git GIT_TAG main)
FetchContent_MakeAvailable(cantus)
target_link_libraries(app PRIVATE cantus::cantus)
#include <cantus/cantus.h>

auto matches = cantus::detect_chord({60, 64, 67});

find_package(cantus) against an installed prefix and add_subdirectory work the same way. Runnable versions of these examples are in examples/ and run with make examples; the browser example there is a bundler template that make examples does not run.

Building from source

make build         # C++ core, command-line tool and tests in build/
make test-cxx      # run the C++ tests
make wasm          # WebAssembly package (needs Emscripten)
make build-node    # Node-API addon
make build-shared  # shared library for the Python binding
make examples      # build and run the examples in examples/ (not the browser one)

Documentation

The pages are also in Japanese under docs/ja/. Contributor rules are in CONTRIBUTING.md.

What it doesn't do

  • No I/O, notation or audio. No MIDI file reader or writer, no score rendering, no audio analysis, no playback. Bring your own parser and hand it note events. For the layer below, libsonare covers audio analysis, mastering, synthesis and SMF I/O; the two share no code and neither requires the other.
  • No microtonal analysis. Frequencies, cents and just-intonation ratios live in core, but everything above the pitch layer runs on twelve pitch classes.
  • No rāga or maqām-style modal grammars. WORLD_SCALES records the pitch material a tradition names, not the grammar built on it.
  • No corpus. Nothing is bundled to run statistics over.

License

Apache License 2.0.

About

Pure-TypeScript, zero-dependency music theory engine: harmonic analysis, chord detection, chord and scale vocabulary, voicing and counterpoint, reharmonization, and seeded part generation over MIDI note events.

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages