Learn R Programming

musicMCT

The “MCT” in musicMCT stands for Modal Color Theory, a theory of musical scale structure developed by Paul Sherrill, “Modal Color Theory,” Journal of Music Theory 69/1 (2025): 1-49. The goal of this package is to give musicians and music scholars computational tools that make it easier to work with this theory. In a nutshell, Modal Color Theory models musical scales as points in a geometry. The locations of those points relative to various hyperplane arrangements tell us a lot about the scales’ internal structures and mutual relationships. The shape of those hyperplane arrangements gets pretty complex: for the important case of seven-note scales, the main arrangement has 42 hyperplanes in a 6-dimensional space. Computational tools are therefore very helpful.

If you’ve ever wondered why a piece of music uses one scale rather than another; if you want to know more about the jazz chord-scale concept of lydian being “bright” and locrian being “dark”; if you’ve ever wanted to design your own microtonal scale from scratch; if you’re a theorist who wants a geometrical perspective on concepts like voice leading and maximal evenness; if you’re an ethnomusicologist looking to interpret tuning data: musicMCT might be useful to you.

Installation

You can install the latest released version of musicMCT from CRAN with:

install.packages("musicMCT")

Alternatively, you can install the development version of musicMCT from GitHub with:

install.packages("remotes")
remotes::install_github("satbq/musicMCT")

In addition to the package itself, you will probably want to use the following large files which contain data about the MCT geometries:

  • representative_scales.rds (~80 MB) contains a list of all scalar colors for scales of 2-7 notes, with one concrete scale to represent each color
  • representative_signvectors.rds (~10 MB) contains a list of their corresponding sign vectors
  • color_adjacencies.rds (~130 MB) contains information about the adjacency relationships between all these colors (in the form of an adjacency list)

Download these files, save them to your working directory, and load them with:

representative_scales <- readRDS("representative_scales.rds")
representative_signvectors <- readRDS("representative_signvectords.rds")
color_adjacencies <- readRDS("color_adjacencies.rds")

Example

For a detailed introduction to using this package, please see the introductory vignette.

As a very quick example, let’s define the most common “just intonation” version of the major scale and run a few tests on it:

library(musicMCT)
just_dia_frequency_ratios <- c(1, 9/8, 5/4, 4/3, 3/2, 5/3, 15/8)
just_dia <- 12 * log2(just_dia_frequency_ratios)

# This definition of the just diatonic explicitly derives it from the 
# frequency ratios, which I've done to model that process for you. However,
# musicMCT also has a convenience function that will give us the 
# same result much faster: try out j(dia) or j(1,2,3,4,5,6,7) for yourself.

# The modes of the scale are displayed as the columns in this matrix:
sim(just_dia)
#>           [,1]     [,2]      [,3]      [,4]     [,5]      [,6]     [,7]
#> [1,]  0.000000 0.000000  0.000000  0.000000 0.000000  0.000000 0.000000
#> [2,]  2.039100 1.824037  1.117313  2.039100 1.824037  2.039100 1.117313
#> [3,]  3.863137 2.941350  3.156413  3.863137 3.863137  3.156413 3.156413
#> [4,]  4.980450 4.980450  4.980450  5.902237 4.980450  5.195513 4.980450
#> [5,]  7.019550 6.804487  7.019550  7.019550 7.019550  7.019550 6.097763
#> [6,]  8.843587 8.843587  8.136863  9.058650 8.843587  8.136863 8.136863
#> [7,] 10.882687 9.960900 10.175963 10.882687 9.960900 10.175963 9.960900

# A few pieces of evidence that the scale is "pairwise well-formed":
asword(just_dia)
#> [1] 3 2 1 3 2 3 1
howfree(just_dia)
#> [1] 2
isgwf(just_dia)
#> [1] TRUE

# A 15 equal-tempered approximation of just-dia which preserves its "color":
quantized_just_dia <- quantize_color(just_dia)
print(quantized_just_dia)
#> $set
#> [1]  0  3  5  6  9 11 14
#> 
#> $edo
#> [1] 15

# Finally, let's see a rough brightness graph for the scale. (R can assemble the
# necessary information, but musicMCT doesn't yet make the graphs pretty.)
brightnessgraph(quantized_just_dia$set, edo=quantized_just_dia$edo)

Acknowledgments

Thanks to Nate Mitchell for designing the package’s hex sticker logo.

Copy Link

Version

Install

install.packages('musicMCT')

Monthly Downloads

147

Version

0.3.0

License

GPL (>= 3)

Issues

Pull Requests

Stars

Forks

Maintainer

Paul Sherrill

Last Published

November 3rd, 2025

Functions in musicMCT (0.3.0)

dft

The musical Discrete Fourier Transform of a pitch-class set
isgwf

Is a scale n-wise well formed?
make_infrared_ineqmat

Define hyperplanes for infrared arrangements
get_relevant_rows

Which hyperplanes affect a given generic interval?
fpunique

Unique real values up to some tolerance
make_offset_ineqmat

Translate a hyperplane arrangement to a new center
ifunc

All intervals from one set to another
ineqmats

Hyperplane arrangements for MCT spaces
make_anaglyph_ineqmat

Define hyperplanes for cross-type voice leadings
make_black_ineqmat

Define hyperplanes for transposition-sensitive arrangements
ianring

Look up a scale at Ian Ring's Exciting Universe of Music Theory
howfree

Count a scale's degrees of freedom
make_white_ineqmat

Define hyperplanes for white arrangements
make_roth_ineqmat

Define hyperplanes for Rothenberg arrangements
isproper

Rothenberg propriety
intervalspectrum

Specific sizes corresponding to each generic interval
ineqsym

Symmetries of hyperplane arrangements define equivalent scales
maxeven

Maximally even scales
makeineqmat

Define hyperplanes for the Modal Color Theory arrangements
minimize_vl

Smallest voice leading between two sets
meantone_fifth

Define a tempered fifth for various meantone scales
j

Convenient just-intonation intervals and scales
ivec

Interval-class vector
saturate

Modify evenness without changing hue
populate_flat

Randomly generate scales on a flat
sc

Set class from Forte's list
optc_test

Does a scale lie in the canonical fundamental domain for OPTC symmetries?
iswellformed

Well-formedness, Myhill's property, and/or moment of symmetry
isym

Test for inversional symmetry
rotate

Circular rotation of an ordered tuple
realize_stepword

Define scale by entering its relative step sizes
quantize_color

Find a scale mod k that matches a given color
project_onto

Closest point on a given flat
signed_interval_class

Ordered pitch-class interval represented as interval class with sign
signvector

Detect a scale's location relative to a hyperplane arrangement
sc_comp

Set class complement
set_from_signvector

Create a scale from a sign vector
scale_palette

Orbit of a scale under symmetries of hyperplane arrangement
same_hue

Do two scales lie on the same ray?
roth_ineqmats

Hyperplane arrangements for Rothenberg arrangements
normal_form

Hook's OPTIC normal forms
subset_multiplicities

Count the multiplicities of a subset-type's varieties
step_signvector

Specify a scale's step pattern with a sign vector
musicMCT-package

musicMCT: Analyze the Structure of Musical Scales
primeform

Prime form of a set using Rahn's algorithm
quantize_hue

Find a scale mod k that matches a given hue
primary_hue

Primary colors
readSCL

Import a Scala (.scl) file as a scale
tc

Transpositional combination & pitch multiplication
subsetspectrum

Subset varieties for all subsets of a fixed size
subset_varieties

Specific varieties of scalar subsets given a generic shape
vl_generators

Which transpositions give elementary voice leadings?
sim

Scalar (and interscalar) interval matrix
simplify_scale

Best ways to regularize a scale
surround_set

Random scales uniformly distributed on a hypersphere around an input
svzero_fingerprint

Distinguish different types of interval equalities
vl_rolodex

Minimal voice leadings to all transpositions of some Tn-type mod k
writeSCL

Create a Scala tuning file from a given scale
tn

Transposition and Inversion
tndists

Distances between continuous transpositions of a set
whichsvzeroes

Which interval-comparison equalities does a scale satisfy?
set_to_distribution

Convert between pitch-class sets and distributions
tnprime

Transposition class of a given pc-set
z

Frequency ratios to logarithmic pitch intervals (e.g. semitones)
zmate

Twin set in the Z-relation (Z mate)
vlsig

Elementary voice leadings
vl_dist

How far apart are two scales?
tsym

Test for transpositional symmetry
whichmodebest

Smallest crossing-free voice leading between two pitch-class sets
anazero_fingerprint

Are regularities within or between sets in a pair?
colornum

Reference numbers for scale structures
clockface

Visualize a set in pitch-class space
brightness_comparisons

Voice-leading brightness relationships for a scale's modes
brightnessgraph

Visualize brightness relationships among modes of a scale
clampitt_q

Voice leadings between inversions with maximal common tones
carlos_step

Define a step size for one of Wendy Carlos's scales
convert

Convert between octave measurements
asword

Algebraic word of a set's step sizes
comparesignvecs

Do two sign vectors represent adjacent colors?
fpmod

Modulo division with rounding
fortenums

Allen Forte's list of set classes
eps

The brightness ratio
fortenum

Forte number from set class
evenness

How even is a scale?
flex_points

Voice-leading inflection points
edoo

Perfectly even scales (the color white)
coord_to_edo

Coordinate systems for scale representation
emb

How many instances of a subset-type exist within a scale? How many scales embed a subset?