Eikosany: Microtonal Algorithmic Composition with R

M. Edward (Ed) Borasky

2023-08-19

1 Algorithmic Composition

Overview of Methods (Nierhaus 2009)

  • Markov Models / Stochastic
  • Generative Grammars
  • Transition Networks
  • Chaos and Self-Similarity
  • Genetic Algorithms
  • Cellular Automata
  • Artificial Neural Networks

My Main Compositional Focus

  • Markov Models / Stochastic
  • Pioneered by Iannis Xenakis (Xenakis 1992)
  • Random chord progressions on microtonal harmonic structures

When Harry Met Iannis (2021) (Borasky 2021)

  • Microtonal harmonic structure is Harry Partch’s Tonality Diamond (Partch 1979)
  • Tonality Diamond was an inspiration for Erv Wilson’s Combination Product Sets

2 Musical Scales

Types of scales

  • Standard “western” tuning - 12 equally-spaced tones / octave
    • abbreviated 12-TET (12 tone equal temperament) or 12-EDO (12 equal divisions of the octave)
  • Alternative tuning - anything else

12-TET Scale Table

library(eikosany)
vanilla <- et_scale_table() # default is 12-TET
print(vanilla)
    note_name    ratio ratio_frac ratio_cents interval_cents degree
 1:         C 1.000000          1           0             NA      0
 2:     C#|Db 1.059463  1461/1379         100            100      1
 3:         D 1.122462  1714/1527         200            100      2
 4:     D#|Eb 1.189207  1785/1501         300            100      3
 5:         E 1.259921    635/504         400            100      4
 6:         F 1.334840  3249/2434         500            100      5
 7:     F#|Gb 1.414214   1393/985         600            100      6
 8:         G 1.498307  2213/1477         700            100      7
 9:     G#|Ab 1.587401   1008/635         800            100      8
10:         A 1.681793  3002/1785         900            100      9
11:     A#|Bb 1.781797   1527/857        1000            100     10
12:         B 1.887749  2943/1559        1100            100     11
13:        C' 2.000000          2        1200            100     12

Cents??

  • A logarithmic measure used by scale theorists
  • 1 cent = 1/100th of a semitone
  • 12 semitones = 1200 cents = 1 octave = ratio of 2/1

Alternative tunings

  • scales from other cultures
  • “just” scales - scales based on rational numbers
  • scale repetition periods different from the octave
  • scale repetition period divided into more than 12 tones
  • combinations of the above!

Microtonal music

  • Usually defined as an octave divided into more than 12 tones
  • Common microtonal scales
    • 19-TET
    • 24-TET aka quarter tones
    • 31-TET

3 Erv Wilson (Narushima 2019)

Ervin Wilson (June 11, 1928 – December 8, 2016)

  • Mexican/American (dual citizen)
  • Prolific music theorist
  • Developed keyboard layouts, scales and lattices
  • Primarily known for theories of microtonal just scales

Combination Product Set Scales (Narushima 2019, chap. 6)

  • Focus of the eikosany package
  • Start with a set of N harmonic factors
  • For even number of factors N, choose = N/2
  • For an odd number, choose = either N/2 - 1/2 or N/2 + 1/2
    • Four factors: choose 2: six combinations (hexany)
    • Five factors: choose 2 or 3: ten combinations (dekany)
    • Six factors: choose 3: 20 combinations (eikosany)
    • Pascal’s Triangle is your friend

Making the Scale

  • Take all the combinations of the factors with choose elements
  • Take the products of the combinations
  • Reduce the products to ratios in [1, 2)
    1. Divide all by smallest product
    2. Multiply or divide by powers of two to get values in [1, 2)
  • Sort

Example: 1-3-5-7 Hexany

  • Products of combinations: 1*3, 1*5, 1*7, 3*5, 3*7, 5*7
  • Raw ratios (divide by smallest product): 1 5/3 7/3 5 7 35/3
  • Reduce: 1 5/3 7/6 5/4 7/4 35/24
  • Sort: 1 7/6 5/4 35/24 5/3 7/4

Using the package!

hexany_scale_table <- cps_scale_table(
  harmonics = c(1, 3, 5, 7),
  choose = 2,
  root_divisor = 3
)
print(hexany_scale_table)
   note_name    ratio ratio_frac ratio_cents interval_cents degree
1:       1x3 1.000000          1      0.0000             NA      0
2:       1x7 1.166667        7/6    266.8709      266.87091      1
3:       3x5 1.250000        5/4    386.3137      119.44281      2
4:       5x7 1.458333      35/24    653.1846      266.87091      3
5:       1x5 1.666667        5/3    884.3587      231.17409      4
6:       3x7 1.750000        7/4    968.8259       84.46719      5
7:      1x3' 2.000000          2   1200.0000      231.17409      6

The Chord Table

  • Like scales, chords are combinations of harmonic factors
  • Currently only works for even number of factors
  • For a chord table, we take choose + 1 combinations
    • Four factors: three combinations (four triads)
    • Six factors: four combinations (15 tetrads)

Harmonic and Subharmonic Chords

  • Each chord has a harmonic and subharmonic form
  • Roughly corresponds to major and minor chords
  • Four factors: four harmonic triads and four subharmonic triads
  • Six factors: 15 harmonic tetrads and 15 subharmonic tetrads
  • In the chord table, the subharmonic ones have “/” in their names

The Hexany Chord Table

hexany_chord_table <- cps_chord_table(hexany_scale_table)
print(hexany_chord_table)
      chord degrees chord_index is_subharm
1:    1:3:5   1:3:5           1          0
2: /1:/3:/5   0:2:4           1          1
3:    1:3:7   2:3:4           2          0
4: /1:/3:/7   0:1:5           2          1
5:    1:5:7   0:2:5           3          0
6: /1:/5:/7   1:3:4           3          1
7:    3:5:7   0:1:4           4          0
8: /3:/5:/7   2:3:5           4          1

4 Pseudo-Demo

The 1-3-5-7-9-11 Eikosany

  • Six harmonic factors, choose 3
eikosany_scale_table <- cps_scale_table(
  harmonics = c(1, 3, 5, 7, 9, 11),
  choose = 3,
  root_divisor = 33
)

The Eikosany Scale Table

print(eikosany_scale_table)
    note_name    ratio ratio_frac ratio_cents interval_cents degree
 1:    1x3x11 1.000000          1     0.00000             NA      0
 2:     3x5x9 1.022727      45/44    38.90577       38.90577      1
 3:     1x5x7 1.060606      35/33   101.86668       62.96090      2
 4:    3x9x11 1.125000        9/8   203.91000      102.04332      3
 5:    1x7x11 1.166667        7/6   266.87091       62.96090      4
 6:     5x7x9 1.193182     105/88   305.77668       38.90577      5
 7:    3x5x11 1.250000        5/4   386.31371       80.53704      6
 8:     1x3x7 1.272727      14/11   417.50796       31.19425      7
 9:    7x9x11 1.312500      21/16   470.78091       53.27294      8
10:     1x5x9 1.363636      15/11   536.95077       66.16987      9
11:     3x7x9 1.431818      63/44   621.41797       84.46719     10
12:    5x7x11 1.458333      35/24   653.18462       31.76665     11
13:    1x9x11 1.500000        3/2   701.95500       48.77038     12
14:     3x5x7 1.590909      35/22   803.82168      101.86668     13
15:     1x3x9 1.636364      18/11   852.59206       48.77038     14
16:    1x5x11 1.666667        5/3   884.35871       31.76665     15
17:    3x7x11 1.750000        7/4   968.82591       84.46719     16
18:     1x3x5 1.818182      20/11  1034.99577       66.16987     17
19:    5x9x11 1.875000       15/8  1088.26871       53.27294     18
20:     1x7x9 1.909091      21/11  1119.46296       31.19425     19
21:   1x3x11' 2.000000          2  1200.00000       80.53704     20
    note_name    ratio ratio_frac ratio_cents interval_cents degree

The Eikosany Chord Table

print(eikosany_chord_table <-
  cps_chord_table(eikosany_scale_table)
)
           chord    degrees chord_index is_subharm
 1:      1:3:5:7  3:8:12:18           1          0
 2:  /1:/3:/5:/7  2:7:13:17           1          1
 3:      1:3:5:9  4:8:11:16           2          0
 4:  /1:/3:/5:/9  1:9:14:17           2          1
 5:     1:3:5:11  5:8:10:19           3          0
 6: /1:/3:/5:/11  0:6:15:17           3          1
 7:      1:3:7:9 6:11:15:18           4          0
 8:  /1:/3:/7:/9 7:10:14:19           4          1
 9:     1:3:7:11   1:5:9:18           5          0
10: /1:/3:/7:/11   0:4:7:16           5          1
11:     1:3:9:11  2:5:11:13           6          0
12: /1:/3:/9:/11  0:3:12:14           6          1
13:      1:5:7:9   0:3:6:16           7          0
14:  /1:/5:/7:/9   2:5:9:19           7          1
15:     1:5:7:11  1:3:10:14           8          0
16: /1:/5:/7:/11  2:4:11:15           8          1
17:     1:5:9:11 7:10:13:16           9          0
18: /1:/5:/9:/11 9:12:15:18           9          1
19:     1:7:9:11  1:6:13:17          10          0
20: /1:/7:/9:/11  4:8:12:19          10          1
21:      3:5:7:9  0:4:12:15          11          0
22:  /3:/5:/7:/9  1:5:10:13          11          1
23:     3:5:7:11 9:12:14:19          12          0
24: /3:/5:/7:/11 6:11:13:16          12          1
25:     3:5:9:11   2:4:7:19          13          0
26: /3:/5:/9:/11   1:3:6:18          13          1
27:     3:7:9:11  2:9:15:17          14          0
28: /3:/7:/9:/11  3:8:10:16          14          1
29:     5:7:9:11  0:7:14:17          15          0
30: /5:/7:/9:/11  5:8:11:18          15          1
           chord    degrees chord_index is_subharm

What Does It Sound Like?

  • To hear the scale:
    1. Get a synthesizer
    2. Map the keys of the synthesizer to the notes of the scale
    3. Play the keys
  • But that’s kind of expensive and I’m in a hurry
  • So I’ll emulate it in R!

First Step - Make a Keyboard Map

  • Maps MIDI note numbers to frequencies
  • MIDI note numbers range from 0 to 127
  • MIDI note number 60 is middle C
  • Our 20-note scale is note numbers 60:79
# this is the whole keyboard
hexany_map <- keyboard_map(hexany_scale_table)
eikosany_map <- keyboard_map(eikosany_scale_table)

# extract scale from middle C
hexany_scale_map <- hexany_map[
  note_number %in% 60:66,
  list(note_number, freq)
]
eikosany_scale_map <- eikosany_map[
  note_number %in% 60:80,
  list(note_number, freq)
]

The Hexany Scale Map

print(hexany_scale_map)
   note_number     freq
1:          60 261.6256
2:          61 305.2298
3:          62 327.0320
4:          63 381.5373
5:          64 436.0426
6:          65 457.8447
7:          66 523.2511

The Eikosany Scale Map

print(eikosany_scale_map)
    note_number     freq
 1:          60 261.6256
 2:          61 267.5716
 3:          62 277.4817
 4:          63 294.3288
 5:          64 305.2298
 6:          65 312.1669
 7:          66 327.0320
 8:          67 332.9780
 9:          68 343.3836
10:          69 356.7621
11:          70 374.6002
12:          71 381.5373
13:          72 392.4383
14:          73 416.2225
15:          74 428.1146
16:          75 436.0426
17:          76 457.8447
18:          77 475.6828
19:          78 490.5479
20:          79 499.4670
21:          80 523.2511
    note_number     freq

Second Step - Make Waves!

  • uses seewave and tuneR (Sueur 2018)
  • creates a multisample - a collection of WAV files
    • can be used in sample-based workflows
    • emulates multisamples captured by 1010music Blackbox

Make Waves!

make_waves <- TRUE # set to TRUE if you want to re-render the WAVs
if (make_waves) {
  scale_multisample(
   keyboard_map = hexany_scale_map,
   start_note_number = 60,
   end_note_number = 66,
   duration_sec = 2,
   output_directory = "./Hexany-Scale-Multisample"
  )
  scale_multisample(
   keyboard_map = eikosany_scale_map,
   start_note_number = 60,
   end_note_number = 80,
   duration_sec = 2,
   output_directory = "./Eikosany-Scale-Multisample"
  )
}
[1] "./Eikosany-Scale-Multisample"

Make CPS Chord WAVs

  if (make_waves) {
    render_cps_chords(hexany_scale_table, "./hexany_chords")
    render_cps_chords(eikosany_scale_table, "./eikosany_chords")
  }
[1] "./eikosany_chords"

5 Roadmap

Current status

  • Enough infrastructure to manually make music!
    • (which was my initial goal)
  • Documentation - you’re looking at it

Current plan

  1. Clean up documentation and do a first release (August)
    • Hoping to release an album / EP on Bandcamp
  2. Open feature requests for triage
  3. Add consonance analysis capability (Sethares 2013)
  4. Remove the MIDI functionality!
    • MIDI is a great language for 4/4 time 12-EDO music
    • For microtonal algorithmic composition, not so much
    • The “other tools” in the Appendix are designed to deal with MIDI so I don’t have to!

Where does all this stuff live?

Appendix - Microtonal Music Resources

PC / Mac / iOS Software

  • Scala. Note: this is not the Scala multi-paradigm programming language that runs on the Java Virtual Machine. This is a specialized tool for working with musical scales.

  • ODDSound MTS-ESP. This is a plugin for digital audio workstations (DAWs) that facilitates production of microtonal music. I own a copy and if you’re making microtonal electronic music, you should too. The Eikosany and other scales Erv Wilson developed all ship with MTS-ESP, so you don’t really need my R package to compose with them.

  • Entonal Studio. Entonal Studio is a user interface package for microtonal composition. It can operate as a standalone application, a plugin host or a plugin. I own a copy of Entonal Studio and recommend it highly.

PC / Mac / iOS Software (continued)

“Infinitone DMT is a DAW plugin and standalone that empowers musicians to easily use micro-tuning within their own workflow.

“As a plugin, Infinitone DMT is inserted in your DAW as a MIDI effect.

“The standalone can be used separately from a DAW, or it can be used in conjunction with a DAW by routing MIDI data from the DAW to the standalone (and back).”

PC / Mac / iOS Software (continued)

  • Universal Tuning Editor. Universal Tuning Editor is an application for computing and visualizing microtonal scales and tunings, and includes tools to interface with hardware and software synthesizers.

  • Wilsonic. This is a free app that runs on iOS devices. I don’t have any iOS devices so I’ve never used this.

    There is also a version of Wilsonic in development for use with ODDSound MTS-ESP. See https://wilsonic.co/downloads/downloads-mts-esp/ for the details.

  • Surge XT. Surge XT is an open source full featured software synthesizer. The Surge XT community has invested a significant level of effort into supporting alternate tuning systems.

See the Xenharmonic Wiki List of microtonal software plugins for more ways of making microtonal music.

Websites

YouTube Playlists

References

Borasky, M. Edward (Ed). 2021. “When Harry Met Iannis.” https://algocompsynth.bandcamp.com/album/when-harry-met-iannis.
Narushima, T. 2019. Microtonality and the Tuning Systems of Erv Wilson. Routledge Studies in Music Theory. Taylor & Francis Limited.
Nierhaus, G. 2009. Algorithmic Composition: Paradigms of Automated Music Generation. Mathematics and Statistics. Springer Vienna. https://books.google.com/books?id=jaowAtnXsDQC.
Partch, H. 1979. Genesis of a Music: An Account of a Creative Work, Its Roots, and Its Fulfillments, Second Edition. Hachette Books.
Sethares, W. A. 2013. Tuning, Timbre, Spectrum, Scale. Springer London.
Sueur, J. 2018. Sound Analysis and Synthesis with r. Use r! Springer International Publishing.
Xenakis, I. 1992. Formalized Music: Thought and Mathematics in Composition. Harmonologia Series. Pendragon Press.