Skip to content

Alternative implementations of a twelve tone matrix and possible design benefits #33

@jgarte

Description

@jgarte

Hi,

What do you think if we were to re-implement a twelve tone matrix without needing to use numpy.zeros?

For example we could generate the 12X12 matrix like this:

>>> from pprint import PrettyPrinter
>>> matrix = [[0] * 12] * 12
>>> pp = PrettyPrinter(indent=4)
>>> pp.pprint(matrix)

   [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

We can then proceed to implement the compose function in terms of mutating the above matrix list variable to produce a matrix with the canonical row forms: P, R, I, and RI.

One possible algorithm:

We can loosely implement the steps as described in this instructable:

https://www.instructables.com/Create-a-Twelve-Tone-melody-with-a-Twelve-Tone-Mat/

  1. Compute the interval adjacencies of the initial row and store that in a variable.
  2. Compute the inversion of the initial row using step 1 and store that in a variable.
  3. Use the List[int] variables created in steps 1 and 2 to mutate/compute the rest of the 12 X 12 List[List[int]].

Another alternative could be to outsource the matrix generation logic to the music21 library:

https://web.mit.edu/music21/doc/moduleReference/moduleSerial.html?highlight=row#music21.serial.ToneRow.row

Using music21 would be an implementation detail of twelve-tone.

The cool thing that might arise from using music21 is that we could piggyback on its features to add/invent CLI flags for twelve-tone such as --historical that let's the user ask for a historical tone row, which is kind of cute:

> bergLyric = serial.getHistoricalRowByName('BergLyricSuite')
> bergLyric.pitchClasses()
[5, 4, 0, 9, 7, 2, 8, 1, 3, 6, 10, 11]

twelve-tone using music21's getHistoricalRowByName method

$ twelve-tone --historical

F E C A G D G♯ C♯ D♯ F♯ A♯ B

or with --verbose

$ twelve-tone --historical --verbose

🚀 The tone row from Berg's Lyric Suite!
F E C A G D G♯ C♯ D♯ F♯ A♯ B

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions