Web MIDI APIのライブラリWebMidi.jsを使ってみました。指を離したときに音が急に切れるのでプツプツという音がしますが許してください。ブラウザではMIDIキーボードも使えるのかと感動しました。
index.html
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/webmidi"></script>
</head>
<body>
<script>
const audioCtx = new AudioContext();
const A4_FREQ = 440;
const A4_NUMBER = 69;
function note2Freq(note){
const { number } = note;
const dif = number - A4_NUMBER;
const freq = Math.pow(2, dif / 12) * A4_FREQ;
return freq;
}
WebMidi.enable(err=>{
if(err){
alert("Web MIDI APIは使えません。");
return;
}
const sourceNodeBuffer = [];
WebMidi.inputs[0].addListener('noteon', "all", e=>{
const sourceNode = audioCtx.createOscillator();
sourceNode.connect(audioCtx.destination);
sourceNode.note = e.note;
sourceNode.frequency.value = note2Freq(e.note);
sourceNode.start();
sourceNodeBuffer.push(sourceNode);
});
WebMidi.inputs[0].addListener('noteoff', "all", e=>{
const sourceNode = sourceNodeBuffer.find(
node => (
node.note.number === e.note.number &&
node.note.name === e.note.name &&
node.note.octave === e.note.octave
)
);
sourceNode.stop();
sourceNode.disconnect();
const index = sourceNodeBuffer.indexOf(sourceNode);
sourceNodeBuffer.splice(index, 1);
});
});
</script>
</body>