/** * Sampler * @module lib/sampler.js; */ import Tone from "tone"; let root = 440; let output; let ready; let current = ""; let samples = {}; const player_count = 12; export function load(out, readyCallback) { output = out; ready = readyCallback; document.body.addEventListener("dragover", dragOver); document.body.addEventListener("drop", drop); } /** * Drag and drop */ export function dragOver(event) { event.preventDefault(); } export function drop(event) { event.preventDefault(); const files = event.dataTransfer.items ? [...event.dataTransfer.items] .filter((item) => item.kind === "file") .map((item) => item.getAsFile()) : [...event.dataTransfer.files]; const file = files[0]; const reader = new FileReader(); reader.addEventListener( "load", () => loadSampleFromFile(file, reader.result), false, ); if (file) { reader.readAsDataURL(file); } } export function loadSampleFromFile(file, url) { const { name } = file; current = name; const sample = (samples[name] = samples[name] || {}); sample.root = 440; sample.players = []; sample.index = -1; for (let i = 0; i < player_count; i++) { let player = new Tone.Player({ url, retrigger: true, playbackRate: 1, }); player.name = name; player.connect(output); sample.players.push(player); } console.log("+ Sampler:", name, `(${sample.players.length} voices)`); ready(); } /** * Player */ let last = [1, 440]; function stop() { for (const sample of Object.values(samples)) { sample.players.forEach((player) => player.stop()); } } function play(interval, root) { last = [interval, root]; const sample = samples[current]; sample.index = (sample.index + 1) % sample.players.length; const player = sample.players[sample.index]; player.playbackRate = (interval * root) / sample.root; player.start(); } function pause() { // no-op } export default { load, play, pause, stop }; // for help tuning function keydown(e) { // console.log(e.keyCode) if (e.metaKey && last && current) { const sample = samples[current]; const step = e.shiftKey ? (e.ctrlKey ? 0.1 : 1) : 10; switch (e.keyCode) { case 38: // up e.preventDefault(); sample.root -= step; stop(); play(last[0], last[1]); break; case 40: // down e.preventDefault(); sample.root += step; stop(); play(last[0], last[1]); break; } } } window.addEventListener("keydown", keydown, true);