Toronto, Ontario, Canada

A fractal sequencer toy

2022-05-20

Here's a fractal chord sequencer you can play right in your browser.

 

F
D
Bb
C
F
C

Transposition/coset:

C

How to play

The play/pause (  /  ) and reset (  ) buttons are reasonably self-explanatory. Pause takes effect at the end of the current bar, so it won't be instantaneous when you press the button.

Just below those buttons are boxes for the sequence substitution rule. You can choose the chords that will define the sequence with the up/down/left/right buttons, but note that the sequencer does not just play these chords in a loop. It does a fractal substitution (described below) to generate an effectively infinite sequence of chords from the ones you enter.

Note names C, C#, D, Eb, and so on refer to the roots of chords, and the other symbols describe chord qualities as follows. The basic shape, such as rectangle or diamond, describes the core quality of the chord. When there is more than one symbol for a given chord, differentiated by dots and subscript numbers, the different symbols sound the same but have different effects when they interact with other chords in the fractal substitution algorithm.

You can change a few other settings. "Stages" is the number of chords in the substitution rule, adjustable from 2 to 12. "Tempo" is the speed at which the sequencer runs, in beats per minute. The default is 130, which is reasonable for most grooves, but some of the grooves sound better a little slower or faster, so you should experiment. The "groove" selection controls not only the drum track, but also the rhythm for playing the chord notes and some details of how it selects the voicing (specific notes) to make up each chord. Finally, "transposition/coset" sets a root note and chord symbol that will be applied to all the chords in the sequence, outside the recursive substitution.

As you change settings, the query string in your browser's location bar should be updated with each change. So you can bookmark the URL and return to the same settings, share your unique sequence creation on social media, and so on.

This has been tested only in my old Firefox installation. That means it should probably be compatible with everything else, but I'll be interested to hear reports on how well it works in other browsers.

How it works: recursive substitution

This sequencer toy is my latest experiment in recursively-generated fractal chord progressions. You may want to read my earlier article on those, and the notes on my more recent piece Aconcagua. Those were focused on specific pieces of music written using fractal chord progressions; this time around, I've turned the concept into an interactive piece of sequencing software.

Suppose you have a chord progression like the doo-wop progression, I-vi-IV-V. If you play it in the key of C, you get the four chords C-Am-F-G. But you could play it in some other key. The same progression in A would be A-F#m-D-E. In F, it would be F-Dm-Bb-C; and so on.

So suppose we take the I-vi-IV-V progression, C-Am-F-G, and play it four times, first in C, then in A, then in F, then in G. The progression itself (C-A-F-G) tells us in what key to play the whole progression.

C-Am-F-G-A-F#m-D-E-F-Dm-Bb-C-G-Em-C-D

That's 16 chords; and we can add another level by playing that entire 16-chord progression four times, first starting on C, then transposed to start on A, then starting on F... this recursive substitution can be carried to as many levels as desired, increasing in length by a factor of four for each level, sequence of chords as long as desired with the same structure at both long and short time scales.

In my piece Dharmapala I added an additional wrinkle: whenever substituting into a minor chord, I swapped the major and minor chords. In that piece I was using the vi-IV-I-V progression ("sensitive female"), so playing it in C would be Am-F-C-G; but when substituting into the chord Am, instead of just transposing it to give F#m-D-A-E, I swapped major and minor to give F#-Dm-Am-Em. I found that applying that swap throughout the fractal substitution made the music more interesting.

Without the major-minor swap, C-Am-F-G as I said would give these chords in the second level of substitution:

C-Am-F-G-A-F#m-D-E-F-Dm-Bb-C-G-Em-C-D

With the major-minor swap, the same C-Am-F-G generating rule gives these (difference bolded):

C-Am-F-G-Am-F#-Dm-Em-F-Dm-Bb-C-G-Em-C-D

In this interactive sequencer, I'm applying a similar though more complicated idea: chord qualities are extended into 36 different symbols, each of which transforms the other chord qualities in a different way.

A little group theory

The sequencer first plays through the generating rule (sequence of chords) as written. Then it plays it with a second level of substitution - so, first chord in the rule combined with each chord in the rule, then the second chord in the rule combined with each chord, and so on. Then it proceeds to three levels of recursive substitution, four levels, and so on.

If the chords are just basic major chords, denoted by the symbol , then the roots are added up as musical transpositions and the chords remain just basic major chords. But using the other symbols makes the chord qualities change in ways that get more complicated as more symbols stack up. For example, is a minor chord like in Dharmapala: it exchanges the major chord symbol with itself.

You could program the sequencer to use the generating rule AFCG, or follow that link, and get basically the same sequence of chords that was used in Dharmapala. Each minor chord denoted by exchanges major and minor chords when it comes up in the substitution process.

Note that I said a minor chord denoted by . Other minor chords are possible. If you instead used the symbol for the minor chord in the sequence, then it would combine with itself to give - another minor chord - as well as combining with to give a minor chord. So in the second level of substitution, there would be more minor chords. And in the third and later levels, other chord symbols would start appearing as a result of using , such as (minor with added second).

To get some idea of how the chord symbols transform each other to make the music more complicated, follow this link to try the generating rule CAFG. That's the doo-wop progression again, with my best attempt at a twist groove straight out of 1959. For the first dozen bars or so it's just something light and happy that Chubby Checker might play. But then it gets, well, twisted by the consequences of the major chord symbols and , which change others into suspended and diminished chords. Eventually the doo-wop harmony is almost unrecognizable.

At each step the sequencer shows its chord symbol calculation next to the reset and play/pause buttons, so you can get some idea of what it's doing. You can also set a chord symbol with the "transposition/coset" option, which will be applied uniformly to all the chords in the sequence. For instance, if you set this to a minor chord and all the chords in the generating rule to , then you would end up with a sequence of only minor chords.

The chord symbol calculation is based on a branch of mathematics called group theory, which is the abstract study of symmetry. The chord symbols are elements of a group, and they combine with each other according to an operation that has the basic group properties of having associativity, an identity, and inverses. I've carefully selected which group to use, and how to map group elements into chord qualities, to produce what I think will be musically useful behaviour.

I don't encourage readers to try too hard to understand the details of the math because they are not very relevant to actually playing the sequencer. It is probably better to just experiment until the results sound good. But if you insist on knowing the exact definition of the rule for how chord symbols transform each other, here it is. First of all, the roots of chords (as notes of the 12-note scale) simply add. The note C is zero semitones; other notes are however many semitones from C; and the scale wraps around at the end of the octave. So, for instance, C·E=E, and D·G=A. I am writing a centre-dot · for the operation that combines two notes. Group theorists may note that roots of chords are isomorphic to C12.

The symbols for chord qualities are visually complicated, but each of the 36 symbols can be described by an integer from 0 to 17 (shown in the subscript) and a bit 1 or 0 which indicates whether that symbol has a dot in the middle. For example, is described by (0,0) and is described by (7,1). In that representation, the rule for combining chord qualities is summarized as follows.

For example, ·= and ·=. You may note that is the identity - combine it with any other symbol and you get the other symbol - while is self-inverse, with ·=, and happens to be the only self-inverse symbol.

These rules make the chord symbols isomorphic to the dicyclic group of order 36, or Dic9, a group chosen to be non-abelian, about the right size, and have many subgroups of about the right size. Considering both the root notes and the quality symbols together, the group describing entire chords is the direct product C12×Dic9, with 432 elements.

Subgroups

As mentioned above, the chord quality symbols and affect each other as follows.

If you combine any number of copies of these two symbols, the result is always one of the two. So, if you wrote your generating rule with only these two symbols, you could be sure that the calculation would never have any other result. Such a sequence would only ever contain major and minor chords, not anything weird like elevenths. Moreover, although this is harder to state precisely, you could reasonably expect that a sequence generated from a reasonably long rule that contained only and , after several levels of substitution, would contain major and minor chords in roughly equal proportions.

In mathematical terms we can say that these two elements of the group form a subgroup: a subset {, } which is closed under the group operation. Combining elements of the subgroup always gives elements of the subgroup. Subgroups are musically useful because we can use them to control what kinds of chords the sequencer will generate.

Suppose you want to get both major and minor chords, but mostly major. Then you might build your sequence using the chord symbols {, , , }, which form a larger subgroup of three major chords and one minor. The sequence will remain within the subgroup and if it ends up uniformly distributed, it will contain mostly major but also some minor chords.

Here is a list of all the subgroups of the chord quality symbols (subgroups of Dic9 in the sequencer's notation).

Grooves and voicing

The "grooves" are not really the point of this toy, and the UI doesn't let you do much with them except select one. But it's probably worth talking a bit about how they work.

First, there's the matter of voicing - choosing exactly which notes to play to make up the chosen chord. The recursive substitution selects a chord for each bar of music, which specifies between three and six "notes" in the sense of pitch classes - offsets in terms of however many semitones from the start of the octave without specifying which octave. For example, the C major chord consists of pitch classes 0, 4, and 7 (notes named C, E, and G).

This sequencer uses an internal notion of six voices, so from the pitch classes, it needs to choose six specific pitches that are in particular octaves; confusingly, in music specific pitches are also traditionally called "notes" even though they are different from pitch classes. In my code I use the term "voicing" to refer to the collection of six specific pitches, which I represent using MIDI note numbers.

In Dharmapala I used a constraint solver written in Prolog to choose the voicings for the chords to meet my musical goals, running offline with a fair bit of human supervision. I didn't want to implement something like that in Javascript and try to make it run in real time, so I used a much simpler branch and bound algorithm here. It still does some clever things. The voicing for each bar is chosen to have the following properties:

Distance between voicings is defined by sorting them and then taking the L1 metric (sum of absolute differences), so that for instance the distance between (1,2,3) and (1,3,7) is 5. Each groove specifies, as well as the constant target voicing, the relative weights to be applied to the distance from the previous bar and the distance from the target. The branch and bound algorithm runs to find the voicing that minimizes the weighted distance while obeying the other constraints, with ties broken arbitrarily.

The point of the "constant target voicing" is to allow different grooves to aim for different pitch ranges and open or closed harmony styles. For instance, the voicing target for the "Discotheque" groove is (30,31,32,66,69,72), which encourages the three lowest voices to be as low as possible, while the other three will be higher and fairly close to each other. The rhythmic patterns for this groove play the bottom three voices as bass notes and the top three as blips of chords. The "Node Rums" groove, on the other hand, uses a voicing target of (40,45,50,59,64); its chords will be nearer the middle of the pitch range, and will tend toward more open harmony. Despite being the same chords in the sense of containing the same pitch classes, chords in these two grooves will sound different from each other.

Given a voicing, the sequencer chooses a pattern for the bar. Each groove contains several patterns specifying samples to play at specific beats in the bar, including both unpitched drum samples and pitched samples that are parameterized by notes from the voicing. A single pattern might say "play notes 1, 2, and 3 from the voicing using this sample set on beats 1 and 3; play notes 4, 5, and 6 from the voicing using that sample set on beats 2 and 4; and play the kick drum sample on beats 1, 2, 3, and 4." Each groove also contains a list of rules specifying when to play the different patterns, with conditions like "on the final bar of the substitution rule," "with such-and-such probability," and "on bar numbers congruent to zero modulo k." The end result is that the rhythms can be fairly complex despite being generated by simple logic.

Planning out the grooves and finding appropriate samples for them was fun, but also a lot of work, which is why I ended up only defining six choices. I think they nonetheless do a reasonable job of covering a range of musical styles. Building a similar Web-based toy with more focus on user control of the groove might be interesting, but wasn't my main interest here; I was more interested in building a way for visitors to explore fractal chord sequences and the group-theory stuff.

Every time I write about a way of generating sequences, whether it's fractal chords, hypercube walks, or something else, I get the question of whether I'm going to build and sell a module to do it. This one is probably a better candidate for that than some of the others, but still not a great candidate. I discuss this kind of issue, and other ideas for future products, a lot in my weekly Twitch stream. I think the fractal sequencer would need to have a lot of front-panel controls, and it would need to be a digital module, with a lot of effort going into programming the firmware; both those things mean it would be expensive. I would need to be sure that I could sell a significant number of them at at least a thousand dollars each (quite possibly more) and even if there are a lot of people who will enjoy poking at the fractal sequencer in a Web browser for a few minutes for free, there are fewer who would really spend the money for a permanent hardware device just to do it. Nonetheless, I'll be interested to see whether this Web page version attracts attention and interest. There's certainly more that can be done with the fractal substitution and group-based chord transformation concepts.

All about normalling || Do you really want that scope?

Comments

Works well in my Chrome browser!! I like the Sine Surf setting (quirky) and The Node Rums. I know that the rhythm is not the idea of your work, but they are interesting. You don't mention if anyone can use any of these sequences in their own creative work here? Maybe I missed it. Thanks for all your effort. Oo took me a few shakes to work out your Anti Spam ha ha
Steve Cournane - 2022-05-22
I don't claim copyright on the output myself, but it might be difficult to do a really careful clearance of possible claims on the drum samples in particular, which I got from the "Hydrogen" sequencer software (hydrogen-music.org). It credits them to "L.-E. Johansson" and the field for copyright license in the relevant XML file is left blank. I'd hesitate to sell commercial recordings on a major label made with these samples, but I feel okay about posting them in this toy, and I figure what others choose to do with the output is their business.
Matthew Skala - 2022-05-22
Nice. Still not sure about what it's doing but I certainly like it. Will re-read the "How it Works" part a few more times and maybe it will sink in.
Darryl McGee - 2022-06-01
This is great fun! Thanks Matthew
Alan - 2022-06-02
Anti-spam, fill in the blank: Coast Synthesis

Subscribe to our newsletter