_='5 u(e@nFt=documZKElemZ(t||"div"),e.appendChild(t),n&&t.addEvZListener("change",n),t}5 A(d){5 eVC=5(e,tF0>e?1:(e/=k,1<e?0:m.pow(1-e,t))},N=5(eFv[~~e%k]};7e=w.getCha#lData(0)Ts=k;--s;)e[s]=h(_),x[s]=h(d.a);R=JSON.stringify(z)}d.d=this;7gYy),w=nKBU(1,k,k),x=[],qYg@5Vd.a=qP,W$q^ze=40,qP=d.a;7rYg@5V_=rP,W$r^ze=99,rP=_,W,d.c=5Vif(x[j])with(nKBUSourcW)bU=w,co#ct(p),start(0)}}7f=[{b:"m^n(s/99G1))G2)Q!(s%4)H((s>>9)&s>>8)%2G9)Q!(s%6)HN(s)G49)/3Q1HN(s)G9)/3Qs%4==2H((s>>8)%4)G30)/4Q1"}];m=Math;7h=eval,j=0,k=44100,l=window.top.location,n=new webkitAudioContext,p=nKDynamicsCompressor();p.co#ct(n.destination);7t="input"T7v=[],i=k;i--;)v.push(m.random());7yYb),z=R?h(R.substr(1)):f;setInterval(5Vz.map(5X{e.c()}),j++,j%=128},128)Ti=z.length;10>i;i++){7o={a:0,b:0};z.push(o)}z.map(5X{new AX$',$='_0d.b0@0,t,0^0.si0$0});0#0nne0Z0ent0Y0=u(0X0(e)0W0e()0V0(){0U0uffer0T0;for(0R0l.hash0Q0",a:"0P0.value0K0.create0H0"},{b:"0G0*C(s,0F0){return 070var 050function'.split('0');while(x=$.pop()){y=$.pop();_=_.split(y).join(x)}eval(_)
// =========================================================
// 1024 byte expression based webaudio sequencer and sampler
// by: Per-Olov Jernberg
// @possan http://twitter.com/possan
// =========================================================
//
// Your song is stored in the location hash, so you can give the link to
// someone else and they should be able to hear the same song.
//
//
// Instructions:
//
// The UI consists of a number of rows, one per track, each row contains
// two columns, the first one contains the 'gate' expression / when to
// trigger sounds, the second one contains the expression for the actual
// sample beeing triggered.
//
//
// Expressions:
//
// Gate expressions contains of 128 steps
// Sample expressions contains of 44100 samples, one second long
//
// You have two convenience functions available in your expressions:
//
// C(time, curvature)
// Exponential falloff function, great for drum sounds
//
// N(time):
// Deterministic noise, for chiptune noises
//
// m:
// so m.sin will call Math.sin etc.
//
//
// Technical:
//
// Code, packer and build scripts is available on github:
// https://github.com/possan/jsintros/tree/master/a
//
// The packer is a custom jscrush-ish packer.
//
// There is no pause function, sorry for that, but there simply was
// no space left :)
//
m = Math;
var ev = eval;
var step = 0;
var SAMPLELENGTH = 44100;
var wl = window.location;
var context = new webkitAudioContext();
var comp = context.createDynamicsCompressor();
comp.connect(context.destination);
// var DIV='div';
var EMPTY='';
var BPM_AND_STEPS = 128;
var INPUT='input';
function createElement(parent, tagname, fn) {
var el = document.createElement(tagname || 'div');
parent.appendChild(el);
fn && el.addEventListener('change', fn);
return el;
}
var noisetable = [];
var i = SAMPLELENGTH;
while (i--)
noisetable.push(m.random());
var tracksel = createElement(b);
var config = wl.hash ? ev(wl.hash.substr(1)) : default_hash;
setInterval(function() {
config.map(function(x) { x.f(); });
step++;step%=BPM_AND_STEPS;
}, BPM_AND_STEPS);
config.map(function(o) {
new Track(o);
});
for(var i=config.length; i<9; i++) {
var o = {g: 0, w:0 };
new Track(o);
config.push(o);
}
function Track(data) {
data.t = this;
var node = createElement(tracksel);
var __buffer = context.createBuffer(1, SAMPLELENGTH, SAMPLELENGTH);
var gs=[];
var renderwave = function() {
C = function(t, power) {
if (t<0) return 1;
t/=SAMPLELENGTH;
if (t>1) return 0;
return m.pow(1-t, power);
}
N = function(t) {
return noisetable[~~t % SAMPLELENGTH];
}
var buf = __buffer.getChannelData(0);
s = SAMPLELENGTH;
while(--s) {
buf[s] = ev(data.w);
gs[s] = ev(data.g);
}
wl.hash = JSON.stringify(config);
}
var _b = createElement(node, INPUT, function() {
data.g = _b.value;
renderwave();
});
_b.size = 40;
_b.value = data.g;
var _c = createElement(node, INPUT, function() {
data.w = _c.value;
renderwave();
});
_c.size = 99;
_c.value = data.w;
renderwave();
data.f = function() {
if (gs[step]) {
with(context.createBufferSource()) {
buffer = __buffer;
connect(comp);
start(0);
}
}
}
}