Hacker News new | past | comments | ask | show | jobs | submit login
Algorithmic symphonies from one line of code (countercomplex.blogspot.com)
204 points by a1k0n on Oct 2, 2011 | hide | past | favorite | 36 comments



Firstly, this sounds quite a bit like the Symphony For Dot Matrix Printers. If you haven't heard it, I urge you to find a copy. I've linked to some video below, but it is significantly better as an album. It has all the compositional richness of a classical symphony, performed in realtime by an orchestra of printers. I dare say, it is my single favourite musical work.

Secondly, I'm reminded of the cassette tapes that computer programs used to come on (Commodore 64, etc). My friend had a box full of these cassettes, but I can't remember what machine they were for. We used to listen to the tapes and jam along with our laptops. It was a bit like having a garage band, I guess, but for tech-heads.

Symphony #1 For Dot Matrix Printers (video excerpt): http://vimeo.com/6868193

Symphony #2 For Dot Matrix Printers (full concert video): http://vimeo.com/16207657

#1 is my favourite, but #2 is also fascinating. #1 has more immediate textural/tonal exploration, while #2 is a more gradual evolution. Feel free to skip around the videos to get a sense of the breadth of sounds in these symphonies.


Those are indeed fascinating.

I do find this a bit of a stretch: "Leaving the constituent elements untouched, the process imposes a new order upon them, reorganizing the sounds along a musical structure." There are parts in there that are almost certainly slowed after recording. The deep thud of the carriage changing direction (starting at 1:47 in video #1) is one such sound that I believe has been slowed.

I could certainly be mistaken.


What you're hearing is almost certainly the Proximity Effect: http://en.wikipedia.org/wiki/Proximity_effect_(audio)

I used to record music for a living. I was really big on using natural sounds in unexpected ways. There are a lot of things you can do with creative use of microphones.


I made an HTML5 generator. Check it out:

http://www.olegkikin.com/audio/audio.html

You can pass custom formulas in a hash tag:

http://www.olegkikin.com/audio/audio.html#(t%3E%3E12|t%3E%3E...


Cool. But yours outputs 16-bit signed audio whereas by default /dev/dsp outputs 8kHz 8-bit unsigned audio, so it sounds a little bit different. Also, http://www.bemmu.com/music/index.html beat you to it and http://wurstcaptures.untergrund.net/music/ also does URL-formulas :).

(As an aside, bemmu's is creating a 16-bit signed .WAV data from 8-bit signed functions, so it isn't doing it quite right either. Why not just create an 8-bit WAV data block? I've done so here: http://a1k0n.net/code/audiogen.html)


This simple formula produces an interesting sound in your a1k0n.net player: (t % 1000) & t

Multiplying the whole thing by t adds to it.

Edit: t >> (t % 8) also produces an interesting sound; changing the number 8 changes the pitch.

Edit 2: On the theory that primes might create an interesting beat frequency, I tried this which almost sounds like a 3 part harmony: (t >> (t % 7)) & (t >> (t % 5)) & (t >> (t % 3))


Those are really cool! Is there any way to explain what the different symbols and operators are doing? I'm a web developer and have a very vague understanding of a little bit of the code but am also a musician and would love to understand a little more so I could try to make my own (without just randomly typing numbers and symbols). For example, is there some correlation between adding a ">>" or "%" operator and how that effects the timing? I saw some of the super basic formulas referenced in the blog post, and see that t[asterisk]4 generates a tone, t[asterisk]5 generates a higher tone, etc. -- is there a way, for example, to put those one after the other to compose something (or is that defeating the purpose of this exercise)?

Maybe another way to ask the question, is in your 3-part harmony example, do certain portions of the code correspond to certain parts of the generated tone?

Or is this all just totally random, trial-and-error stuff?

Thanks!


Some of the really compact formulae are trial-and-error stuff, but it doesn't have to be. You can make an arbitrarily complicated software synthesizer with this thing, and if you just want to compose algorithmic music in a "constructivist" way, you can do something like this:

    SS=function(s,o,r,p){var c=s.charCodeAt((t>>r)%p);return c==32?0:31&t*
    Math.pow(2,c/12-o)},SS("0 0     7 7     037:<<",6,10,32) + (t&4096?SS(
    "037",4,8,3)*(4096-(t&4095))>>12 : 0)
So I've defined a function "SS" which stands for sawtooth wave applied to sequencer -- where a sequencer takes an ASCII representation of notes and a speed and a base octave, and converts them into relative note frequencies, and then the sawtooth wave synth is done by 31&t*<multiplier> -- which is a number that cycles between 0 and 31 at a frequency determined by the multiplier. Just typing "31&t" into the code will give you a sawtooth wave at 8000/32 = 250Hz which is either a flat middle C or a sharp B below that. 8000 being the sample rate, 32 being the number of steps in the wave generated by "t&31".

So one of those is synthesizing a bassline and the other one is an arpeggio that starts and stops when t&4096 is true, which means it's "off" for about half a second and "on" for about half a second (8000/4096 to be precise). Add the bassline to the arpeggio and you get both voices at once.

My version has a textarea just so I could put things like that together. The OP, however, is less interested in the constructivist approach and more in the trial-and-error approach where you find something that can be implemented in 10 bytes of assembler and it magically produces a symphony.


My mind is blown! I have a zillion more questions -- if it's fun for you to talk about this please email me (address in my profile). Either way, thanks -- this is absolutely fascinating.


I'm not a musician, so this is just my understanding of the changes as a programmer and after trial and error.

The '<<' and '>>' are bit-wise shift operators[1].

The '>>' is a right-shift which is equivalent to dividing by a factor of two. e.g. t>>n == t/(2^n) This can be used to generate a beat.

The '<<' is a left-shift which is equivalent to multiplying by a factor of two. e.g. t<<n == t[asterisk](2^n) This tends to shift the pitch

The modulo operator[2], '%', has very little effect, in combinations it can generate a looping set of ranged variance, which is particularly pronounced when combined with a division operator to create clear stepping. It monotonically increases to n, and then falls back to 0 and starts increasing again. e.g. t[asterisk](t%16/64) This increases through 16 phases, holding for 4 periods.

Addition, '+', and subtraction, '-' haven't been very useful for me except when using sin(t) or cos(t) which oscillate between -1 and 1 resulting in some interesting changes to the beat. e.g.t>>4+cos(t) is shifting between t>>3 and t>>5.

The AND '&', OR '|', a short circuiting OR, '||' come in during composition. Plain OR tends to generate better results, but that's trial and error talking. Honestly, too tired to think about this.

[1] http://en.wikipedia.org/wiki/Bitwise_operation#Logical_Shift [2] http://en.wikipedia.org/wiki/Modular_arithmetic


Where is /dev/audio on OS X?


I don't know if there's a way to play it real-time. I was trying to install sox from homebrew, but it can't grab its libogg dependency, downloads.xiph.org isn't working right now, seemingly.

However, you can do this:

  $ ./soundprog > temp.au
  
hit CTRL-C (Hit it fast! You don't need it to run very long, and it will write to the resulting file very very quickly! Consider modifying the code to have a limit on the for loop.)

Then open the resulting .au file in Audacity (http://audacity.sourceforge.net/). It'll play fine.

Not as simple just writing to a sound device, but it works.


Ok, looks like xiph.org was just having a hiccup. You can do it real time with sox.

First, Get sox. I prefer homebrew for Unix type stuff (http://mxcl.github.com/homebrew/), but it's likely MacPorts, Fink, and other sources have sox available too. If using Homebrew, just:

  $ brew install sox
Compile your program. Run it like this:

  $ ./soundprog | sox -r 8000 -t u8 - -d
Voila, just like having a sound device. You can play with the 8000 to make it faster or slower (modifying the pitch as well).


I think you'd have to write some kind of CoreAudio stub.

But if you just want to play with this stuff, see the Javascript version here:

http://wurstcaptures.untergrund.net/music/


This one, from HAKMEM's circle-drawing hack, generates a simple pure sine wave:

    main(t,u){for(t=u=85;;t+=u>>2,u-=t>>2)putchar(t+128);}
BTW, I think the comments saying that aplay or pacat are equivalent to /dev/audio are slightly mistaken. /dev/audio is μ-law, like aplay -f MU_LAW. aplay defaults to linear unsigned 8-bit. With the sine wave above, the difference is very noticeable. With the various distorted sawtooths and white-noises in the original videos, it's harder to tell, but I'm reasonably sure that they're using μ-law, not linear.

BTW, aplay refuses to play 8-bit audio on my Logitech USB speakers. So I ended up using sox to convert:

    ./viznut1 | sox -r 8000 -U -t u8 - -t s16 - | aplay -f S16_LE -D hw:1,0
The -U specifies μ-law conversion.

I created a Git repository for these programs at https://github.com/kragen/viznut-music.


Long live the demoscene.


Yeah this is awesome. Party like it's 1985


If you're using Pulseaudio, replace

  $ ./a.out > /dev/dsp
with

  $ ./a.out | pacat --rate=8192


That doesn't work for their example:

main(t){for(t=0;;t++)putchar(t*(((t>>12)|(t>>8))&(63&(t>>4))));}

use this in stead:

./a.out | pacat --rate=8000 --channels=1 --format=u8

Note that the rate only changes the speed, just like the RPM of a record would.


Thanks!


If you're using ALSA, ./a.out | aplay




Reminds me of the audio equivalent of the argument put forth in Wolfram's NKS.


Someone over on reddit.com/r/coding put together a version that graphs the output:

http://langtons.atspace.com/audio/waveform.html

Enter something like t^(t%127) and the similarities are even more striking. :)


For anyone doubting that this would ever be recognised as "music," think again - http://www.youtube.com/watch?v=A8QLkThdzmA


Here's a basic Java skeleton for experimenting with these code snippets: http://pastebin.com/C0pKEjyN


My attempt at a complex melody:

http://tinyurl.com/453z7w2

xor seems to be really good for that


This one is really good. I think it's much more interesting when something resembling a melody emerges from the code.


Except for the high pitch squeals that nearly gave me a headache.


    t * ((t>>sin(7)|t>>cos(10))&tan(3221)&t>>44)
Alarm clock?


I think t * ((t>>0|t>>1)&tan(3221)&t>>46) Works a little better, or it's more like a phone ringer.


must've been lost in the rush http://news.ycombinator.com/item?id=3061884


I'm hooked

(t>>2|t>>6)*(t>>5|t>>7)


awesome, could i do this on ubuntu ?


On Ubuntu 10.10:

sound.c:

    #include <stdio.h>
    #include <math.h>

    int main()
    {
        int t;

        for ( t=0; ; t++ ) putchar( t*((t>>9|t>>13)&25&t>>6) );
    }
Then to compile and run:

    $ gcc sound.c && ./a.out | aplay -




Consider applying for YC's first-ever Fall batch! Applications are open till Aug 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: