Theramine
theramine built with web audio API oscillator and filter
by Soviut
HTML
<h1>Click to Play Note</h1>
<p>Horizontal position is frequency, vertical is filter.</p>
CSS
html {
font-family: arial, helvetica, san-serif;
transition: background-color 100ms ease-in-out;
}
html:active {
background-color: cornflowerblue;
cursor: move;
}
JavaScript
var context = new AudioContext();
console.log(context);
var amp = context.createGain();
amp.connect(context.destination);
amp.gain.value = 0.5;
var osc;
var maxFreq = 3000;
var minFreq = 100;
var waveforms = ['sine', 'sawtooth', 'square', 'triangle'];
var filter;
var maxFilterFreq = 3000;
var minFilterFreq = 100;
var playing = false;
function updateAudio(e) {
filter.frequency.value = (1 - e.pageY / $(document).height()) * (maxFilterFreq - minFilterFreq);
osc.frequency.value = (e.pageX / $(document).width()) * (maxFreq - minFreq);
//amp.gain.value = 1 - (e.pageY / $(document).height());
}
$doc = $(document);
$doc.on('mousedown touchstart', function(e) {
e.preventDefault();
playing = true;
filter = context.createBiquadFilter();
filter.type = 'lowpass';
filter.connect(amp);
if (osc) {
osc.stop(0);
}
osc = context.createOscillator();
osc.connect(filter);
osc.type = waveforms[Math.floor(Math.random() * waveforms.length)];
osc.start(0);
updateAudio(e);
});
$doc.on('mousemove touchmove', function(e) {
e.preventDefault();
if (playing) {
updateAudio(e);
}
});
$doc.on('mouseup touchend', function(e) {
e.preventDefault();
playing = false;
osc.stop(0);
});