Clickable Piano Example
This example creates a simple piano to be played with the mouse. It also allows uploading a sound bank instead of using a built-in one.
We need to add an input for uploading the sound bank and the table for our piano.
piano.html
<label for="sound_bank_input">Upload the sound bank.</label>
<input accept=".sf2, .sf3, .dls" id="sound_bank_input" type="file" />
<table>
<tr id="piano"></tr>
</table>
<!-- note the type="module" -->
<script src="piano.js" type="module"></script>
We create a 36-key keyboard and add pointer events to it which control the note-on and note-off messages.
piano.js
// Import the modules
import { WorkletSynthesizer } from "../../src/index.js";
import { EXAMPLE_WORKLET_PATH } from "../examples_common.js";
document
.querySelector("#sound_bank_input")
.addEventListener("change", async (event) => {
// Check if there's a file uploaded
if (!event.target.files[0]) {
return;
}
const file = event.target.files[0];
const sfFile = await file.arrayBuffer(); // Convert to array buffer
// Create the context and add audio worklet
const context = new AudioContext();
await context.audioWorklet.addModule(EXAMPLE_WORKLET_PATH);
// Create the synthesizer
const synth = new WorkletSynthesizer(context);
synth.connect(context.destination);
await synth.isReady;
await synth.soundBankManager.addSoundBank(sfFile, "main");
// Create a 36-key piano
const piano = document.querySelector("#piano");
for (let index = 0; index < 36; index++) {
/**
* @type {HTMLElement}
*/
const key = document.createElement("td");
key.style.background = "white";
key.style.height = "10em";
key.style.width = "2em";
key.style.margin = "0.2em";
piano.append(key);
// Add mouse events
key.addEventListener("pointerdown", () => {
// Key press: play a note
synth.noteOn(0, 46 + index, 127);
key.style.background = "red";
});
key.addEventListener("pointerup", () => {
// Key release: stop a note
synth.noteOff(0, 46 + index);
key.style.background = "white";
});
key.addEventListener("pointerleave", key.onpointerup);
}
});