Carmen - Programmatic Music Composition
Table of Contents
- Features
- Prerequisites
- Installation
- Usage
- Examples
- Carmen Language Quick Start
- Development
- Community
- License
Carmen is a novel, programmatic language designed for music composition. It provides a flexible and expressive syntax to define musical structures, from simple melodies to complex multi-movement scores. It is built with a focus on clarity, modularity, and control, allowing composers and developers to create music through code.
Features
- Expressive Musical Notation: Define pitches, durations, chords, rests, and dynamics with a clear and concise syntax.
- Hierarchical Structure: Organize your music into sequences, multi-voice parts, staves, timelines, movements, and scores.
- Programmatic Control: Use variables, functions, conditionals (
if/else), and loops (for,while) to generate and manipulate musical material. - Powerful Transformations: Leverage built-in functions for music theory operations like transposition (
T), inversion (I), normal/prime form calculation, and more. - Context Management: Control tempo, time signatures, key signatures, and clefs at any point in the score.
- Extensible and Modular: Define reusable musical patterns with functions and extend musical parts to build complex compositions from simpler blocks.
- Multiple Export Formats: Export your compositions to various formats, including plain text summaries and LilyPond for beautiful sheet music engraving.
- Developer Tools: Includes tools for tokenizing, parsing, and inspecting the Abstract Syntax Tree (AST) of Carmen code for debugging and analysis.
Prerequisites
- Rust toolchain (for installation via cargo or building from source)
- LilyPond (optional, for generating beautiful sheet music from exported
.lyfiles)
Installation
Using Cargo (Recommended)
The easiest way to install Carmen is through Cargo, Rust's package manager:
This will download, compile, and install the carmen executable from crates.io.
Building from Source
For development purposes or to use the latest unreleased features, you can build from source:
You will need to have the Rust programming language toolchain installed on your system.
- Clone the repository:
- Build the project:
The compiled binary will be located attarget/release/carmen.
Usage
The carmen executable can be used to run scripts, start an interactive REPL, or export compositions.
Running a Script
To execute a script file, pass its path to the carmen executable:
Interactive REPL
To experiment with the language, you can run carmen without any arguments to start the interactive Read-Eval-Print Loop (REPL).
carmen Language REPL
Type 'exit' or press Ctrl+C to quit
carmen> 1/4 c4;
carmen> let theme = [1/8 [c4, d, e, f, g, a, b, c5]];
carmen> theme |> transpose(2);
Exporting a Score
Use the --export flag to convert a .carmen file into other formats.
# Export to LilyPond format
# Export to a plain text summary
Debugging
Carmen provides flags to inspect the compilation process, which is useful for debugging.
--tokenize: Shows the stream of tokens from the lexer.--parse: Displays the Abstract Syntax Tree (AST).--inspect: Provides a more detailed, human-readable view of the AST.
Carmen Language Quick Start
Here is a small example of a multi-staff piano part written in Carmen.
// File: example.carmen
score "Simple Piano Piece" {
@composer "Jane Doe";
@tempo 120;
timeline {
part "Piano" {
staff 0 { // Right hand
@clef "treble";
[1/4 c5, 1/8 d5, 1/2 e5];
};
staff 1 { // Left hand
@clef "bass";
[1/4 c3, 1/8 g3, 1/2 e4];
};
};
};
};
To compile this and generate a LilyPond file for sheet music:
Once you have the example.ly file, you can generate a PDF of the sheet music using LilyPond:
For a complete guide to the language syntax and features, please see the Language Manual.
Examples
Basic Melody
// Simple melody with rests and dynamics
let melody = [
1/4 c4 mf,
1/8 d4,
1/8 e4,
1/2 f4 p,
1/4 ~
];
Multi-Voice Bach Chorale
Carmen excels at complex multi-voice compositions. Here's an excerpt from Bach's BWV 147:
let voice_1 = [
1/12 [~, g4, a, b, d5, c, c, e, d, d, g, fs, g, d, b4, g, a, b, c5, d, e, d, c, b4, a, b, g],
1/12 [fs4, g],
3/12 a4,
1/12 [g4, c5, b4, a],
];
let voice_2 = [
1/12 [~, b3, d4],
1/4 [d4, e, g, e, b3, a, d4],
1/2 c4,
1/4 [a3, fs4]
];
score "BVW 147" {
@composer "J S Bach";
@title "BVW 147";
@key_signature "G";
@time_signature 3/4;
@tempo 100;
timeline {
part "Violin" {
@clef "treble";
voice_1;
};
part "Violin 2" {
@clef "treble";
voice_2;
};
};
};
Musical Transformations
// Define a theme and apply transformations
let theme = 1/4 [c4, d, e, f];
// Apply transformations
let transposed = theme |> transpose(7); // Transpose up a perfect fifth
// Pitch class set analysis
let chord_set = {0, 4, 7}; // C major triad as pitch classes
let normal = chord_set |> normal_form(); // Get normal form
let prime = chord_set |> prime_form(); // Get prime form
let ic_vec = chord_set |> ic_vector(); // Get interval class vector
let inverted = chord_set |> invert(2); // Get inversions
Multi-Staff Piano Score
score "Piano Piece" {
@composer "Carmen User";
@tempo 120;
@time_signature 4/4;
timeline {
part "Piano" {
staff 0 {
@clef "treble";
[1/4 c5, 1/8 d5, 1/2 e5];
};
staff 1 {
@clef "bass";
[1/4 c3, 1/8 g3, 1/2 e4];
};
};
};
};
For more examples, see the examples/ directory.
Development
If you want to contribute to Carmen or work on the project for development purposes:
- Clone the repository:
- Build in debug mode:
- Run tests:
- Run with your changes:
We welcome contributions! Please see our contributing guidelines for more information.
Community
- Issues & Bug Reports: GitHub Issues
- Documentation: Language Manual
- Crate Documentation: docs.rs/carmen-lang
License
This project is dual-licensed under the terms of the MIT License and the Apache License 2.0. You may choose to use this software under the terms of either license.