1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/**
* 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) {
if (document.activeElement !== document.body) {
return;
}
// 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);
|