web audio api, random tuned pitches
body {
background: black;
color: #ddd;
font-size: 1.2rem;
letter-spacing: 1px;
line-height: 0.5rem;
text-align: center;
font-family: arial;
padding: 1rem;
display: flex;
flex-direction: column;
height: 100vh;
justify-content: center;
}
.play {
background: white;
border-radius: 10px;
width: 4rem;
height: 4rem;
flex-shrink: 0;
margin: 1rem auto;
display: flex;
justify-content: center;
align-items: center;
color: black;
cursor: pointer;
}
.stop {
color: red;
padding:1rem;
cursor: pointer;
}
.bpm {
margin: 1rem auto;
max-width: 4rem;
padding: .3rem;
font-size: 1.5rem;
}
// setting bpm
var bpm = 220; // used to calc time in minutes e.g. 6000 / bpm
var oscillatorTypes = ["sine", "square", "sawtooth", "triangle"];
window.addEventListener(
"keydown",
function(event) {
if (event.defaultPrevented) {
return; // Do nothing if the event was already processed
}
switch (event.keyCode) {
case 83:
makeSound(3);
break;
case 65:
makeSound(2);
break;
case 32:
makeSound(1);
break;
case 68:
makeSound(0);
break;
default:
return; // Quit when this doesn't handle the key event.
}
// Cancel the default action to avoid it being handled twice
event.preventDefault();
},
true
);
function makeSound(tone) {
var pitches = [
"21",
"24",
"29",
"32",
"36",
"38",
"43",
"49",
"58",
"65",
"73",
"77",
"87",
"98",
"103",
"116",
"130",
"146",
"155",
"196",
"233",
"293",
"349",
"466"
];
var randPitch = pitches[Math.floor(Math.random() * pitches.length)];
var context = new (window.AudioContext || window.webkitAudioContext)();
var oscillator = context.createOscillator();
oscillator.frequency.value = randPitch;
oscillator.type = tone; // random option, could also pass in as arguement e.g.
// oscillator.type = oscillatorTypes[tone];
var gain = context.createGain();
oscillator.connect(gain);
gain.connect(context.destination);
var now = context.currentTime;
gain.gain.setValueAtTime(0.5, now);
gain.gain.exponentialRampToValueAtTime(0.01, now + 0.5);
oscillator.start(now);
oscillator.stop(now + 0.5);
setTimeout(function() {
context.close();
}, 300);
}
// bpm
var playBtn = document.getElementById("play");
var stopBtn = document.getElementById("stop");
var playing = false;
playBtn.onclick = function() {
if(playing == false){
bmp = parseInt(document.getElementById("bpm").value);
console.log(bmp);
var id = intervalTrigger();
playing = true;
// stop button setup
stopBtn.onclick = function() {
clearInterval(id);
playing = false;
};
}
function intervalTrigger() {
return window.setInterval(function() {
var randOsc =
oscillatorTypes[Math.floor(Math.random() * oscillatorTypes.length)];
makeSound(randOsc);
}, 60000 / bpm);
}
};
// var id = intervalTrigger();
// clearInterval
<h1>Web Audio API</h1>
<h2>Tone generator & BPM</h2>
<input id="bpm" class="bpm" type="number" value="120">
<div class="play" id="play">Play</div>
<div class="stop" id="stop">Stop</div>
<p>Tones generated but also bound to keys:</p>
<p>a</p>
<p>s</p>
<p>d</p>
<p>space</p>