145 lines
9.1 KiB
Markdown
145 lines
9.1 KiB
Markdown
# Bytebeat
|
|
|
|
Bytebeat is a [procedural](procgen.md) [chiptune](chiptune.md)/8bit style [music](music.md) generated by a short expression in a [programming language](programming_language.md); it was discovered/highlighted in 2011 by [Viznut](viznut.md) (author of [countercomplex](countercomplex.md) 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 [demoscene](demoscene.md). There has even been a [paper](https://arxiv.org/abs/1112.1368) written about bytebeat. Bytebeat can produce music similar (though a lot simpler) to that created e.g. with [music trackers](music_tracker.md) but with a lot less complexity and effort. These techniques can also be used to produce non-musical sounds, one may imagine for example imagine a racing game where the sound of car engine is created this way.
|
|
|
|
This is a [beautiful](beauty.md) [hack](hacking.md) for [LRS](lrs.md)/[suckless](suckless.md) programmers because it takes quite a tiny amount of code, space and effort to produce nice music, e.g. for [games](game.md) (done e.g. by [Anarch](anarch.md)).
|
|
|
|
8bit samples corresponding to `unsigned char` are typically used with bytebeat. The formulas take advantage of [overflows](overflow.md) that create rhythmical patterns with potential other operations such as multiplication, division, addition, squaring, bitwise/logical operators and conditions adding more interesting effects.
|
|
|
|
Bytebeat also looks kind of cool when rendered as an image (outputting pixels instead of audio samples).
|
|
|
|
## How To
|
|
|
|
Quick experiments with bytebeat can be performed with online tools that are easy to find on the [web](www.md), these usually use [JavaScript](javascript.md).
|
|
|
|
Nevertheless, traditionally we use [C](c.md) 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 (int i = 0; i < 10000; ++i)
|
|
putchar(
|
|
i / 3 // < 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:
|
|
|
|
- Outputting the variable `i` creates a periodical saw-shaped beat, **multiplication/division decreases/increases the speed, addition/subtraction shifts the phase backward/forward**.
|
|
- Squaring (and other powers) create a **wah-wah effect**.
|
|
- Crazier patterns can be achieved by **using the variable in places of numerical constants**, e.g. `i << ((i / 512) % 8)` (shifting by a value that depends on the variable).
|
|
- Modulo (`%`) increases the frequency and **decreases volume** (limits the wave peak).
|
|
- So called **Sierpinski harmonies** are often used melodic expressions of the form `i*N & i >> M`.
|
|
- Bitwise and (`&`) can add distortion (create steps in the wave).
|
|
- A **macro structure** of the song (silent/louds parts, verse/chorus, ...) can be achieved by combining multiple patterns with some low-frequency pattern, e.g. this alternates a slower and faster beat: `int cond = (i & 0x8000) == 0;`, `cond * (i / 16) + !cond * (i / 32)`
|
|
- **Extra variables** can add more complexity (e.g. precompute some variable `a` which will subsequently be used multiple times in the final formula).
|
|
|
|
## Copyright
|
|
|
|
It is not exactly clear whether, how and to what extent [copyright](copyright.md) 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](free_culture.md) [licenses](license.md) such as [CC-BY-SA](cc-by-sa.md), 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 good to stick [CC0](cc0.md) to any released bytebeat just in case.
|
|
|
|
## Examples
|
|
|
|
A super-simple example can be just a simple:
|
|
|
|
- `i / 16`
|
|
|
|
The following more complex examples come from the [LRS](lrs.md) game [Anarch](anarch.md) (these are legally safe even in case copyright can apply to bytebeat as Anarch is released under [CC0](cc0.md)):
|
|
|
|
- distortion guitar rhythmical beat: `~((((i >> ((i >> 2) % 32)) | (i >> ((i >> 5) % 32))) & 0x12) << 1) | (i >> 11)`
|
|
- electronic/techno: `((0x47 >> ((i >> 9) % 32)) & (i >> (i % 32))) | (0x57 >> ((i >> 7) % 32)) | (0x06 >> ((i >> ((((i * 11) >> 14) & 0x0e) % 32)) % 32))`
|
|
- main theme, uses an extra variable: `(((i) & 65536) ? (a & (((i * 2) >> 16) & 0x09)) : ~a)`, where `uint32_t a = ((i >> 7) | (i >> 9) | (~i << 1) | i)`
|
|
|
|
Here is an [ASCII](ascii_art.md) 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
|
|
```
|
|
|
|
## See Also
|
|
|
|
- [music tracker](music_tracker.md)
|
|
- [databending](databending.md)
|
|
- [MIDI](midi.md)
|
|
- [beatbox](beatbox.md)
|
|
- [animalese](animalese.md) / [beep speech](beep_speech.md) |