Skip to content

Instantly share code, notes, and snippets.

@p01
Last active November 26, 2015 22:48
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save p01/f86cb505f6b4acf467ab to your computer and use it in GitHub Desktop.
Save p01/f86cb505f6b4acf467ab to your computer and use it in GitHub Desktop.
Live coding at Creative Coding Singapore
<style>
#b {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(circle, #000, #123);
}
</style><audio id="a"></audio><canvas id="b"></canvas><script>
c= b.getContext('2d');
str='';
notesFreq = [155,195,261,155,233,155,195,207,195,207,195,207,195,207,195,261,155,233,155,233,261,155,233,155,233,155,233,261,155,195,261,195,207,195,261,155,233,155,233,155,195,207,233,155,233,155,195,207,195,207,233,261,155,233,261,233,261,155,195,207,195,207,195,207,195,261,233,155,195,207,233,261,233,155,233,261,155,195,207,195,261,155,233,261,155,233,261,195,261,233,261,155,233,155,195,207,233,261,233,155,195,261,233,155,195,261,195,261,155,233,261,195,207,233,261,195,207,195,261,233,155,195,261,155,195,207,195,261];
notesIndex = 0;
for(t=0;t<60;) {
frac = (t&4 ? t*4 : t/2)%1;
notesIndex += frac == 0;
sample = Math.sin(notesFreq[notesIndex%notesFreq.length]*t *Math.PI*2) * (1-frac) * 16;
frac = t*2%1;
sample += (Math.random()-.5) * Math.max(0,1-frac*frac*frac*4) * 3;
str+=String.fromCharCode(127+ sample);
t += 1/16384;
}
a.src = 'data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAA'
+ 'EAAAABA' // 16khz
+ 'AAABAAgAZGF0YQAAAAAA' + btoa(str);
a.play();
MAX = 2560;
ps = [];
for(i=0;i<MAX;i++) {
ps.push({
x:(Math.random()*256-128)*3,
y:(Math.random()*256-128)*3,
z:(Math.random()*256-128)*3,
i:i,
u: i / 48 % 1,
v: i / 48 / 48
})
}
function render() {
requestAnimationFrame(render);
// clear and set viewport
H = b.height = 512;
W = b.width = 0| H * innerWidth/innerHeight;
time = a.currentTime;
c.translate(W/2,H/2);
c.rotate( (time*2&13)/32 );
c.fillStyle = '#fff';
c.fillText([W,H,time],16,16);
for(i=0;i<MAX;i++) {
p = ps[i];
p.col = '#eee'
if(p.v < 1) {
pangle = p.u*Math.PI*2;
// Sync on the hihat
frac = time*2%1;
sample = Math.max(0,1-frac*frac*frac*4);
d = 96 + 32 * sample * Math.cos(time*3+p.v*Math.PI*2*2) * Math.cos(time*2+pangle*3);
p.y = (p.v*256-128)*2.5;
p.x = d*Math.cos(pangle);
p.z = d*Math.sin(pangle);
l = Math.sin(time*2+pangle*3);
baseLight = 127+64*l|0
p.col =
'rgb('+[
baseLight+64*Math.cos(pangle)|0,
baseLight+64*Math.cos(pangle+2)|0,
baseLight+64*Math.cos(pangle+4)|0
]+')'
}
p.rx = Math.cos(time) * p.x - Math.sin(time) * p.z;
p.rz = Math.sin(time) * p.x + Math.cos(time) * p.z;
p.ry = p.y;
p.p = (p.rz+192) / 256;
p.sx = p.p * p.rx;
p.sy = p.p * p.ry;
}
ps.sort((a,b) => a.p-b.p);
ps.forEach(p => {
s = p.p*14;
c.fillStyle = p.col;
c.fillRect(p.sx,p.sy,s,s)
})
}
render();
</script>
@p01
Copy link
Author

p01 commented Nov 24, 2015

In the 2nd revision the amplitude of bumps in U & V is synchronized with the hihats in the "music".
It's nothing really but it illustrate better what I said during the introduction talk about using ONE formula to drive the Visuals & Audio.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment