bytebeat-composer/src/index.pug

255 lines
9.9 KiB
Text
Raw Permalink Normal View History

2023-12-25 18:51:35 +01:00
doctype html
html(lang="en")
head
meta(charset="utf-8")
meta(name="viewport" content="width=device-width,initial-scale=1")
meta(name="description" content="JS algorithmic music generator")
meta(name="author" content="SArpnt")
title Bytebeat composer
link(href="/favicon.png" rel="shortcut icon")
link(href="/style.css" type="text/css" rel="stylesheet")
2024-08-06 03:51:03 +02:00
script(src="/interface.js" defer type="module")
2023-12-28 04:37:48 +01:00
link(rel="modulepreload" as="audioworklet" href="/audio-worklet.js")
2023-12-25 18:51:35 +01:00
body
main#content
section.container-fixed
#code-editor-container
textarea#code-editor(aria-label="Code editor" spellcheck="false")
| (t*(1+(5&t>>10))*(3+(t>>17&1?(2^2&t>>14)/3:3&(t>>13)+1))>>(3&t>>9))&(t&4096?(t*(t^t%9)|t>>3)>>1:255)
#controls
span#control-time.control-group.control-time
button#control-time-unit(title="Time unit" onclick="bytebeat.changeTimeUnit()")
2023-12-25 18:51:35 +01:00
label#control-time-unit-label(for="control-time-value") t
input#control-time-value(
onchange="bytebeat.setByteSample(bytebeat.convertFromUnit(+this.value)); this.value = ''"
style="width:8em"
2023-12-25 18:51:35 +01:00
placeholder="0"
type="number"
title="Time value"
)
span.control-group.control-time.buttons
button#control-restart(onclick="bytebeat.resetTime()" title="Restart") ⏮︎
button#control-fr(onclick="bytebeat.setPlaySpeed(-4)" title="Fast reverse") ⏪︎
button#control-reverse(onclick="bytebeat.setPlaySpeed(-1)" title="Reverse") ⏴︎
button#control-pause(onclick="bytebeat.setPlaySpeed(0)" title="Pause") ⏸︎
button#control-play(onclick="bytebeat.setPlaySpeed(1)" title="Play") ⏵︎
button#control-ff(onclick="bytebeat.setPlaySpeed(4)" title="Fast Forward") ⏩︎
2023-12-25 18:51:35 +01:00
span.control-group.control-playback
input#control-volume(
oninput="bytebeat.setVolume()"
2023-12-25 18:51:35 +01:00
value="0.6"
step="any"
max="1"
min="0"
type="range"
title="Volume"
style="width:8em"
2023-12-25 18:51:35 +01:00
)
span.control-group.control-view.buttons
button#control-scaledown(onclick="bytebeat.changeScale(-1)" title="Zoom in") +
button#control-scaleup(onclick="bytebeat.changeScale(1)" title="Zoom out") -
2023-12-25 18:51:35 +01:00
//
span.control-group.control-record.buttons
button(title="Share" onclick="") 🔗︎
button(title="Download" onclick="") 📥︎
button(title="Upload" onclick="") 📤︎
button(title="Record" onclick="") ⏺︎
span.control-group.control-song
select#control-song-mode(
onchange="bytebeat.setSongMode(this.value); bytebeat.refresh()"
2023-12-25 18:51:35 +01:00
title="Playback mode"
)
option(value="Bytebeat" selected) Bytebeat
option(value="Signed Bytebeat") Signed Bytebeat
option(value="Floatbeat") Floatbeat
option(value="Funcbeat") Funcbeat
span.control-group
2023-12-28 21:34:32 +01:00
input#control-sample-rate.control-song.control-round-right(
onchange="bytebeat.setSampleRate(+this.value); bytebeat.refresh()"
2023-12-25 18:51:35 +01:00
onblur="this.value||=this.placeholder;this.placeholder=''"
onfocus="this.placeholder=this.value;this.value=''"
style="width:6em"
2023-12-25 18:51:35 +01:00
value="8000"
list="samplerates"
step="any"
min="0"
type="number"
title="Sample rate"
)
span.text
2023-12-28 21:34:32 +01:00
label.control-song(for="control-sample-rate") Hz
label.control-playback(for="control-sample-rate-divisor") /
input#control-sample-rate-divisor.control-playback.control-round-left.control-round-right(
onchange="bytebeat.setSampleRateDivisor(+this.value); bytebeat.refresh()"
style="width:3em"
2023-12-25 18:51:35 +01:00
value="1"
step="1"
min="1"
type="number"
title="Sample rate divisor"
)
datalist#samplerates
option(value="8000")
option(value="11025")
option(value="16000")
option(value="22050")
option(value="32000")
option(value="44100")
option(value="48000")
#error
#canvas-container(onclick="bytebeat.togglePlay()")
2023-12-25 18:51:35 +01:00
canvas#canvas-main(height="256" width="1024" aria-label="Oscillioscope")
#canvas-timecursor
#canvas-toggleplay.canvas-toggleplay-show
svg#svg-canvas-toggleplay-play
use(xlink:href="#symbol-play")
svg#svg-canvas-toggleplay-pause
use(xlink:href="#symbol-pause")
section.container-scroll
details
summary
2023-12-25 21:56:34 +01:00
h1 Info — about bytebeat
2023-12-25 18:51:35 +01:00
article
section
p.
Bytebeat music (or one-liner music) was invented in
September 2011. Simple bytebeats are often a piece of
rhythmic and somewhat melodic music with no score, no
instruments, and no real oscillators. It's simply an
expression that defines a waveform as a function of
time, processed (usually) 8000 times per second,
resulting in an audible waveform with a 256-step
resolution from silence (0) to full amplitude (256). If
you put that formula into a program with a loop that
increments time variable (t), you can generate the
headerless unsigned 8 bit mono 8kHz audio stream on
output, like in this application. Since these directly
output a waveform, they have great performance in
compiled languages and can often be ran on even the
weakest embedded devices.
// TODO link the info.md
2023-12-25 18:51:35 +01:00
section
p
2023-12-25 21:56:34 +01:00
a(target="_blank" href="http://canonical.org/~kragen/bytebeat") History of bytebeat
2023-12-25 18:51:35 +01:00
figure.figure-list
figcaption Original blog posts and videos from Viznut:
ul
li
a(
target="_blank"
href="https://countercomplex.blogspot.com/2011/10/algorithmic-symphonies-from-one-line-of.html"
) Blog posts #1
li
a(
target="_blank"
href="https://countercomplex.blogspot.com.au/search/label/algorithmic%20music"
) Blog posts #2
li
a(target="_blank" href="https://www.youtube.com/watch?v=GtQdIYUtAHg") YouTube video #1
2023-12-25 18:51:35 +01:00
li
a(target="_blank" href="https://www.youtube.com/watch?v=qlrs2Vorw2Y") YouTube video #2
2023-12-25 18:51:35 +01:00
li
a(target="_blank" href="https://www.youtube.com/watch?v=tCRPUv8V22o") YouTube video #3
2023-12-25 18:51:35 +01:00
figure.figure-list
figcaption Online JavaScript players:
ul
li
a(target="_blank" href="https://dollchan.net/bytebeat") by SthephanShi
li
a(
target="_blank"
href="https://greggman.com/downloads/examples/html5bytebeat/html5bytebeat.html"
) by Greggman
li
2023-12-25 21:56:34 +01:00
a(target="_blank" href="https://entropedia.co.uk/generative_music") by Paul Hayes
2023-12-25 18:51:35 +01:00
li
a(target="_blank" href="https://wurstcaptures.untergrund.net/music") by Bemmu and Rarefluid
2023-12-25 18:51:35 +01:00
section
p.
This webpage has a collection of bytebeat music found by
SthephanShi, I may add my own compositions here too.
Playback modes are:
2023-12-25 18:51:35 +01:00
ul
li.
Bytebeat — audio output is from 0 to 255, values
outside this are wrapped, and non-integers are
floored.
li.
Signed Bytebeat — audio output is from -128 to
127, values outside this are wrapped, and
non-integers are floored. This is an uncommon format,
which comes from c allowing char to be signed or
unsigned depending on the compiler.
li.
Floatbeat — audio output is from -1.0 to 1.0,
values outside this are clipped. This allows higher
quality audio, and is common for other generative
music.
li.
Funcbeat — based on TinyRave, code is not an
expression, and is only ran once. The returned
function is ran with time in seconds, output is -1.0 to 1.0.
2023-12-25 18:51:35 +01:00
p
| This website is made by SArpnt, and is a fork of
2023-12-26 04:42:04 +01:00
|
2023-12-25 18:51:35 +01:00
a(target="_blank" href="https://dollchan.net/bytebeat") bytebeat-composer
2023-12-26 04:42:04 +01:00
|
2023-12-25 18:51:35 +01:00
| by
2023-12-26 04:42:04 +01:00
|
2023-12-25 18:51:35 +01:00
a(target="_blank" href="https://github.com/SthephanShinkufag") SthephanShi
| , which is a fork of
2023-12-26 04:42:04 +01:00
|
2023-12-25 21:56:34 +01:00
a(target="_blank" href="https://entropedia.co.uk/generative_music") 8-bit Generative Composer
2023-12-26 04:42:04 +01:00
|
2023-12-25 18:51:35 +01:00
| by
2023-12-26 04:42:04 +01:00
|
2023-12-25 18:51:35 +01:00
a(target="_blank" href="https://github.com/paulhayes") Paul Hayes
| .
details(open)
summary
h1 Library
#library
// TODO: generate these automatically with templates, and create template for individual songs
details
summary
2023-12-25 21:56:34 +01:00
h2 Classic — C compatible code
2023-12-25 18:51:35 +01:00
#library-classic
details
summary
2023-12-25 21:56:34 +01:00
h2 Compact JS — compact JavaScript code
2023-12-25 18:51:35 +01:00
#library-js-code
details
summary
2023-12-25 21:56:34 +01:00
h2 Big JS — big JavaScript code
2023-12-25 18:51:35 +01:00
#library-js-bigcode
details
summary
2023-12-25 21:56:34 +01:00
h2 Floatbeat — high quality output from -1.0 to 1.0
2023-12-25 18:51:35 +01:00
#library-floatbeat
details
summary
2023-12-25 21:56:34 +01:00
h2 Funcbeat — statement based
2023-12-25 18:51:35 +01:00
#library-funcbeat
details
summary
2023-12-25 21:56:34 +01:00
h2 SthephanShi — code SthephanShi created
2023-12-25 18:51:35 +01:00
#library-sthephanshi
details
summary
2023-12-25 21:56:34 +01:00
h2 SArpnt — code SArpnt created
2023-12-25 18:51:35 +01:00
#library-sarpnt
footer
2024-03-12 19:50:03 +01:00
a.link(target="_blank" href="https://dollchan.net/btb") Dollchan Discussion board
2023-12-25 18:51:35 +01:00
br
a.link(target="_blank" href="https://git.disroot.org/SArpnt/bytebeat-composer") Source code
2023-12-25 18:51:35 +01:00
// TODO: create svgs for all controls
svg(style="display:none" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg")
symbol#symbol-play(viewBox="0 0 32 32")
path(
d="m23 14.3-9-5.2c-1.3-.8-3 .2-3 1.7v10.4c0 1.5 1.7 2.5 3 1.7l9-5.2c1.3-.7 1.3-2.7 0-3.4z"
)
symbol#symbol-pause(viewBox="0 0 32 32")
path(
d="M12.5 23c-1.1 0-2-.9-2-2V11c0-1.1.9-2 2-2s2 .9 2 2v10c0 1.1-.9 2-2 2zm7 0c-1.1 0-2-.9-2-2V11c0-1.1.9-2 2-2s2 .9 2 2v10c0 1.1-.9 2-2 2z"
)