Skip to content

Instantly share code, notes, and snippets.

@cheery
Created October 5, 2014 17:17
Show Gist options
  • Save cheery/2c20a79773a6205f796a to your computer and use it in GitHub Desktop.
Save cheery/2c20a79773a6205f796a to your computer and use it in GitHub Desktop.
Improved beatbox for potasmic
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