Skip to content

Instantly share code, notes, and snippets.

@miketahani
Last active November 9, 2015 23:54
Show Gist options
  • Save miketahani/bbbbc9c4f4ba5d9cfc53 to your computer and use it in GitHub Desktop.
Save miketahani/bbbbc9c4f4ba5d9cfc53 to your computer and use it in GitHub Desktop.
d3.unconf ticket

hacky web audio api + d3.

instructions

allow mic access, talk at computer.

view here

<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8'>
<style>
body, #map, svg, canvas {
margin: 0;
padding: 0;
}
#stroke-text {
stroke: #1a1a1a;
stroke-width: 0.5;
fill: none;
}
</style>
</head>
<body>
<script src='//d3js.org/d3.v3.min.js' charset='utf-8'></script>
<script>
var w = 900,
h = 650,
halfH = h/2;
var svg = d3.select('body').append('svg')
.attr({width: w, height: h});
var clipPath = svg.append('defs')
.append('clipPath').attr({id: 'text-clip'});
var text = clipPath.append('text')
.attr({
x: w/2,
y: halfH,
// right side of the data is rarely active
// there's cleaner ways to do this but meh
textLength: w * 0.8 + 'px'
})
.style({
'text-anchor': 'middle',
font: '200px sans-serif'
})
.text('d3.unconf');
var g = svg.append('g').style('clip-path', 'url(#text-clip)');
var strokeText = text.node().cloneNode(true);
strokeText.id = 'stroke-text';
svg.node().appendChild(strokeText);
var audioContext = new AudioContext(),
analyser = audioContext.createAnalyser();
analyser.fftSize = 256;
var size = analyser.frequencyBinCount,
barw = w / size,
barw = Math.ceil((w - 2 * barw) / size),
min = 1,
mod = (h-5*min)/2+min,
bottom = halfH + (5*min);
// mod = h - 20;
// overshoot hue on purpose
// var hue = d3.scale.linear().domain([0, 128]).range([140, 0]);
var color = d3.scale.linear()
.domain([0, 255])
.range(['#ffba00', '#007eff'])
.interpolate(d3.interpolateHcl);
var bfBuf = new Uint8Array(size),
tdBuf = new Uint8Array(size);
navigator.webkitGetUserMedia({audio: true}, function (stream) {
var microphone = audioContext.createMediaStreamSource(stream);
microphone.connect(analyser);
go();
}, function (err) { console.log(err); });
function go () {
requestAnimationFrame(go);
render();
}
function render () {
analyser.getByteFrequencyData(bfBuf);
var rect = g.selectAll('rect')
.data(bfBuf);
rect.enter().append('rect')
.attr({
x: function (d, i) {
return i * barw + barw;
},
width: barw
})
.style({'stroke-width': 1});
// inefficient
rect.attr({
height: function (d) {
return d/255 * mod + min;
},
y: function (d) {
return bottom - (d/255 * mod + min);
},
fill: function (d) {
// return 'hsl(' + ~~hue(d) + ', 100%, 70%)';
return color(d);
},
stroke: function (d) {
return color(d);
}
});
rect.exit().remove();
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment