Pitch and Interval Libraries

Overview of the spelled pitch and interval notation syntax.

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);
}