-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
90 lines (74 loc) · 1.71 KB
/
index.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/**
* @module sampler
* @author stagas
* @desc sampler
* @license mit
*/
export default Sampler;
export function Sampler(n){
if (!(this instanceof Sampler)) return new Sampler(n);
this.voices = Array(n || 4);
this.voice = 0;
this.coeff = 0;
this.bank = {};
}
Sampler.prototype.add = function(key, sample){
this.bank[key] = Sample(sample);
return this;
};
Sampler.prototype.tune = function(n){
this.coeff = n;
return this;
};
Sampler.prototype.play = function(key, vol, speed){
this.voices[this.voice++] = {
sample: Sample(this.bank[key]),
vol: vol || 1,
speed: (speed || 1) * this.coeff
};
if (this.voice === this.voices.length) this.voice = 0;
return this;
};
Sampler.prototype.mix = function(){
return this.voices.reduce(sum, 0);
};
export function Sample(buffer){
var header, floats;
if (buffer.floats) {
floats = buffer.floats;
} else {
floats = wavToFloat32Array(buffer);
header = new DataView(buffer, 0, 44);
floats.sampleRate = header.getUint32(24, true);
}
var len = floats.length;
var i = 0;
var s = 0;
play.play = play;
play.floats = floats;
var coeff = floats.sampleRate / sampleRate;
return play;
function play(speed){
if (i > len) return 0;
s = floats[i|0];
i += (speed || 1) * coeff;
return isNaN(s) ? 0 : s;
}
}
export function wavToFloat32Array(buffer){
var view = new DataView(buffer, 44);
var len = view.byteLength / 2;
var floats = new Float32Array(len);
for (var i = 0; i < view.byteLength; i += 2) {
var s = view.getUint16(i, true);
if (s > 32767) {
s -= 65536;
}
s /= 32768;
floats[i/2] = s;
}
return floats;
}
function sum(p, n){
return p + n.sample(n.speed) * n.vol;
}