-
Notifications
You must be signed in to change notification settings - Fork 1
/
guide.html
121 lines (116 loc) · 5.2 KB
/
guide.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>A Guide To Bytebeat</title>
<style media="screen">
body {
font-family: "Carlito", sans-serif;
background-color: #10101d;
color: #e4dfc0;
}
h1, h2 {
font-family: "Fira Code", sans-serif;
}
h2 {
font-size: 14pt;
}
code {
font-family: "Fira Code", monospace;
color: #eff;
}
a {
color: #e4cf00;
}
a:hover {
color: #fb0;
}
a:visited {
color: #a7e;
}
main {
display: table;
margin: 0 auto;
padding-left: 2ch;
padding-right: 2ch;
background-color: #10101dcc;
max-width: 80ch;
width: 88vw;
}
</style>
</head>
<body>
<main>
<h1>Bytebeat</h1>
<article>
<nav>
<ul>
<li><a href="#what">What is bytebeat?</a></li>
<li><a href="#pcm">How is audio represented on computers?</a></li>
<li><a href="#integers">Binary representation of integers</a></li>
<li><a href="#arithmetic">Arithmetic operators</a></li>
<li><a href="#logic">Logical operators</a></li>
<li><a href="#oscillators">Oscillators</a></li>
<li><a href="#music">Making music</a></li>
<li><a href="#helpers">Helper functions</a></li>
</ul>
<a href="http://stellartux.github.io/websynth">< Back</a>
</nav>
<section id="what">
<h2>What is bytebeat?</h2>
<p>
Bytebeat is music generated from short programs. Specifically, these programs generate <abbr title="pulse code modulation">PCM</abbr> audio as a function of time. The first explanation I ever read of bytebeat was <a href="http://canonical.org/~kragen/bytebeat/">this web page</a>, and every page I've seen mention bytebeat links back to it too, so I'll carry on the tradition.
</p><p>
To summarise that page, a bytebeat program is a piece of code, which when put in a loop that increments a value <code>t</code>, generates a piece of music. Below is Crowd, one of the first pieces of bytebeat music discovered.
</p><bytebeat-player>((t<<1)^((t<<1)+(t>>7)&t>>12))|t>>(4-(1^7&(t>>19)))|t>>7</bytebeat-player>
<sub>Crowd by Kragen, CC-BY</sub>
</section>
<section id="pcm">
<h2>How is audio represented on computers?</h2>
<p>
As a list of numbers, just like everything else. The most common way of representing a waveform on a computer is called Linear Pulse Code Modulation, where the list of numbers are called samples and they represent discrete amplitude levels. The samples are spaced evenly in time.
</p><p>
The most common audio sampling encoding is signed integer 16-bit 44.1kHz, meaning that each sample lasts 1/44100 seconds (about 22 microseconds), and is an integer between -32768 and 32767. Larger bitdepths are typically represented with samples as floats between -1 and 1, allowing the signal to be described independently of the quantization step. The size of the quantization step is <code>0.5**(n-1)</code> where n is the bitdepth (0.000030517578125 for 16-bit).
</p><p>
The typical encoding used in bytebeat is unsigned integer 8-bit 8kHz, i.e. each sample is a value between 0 and 255, and is played for 1/8000th of a second (125 microseconds). This encoding is used because it is the default encoding used by aout on Linux, as it was the standard encoding when PCM sound cards first came to market.
</p>
</section>
<!--
<section id="integers">
<h2>Binary Integers</h2>
<p>
</p>
</section>
<section id="arithmetic">
<h2>Arithmetic Operators</h2>
<p>
You know these ones already. Addition <code>+</code>, subtraction <code>-</code>, multiplication <code>*</code>, division <code>/</code>.</p>
<p> Technically in "proper" integer arithmetic, division is truncated, so for example, <code>9 / 4</code> would return <code>2</code> as opposed to the <code>2.25</code> you might expect. That's how it works in C, and in most programming languages, but JavaScript automatically converts the integer to a float for you, giving the answer that you'd normally expect. </p>
</section>
<section id="logic">
<h2>Logical operators</h2>
<p></p>
</section>
<section id="oscillators">
<h2>Oscillators</h2>
</section>
<section id="music">
<h2>Making Music</h2>
</section>
-->
<section id="helpers">
<h2>Helper Functions</h2>
<p>The <a href="https://mdn.io/math"><code>Math</code> object</a> is included, so <code>sin</code> calls <code>Math.sin</code>, <code>cos</code> calls <code>Math.cos</code>, etc.
</p>
<p>In C, it is possible to parse a character as an integer. Some bytebeat composers use this to index into a string to iterate through a list of integers in a compact syntax. For example, in C, <code>"HEADACHE"[t%8]</code> would produce the numbers <code>[72, 69, 65, 68, 65, 67, 72, 69]</code> repeatedly, the ASCII character codes for the letters "HEADACHE".
</p><p>
To imitate this behaviour in JavaScript, the function <code>int</code> works as <code>Math.floor</code> for numbers, and as <code>(x,i) => x.charCodeAt(i)</code> for strings. For example the C code <code>"HEADACHE"[(t>>11)%8]</code> could be written as <code>int("HEADACHE",(t>>11)%8)</code>.
</p>
<bytebeat-player samplerate="14080" length="136">int("HEADACHEGOLDFISH",(tt>>10)%(8+(8&((tt>>14)|(tt>>15)))))*(2**(n=2+((tt>>15-(3&tt>>18))%4))/3**n*n*t&~7&0x1e70>>((tt>>16)%8))</bytebeat-player>
<sub>Headache Goldfish by Stellartux, CC-BY</sub>
</section>
</article>
</main>
<script src="src/bytebeat-player.js" type="module" charset="utf-8"></script>
</body>
</html>