Skip to content

Commit d4fbe57

Browse files
oubiwannclaude
andcommitted
docs: overhaul README for v0.4.0
Complete rewrite reflecting the new workspace structure, all 12 modules, correct crate names, ./bin/mt CLI examples, feature flags, code examples for harmony analysis, neo-Riemannian transformations, and set theory. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 11e2d76 commit d4fbe57

File tree

1 file changed

+204
-115
lines changed

1 file changed

+204
-115
lines changed

README.md

Lines changed: 204 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,156 +1,245 @@
1-
## Rust Music Theory
1+
# Music Theory for Rust
22

3+
[![CI](https://github.com/music-comp/mt-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/music-comp/mt-rs/actions/workflows/ci.yml)
34
[![Coverage](https://img.shields.io/badge/coverage-96%25-brightgreen)](https://github.com/music-comp/mt-rs)
4-
[![Crates.io](https://img.shields.io/crates/v/rust-music-theory.svg?style=flat-square)](https://crates.io/crates/rust-music-theory)
5-
[![Documentation](https://docs.rs/rust-music-theory/badge.svg)](https://docs.rs/rust-music-theory)
5+
[![Crates.io](https://img.shields.io/crates/v/music-comp-mt.svg)](https://crates.io/crates/music-comp-mt)
6+
[![Documentation](https://docs.rs/music-comp-mt/badge.svg)](https://docs.rs/music-comp-mt)
7+
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
68

7-
A library and executable that provides programmatic implementation of the basis of the music theory.
9+
[![][logo]][logo-large]
810

9-
## Table of Contents
11+
*A comprehensive music theory library and CLI for Rust*
1012

11-
- [Overview](#overview)
12-
- [Usage as a Library](#usage-as-a-library)
13-
- [Usage as an Executable](#usage-as-an-executable)
14-
- [Building From Source](#building-from-source)
15-
- [Roadmap](#roadmap)
13+
This library covers music-theoretic fundamentals through graduate-level theory: notes, intervals, chords, scales, harmony analysis, voice leading, neo-Riemannian transformations, pitch-class set theory, counterpoint, and figured bass.
1614

17-
## Overview
15+
Every music theory fact in the library has been verified against 4,315 concept cards from 29 authoritative textbooks.
1816

19-
`Rust Music Theory` is used to procedurally utilize music theory notions like Note, Chord, Scale,
20-
Interval and more. The main purpose of this library is to let music theory be used in other programs and produce music/audio in a programmatic way.
17+
Note that this project started as a fork of Ozan Kaşıkçı's [excellent library](https://github.com/ozankasikci/rust-music-theory).
2118

22-
## Usage as a Library
19+
## Quick Start
20+
21+
### As a Library
2322

24-
Add `rust-music-theory` as a dependency in your Cargo.toml.
2523
```toml
2624
[dependencies]
27-
rust-music-theory = "0.3"
25+
music-comp-mt = "0.4"
2826
```
2927

30-
After installing the dependencies, you can use the library as follows.
3128
```rust
32-
extern crate rust_music_theory as rustmt;
33-
use rustmt::note::{Note, Notes, Pitch, PitchSymbol::*};
34-
use rustmt::scale::{Scale, ScaleType, Mode, Direction};
35-
use rustmt::chord::{Chord, Number as ChordNumber, Quality as ChordQuality};
36-
37-
// to create a Note, specify a pitch and an octave;
38-
let note = Note::new(Pitch::from(As), 4);
39-
40-
// Scale Example
41-
let scale = Scale::new(
42-
ScaleType::Diatonic,
43-
Pitch::from(C),
44-
4,
45-
Some(Mode::Ionian),
46-
Direction::Ascending,
29+
use music_comp_mt::note::{Notes, Pitch, PitchSymbol::*};
30+
use music_comp_mt::chord::{Chord, Quality, Number};
31+
use music_comp_mt::scale::{Scale, ScaleType, Mode, Direction};
32+
use music_comp_mt::interval::Interval;
33+
34+
// Notes and chords
35+
let chord = Chord::new(Pitch::from(C), Quality::Major, Number::Triad);
36+
assert_eq!(chord.format_notes(), "Notes:\n 1: C\n 2: E\n 3: G\n");
37+
38+
// Correct enharmonic spelling everywhere
39+
let gm = Chord::new(Pitch::from(G), Quality::Minor, Number::Triad);
40+
let notes = gm.notes(); // G, Bb, D — not G, A#, D
41+
42+
// Identify chords from notes
43+
let matches = Chord::identify(&[Pitch::from(E), Pitch::from(G), Pitch::from(C)]);
44+
// Finds: C major, first inversion
45+
46+
// Calculate intervals between pitches (letter-aware)
47+
let interval = Interval::between(
48+
&Pitch::from(F),
49+
&Pitch::from(B),
4750
).unwrap();
48-
49-
let scale_notes = scale.notes();
50-
51-
// Chord Example
52-
let chord = Chord::new(Pitch::from(C), ChordQuality::Major, ChordNumber::Triad);
53-
54-
let chord_notes = chord.notes();
51+
// Augmented 4th (not diminished 5th — letters matter)
52+
53+
// Find scales containing a set of notes
54+
let scales = Scale::identify(&[
55+
Pitch::from(C), Pitch::from(D), Pitch::from(E),
56+
Pitch::from(Fs), Pitch::from(G), Pitch::from(A), Pitch::from(B),
57+
]);
58+
// Matches: C Lydian, G Ionian, ...
5559
```
5660

57-
For detailed examples, please see the tests folder.
61+
### As a CLI
5862

59-
## Usage as an Executable
63+
```sh
64+
cargo install music-comp-mt-cli
65+
```
6066

61-
`cargo install --git https://github.com/ozankasikci/rust-music-theory`
67+
After building with `make build`, the binary is at `./bin/mt`:
6268

63-
This lets cargo install the library as an executable called `rustmt`. Some usage examples;
69+
```sh
70+
$ ./bin/mt scale C Ionian
71+
Notes:
72+
1: C
73+
2: D
74+
3: E
75+
4: F
76+
5: G
77+
6: A
78+
7: B
79+
8: C
80+
81+
$ ./bin/mt chord G "dominant seventh"
82+
Notes:
83+
1: G
84+
2: B
85+
3: D
86+
4: F
6487

65-
`rustmt scale D Locrian`
66-
```yaml
88+
$ ./bin/mt scale D Locrian
6789
Notes:
6890
1: D
69-
2: D#
91+
2: Eb
7092
3: F
7193
4: G
72-
5: G#
73-
6: A#
94+
5: Ab
95+
6: Bb
7496
7: C
7597
8: D
98+
99+
$ ./bin/mt scale list
100+
$ ./bin/mt chord list
76101
```
77-
`rustmt chord C# Dominant Eleventh`
78-
```yaml
79-
Notes:
80-
1: C#
81-
2: F
82-
3: G#
83-
4: B
84-
5: D#
85-
6: G
102+
103+
## Modules
104+
105+
### Fundamentals
106+
107+
| Module | Description |
108+
|--------|-------------|
109+
| `note` | `Pitch`, `Note`, `NoteLetter`, `PitchSymbol`, `KeySignature`, enharmonic equivalence, transposition |
110+
| `interval` | Simple and compound intervals (0-24 semitones), quality/number classification, letter-aware `between()`, inversion |
111+
| `chord` | 22+ chord types, letter-based spelling, identification with inversion detection, regex parsing |
112+
| `scale` | 8 scale types, 14 modes, identification from notes, ascending/descending support |
113+
114+
### Harmony & Analysis
115+
116+
| Module | Description |
117+
|--------|-------------|
118+
| `harmony` | Diatonic triads/sevenths, common tones, chord-scale compatibility, pivot chords |
119+
| `analysis` | Roman numeral labeling (I, vi, V7, vii°, etc.), secondary dominant detection (V/x) |
120+
| `voice_leading` | Optimal voice assignment minimizing total semitone movement |
121+
122+
### Advanced Theory
123+
124+
| Module | Description |
125+
|--------|-------------|
126+
| `neo_riemannian` | P, R, L operations on triads with chaining |
127+
| `set_class` | `PitchClassSet` with normal/prime form, T_n, I_n, interval vector, Forte numbers |
128+
| `counterpoint` | First-species rule checking (parallel 5ths/8ves, consonance, voice crossing) |
129+
| `figured_bass` | Realize figured bass symbols into chord voicings |
130+
131+
## Feature Flags
132+
133+
| Flag | Description |
134+
|------|-------------|
135+
| `midi` | Enables `Note::midi_pitch()` for MIDI pitch number conversion |
136+
| `serde` | Derives `Serialize`/`Deserialize` on all public types |
137+
138+
```toml
139+
music-comp-mt = { version = "0.4", features = ["serde", "midi"] }
140+
```
141+
142+
## Examples
143+
144+
### Harmony Analysis
145+
146+
```rust
147+
use music_comp_mt::harmony;
148+
use music_comp_mt::analysis;
149+
use music_comp_mt::note::{Pitch, PitchSymbol::*};
150+
use music_comp_mt::chord::{Chord, Quality, Number};
151+
use music_comp_mt::scale::Mode;
152+
153+
// Diatonic chords in C major
154+
let chords = harmony::diatonic_triads(Pitch::from(C), Mode::Ionian);
155+
// I=C maj, ii=D min, iii=E min, IV=F maj, V=G maj, vi=A min, vii°=B dim
156+
157+
// Roman numeral analysis
158+
let g7 = Chord::new(Pitch::from(G), Quality::Dominant, Number::Seventh);
159+
let rn = analysis::roman_numeral(Pitch::from(C), Mode::Ionian, &g7).unwrap();
160+
assert_eq!(rn.label, "V7");
161+
162+
// Secondary dominant detection
163+
let d_major = Chord::new(Pitch::from(D), Quality::Major, Number::Triad);
164+
let sd = analysis::secondary_dominant(Pitch::from(C), Mode::Ionian, &d_major).unwrap();
165+
assert_eq!(sd.label, "V/V");
166+
167+
// Pivot chords between C major and G major
168+
let pivots = harmony::pivot_chords(
169+
Pitch::from(C), Mode::Ionian,
170+
Pitch::from(G), Mode::Ionian,
171+
);
172+
// G major is V in C, I in G; C major is I in C, IV in G; etc.
86173
```
87174

88-
`rustmt scale list`
89-
```yaml
90-
Available Scales:
91-
- Major|Ionian
92-
- Minor|Aeolian
93-
- Dorian
94-
- Phrygian
95-
- Lydian
96-
- Mixolydian
97-
- Locrian
98-
- Harmonic Minor
99-
- Melodic Minor
175+
### Neo-Riemannian Transformations
176+
177+
```rust
178+
use music_comp_mt::neo_riemannian::{transform, transform_chain, NROperation};
179+
use music_comp_mt::chord::{Chord, Quality, Number};
180+
use music_comp_mt::note::{Pitch, PitchSymbol::*};
181+
182+
let c_major = Chord::new(Pitch::from(C), Quality::Major, Number::Triad);
183+
184+
// P (Parallel): C major → C minor
185+
let c_minor = transform(&c_major, NROperation::P).unwrap();
186+
187+
// R (Relative): C major → A minor
188+
let a_minor = transform(&c_major, NROperation::R).unwrap();
189+
190+
// Chain operations: C major → P → R → L
191+
let path = transform_chain(&c_major, &[NROperation::P, NROperation::R, NROperation::L]).unwrap();
100192
```
101193

194+
### Pitch-Class Set Theory
195+
196+
```rust
197+
use music_comp_mt::set_class::PitchClassSet;
198+
199+
let major_triad = PitchClassSet::new(&[0, 4, 7]);
200+
assert_eq!(major_triad.prime_form(), vec![0, 3, 7]);
201+
assert_eq!(major_triad.forte_number(), Some("3-11".to_string()));
202+
assert_eq!(major_triad.interval_vector(), [0, 0, 1, 1, 1, 0]);
102203

103-
`rustmt chord list`
104-
```yaml
105-
Available chords:
106-
- Major Triad
107-
- Minor Triad
108-
- Suspended2 Triad
109-
- Suspended4 Triad
110-
- Augmented Triad
111-
- Diminished Triad
112-
- Major Seventh
113-
- Minor Seventh
114-
- Augmented Seventh
115-
- Augmented Major Seventh
116-
- Diminished Seventh
117-
- Half Diminished Seventh
118-
- Minor Major Seventh
119-
- Dominant Seventh
120-
- Dominant Ninth
121-
- Major Ninth
122-
- Dominant Eleventh
123-
- Major Eleventh
124-
- Minor Eleventh
125-
- Dominant Thirteenth
126-
- Major Thirteenth
127-
- Minor Thirteenth
204+
// Transpose and invert
205+
let transposed = major_triad.transpose(5); // T_5
206+
let inverted = major_triad.invert(0); // I_0
128207
```
129208

130209
## Building From Source
131210

132-
To quickly build and run the executable locally;
133-
134-
`git clone http://github.com/ozankasikci/rust-music-theory && cd rust-music-theory`
211+
```sh
212+
git clone https://github.com/music-comp/mt-rs && cd mt-rs
213+
make build # Build library + CLI
214+
make test # Run all 349 tests
215+
make lint # Clippy + fmt (same checks as CI)
216+
make coverage # Generate coverage report (96%+)
217+
make docs # Build rustdoc (warnings as errors)
218+
make check-all # Build + lint + coverage + docs
219+
```
135220

136-
Then you can directly compile using cargo. An example;
221+
## Project Structure
137222

138-
`cargo run -- scale D Locrian`
139-
```yaml
140-
Notes:
141-
1: D
142-
2: D#
143-
3: F
144-
4: G
145-
5: G#
146-
6: A#
147-
7: C
148-
8: D
149223
```
224+
Cargo.toml workspace root
225+
mt/ library crate (music-comp-mt)
226+
src/
227+
lib.rs
228+
note/, interval/, chord/, scale/
229+
harmony/, analysis/, voice_leading/
230+
neo_riemannian/, set_class/, counterpoint/, figured_bass/
231+
tests/
232+
mt-cli/ binary crate (music-comp-mt-cli)
233+
src/
234+
main.rs, cli.rs
235+
tests/
236+
```
237+
238+
## License
239+
240+
MIT
241+
242+
[//]: ---Named-Links---
150243

151-
## Roadmap
152-
- [x] Properly display enharmonic spelling
153-
- [x] Add inversion support for chords
154-
- [ ] Add missing modes for Melodic & Harmonic minor scales
155-
- [ ] Add support for arbitrary accidentals
156-
- [ ] Add a mechanism to find the chord from the given notes
244+
[logo]: https://avatars.githubusercontent.com/u/255628285?s=250
245+
[logo-large]: https://avatars.githubusercontent.com/u/255628285

0 commit comments

Comments
 (0)