• Stars
    star
    369
  • Rank 115,686 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 13 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Bytebeats in HTML5

HTML5 Bytebeat

Bytebeat is the name of type of music made from math.

You provide a function who's only input is time t and from that write some code to generate a sound.

In this particular case t is an 8000hz timer that counts up. For example

sin(t) * 127 + 127

You can choose traditional bytebeat where the output of your function is expected to be 0 to 255 or you can choose floatbeat where the output is expected to be -1 to +1.

Functions are just plain JavaScript though sin, cos, tan, floor, ceil and int will automatically be converted to Math.sin, Math.cos, Math.tan, Math.floor, Math.ceil, and Math.floor respectively.

Click here to try your hand at Bytebeat.

Instructions

Modes

There 2 modes

  • bytebeat: Your expression is expected to generate byte values from 0 to 255
  • floatbeat: Your expression is expected to generate float values from -1.0 to 1.0

Expression Types

  • Infix: Standard expressions eg. "(t * 2) / 4"
  • Postfix(rpn): Reverse Polish Notation eg "t 2 * 4 /"
  • glitch: glitch format or glitch urls.
  • function: Return a function. eg. "return t => (t * 2) / 4"

Infix is standard JavaScript so all Math functions are available. Most math functions you can drop the "Math." part. In other words

sin(t)

is the same as

Math.sin(t)

Postfix requires that each element have at least one space between it.

t2*    // BAD!
t 2 *  // Good!

If you're unfamiliar with postfix see below

Glitch is a format used by glitch machine for sharing. Examples

These can be prefixed with "glitch://". For example

There's a bunch more here. I have a feeling there's a bug or 2 left for full glitch support

Function

Expects a function body vs infix which expects an expression

infix: sin(t)

function: return t => sin(t)

Note thought that "function" receives t in seconds, not samples.

See below

Postfix

Postfix in this case I guess can be described as forth like. It works with a stack. Each command either adds things to the stack or uses what's on the stack to do something. For example

123       // pushes 123 on the stack               stack = 123
456       // pushes 456 on the stack               stack = 123, 456
+         // pop the stop 2 things on the stack
          // adds them, puts the result on the
          // stack                                 stack = 569

Note the stack is only 256 elements deep. If you push 257 elements it wraps around. Similarly if you use pick with a large value your pick will wrap around. The stack is neither cleared nor reset on each iteration of your function. Some postfix based bytebeat songs take advantage of this where each iteration leaves things on the stack for the next iteration.

operators

The postfix operators are

>, < ,=

These take the top two things from the stack, do the comparision, then push 0xFFFFFFFF if the result is true or 0x0 if the result is false. Think of it has follows: If the TOP thing on the stack is >, <, or = to the next thing on the stack then 0xFFFFFFFF else 0x0

drop

removes the top thing from the stack

dup

duplicates the top thing on the stack.

swap

swaps the top 2 things on the stack

pick

pops the top thing from the stack and duplicates one item that many items back. In other words if the stack is 1,2,3,4,5,6,7,3 then pick pops the top thing 3 and duplicates the 3rd thing back counting from 0, which is no 4. The stack is then 1,2,3,4,5,6,7,4.

Another way to look at it is dup is the same as 0 pick.

put

sets the n'th element from the top of the stack to the current top. In other words if the stack is 1,2,3,4,5,6,7,3,100 then put will pull the top 100 and then set the 3 element back. The stack will then be 1,2,3,4,100,6,7,3.

abs, sqrt, round, tan, log, exp, sin, cos, tan, floor, ceil, int min, max, pow

These operators all pop the top value from the stack, apply the operator, then push the result on the stack

/, +, -, *, %, >>, <<, |, &, ^, &&, ||:

These operators pop the top 2 values from the stack, apply the operator, then push the result. The order is as follows

b = pop
a = pop
push(a op b)

In other words 4 2 / is 4 divided by 2.

~

Pops the top of the stack, applies the binary negate to it, pushes the result.

Function

See Rant.

"function" means you could write code that returns a function. The simplest example might be

return function(t) {
  sin(t);
}

or shorter

return t => sin(t);

The point being you can write more generic JavaScript. For example

const notes = [261.62, 329.628, 391.995, 523.25, 391.995, 329.628, 261.62, 261.62, 1, 1];

function getNote(t) {
  const ndx = (t * 4 | 0) % notes.length;
  return note = notes[ndx];
}

return function(t) {
  const note = getNote(t);
  return sin(t * 10 * note);
}

Example

But see Rant why this is seems kind of missing the point.

Stereo

You can emit an array with 2 values for left and right channels. Eg.

[sin(t), sin(t / 2)]

Extra

Comments can be both // or /* */ style and I'd personally suggest you use comments for your name, the song's name, etc...

There are several extra inputs available:

The mouse position is available as mouseX and mouseY

sin(t * mouseX * 0.001) + cos(t * mouseY * 0.003)

The size of the window is available width and height

Also note, using the comma operator you can write fairly arbitrary code. See this example.

Putting a comment in form of

// vsa: <url>

Will apply a vertexshaderart piece. Example

Rant

The original bytebeat, or at least the one I saw, was fairly simple. 8bits, stack based, few options. When I built a live JavaScript version I just thought "you get an expression that takes time and returns a value". The end.

A few obvious additions, at least to me, were floatbeat, because the Web Audio API itself takes floats and IIRC some original C based thing that took a function expected floats. In fact I wrote that first. I just fed an expression that returns floats into the Web Audio API. I then manually converted a few beatbyte expressions by just putting (original-bytebeat-expression) / 127 - 1.

The reason I didn't just stick with floatbeat is bytebeat expressions already existed and wanted people to be able to use them without having to understand how to convert, even though it's trivial.

But now I see people have added signed bytebeat. What is the point? Any signed bytebeat can be turned in to regular bytebeat by just putting + 0x80 at the end of your expression. The entire point of bytebeat is to be self sufficient, to put what you need in the expression itself.

I then found a funcbeat in which instead of an expression you pass it a function body. AFAICT the advantage is you can write code and declare other functions and data vs having to squeeze everything into an expression with commas. For example:

const notes = [261.62, 329.628, 391.995, 523.25, 391.995, 329.628, 261.62, 261.62, 1, 1];

function getNote(t) {
  const ndx = (t * 4 | 0) % notes.length;
  return note = notes[ndx];
}

return function(t) {
  const note = getNote(t);
  return sin(t * 10 * note);
}

But again, What is the point? If you're going to write real code with no limits then why do it this way all? Just write code, no need to try to cram it into a bytebeat player?

Then I found that some people had added a time divisor. For example, instead of t counting in samples it can count in seconds (fractional values). But again, what is the point? Why does this option need to exist when you can just divide t by the sample rate in the expression itself?

It'd be like if someone added various options for time. t = sample, t = sample / sampleRate, t = sin(sammple), t = sin(sample / sampleRate), etc... The whole point is to PUT THE MATH IN YOUR EXPRESSION!!!. There is no need to add these options ๐Ÿ˜ค

</rant> ๐Ÿ˜›

For more info

Check out http://canonical.org/~kragen/bytebeat/ and be sure follow the many links.

Special thanks to:

Library

You can use this as a library. The library provides a ByteBeatNode which is a WebAudio AudioNode.

Example usage:

import ByteBeatNode from 'https://greggman.github.io/html5byteabeat/dist/1.x/ByteBeat.module.js';

async function start() {
  const context = new AudioContext();
  context.resume();  // needed for safari
  await ByteBeatNode.setup(context);
  byteBeatNode = new ByteBeatNode(context);
  byteBeatNode.setType(ByteBeatNode.Type.byteBeat);
  byteBeatNode.setExpressionType(ByteBeatNode.ExpressionType.infix);
  byteBeatNode.setDesiredSampleRate(8000);
  byteBeatNode.setExpressions(['((t >> 10) & 42) * t']);
  byteBeatNode.connect(context.destination);
}

Live examples:

API

There's just one class ByteBeatNode. You must call the async function ByteBeatNode.setup before using the library.

  • reset()

    re-starts the time to 0

  • isRunning(): bool

    true or false if running. The node is considered running if it's connected.

  • async setExpressions(expressions: string[], resetToZero: bool)

    Pass in array of 1 or 2 expressions. If 2 expressions it is assumed each expression is for a different channel. If a single expression returns an array of 2 values that is also also assumed to be 2 channels. Otherwise, it's 1 channel and will be output to both left and right channels.

    Note: this function is async. You can catch expression errors with try/catch.

  • setDesiredSampleRate(rate: number)

    Sets the sample rate for the expression (eg 8000, 11000, 22050, 44100, 48000)

  • getDesiredSampleRate(): number

    Returns the previously set sample rate

  • setExpressionType(expressionType: number)

    Sets the expression type. Valid expression types

    ByteBeatNode.ExpressionType.infix             // sin(t / 50)
    ByteBeatNode.ExpressionType.postfix           // t 50 / sin
    ByteBeatNode.ExpressionType.glitch            // see docs
    ByteBeatNode.ExpressionType.function          // return function() { sin(t / 50); }
    
  • getExpressionType(): number

    Gets the expression type

  • setType(type: number)

    Sets the output type.

    Valid types

    ByteBeatNode.Type.byteBeat          // 0 <-> 255
    ByteBeatNode.Type.floatBeat         // -1.0 <-> +1.0
    ByteBeatNode.Type.signedByteBeat    // -128 <-> 127
    
  • getType(): number

    Gets the type

  • getNumChannels(): number

    Returns the number of channels output by the current expression.

  • getSampleForTime(time: number, context, stack, channel: number)

    Gets a -1 to +1 from the current expression for the given time (time is the t value in your expression)

    This function is useful for visualizers.

    To make a stack call ByteBeatNode.createStack(). To create a context call ByteBeatNode.createContext. A stack is used for postfix expressions. See docs on postfix. The context is used for keeping expressions state for expressions that try hacks to keep state around like if they build a large note table and assign it to window. It won't actually be assigned to window, it will be assigned to the context (in theory)

Development / running locally

git clone https://github.com/greggman/html5bytebeat.git
cd html5bytebeat
npm i
npm start

The instructions above assume you have node.js installed. If not, if you're on windows use nvm-windows, or if you're on mac/linux use nvm.

Or you can just use the installers at nodejs.org though I'd recommend nvm and nvm-windows personally as once you get into node dev you'll likely need different versions for different projects.

License

MIT

More Repositories

1

twgl.js

A Tiny WebGL helper Library
JavaScript
2,451
star
2

better-unity-webgl-template

A better default template for Unity WebGL
HTML
630
star
3

HappyFunTimes

A System for creating 10-100+ player local games
JavaScript
371
star
4

webgl-memory

A library to track webgl-memory
JavaScript
306
star
5

tdl

A low-level WebGL library
JavaScript
280
star
6

ffmpegserver.js

Receives canvas frames from browser to generate video on the server. Compatible with CCapture.js
JavaScript
267
star
7

servez

A simple web server for local web development.
JavaScript
258
star
8

hsva-unity

A Hue Saturation Value adjustment shader for Unity. Useful for making lots of character colors.
GLSL
202
star
9

webgl-lint

Checks your WebGL usage for common issues
JavaScript
160
star
10

wgpu-matrix

Fast WebGPU 3d math library
JavaScript
129
star
11

virtual-webgl

Virtualize WebGL Contexts
JavaScript
105
star
12

unzipit

Random access unzip library for JavaScript
JavaScript
100
star
13

unity-webgl-copy-and-paste

Support Copy and Paste in Unity WebGL
C#
90
star
14

doodles

Random JavaScript doodles
JavaScript
58
star
15

getuserimage-unity-webgl

How to ask the user for a photo in Unity-WebGL
C#
55
star
16

webgl-helpers

some tiny webgl scripts that might come in handy
JavaScript
54
star
17

webgpu-memory

Track your WebGPU memory usage
JavaScript
43
star
18

servez-cli

The cli version of servez
JavaScript
38
star
19

ImHUI

Experimental UI
TypeScript
34
star
20

webgl-capture

code to help make a reduced test case for WebGL by capturing the commands and generating a stand alone program
JavaScript
34
star
21

oes-vertex-array-object-polyfill

WebGL OES_vertex_array_object polyfill for GPUs/Drivers/Browsers that don't have it
JavaScript
33
star
22

hft-unity3d

Unity3D Libraries for HappyFunTimes
C#
31
star
23

requestanimationframe-fix.js

Fix for requestAnimationFrame with lots of elements
JavaScript
31
star
24

webgpu-utils

Some helpers for webgpu
JavaScript
30
star
25

youtube_chromecast_speed_hack

A way to play a youtube video on Chromecast with settable speed
HTML
28
star
26

pico-8-post-processing

post process pico-8
JavaScript
28
star
27

hft-tonde-iko

A Multi-Machine Platformer
JavaScript
24
star
28

react-split-it

A React Based Splitter
JavaScript
24
star
29

pixel-perfect.js

Display Image Pixel Perfect
HTML
22
star
30

gradient-editor

A Jquery based gradient editor
JavaScript
20
star
31

jsgist

A code playground that stores data as github gists
JavaScript
16
star
32

interval-timer

A Simple Interval Timer
JavaScript
16
star
33

html5-gamepad-test

HTML
15
star
34

webgpu-avoid-redundant-state-setting

Check for and avoid redundant state setting
JavaScript
15
star
35

webgl-canvas-2d

A minimal implementation of the canvas 2D API through WebGL
JavaScript
14
star
36

rockfall

Rockfall. A game where rocks fall
JavaScript
14
star
37

jsbenchit

A JavaScript benchmark static page website that uses gists to store benchmarks
JavaScript
14
star
38

fanfictionreader

Reads your fanfiction to you.
JavaScript
13
star
39

happyfuntimes.net

The HappyFunTimes.net code
JavaScript
10
star
40

dekapng

Make giant PNG files in the browser
TypeScript
10
star
41

hft-gamepad-api

Emulates the HTML5 Gamepad API using smartphones and HappyFunTimes
JavaScript
10
star
42

hft-boomboom

A happyfuntimes game with splosions
JavaScript
9
star
43

DeJson.NET

A simple serialization library from JSON to C# classes based on MiniJSON good for Unity3D
C#
9
star
44

oculus-anti-spy

Try top stop Facebook from spying on all Oculus Activity
JavaScript
8
star
45

uzip-module

An ES6 module version of UZIP.js
JavaScript
8
star
46

imageutils

A few image utils for in browser JavaScript
JavaScript
7
star
47

hft-unity-gamepad

A Generic HappyFunTimes Gamepad for Unity
JavaScript
7
star
48

MoPho-V

A Community Supported Movie and Photo Viewer
JavaScript
6
star
49

sharks-with-frickin-lasers

JavaScript
6
star
50

hft-clean

The simplest happyfuntimes example, no other scripts
JavaScript
6
star
51

webgpu-helpers

Small scripts useful when debugging or developing webgpu
JavaScript
6
star
52

octopus

JavaScript
5
star
53

audiostreamsource.js

Provides a streamed audio source for WebAudio across browsers
JavaScript
5
star
54

dump-all-the-shaders

A script you can add to dump all your shaders to the console.
JavaScript
4
star
55

epub-viewer

A simple epub viewer. Client side only
HTML
4
star
56

image-grid

A simple image-grid for displaying images um, in a grid in the browser
JavaScript
4
star
57

simple-new-tab-page

A simple new tab page extension
JavaScript
4
star
58

other-window-ipc

IPC between windows in Electron
JavaScript
4
star
59

macos-opengl-experiments

Simple OpenGL stuff on MacOS
Objective-C++
3
star
60

rest-url

Makes REST urls
JavaScript
3
star
61

aws-oauth-helper

An AWS Lambda function to handle the oauth client secret part of oauth
JavaScript
3
star
62

unity-load-mp3-at-runtime

example of loading mp3 at runtime
C#
3
star
63

soundcloud-audio-reactive-example

Soundcloud audio reactive example using new API
JavaScript
3
star
64

hft-unityvideofromunity

An example of sending WebCam video FROM unity to the controller (phones)
C#
3
star
65

muigui

baking
JavaScript
3
star
66

hft-syncthreejs

Shows syncing a three.js example across multiple machines using HappyFunTimes
JavaScript
3
star
67

fixallthetags

SO script to fix tags
JavaScript
3
star
68

hft-local

Run a HappyFunTimes game without HappyFunTimes (no networking .. sometimes good for demos)
JavaScript
3
star
69

screenshot-ftw

screenshot a window across OSes
C++
3
star
70

webgl-benchmarks

WebGL Benchmarks (NOT GPU BENCHMARKS!!!)
JavaScript
3
star
71

opengl-fundamentals

JavaScript
3
star
72

stackoverflow-getallanswers

Get all answers for a particular user (and all the questions for those answers)
Python
3
star
73

hft-unitysimple

The simplest Unity example for HappyFunTimes using C#
C#
3
star
74

jsgistrunner

JavaScript
2
star
75

fisheye-skybox-unity

Make a fisheye skybox shader in unity
ShaderLab
2
star
76

cssparse.net

CSS string to Unity3D Color parser
C#
2
star
77

u2b-ux

better youtube ux
JavaScript
2
star
78

hft-unity-character-select

A HappyFunTimes Unity example showing spawning different prefabs based on player character selection
C#
2
star
79

native-msg-box

Allows you to display a native MessageBox / Dialog from node.js
JavaScript
2
star
80

hft-simple

A simple example for HappyFunTimes
JavaScript
2
star
81

hft-jumpjump

The HappyFunTimes JumpJump Example Platformer
JavaScript
2
star
82

servez-lib

The server part of servez
JavaScript
2
star
83

check-all-the-errors

load all your pages, check for javascript errors
JavaScript
2
star
84

hft-unity-2-button-gamejam

A Unity HappyFunTimes Template for the Pico Pico Cafe 2 Button Gamejam
C#
2
star
85

hft-simple-no-electron

an example of using happyfuntimes without electron
JavaScript
2
star
86

eslint-plugin-one-variable-per-var

Enforce one variable declaration per var statement
JavaScript
2
star
87

ldcp

low dependencies cp for node
JavaScript
2
star
88

LUT-to-PNG

Convert a LUT or CUBE file to a PNG (for Unreal / Unity)
JavaScript
2
star
89

hft-powpow

A simple space shooter game for HappyFunTimes
JavaScript
1
star
90

hft-utils

Various JavaScript files shared among HappyFunTimes example games
JavaScript
1
star
91

vertexshaderart.org

vertexshaderart.org
1
star
92

hft-sync2d

Example showing syncing canvas 2d across machines using HappyFunTimes
JavaScript
1
star
93

dns-server

Automatically exported from code.google.com/p/dns-server
C++
1
star
94

bloom

look at the source
JavaScript
1
star
95

hft-unity-cardboard

Example of using HappyFunTimes with Unity and Google Cardbard
C#
1
star
96

webgpu-dev-extension

Explorational WebGPU Dev Extension
JavaScript
1
star
97

font-utils

Some font utils I wrote to generate fonts for gamemaker
C
1
star
98

jsbenchit-comments

just a point to host jsbenchit comments on another domain for security
HTML
1
star
99

hft-c

HappyFunTimes support for C / C++ based games
C++
1
star
100

hft-exe

HappyFunTimes executable creator
C
1
star