Serialist Matrix in SuperCollider

Posted on Posted in Ideas, Tutorials

A friend casually asked me a question related to making a serialist twelve tone matrix with SuperCollider so I thought I’d share my solution here.

DISCLAIMER: If you are in a post-tonal theory class and just looking for a lazy way to make a matrix, stop it! Learn to do this by hand first… or use any of the other millions of online matrix generators… I’m also not going to explain much about the music theory: only the code.

OTHER DISCLAIMER: I don’t write serialist music. I did this for the fun of it.

The first thing we need is an initial row to work with. Feel free to grab your favorite or make your own. As for me, I’m going to make a random one like so:

~p0 = (0..11).scramble;

If you are unfamiliar with this shorthand: (0..11) will generate an array of integers counting from 0 to 11 in this case. .scramble will then scramble that (who’da thought?!) giving us a random tone row, which I’ll call ~p0.

Next we need to get the inversion. That’s also a one-liner:

~i0 = (12 - ~p0) % 12;

This should be pretty straightforward. The inversion of a pitch class is 12 – the pitch class, then you mod 12 to put it within the 0 – 11 range.

Cool. Now for the cooler part! We can make the complete matrix with just one more line of code:

~mat = ~i0.collect{arg n; (n + ~p0) % 12; };

WOW! Such matrix XD. For those of you who don’t use .collect, you’re missing out. It’s just like .do (it uses a function to iterate over a collection) except that it returns a new collection. I’ve been getting more into functional programming lately (specifically Haskell) and .collect is basically like map. Since a matrix is really just the prime row transposed (added) to each pitch class in the inversion row (then mod 12ed), the function we give to .collect does literally that, and then gives us a collection of rows (a 2D array).

To make it a little easier to see, lets print out each row on its own line shall we:

~mat.do{arg row; row.postln};

There you have it. With only two lines of necessary code (plus one for the prime row and one more for printing it), you can create a 12 tone matrix in SuperCollider! Just for fun I also made an ultra condensed “twitter” version:

(p=(0..11).scramble;i=(12-p)%12;m=i.collect{|n|(n+p)%12};m.do{|r|r.postln})

which is only 75 characters long (or 57 if you don’t care about printing each row to its own line).

One more point I’d like to make: there is no reason why this needs to be locked into 12 slots. If you replace all the % 12 stuff with calling .size on the collection you are talking about, you can handle any number of things you’d like.

I’ve also turned this into a class which is available on my github. In addition to using the exact same approach to make the matrix itself, this class can print the matrix in a slightly better formatter way than I showed above. I also added methods to return the P, I, R, and RI rows by index. You can look at the code to see exactly how this is achieved but basically R(n) is P(n).reverse, I(n) uses .flop to rotate the matrix 90 degrees, and you can probably guess how RI(n) works from that.