Created
October 5, 2014 17:17
-
-
Save cheery/2c20a79773a6205f796a to your computer and use it in GitHub Desktop.
Improved beatbox for potasmic
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var bpm = 140; | |
var tuning = 440; | |
var transpose = 12; | |
// constants | |
var tau = 2 * Math.PI; | |
// adjust tuning to bpm | |
tuning *= 120 / bpm; | |
var rhythm = [ | |
[kicks, "x.......x......."], | |
[snares, "....x.x...x.x..."], | |
[hats, "xxx.x.x.x..x..x..x..x...x.....x."], | |
[bleep, "1.2.5...........................1.2.1..........................."] | |
]; | |
function kicks(t, b) { | |
return clip(env2(1/2, 8*sin(33, t), -0.1, 15, b), 0.4); | |
} | |
function snares(t, b) { | |
return clip(env2(1/8, 4*sin(33, t), 42, 15, b), 0.2); | |
} | |
function hats(t, b) { | |
return clip(env2(1/16, tri(441098 * Noise(), b), 120, 20, b), 0.1); | |
} | |
function bleep(t, b, k) { | |
return Math.sin(tau*t*440*k) * Math.exp(-b*20); | |
} | |
var beat = new BeatBox(rhythm, 1/16); | |
function dsp(t) { | |
var b; | |
b = t * bpm / 120; | |
return beat.run(t, b) * 0.5; | |
} | |
function BeatBox(patterns, div) { | |
this.div = div; | |
this.blocks = []; | |
var k = patterns.length; | |
for (var j = 0; j < k; j++) | |
{ | |
var pattern = patterns[j][1]; | |
var seq = []; | |
var l = pattern.length; | |
for (var i = 0; i < l; i++) | |
{ | |
var code = pattern[i]; | |
var val = null; | |
if (code==='x') val = 1; | |
if (/[0-9]/.test(code)) val = parseInt(code); | |
seq.push(val); | |
} | |
this.blocks.push({seq:seq, start:0, rst:0, fn:patterns[j][0]}); | |
} | |
} | |
BeatBox.prototype.run = function(t, b) { | |
var sum = 0; | |
var measure = this.div; | |
var k = this.blocks.length; | |
for (var j = 0; j < k; j++) { | |
var block = this.blocks[j]; | |
var idx = Math.floor(b / measure / 2 | 0); | |
var sig = sequence(measure, block.seq, b); | |
if(block.rst != idx && sig !== null) block.start = t; | |
block.rst = idx; | |
var start = t - block.start; | |
sum += block.fn(t, start, sig); | |
} | |
return sum; | |
}; | |
function sequence(measure, seq, t){ | |
return seq[(t / measure / 2 | 0) % seq.length]; | |
} | |
function env2(measure, x, y, z, t){ | |
if(t > measure) return 0; | |
return env(measure, x, y, z, t); | |
} | |
function env(measure, x, y, z, t){ | |
var ts = t / 2 % measure; | |
return Math.sin(x * (Math.exp(-ts * y))) * Math.exp(-ts * z); | |
} | |
function clip(x,max) { | |
return Math.min(max, Math.max(x, -max)); | |
} | |
function sin(x, t){ | |
return Math.sin(tau * t * x); | |
} | |
function saw(x, t){ | |
return 1-2 * (t % (1/x)) * x; | |
} | |
function tri(x, t) { | |
return Math.abs(1 - (2 * t * x) % 2) * 2 - 1; | |
} | |
function Noise() { | |
return Math.random() * 2 - 1; | |
} | |
function sqr(x, t) { | |
return sin(x, t) > 0 ? 1 : -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment