Bytebeat is a procedural chiptune/8bit style music generated by a short expression in a programming language; it was discovered/highlighted in 2011 by Viznut (author of countercomplex blog) and others, and the technique capable of producing quite impressive music by single-line code has since caught the attention of many programmers, especially in the demoscene. There has even been a paper written about bytebeat. Bytebeat can produce music similar (though typically a bit simpler) to that created e.g. with music trackers but with a lot less complexity, storage size and usually also less effort. The techniques can also be used to produce non-musical sounds, for example a car engine in a racing game etc. There are now communities, such as https://dollchan.net, who experiment, investigate and create at times very advanced bytebeat.
Some advantages of bytebeat music are:
This is a beautiful hack for LRS/suckless programmers because it takes quite a tiny amount of code, space and effort to produce nice music, e.g. for games (done e.g. by Anarch).
8bit samples corresponding to unsigned char
are typically used with bytebeat (but it's not a necessity). The formulas take advantage of wrap-around overflows occurring when a variable is constantly incremented in loop, which when played as as sound will create a rhythmical pattern, i.e. the value keeps going up and upon reaching the maximum value jumps back to minimum, creating a saw-shaped waveform of a fixed frequency. This is built upon by using operators such as bit shifts, addition and multiplication, but also other bitwise operators and more complex functions to create more interesting effects.
Bytebeat also looks very cool when rendered as an image (outputting pixels instead of audio samples). Oftentimes we see fractal patterns in it.
By now some have mastered the art of bytebeat and have taken it to the level at which we can produce tracks sounding like completely legitimate music. Making bytebeat manually is simple in that it can be done quickly and easily, but difficult by the fact that we're dealing with a chaotic and therefore unpredictable system, so finding a good sounding formula is very much a trial and error effort. Nonetheless it is possible to tame the system to a degree, for instance by composing libraries of patterns and advanced bytebeat editors or by using genetic programming and/or bruteforce to simply search for a formula that will best approximate a real audio track. This way people have produced bytebeat formulas playing Rickroll etc. As one would expect such formulas are considerably more complex than the simple, manually created bytebeat -- sometimes taking several lines of code as opposed to just several characters -- but even so it is incredible that a whole music track that would otherwise take hundreds of kilobytes to store can be compressed this way into a bunch of instructions taking orders of magnitude less storage space.
Quick experiments with bytebeat can be performed with online tools that are easy to find on the web, these usually use JavaScript.
Nevertheless, traditionally we use C for bytebeat. We simply create a loop with a time variable (i
) and inside the loop body we create our bytebeat expression with the variable to compute a char that we output.
A simple "workflow" for bytebeat "development" can be set up as follows. Firstly write a C program:
#include <stdio.h>
int main(void)
{
for (unsigned int i = 0; i < 10000; ++i)
putchar(
(i >> 4) + (i * i) % 64 // < bytebeat formula here
);
return 0;
}
Now compile the program and play its output e.g. like this:
gcc program.c && ./a.out | aplay
Now we can just start experimenting and invent new music by fiddling with the formula indicated by the comment.
General tips/tricks and observations are these:
i
creates a periodical saw-shaped beat, multiplication/division decreases/increases the speed, addition/subtraction shifts the phase backward/forward.i << ((i / 512) % 8)
(shifting by a value that depends on the variable).%
) increases the frequency and decreases volume (limits the wave peak).i*N & i >> M
.&
) can add distortion (create steps in the wave).int cond = (i & 0x8000) == 0;
, cond * (i / 16) + !cond * (i / 32)
a
which will subsequently be used multiple times in the final formula).It is not exactly clear whether, how and to what extent copyright can apply to bytebeat: on one hand we have a short formula that's uncopyrightable (just like mathematical formulas), on the other hand we have music, an artistic expression. Many authors of bytebeat "release" their creations under free licenses such as CC-BY-SA, but such licenses are of course not applicable if copyright can't even arise.
We believe copyright doesn't and SHOULDN'T apply to bytebeat. To ensure this, it is possibly good to stick CC0 to any released bytebeat just in case.
A super-simple example can be just a simple:
i * 2
The following more complex examples come from the LRS game Anarch (these are legally safe even in case copyright can apply to bytebeat as Anarch is released under CC0):
~((((i >> ((i >> 2) % 32)) | (i >> ((i >> 5) % 32))) & 0x12) << 1) | (i >> 11)
((0x47 >> ((i >> 9) % 32)) & (i >> (i % 32))) | (0x57 >> ((i >> 7) % 32)) | (0x06 >> ((i >> ((((i * 11) >> 14) & 0x0e) % 32)) % 32))
(((i) & 65536) ? (a & (((i * 2) >> 16) & 0x09)) : ~a)
, where uint32_t a = ((i >> 7) | (i >> 9) | (~i << 1) | i)
Here is an ASCII visualization of the first track:
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
M'''''''''''''''M'''''''''''''''k'M'''''''''''''k'M'''''''''''''
c;xxxxxxxxxxxxxxc;cxxxxxxxxxxxxx,;xxxxxxxxxxxxxx,;cxxxxxxxxxxxxx
. ;.:;;;;;;;;;;;. ;.:;;;;;;;;;;;0 . :;;;;;;;;;;;0 . :;;;;;;;;;;;
okokokkkkkkkkkkklklkokkkkkkkkkkkokokokkkkkkkkkkklklkokkkkkkkkkkk
xkX0000000000000ckX0000000000000xkXK000000000000ckXK000000000000
oMKMKMMMMMMMMMMMlMkMKMMMMMMMMMMMoMKMKMMMMMMMMMMMlMkMKMMMMMMMMMMM
xK00KWWWWWWWWWWWcKX0KWWWWWWWWWWWxK0KKWWWWWWWWWWWcKXKKWWWWWWWWWWW
xMWMWMWWWWWWWWWWxMWMWMWWWWWWWWWWx0W0WMWWWWWWWWWWx0W0WMWWWWWWWWWW
xMWMWMWWWWWWWWWWxMWMWMWWWWWWWWWWx0W0WMWWWWWWWWWWx0W0WMWWWWWWWWWW
xMMMMMWWWWWWWWWWxMMMMMWWWWWWWWWWx0M0MMWWWWWWWWWWx0M0MMWWWWWWWWWW
xMMMMMWWWWWWWWWWxMMMMMWWWWWWWWWWx0M0MMWWWWWWWWWWx0M0MMWWWWWWWWWW
xMWcWWWWWWWWWWWWxlWcWWWWWWWWWWWWxMWcWWWWWWWWWWWWxlWcWWWWWWWWWWWW
xMccWWWWWWWWWWWWxlccWWWWWWWWWWWWxMccWWWWWWWWWWWWxlccWWWWWWWWWWWW
xMWcWWWWWWWWWWWWxlWcWWWWWWWWWWWWxMWcWWWWWWWWWWWWxlWcWWWWWWWWWWWW
xMccWWWWWWWWWWWWxlccWWWWWWWWWWWWxMccWWWWWWWWWWWWxlccWWWWWWWWWWWW
xMWWWWWWWWWWWWWWxMWWWWWWWWWWWWWWxMXWWWWWWWWWWWWWxMXWWWWWWWWWWWWW
xMWWWWWWWWWWWWWWxMWWWWWWWWWWWWWWxMXWWWWWWWWWWWWWxMXWWWWWWWWWWWWW
xMWXWWWWWWWWWWWWxMWXWWWWWWWWWWWWxMXXWWWWWWWWWWWWxMXXWWWWWWWWWWWW
xMWXWWWWWWWWWWWWxMWXWWWWWWWWWWWWxMXXWWWWWWWWWWWWxMXXWWWWWWWWWWWW
xMWW00WWWWWWWWWWxM0W00WWWWWWWWWWxMWW00WWWWWWWWWWxM0W00WWWWWWWWWW
xMW000WWWWWWWWWWxM0000WWWWWWWWWWxMW000WWWWWWWWWWxM0000WWWWWWWWWW
xMWW00WWWWWWWWWWxM0W00WWWWWWWWWWxMWW00WWWWWWWWWWxM0W00WWWWWWWWWW
xMW000WWWWWWWWWWxM0000WWWWWWWWWWWWW000WWWWWWWWWWWW0000WWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWWMWWWWWWWWWWWWWMWMWWWWWWWWWWWWWMWMWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWWMWWWWWWWWWWWWWMWMWWWWWWWWWWWWWMWMWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWMMWWWWWWWWWWWWWMMMWWWWWWWWWWWWWMMMWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWMMWWWWWWWWWWWWWMMMWWWWWWWWWWWWWMMMWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
MM''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
ccccxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
..::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ooookkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
xxKKKK0000000000000000000000000000000000000000000000000000000000
ooKKMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
xxKKMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxKKMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxxxxxxxKKKKKKKKMMMMMMMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxxxxxxxKKKKKKKKMMMMMMMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxxxxxxxKKKKKKKKMMMMMMMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
xxxxxxxxKKKKKKKKMMMMMMMMWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
Powered by nothing. All content available under CC0 1.0 (public domain). Send comments and corrections to drummyfish at disroot dot org.