Dealing with pitches and intervals correctly is notoriously difficult, which is why researchers often resort to representing both as integers, e.g. defining Middle C as 60, or using pitch classes 0 to 11. However, for many applications, distinguishing between different spellings of pitches (e.g. C♯/D♭) or intervals such as an augmented fourth and a diminished fifth is important. For this reason, we provide a set of libraries that
- can represent and “calculate” with pitches and intervals in the Western notation system correctly;
- provide an abstract interface over different pitch and interval types, which allows you to write generic code;
- provides a standard notation for interval and pitches that is consistent across these libraries.
The different implementations are very small and simple and come with few or no dependencies.
For a quick overview, have a look at our ISMIR 2022 poster.
pitchtypes (Python)
Comes with special support for fast arrays (based on numpy
) and one-hot encodings.
>>> import pitchtypes as pt >>> pt.SpelledPitch("C4") + pt.SpelledInterval("a4:0") F#4
Pitches.jl (Julia)
julia> using Pitches julia> p"C4" + i"a4:0" F♯4
musicology-pitch (Haskell)
ghci> import Musicology.Pitch ghci> let (Just p) = readNotation "C4" :: Maybe SPitch ghci> let (Just i) = readNotation "a4:0" :: Maybe SInterval ghci> p +^ i F♯4
purescript-pitches (Purescript)
> import Data.Maybe > import Data.Pitches > :pa … do … p <- parseNotation "C4" :: Maybe SPitch … i <- parseNotation "a4:0" :: Maybe SInterval … pure $ p +^ i (Just F♯4)
rust-pitches (Rust)
use pitches::spelled::*; fn main() { let p: SpelledPitch = "C4".parse().unwrap(); let i: SpelledInterval = "a4:0".parse().unwrap(); let p2 = p + i; print!("Output: {}", p2); }