diff options
| author | julian laplace <julescarbon@gmail.com> | 2025-07-05 17:06:59 +0200 |
|---|---|---|
| committer | julian laplace <julescarbon@gmail.com> | 2025-07-05 17:06:59 +0200 |
| commit | 200c1a4f0ebd3188faebaea8e7278fc5105227cf (patch) | |
| tree | 12f61dcd756ba57e0f718b87e4eb0e9c30d90f4d /client/lib/sampler.js | |
| parent | d82f99fd89e23fdb62598b616e39537360a10f74 (diff) | |
laod sample
Diffstat (limited to 'client/lib/sampler.js')
| -rw-r--r-- | client/lib/sampler.js | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/client/lib/sampler.js b/client/lib/sampler.js new file mode 100644 index 0000000..08f253d --- /dev/null +++ b/client/lib/sampler.js @@ -0,0 +1,112 @@ +/** + * Sampler + * @module lib/sampler.js; + */ + +import Tone from "tone"; + +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 = 440; + +function play(freq) { + last = freq; + const sample = samples[current]; + sample.index = (sample.index + 1) % sample.players.length; + const player = sample.players[sample.index]; + player.playbackRate = freq / sample.root; + player.start(); +} + +function pause() { + // no-op +} + +export default { load, play, pause }; + +// 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; + play(last); + break; + case 40: // down + e.preventDefault(); + sample.root += step; + play(last); + break; + } + } +} +window.addEventListener("keydown", keydown, true); |
