Saturday, July 13, 2013

The Infamous Cellular Automaton Synth

It started with the obfuscated C competition... and a youtube video. Well, no it really started with learning about Conway's Game of Life. Err.. It started with a video about a 13 year old girl who was implementing Conway's Game of Life on the raspberry pi... Ahem. I became interested in cellular automata and especially linking it to music. I originally tried to emulate this one liner that was getting passed around on IRC:
echo "main(i){for(i=0;;i++)putchar(((i*(i>>8|i>>9)&46&i>>8))^(i&i>>13|i>>6));}" | gcc -x c - && ./a.out | aplay
I tried to implement my own version that used an automaton to do the same sort of thing (I'll let you scratch your head on what it does, or just copy and paste it into your terminal). It took me a while to get it working, but I eventually got an automaton operating successfully on a torus. I then went and obfuscated it thinking of entering it into the IOCC. It looks pretty good:
echo "main(_i_,i,_,i_i){i_i=30;for(i=7;;i=_i_<<1|_i_>>7) {_i_=0;for(_=0;_<8;_++)_i_|=((i_i&1<<((i>>_|i<<(1+~_&7))&7))>0) <<_;putchar(_i_);}}" | gcc -x c - && ./a.out | aplay
Got it? Simple enough. So where did I go with this?

It works. Well. It compiles. Problem is it sounded awful. I was hoping for some really great sound, but just got an annoying buzz. Oh well. I let it rest there.

Then several months later, I contributed a filter to the LV2 Midi filters project using a normal random distribution approximation rather than the uniform distribution method employed initially. I had already looked at the source of many plugins but never got the nerve to jump into developing, but this broke down the wall.

I knew I wanted to make a synth. I'm not sure how exactly I came to decide the way to do it, but eventually I decided to use the cellular automaton code I'd developed in it. I thought for a while, whether each cell would be another note or what, but I eventually settled on making an additive synth with each cell being a harmonic, that sounds when the cell is alive and is silent when the cell is dead. This works pretty well, especially to get pulsating sounds, though the synth isn't limited to those sort of things. The fundamental is always on, and you can easily create a patch that all the harmonics are on or off and don't change. If that doesn't sound so easy, then read on.

An elementary cell automaton basically is a sort of state machine where a number of cells will change in the next time step according to their current state and that of their neighbors. Since this is operating on a toroid this means that the edge cell wraps and is neighbors with the other edge. We use 16 cells, though actually any number is doable by the code. How cells respond is determined by a rule, which is basically an 8 bit number (0-255) where each bit value corresponds to the next state and the bit position is the current state. So for example rule 30 is hex value 0x1E or binary 00011110b. Which means the cells operate as follows:

111 110 101 100 011 010 001 000
 0   0   0   1   1   1   1   0

So a cell sequence of three cells in a row alive, the middle one will die for the next state. If the inital conditon is 0x0100 or 0000000100000000b (16 cells middle one alive) then the sequence looks like:
     00  0     
    00 0000    
   00  0   0   
  00 0000 000  
 00  0    0  0 
00 0000  000000
0  0   000     
00000 00  0    0
      0 0000  00
0    00 0   000
00  00  00 00  
0 000 000  0 0 0
  0   0  000 0 0
0000 00000   0 0
     0    0 00 0
0   000  00 0  0
 0 00  000  0000
 0 0 000  000  
00 0 0  000  0 
0  0 0000  00000

where a 0 is a cell and blank is no cell. I cut it off of course but it will go on indefinitely unless it reaches a stable state (i.e all cells are dead and the last bit of the rule is zero). Wikipedia has a nice article with some great graphics from elementary cell automata, though the images are generated from random initial conditions and not on a torus.

If you want to do some great sound design using the automaton, I recommend getting a pencil and paper and writing out the states and filling in what you want the next state to do:

111 110 101 100 011 010 001 000
 1   1   1   1   0   0   0   0

This rule is 0xF0 = 240. In this example I made it so each cell becomes the state its left neighbor is in. Coupled with an input like 0xAFAA you get diagonal stripes going down:
0 0 00000 0 0 0
 0 0 00000 0 0 0
0 0 0 00000 0 0
 0 0 0 00000 0 0
0 0 0 0 00000 0
 0 0 0 0 00000 0
0 0 0 0 0 00000
 0 0 0 0 0 00000
0 0 0 0 0 0 0000
00 0 0 0 0 0 000
000 0 0 0 0 0 00
0000 0 0 0 0 0 0
00000 0 0 0 0 0
 00000 0 0 0 0 0
0 00000 0 0 0 0
 0 00000 0 0 0 0

This gives an interesting phasor sort of sound. These sequences shown are generated by the rule utility provided with the source of Infamous Plugins, which will help you in your explorations. I used this methodology to make all the presets.

The synth has no filter, though filter like effects can be attained through adjusting the number of harmonics played. If you use this parameter to turn off the harmonics because you don't want that sort of sound I reccommend you also turn the cell lifetime up to the max because the cells are calculated even when they are not going to be played (this way you can "open up" the number of harmonics like a filter for some nice effects). Nothing bad happens if you don't, just wasted CPU cycles.

You can also use the lfos for some FM synthesis or to get some good drum sounds like I do on the kick drum of the demo. The demo is entirely made with the Infamous Cellular Automaton Synth plugin. Have a listen and feel free to comment, make suggestions, ask questions, etc. Oh ya and download the source and install it!

*note: I accidentally deleted this post, but luckily was able to recover it from the linux audio planet! whew.


Donn Jeferson Atienza said...

Hi Spencer, I was interested in your blog about lv2 and developing DAWs for linux, i was hoping we could talk more about it

Spencer said...


My apologies, I did not see your comment until now. I frequent the forum and you can PM me there or continue to comment here.