This repository has been archived by the owner on Jul 24, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bytebeat.html
146 lines (135 loc) · 9.73 KB
/
bytebeat.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta http-equiv="X-UA-Compatible" content="ie=edge"><meta name="description" content="Bytebeat is the method of piping mathematical equations to an audio device make lo-fidelity gritty sounds."><!-- Bing --><meta name="msvalidate.01" content="45CBBE1BD8265A2217DFDA630EB8F84A" /><title>Tiny Brain Fans - Bytebeat</title><link rel="stylesheet" href="tinystyle.css"></head><body>
<main id="main"><article id="content"><h1 id="title">Bytebeat</h1><p>Bytebeat is the method of piping mathematical equations to an audio device make lo-fidelity gritty sounds. They often sound pretty musical due to the mathematical nature of the equations and bitwise operations. But that does not mean that it has to be "musical" to be good either, as you will discover when messing around with it.</p>
<p>Learn more about the history[6-8] and hear examples[9-11] below.</p>
<h2>Make Bytebeat</h2>
<p>A fantastic how-to of the basics including the math operations and how to use them can be found below[1]. I would highly recommend starting here if you don't get binary or bitwise operations.</p>
<p>The super simplest way to implement and test (hear) Bytebeat code is through the many online HTML5/JS apps online[2,3].</p>
<h3>Using Javascript</h3>
<p>Claude Heiland-Allen made a fully Javascript version, making a blob and rendering it as an HTML <code>audio</code> element[15]. I'll break down his implementation here (some formatting edits by me):</p>
<p><strong>bytebeat.html</strong></p>
<pre><code class="language-html"><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>bytebeat</title>
<style>
audio { width: 100%; }
</style>
</head>
<body>
<audio id="a" controls autoplay loop style="width:100%"></audio>
<script>
// length (l) in bytes
// All l[n] vars must have 0 <= l[n] <= 0xFF, and l0 + 0x24 <= 0xFF
var l0 = 0;
var l8 = 0;
var l16 = 0;
var l24 = 1;
// Final length of bytebeat in bytes
var n = l0 + (l8 << 8) + (l16 << 16) + (l24 << 24);
// Create a new Uint8Array that is the length of the header + bytebeat size
var WAV = new Uint8Array(44 + n);
// Set the header of the WAV file as u8 8000Hz stereo
WAV.set(new Uint8Array(
[ 0x52, 0x49, 0x46, 0x46, 0x24+l0, l8, l16, l24
, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20
, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00
, 0x40, 0x1f, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00
, 0x02, 0x00, 0x08, 0x00, 0x64, 0x61, 0x74, 0x61
, l0, l8, l16, l24 ]
));
// For each byte within n / 2 (divided in half for stereo)
for (var t = 0; t < n / 2; t++) {
// For each channel
for (var c = 0; c < 2; c++) {
// Make bytebeat
var k = 2 * c - 1;
var o = t & ((k * t) >> ((-k * t) >> ((t >> 8) & (t >> 16))));
// Write output of bytebeat to end of WAV file
// (Not fully grokking the right side of this yet)
WAV[44 + 2 * t + c] = ((o & 0xFF) + 0x80) & 0xFF;
}
}
// Convert the WAV into a Blob of data and set it as the audio element source
const bytebeatOutput = new Blob([WAV], { type: "audio/wav" });
document.getElementById("a").src = URL.createObjectURL(bytebeatOutput);
</script>
</body>
</html>
</code></pre>
<h3>Using OSX</h3>
<p>My desire when starting to mess with this stuff was trying to figure out how I could do it in the command line, as that was how I had seen it laid out in many examples in Linux. The problem was that the built in tools to pipe data into your audio device was not built in to OSX the way it is built in to Linux, so I had to do some sleuthing. With a lot of help from the Merveilles community[4], I was able to finally figure out the process and I wanted to document it here.</p>
<ol>
<li>Install SoX with homebrew[5]: <code>brew install sox</code></li>
<li><strong>Turn down your volume!</strong></li>
<li>Create a bash script to automate the build, compile, and piping of your Bytebeat formulas[12]</li>
</ol>
<p><strong>bytebeat.sh</strong></p>
<pre><code class="language-shell">#!/bin/bash
# This script creates and plays a simple ByteBeat
# $1: a string with the ByteBeat algorithm; e.g. "((t * 3) & (t >> 5))"
# $2: the name of the file to be created (without an extension)
# Create the C program
PROGRAM="#include <math.h>
// These are `sin` and `cos` functions for your equation
// e.g. "(s(t) >> 5) | c(t)"
int s(double num){
return 256 * sin(num);
};
int c(double num){
return 256 * cos(num);
};
main(t) {
for (t = 0; ; t++) {
putchar( $1 );
}
};"
echo -e "$PROGRAM" > "$2.c"
# Compile the source
gcc "$2.c" -o "$2"
# Play it with standard Bytebeat settings
./"$2" | sox -t u8 -r 8k -c 1 - -d
</code></pre>
<ol start="4">
<li>Set the permissions to be executed by the user: <code>chmod u+x bytebeat.sh </code></li>
<li>Try it out with a bytebeat equation. The script takes two arguments: the equation, and the name of the file to generate and play. e.g. <code>./bytebeat.sh "(t/4)*(t>>8|((14 & t)^3))" test</code></li>
</ol>
<p>If you want to record the noise you've created, one is fairly user friendly and the other one is a bit clunky. </p>
<ol>
<li>The easiest way is to download and install Rogue Amoeba's <a href="https://rogueamoeba.com/loopback/" target="_blank">Loopback</a> to record your system audio. This is very simple and highly recommend it.</li>
<li>
Create a raw audio file on your computer and use <a href="https://www.audacityteam.org/" target="_blank">Audacity</a> to open it. This has mixed results for me.<ol>
<li>Run your script to create the compiled Bytebeat script</li>
<li><a href="shell.html">Pipe</a> the output of this newly compiled script to a file instead of piped to SoX, using <code>Ctrl + C</code> to end it after about a half second: <code>./test > output.raw</code> </li>
<li>
Open the file in Audacity, using <code>File</code> > <code>Import</code> > <code>Raw Data...</code> with the following settings:<ul>
<li>Encoding: Unsigned 8-bit PCM</li>
<li>Byte Order: No endianness</li>
<li>Channels: 1 (Mono)</li>
<li>Start Offset: 0</li>
<li>Amount to Import: 100</li>
<li>Sample Rate: 8000</li>
</ul>
</li>
</ol>
</li>
</ol>
<h2>References</h2>
<ol>
<li><a href="https://github.com/TuesdayNightMachines/Bytebeats" target="_blank">TuesdayNightMachine's Github page</a></li>
<li><a href="https://greggman.com/downloads/examples/html5bytebeat/html5bytebeat.html#t=0&e=0&s=8000&bb=5d00000100180000000000000000141d0150043e1f062919296ab90380807628655b351388d1ffe7d4a000" target="_blank">Gregg Tavares</a></li>
<li><a href="http://wurstcaptures.untergrund.net/music/" target="_blank">Bemmu and rarefluid (in stereo!)</a></li>
<li><a href="https://merveilles.town/web/statuses/105096777143471978" target="_blank">https://merveilles.town/web/statuses/105096777143471978</a></li>
<li><a href="https://chrisrosser.net/posts/2020/04/06/using-sox-on-macos/" target="_blank">https://chrisrosser.net/posts/2020/04/06/using-sox-on-macos/</a></li>
<li><a href="http://canonical.org/~kragen/bytebeat/" target="_blank">Kragen's Writeup</a></li>
<li><a href="https://countercomplex.blogspot.com/2011/10/algorithmic-symphonies-from-one-line-of.html" target="_blank">The original post from Ville-Matias Heikkilä</a> and <a href="https://countercomplex.blogspot.com/2011/10/some-deep-analysis-of-one-line-music.html" target="_blank">his follow up post</a></li>
<li><a href="https://zserge.com/posts/etude-in-c/" target="_blank">ZSerge's article where I first heard about it</a></li>
<li><a href="https://www.youtube.com/watch?v=GtQdIYUtAHg" target="_blank">Bytebeat: Experimental music from very short C programs</a></li>
<li><a href="https://www.youtube.com/watch?v=qlrs2Vorw2Y" target="_blank">Bytebeat: Experimental one-line algorithmic music - the 2nd iteration</a></li>
<li><a href="https://www.youtube.com/watch?v=tCRPUv8V22o" target="_blank">Bytebeat: Music from very short programs - the 3rd iteration</a></li>
<li><a href="https://web.archive.org/web/20160610140821/http://coleingraham.com/2013/04/28/bytebeat-shell-script/" target="_blank">https://web.archive.org/web/20160610140821/http://coleingraham.com/2013/04/28/bytebeat-shell-script/</a></li>
<li><a href="http://royal-paw.com/2012/01/bytebeats-in-c-and-python-generative-symphonies-from-extremely-small-programs/" target="_blank">http://royal-paw.com/2012/01/bytebeats-in-c-and-python-generative-symphonies-from-extremely-small-programs/</a></li>
<li><a href="https://gist.github.com/bzamecnik/a2d45dc0addb8d602d70b1d8df0f9fd0" target="_blank">https://gist.github.com/bzamecnik/a2d45dc0addb8d602d70b1d8df0f9fd0</a></li>
<li><a href="https://mathr.co.uk/misc/2021-12-23_bytebeat.html" target="_blank">https://mathr.co.uk/misc/2021-12-23_bytebeat.html</a></li>
</ol>
<p class="last-modified">Last modified: 202206101419</p></article></main><footer><nav><a href="index.html">Sitemap</a></nav><div class="social"><p>Built using <a href="http://codeberg.org/milofultz/swiki" target="_blank" rel="noopener noreferrer">{{SWIKI}}</a></p><p><a href="http://codeberg.org/milofultz/" target="_blank" rel="noopener noreferrer">Codeberg</a></p><p><a href="http://milofultz.com/" target="_blank" rel="noopener noreferrer">milofultz.com</a></p><p><a href="https://merveilles.town/@milofultz" target="_blank" rel="me noopener noreferrer">Mastodon</a></p></div></footer></body></html>