-
Notifications
You must be signed in to change notification settings - Fork 2
/
worker.js
72 lines (56 loc) · 1.98 KB
/
worker.js
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
onmessage = e => {
const data = e.data.data;
const numberOfChannels = e.data.numberOfChannels;
const duration = e.data.duration;
const sampleRate = e.data.sampleRate;
const initialPitch = e.data.initialPitch;
const timeBetweenSteps = e.data.timeBetweenSteps;
const timeUntilFirstChange = e.data.timeUntilFirstChange;
const enableRandomPitchChange = e.data.enableRandomPitchChange;
const minPitch = e.data.minPitch;
const maxPitch = e.data.maxPitch;
const timeMinBetweenChanges = e.data.timeMinBetweenChanges;
const timeMaxBetweenChanges = e.data.timeMaxBetweenChanges;
const sinePhaseSpeed = e.data.sinePhaseSpeed;
const sinePitchMagnitude = e.data.sinePitchMagnitude;
let newData = data.map(channelData => {
return new Array(channelData.length);
})
let basePitch = initialPitch;
let currentPitch = basePitch;
let timeNextStep = timeBetweenSteps;
let timeNextChange = timeUntilFirstChange;
let newSample = 0;
let time = 0;
while (time < duration) {
const newTime = newSample / sampleRate;
if (enableRandomPitchChange) {
if (newTime >= timeNextChange) {
basePitch = randomRange(minPitch, maxPitch);
timeNextChange += randomRange(timeMinBetweenChanges, timeMaxBetweenChanges);
}
}
if (newTime >= timeNextStep) {
currentPitch = basePitch + Math.sin(newTime * sinePhaseSpeed) * sinePitchMagnitude;
timeNextStep += timeBetweenSteps;
}
const sample = time * sampleRate;
const sampleLeft = Math.floor(sample);
const sampleRight = sampleLeft + 1;
const remainder = sample % 1;
for (let i = 0; i < numberOfChannels; ++i) {
newData[i][newSample] = ((1-remainder) * data[i][sampleLeft]) + ((remainder) * (data[i][sampleRight] ?? 0));
}
newSample++;
time += (1 / sampleRate) * currentPitch;
}
newData = newData.map(newChannelData => {
newChannelData.length = newSample;
return Float32Array.from(newChannelData);
})
postMessage({
data: newData,
length: newSample,
});
}
const randomRange = (min, max) => Math.random() * (max - min) + min;