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')

Version

0.2.0

License

GPL (>= 3)

Issues

Pull Requests

Stars

Forks

Maintainer

Paul Sherrill

Last Published

July 21st, 2025

Functions in musicMCT (0.2.0)

ineqmats

Hyperplane arrangements for MCT spaces
edoo

Perfectly even scales (the color white)
emb

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

Symmetries of hyperplane arrangements define equivalent scales
evenness

How even is a scale?
make_white_ineqmat

Define hyperplanes for white arrangements
makeineqmat

Define hyperplanes for the Modal Color Theory arrangements
ivec

Interval-class vector
meantone_fifth

Define a tempered fifth for various meantone scales
maxeven

Maximally even scales
isym

Test for inversional symmetry
minimize_vl

Smallest voice leading between two sets
primary_hue

Primary colors
musicMCT-package

musicMCT: Analyze the Structure of Musical Scales
make_offset_ineqmat

Translate a hyperplane arrangement to a new center
ifunc

All intervals from one set to another
intervalspectrum

Specific sizes corresponding to each generic interval
isgwf

Is a scale n-wise well formed?
ianring

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

Define hyperplanes for Rothenberg arrangements
get_relevant_rows

Which hyperplanes affect a given generic interval?
populate_flat

Randomly generate scales on a flat
optc_test

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

Set class complement
quantize_hue

Find a scale mod k that matches a given hue
same_hue

Do two scales lie on the same ray?
realize_setword

Define scale by entering its relative step sizes
roth_ineqmats

Hyperplane arrangements for Rothenberg arrangements
subset_varieties

Specific varieties of scalar subsets given a generic shape
readSCL

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

Circular rotation of an ordered tuple
primeform

Prime form of a set using Rahn's algorithm
saturate

Modify evenness without changing hue
sc

Set class from Forte's list
set_from_signvector

Create a scale from a sign vector
project_onto

Closest point on a given flat
set_to_distribution

Convert between pitch-class sets and distributions
surround_set

Random scales uniformly distributed on a hypersphere around an input
svzero_fingerprint

Distinguish different types of interval equalities
whichmodebest

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

Elementary voice leadings
howfree

Count a scale's degrees of freedom
signvector

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

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

Find a scale mod k that matches a given color
sim

Scalar (and interscalar) interval matrix
subsetspectrum

Subset varieties for all subsets of a fixed size
simplify_scale

Best ways to regularize a scale
tsym

Test for transpositional symmetry
vl_generators

Which transpositions give elementary voice leadings?
vl_rolodex

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

Transposition class of a given pc-set
step_signvector

Specify a scale's step pattern with a sign vector
scale_palette

Orbit of a scale under symmetries of hyperplane arrangement
tndists

Distances between continuous transpositions of a set
subset_multiplicities

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

How far apart are two scales?
tn

Transposition and Inversion
tc

Transpositional combination & pitch multiplication
writeSCL

Create a Scala tuning file from a given scale
iswellformed

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

Which interval-comparison equalities does a scale satisfy?
isproper

Rothenberg propriety
make_black_ineqmat

Define hyperplanes for transposition-sensitive arrangements
j

Convenient just-intonation intervals and scales
z

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

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

Visualize brightness relationships among modes of a scale
asword

Algebraic word of a set's step sizes
carlos_step

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

Visualize a set in pitch-class space
coord_to_edo

Coordinate systems for scale representation
colornum

Reference numbers for scale structures
convert

Convert between octave measurements
dft

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

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

Do two sign vectors represent adjacent colors?
eps

The brightness ratio
fortenums

Allen Forte's list of set classes
fortenum

Forte number from set class
fpunique

Unique real values up to some tolerance
flex_points

Voice-leading inflection points