@plotdb/sfx 0.0.0-stage → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/LICENSE +21 -0
- package/README.md +175 -2
- package/index.js +2677 -0
- package/index.min.js +1 -0
- package/package.json +1 -6
package/index.js
ADDED
|
@@ -0,0 +1,2677 @@
|
|
|
1
|
+
(function(){
|
|
2
|
+
(function(){
|
|
3
|
+
var SR, S, ctx, bus, isBuffer, peaks, voice, mediaVoice, stopVoice, currentMusic, stopTimeline, startTimeline, hook, NOTES, rng, make, coef, biquad, biquadTv, noise, env, pan, synth, place, partial, fadeOut, wander, glideOsc, COMB, ALLPASS, reverb, glide, grain, pick, bubble, SURFACE, pink, formantVoice, mix, ease, bar, CHORDS, string, metal, ring, gauss, KIT, VEL, wrap, k;
|
|
4
|
+
if (typeof window !== 'undefined' && window.sfx) {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
SR = 48000;
|
|
8
|
+
S = {
|
|
9
|
+
buffers: {},
|
|
10
|
+
urls: {},
|
|
11
|
+
items: [],
|
|
12
|
+
voices: [],
|
|
13
|
+
errors: [],
|
|
14
|
+
external: false,
|
|
15
|
+
playing: false,
|
|
16
|
+
rate: 1
|
|
17
|
+
};
|
|
18
|
+
ctx = null;
|
|
19
|
+
S.ctx = function(){
|
|
20
|
+
var AC, i$, ref$, len$, b;
|
|
21
|
+
if (ctx) {
|
|
22
|
+
return ctx;
|
|
23
|
+
}
|
|
24
|
+
AC = window.AudioContext || window.webkitAudioContext;
|
|
25
|
+
ctx = new AC();
|
|
26
|
+
S.master = ctx.createGain();
|
|
27
|
+
S.master.connect(ctx.destination);
|
|
28
|
+
S.buses = {};
|
|
29
|
+
for (i$ = 0, len$ = (ref$ = ['music', 'sfx', 'voice']).length; i$ < len$; ++i$) {
|
|
30
|
+
b = ref$[i$];
|
|
31
|
+
S.buses[b] = ctx.createGain();
|
|
32
|
+
S.buses[b].connect(S.master);
|
|
33
|
+
}
|
|
34
|
+
return ctx;
|
|
35
|
+
};
|
|
36
|
+
bus = function(name){
|
|
37
|
+
S.ctx();
|
|
38
|
+
return S.buses[name] || S.buses.sfx;
|
|
39
|
+
};
|
|
40
|
+
S.resume = function(){
|
|
41
|
+
var c;
|
|
42
|
+
c = S.ctx();
|
|
43
|
+
if (c.state === 'suspended') {
|
|
44
|
+
return c.resume();
|
|
45
|
+
} else {
|
|
46
|
+
return Promise.resolve();
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
S.volume = function(name, v, dur){
|
|
50
|
+
var g, now;
|
|
51
|
+
dur == null && (dur = 0.2);
|
|
52
|
+
S.ctx();
|
|
53
|
+
g = name === 'master'
|
|
54
|
+
? S.master
|
|
55
|
+
: S.buses[name];
|
|
56
|
+
if (!g) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
now = ctx.currentTime;
|
|
60
|
+
g.gain.cancelScheduledValues(now);
|
|
61
|
+
g.gain.setValueAtTime(g.gain.value, now);
|
|
62
|
+
return g.gain.linearRampToValueAtTime(v, now + Math.max(0.01, dur));
|
|
63
|
+
};
|
|
64
|
+
isBuffer = function(v){
|
|
65
|
+
return !!(v && typeof v === 'object' && typeof v.getChannelData === 'function' && v.sampleRate);
|
|
66
|
+
};
|
|
67
|
+
S.pending = 0;
|
|
68
|
+
S.load = function(map){
|
|
69
|
+
map == null && (map = {});
|
|
70
|
+
S.pending += Object.keys(map).length;
|
|
71
|
+
return Promise.all(Object.keys(map).map(function(name){
|
|
72
|
+
var v, p;
|
|
73
|
+
v = map[name];
|
|
74
|
+
p = isBuffer(v)
|
|
75
|
+
? Promise.resolve(v)
|
|
76
|
+
: v && v.then
|
|
77
|
+
? v
|
|
78
|
+
: fetch(v).then(function(r){
|
|
79
|
+
if (!r.ok) {
|
|
80
|
+
throw new Error(v + ": HTTP " + r.status);
|
|
81
|
+
}
|
|
82
|
+
return r.arrayBuffer();
|
|
83
|
+
}).then(function(ab){
|
|
84
|
+
return new Promise(function(res, rej){
|
|
85
|
+
return S.ctx().decodeAudioData(ab, res, rej);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
if (typeof v === 'string') {
|
|
89
|
+
S.urls[name] = v;
|
|
90
|
+
}
|
|
91
|
+
return p.then(function(buf){
|
|
92
|
+
return S.buffers[name] = buf;
|
|
93
|
+
})['catch'](function(e){
|
|
94
|
+
return S.errors.push("load " + name + ": " + (e.message || e));
|
|
95
|
+
})['finally'](function(){
|
|
96
|
+
return S.pending--;
|
|
97
|
+
});
|
|
98
|
+
})).then(function(){
|
|
99
|
+
return S.buffers;
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
peaks = new WeakMap();
|
|
103
|
+
S.peak = function(buf){
|
|
104
|
+
var d, w, env, max, i$, to$, i, s, j$, to1$, j;
|
|
105
|
+
if (peaks.has(buf)) {
|
|
106
|
+
return peaks.get(buf);
|
|
107
|
+
}
|
|
108
|
+
d = buf.getChannelData(0);
|
|
109
|
+
w = Math.max(1, Math.round(buf.sampleRate * 0.003));
|
|
110
|
+
env = new Float32Array(Math.ceil(d.length / w));
|
|
111
|
+
max = 0;
|
|
112
|
+
for (i$ = 0, to$ = env.length; i$ < to$; ++i$) {
|
|
113
|
+
i = i$;
|
|
114
|
+
s = 0;
|
|
115
|
+
for (j$ = i * w, to1$ = Math.min(d.length, (i + 1) * w); j$ < to1$; ++j$) {
|
|
116
|
+
j = j$;
|
|
117
|
+
s += d[j] * d[j];
|
|
118
|
+
}
|
|
119
|
+
env[i] = Math.sqrt(s / w);
|
|
120
|
+
if (env[i] > max) {
|
|
121
|
+
max = env[i];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
i = 0;
|
|
125
|
+
while (i < env.length - 1 && env[i] < max * 0.8) {
|
|
126
|
+
i++;
|
|
127
|
+
}
|
|
128
|
+
while (i < env.length - 1 && env[i + 1] > env[i]) {
|
|
129
|
+
i++;
|
|
130
|
+
}
|
|
131
|
+
peaks.set(buf, i * w / buf.sampleRate);
|
|
132
|
+
return peaks.get(buf);
|
|
133
|
+
};
|
|
134
|
+
voice = function(name, opt){
|
|
135
|
+
var buf, c, src, g, when_, level, offset, end, v;
|
|
136
|
+
opt == null && (opt = {});
|
|
137
|
+
buf = isBuffer(name)
|
|
138
|
+
? name
|
|
139
|
+
: S.buffers[name];
|
|
140
|
+
if (!buf) {
|
|
141
|
+
S.errors.push("unknown sound: " + name);
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
c = S.ctx();
|
|
145
|
+
src = c.createBufferSource();
|
|
146
|
+
src.buffer = buf;
|
|
147
|
+
src.loop = !!opt.loop;
|
|
148
|
+
src.playbackRate.value = opt.rate || 1;
|
|
149
|
+
g = c.createGain();
|
|
150
|
+
src.connect(g);
|
|
151
|
+
g.connect(bus(opt.bus || 'sfx'));
|
|
152
|
+
when_ = opt.when || c.currentTime;
|
|
153
|
+
level = opt.gain != null ? opt.gain : 1;
|
|
154
|
+
if (opt.fadeIn) {
|
|
155
|
+
g.gain.setValueAtTime(0, when_);
|
|
156
|
+
g.gain.linearRampToValueAtTime(level, when_ + opt.fadeIn);
|
|
157
|
+
} else {
|
|
158
|
+
g.gain.setValueAtTime(level, when_);
|
|
159
|
+
}
|
|
160
|
+
offset = opt.offset || 0;
|
|
161
|
+
if (opt.duration != null) {
|
|
162
|
+
end = when_ + opt.duration;
|
|
163
|
+
if (opt.fadeOut) {
|
|
164
|
+
g.gain.setValueAtTime(level, Math.max(when_, end - opt.fadeOut));
|
|
165
|
+
g.gain.linearRampToValueAtTime(0, end);
|
|
166
|
+
}
|
|
167
|
+
src.start(when_, offset, src.loop
|
|
168
|
+
? undefined
|
|
169
|
+
: opt.duration * (opt.rate || 1));
|
|
170
|
+
if (src.loop) {
|
|
171
|
+
src.stop(end);
|
|
172
|
+
}
|
|
173
|
+
} else {
|
|
174
|
+
src.start(when_, offset);
|
|
175
|
+
}
|
|
176
|
+
v = {
|
|
177
|
+
name: name,
|
|
178
|
+
src: src,
|
|
179
|
+
gain: g,
|
|
180
|
+
level: level,
|
|
181
|
+
ended: false
|
|
182
|
+
};
|
|
183
|
+
src.onended = function(){
|
|
184
|
+
v.ended = true;
|
|
185
|
+
return S.voices = S.voices.filter(function(x){
|
|
186
|
+
return x !== v;
|
|
187
|
+
});
|
|
188
|
+
};
|
|
189
|
+
S.voices.push(v);
|
|
190
|
+
return v;
|
|
191
|
+
};
|
|
192
|
+
mediaVoice = function(name, opt){
|
|
193
|
+
var c, a, g, when_, level, end, v, go, delay;
|
|
194
|
+
opt == null && (opt = {});
|
|
195
|
+
c = S.ctx();
|
|
196
|
+
a = new Audio();
|
|
197
|
+
a.crossOrigin = 'anonymous';
|
|
198
|
+
a.preload = 'auto';
|
|
199
|
+
a.preservesPitch = true;
|
|
200
|
+
a.loop = !!opt.loop;
|
|
201
|
+
a.src = S.urls[name];
|
|
202
|
+
a.playbackRate = opt.rate || 1;
|
|
203
|
+
g = c.createGain();
|
|
204
|
+
c.createMediaElementSource(a).connect(g);
|
|
205
|
+
g.connect(bus(opt.bus || 'music'));
|
|
206
|
+
when_ = opt.when || c.currentTime;
|
|
207
|
+
level = opt.gain != null ? opt.gain : 1;
|
|
208
|
+
if (opt.fadeIn) {
|
|
209
|
+
g.gain.setValueAtTime(0, when_);
|
|
210
|
+
g.gain.linearRampToValueAtTime(level, when_ + opt.fadeIn);
|
|
211
|
+
} else {
|
|
212
|
+
g.gain.setValueAtTime(level, when_);
|
|
213
|
+
}
|
|
214
|
+
if (opt.duration != null && opt.fadeOut) {
|
|
215
|
+
end = when_ + opt.duration;
|
|
216
|
+
g.gain.setValueAtTime(level, Math.max(when_, end - opt.fadeOut));
|
|
217
|
+
g.gain.linearRampToValueAtTime(0, end);
|
|
218
|
+
}
|
|
219
|
+
v = {
|
|
220
|
+
name: name,
|
|
221
|
+
media: a,
|
|
222
|
+
gain: g,
|
|
223
|
+
level: level,
|
|
224
|
+
ended: false,
|
|
225
|
+
timers: []
|
|
226
|
+
};
|
|
227
|
+
go = function(){
|
|
228
|
+
var seekThenPlay;
|
|
229
|
+
if (v.ended) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
seekThenPlay = function(){
|
|
233
|
+
a.currentTime = opt.offset || 0;
|
|
234
|
+
return a.play()['catch'](function(){});
|
|
235
|
+
};
|
|
236
|
+
if (a.readyState >= 1) {
|
|
237
|
+
return seekThenPlay();
|
|
238
|
+
} else {
|
|
239
|
+
return a.addEventListener('loadedmetadata', seekThenPlay, {
|
|
240
|
+
once: true
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
delay = Math.max(0, when_ - c.currentTime);
|
|
245
|
+
v.timers.push(setTimeout(go, delay * 1000));
|
|
246
|
+
if (opt.duration != null) {
|
|
247
|
+
v.timers.push(setTimeout(function(){
|
|
248
|
+
return stopVoice(v, 0.02);
|
|
249
|
+
}, (delay + opt.duration) * 1000));
|
|
250
|
+
}
|
|
251
|
+
a.onended = function(){
|
|
252
|
+
v.ended = true;
|
|
253
|
+
return S.voices = S.voices.filter(function(x){
|
|
254
|
+
return x !== v;
|
|
255
|
+
});
|
|
256
|
+
};
|
|
257
|
+
S.voices.push(v);
|
|
258
|
+
return v;
|
|
259
|
+
};
|
|
260
|
+
stopVoice = function(v, fade){
|
|
261
|
+
var now, i$, ref$, len$, h, e;
|
|
262
|
+
fade == null && (fade = 0.05);
|
|
263
|
+
if (!v || v.ended) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
now = ctx.currentTime;
|
|
267
|
+
v.gain.gain.cancelScheduledValues(now);
|
|
268
|
+
v.gain.gain.setValueAtTime(v.gain.gain.value, now);
|
|
269
|
+
v.gain.gain.linearRampToValueAtTime(0, now + fade);
|
|
270
|
+
if (v.media) {
|
|
271
|
+
for (i$ = 0, len$ = (ref$ = v.timers).length; i$ < len$; ++i$) {
|
|
272
|
+
h = ref$[i$];
|
|
273
|
+
clearTimeout(h);
|
|
274
|
+
}
|
|
275
|
+
v.ended = true;
|
|
276
|
+
setTimeout(function(){
|
|
277
|
+
v.media.pause();
|
|
278
|
+
v.media.removeAttribute('src');
|
|
279
|
+
return v.media.load();
|
|
280
|
+
}, (fade + 0.02) * 1000);
|
|
281
|
+
S.voices = S.voices.filter(function(x){
|
|
282
|
+
return x !== v;
|
|
283
|
+
});
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
try {
|
|
287
|
+
return v.src.stop(now + fade + 0.01);
|
|
288
|
+
} catch (e$) {
|
|
289
|
+
return e = e$;
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
S.play = function(name, opt){
|
|
293
|
+
var v;
|
|
294
|
+
opt == null && (opt = {});
|
|
295
|
+
S.resume();
|
|
296
|
+
v = voice(name, opt);
|
|
297
|
+
if (!v) {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
v.manual = true;
|
|
301
|
+
return {
|
|
302
|
+
stop: function(fade){
|
|
303
|
+
return stopVoice(v, fade);
|
|
304
|
+
},
|
|
305
|
+
fade: function(to, dur){
|
|
306
|
+
var now;
|
|
307
|
+
dur == null && (dur = 0.5);
|
|
308
|
+
now = ctx.currentTime;
|
|
309
|
+
v.gain.gain.cancelScheduledValues(now);
|
|
310
|
+
v.gain.gain.setValueAtTime(v.gain.gain.value, now);
|
|
311
|
+
return v.gain.gain.linearRampToValueAtTime(to, now + dur);
|
|
312
|
+
},
|
|
313
|
+
voice: v
|
|
314
|
+
};
|
|
315
|
+
};
|
|
316
|
+
S.stop = function(name, opt){
|
|
317
|
+
var i$, ref$, len$, v, results$ = [];
|
|
318
|
+
opt == null && (opt = {});
|
|
319
|
+
for (i$ = 0, len$ = (ref$ = S.voices).length; i$ < len$; ++i$) {
|
|
320
|
+
v = ref$[i$];
|
|
321
|
+
if (v.manual && (!name || v.name === name)) {
|
|
322
|
+
results$.push(stopVoice(v, opt.fade || 0.05));
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return results$;
|
|
326
|
+
};
|
|
327
|
+
currentMusic = null;
|
|
328
|
+
S.music = function(name, opt){
|
|
329
|
+
var fade;
|
|
330
|
+
opt == null && (opt = {});
|
|
331
|
+
fade = opt.fade != null ? opt.fade : 1;
|
|
332
|
+
if (currentMusic) {
|
|
333
|
+
currentMusic.stop(fade);
|
|
334
|
+
}
|
|
335
|
+
currentMusic = null;
|
|
336
|
+
if (!name) {
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
currentMusic = S.play(name, import$({
|
|
340
|
+
loop: true,
|
|
341
|
+
bus: 'music',
|
|
342
|
+
fadeIn: fade
|
|
343
|
+
}, opt));
|
|
344
|
+
return currentMusic;
|
|
345
|
+
};
|
|
346
|
+
S.timeline = function(items){
|
|
347
|
+
items == null && (items = []);
|
|
348
|
+
S.items = items.map(function(it){
|
|
349
|
+
return import$({}, it);
|
|
350
|
+
});
|
|
351
|
+
if (S.playing) {
|
|
352
|
+
S.transport({
|
|
353
|
+
playing: true,
|
|
354
|
+
t: S.t || 0,
|
|
355
|
+
force: true
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
return S;
|
|
359
|
+
};
|
|
360
|
+
S.cues = function(cues, opt){
|
|
361
|
+
cues == null && (cues = []);
|
|
362
|
+
opt == null && (opt = {});
|
|
363
|
+
return S.timeline(cues.map(function(c){
|
|
364
|
+
return import$({
|
|
365
|
+
t: c.t,
|
|
366
|
+
sound: c.sfx || c.sound,
|
|
367
|
+
gain: c.gain
|
|
368
|
+
}, opt);
|
|
369
|
+
}));
|
|
370
|
+
};
|
|
371
|
+
stopTimeline = function(){
|
|
372
|
+
var i$, ref$, len$, v, results$ = [];
|
|
373
|
+
for (i$ = 0, len$ = (ref$ = S.voices).length; i$ < len$; ++i$) {
|
|
374
|
+
v = ref$[i$];
|
|
375
|
+
if (!v.manual) {
|
|
376
|
+
results$.push(stopVoice(v, 0.03));
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return results$;
|
|
380
|
+
};
|
|
381
|
+
startTimeline = function(t0){
|
|
382
|
+
var c, now, R, i$, ref$, len$, it, buf, b, lead, start, len, skip, opt, ref1$, results$ = [];
|
|
383
|
+
c = S.ctx();
|
|
384
|
+
now = c.currentTime + 0.02;
|
|
385
|
+
R = S.rate || 1;
|
|
386
|
+
for (i$ = 0, len$ = (ref$ = S.items).length; i$ < len$; ++i$) {
|
|
387
|
+
it = ref$[i$];
|
|
388
|
+
buf = S.buffers[it.sound];
|
|
389
|
+
if (!buf) {
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
b = it.bus || 'sfx';
|
|
393
|
+
lead = (it.align || (b === 'sfx' ? 'peak' : 'start')) === 'peak' ? S.peak(buf) : 0;
|
|
394
|
+
start = it.t - lead;
|
|
395
|
+
len = it.loop
|
|
396
|
+
? (it.until != null ? it.until : 1e9) - start
|
|
397
|
+
: it.duration || buf.duration / (it.rate || 1);
|
|
398
|
+
if (start + len <= t0) {
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
skip = Math.max(0, t0 - start);
|
|
402
|
+
opt = (ref1$ = import$({}, it), ref1$.bus = b, ref1$.when = now + Math.max(0, start - t0) / R, ref1$.duration = (len - skip) / R, ref1$.rate = (it.rate || 1) * R, ref1$);
|
|
403
|
+
opt.offset = (it.offset || 0) + (it.loop
|
|
404
|
+
? skip % buf.duration
|
|
405
|
+
: skip * (it.rate || 1));
|
|
406
|
+
if (skip > 0 && it.fadeIn) {
|
|
407
|
+
opt.fadeIn = 0;
|
|
408
|
+
}
|
|
409
|
+
if (R !== 1 && (b === 'voice' || b === 'music') && S.urls[it.sound]) {
|
|
410
|
+
results$.push(mediaVoice(it.sound, opt));
|
|
411
|
+
} else {
|
|
412
|
+
results$.push(voice(buf, opt));
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return results$;
|
|
416
|
+
};
|
|
417
|
+
S.transport = function(arg$){
|
|
418
|
+
var ref$, playing, t, ref1$, force, from, rate, was;
|
|
419
|
+
ref$ = arg$ != null
|
|
420
|
+
? arg$
|
|
421
|
+
: {}, playing = ref$.playing, t = (ref1$ = ref$.t) != null ? ref1$ : 0, force = ref$.force, from = ref$.from, rate = ref$.rate;
|
|
422
|
+
if (from && from !== 'player') {
|
|
423
|
+
S.external = true;
|
|
424
|
+
}
|
|
425
|
+
if (rate != null && +rate > 0 && +rate !== S.rate) {
|
|
426
|
+
S.rate = +rate;
|
|
427
|
+
force = true;
|
|
428
|
+
}
|
|
429
|
+
was = S.playing;
|
|
430
|
+
S.playing = !!playing;
|
|
431
|
+
S.t = t;
|
|
432
|
+
S.tAt = (ctx && ctx.currentTime) || 0;
|
|
433
|
+
if (!playing) {
|
|
434
|
+
return stopTimeline();
|
|
435
|
+
}
|
|
436
|
+
S.resume();
|
|
437
|
+
if (was && !force) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
stopTimeline();
|
|
441
|
+
return startTimeline(t);
|
|
442
|
+
};
|
|
443
|
+
hook = function(L){
|
|
444
|
+
var P, play, seek;
|
|
445
|
+
if (!L || !L.player || L.player.__sound) {
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
P = L.player.prototype;
|
|
449
|
+
play = P.play;
|
|
450
|
+
seek = P.seek;
|
|
451
|
+
P.play = function(go){
|
|
452
|
+
var r;
|
|
453
|
+
go == null && (go = true);
|
|
454
|
+
r = play.apply(this, arguments);
|
|
455
|
+
if (!S.external) {
|
|
456
|
+
S.transport({
|
|
457
|
+
playing: this.playing,
|
|
458
|
+
t: this.t
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
return r;
|
|
462
|
+
};
|
|
463
|
+
P.seek = function(t){
|
|
464
|
+
var last, r;
|
|
465
|
+
last = this.t;
|
|
466
|
+
r = seek.apply(this, arguments);
|
|
467
|
+
if (!S.external && this.started) {
|
|
468
|
+
if (this.playing && (this.t < last - 0.01 || this.t - last > 0.3)) {
|
|
469
|
+
S.transport({
|
|
470
|
+
playing: true,
|
|
471
|
+
t: this.t,
|
|
472
|
+
force: true
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
if (!this.playing && S.playing) {
|
|
476
|
+
S.transport({
|
|
477
|
+
playing: false,
|
|
478
|
+
t: this.t
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
return r;
|
|
483
|
+
};
|
|
484
|
+
return L.player.__sound = true;
|
|
485
|
+
};
|
|
486
|
+
if (window.lotion) {
|
|
487
|
+
hook(window.lotion);
|
|
488
|
+
} else {
|
|
489
|
+
document.addEventListener('DOMContentLoaded', function(){
|
|
490
|
+
return hook(window.lotion);
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
S.render = function(duration, opt){
|
|
494
|
+
var sr, oc, i$, ref$, len$, it, buf, b, lead, start, src, g, level, at, len;
|
|
495
|
+
opt == null && (opt = {});
|
|
496
|
+
sr = opt.sampleRate || SR;
|
|
497
|
+
oc = new OfflineAudioContext(2, Math.ceil(duration * sr), sr);
|
|
498
|
+
for (i$ = 0, len$ = (ref$ = S.items).length; i$ < len$; ++i$) {
|
|
499
|
+
it = ref$[i$];
|
|
500
|
+
buf = S.buffers[it.sound];
|
|
501
|
+
if (!buf) {
|
|
502
|
+
continue;
|
|
503
|
+
}
|
|
504
|
+
b = it.bus || 'sfx';
|
|
505
|
+
lead = (it.align || (b === 'sfx' ? 'peak' : 'start')) === 'peak' ? S.peak(buf) : 0;
|
|
506
|
+
start = it.t - lead;
|
|
507
|
+
src = oc.createBufferSource();
|
|
508
|
+
src.buffer = buf;
|
|
509
|
+
src.loop = !!it.loop;
|
|
510
|
+
src.playbackRate.value = it.rate || 1;
|
|
511
|
+
g = oc.createGain();
|
|
512
|
+
level = it.gain != null ? it.gain : 1;
|
|
513
|
+
g.gain.value = level;
|
|
514
|
+
src.connect(g);
|
|
515
|
+
g.connect(oc.destination);
|
|
516
|
+
at = Math.max(0, start);
|
|
517
|
+
if (it.fadeIn) {
|
|
518
|
+
g.gain.setValueAtTime(0, at);
|
|
519
|
+
g.gain.linearRampToValueAtTime(level, at + it.fadeIn);
|
|
520
|
+
}
|
|
521
|
+
len = it.loop
|
|
522
|
+
? (it.until != null ? it.until : duration) - start
|
|
523
|
+
: it.duration || buf.duration / (it.rate || 1);
|
|
524
|
+
if (it.fadeOut) {
|
|
525
|
+
g.gain.setValueAtTime(level, Math.max(at, start + len - it.fadeOut));
|
|
526
|
+
g.gain.linearRampToValueAtTime(0, start + len);
|
|
527
|
+
}
|
|
528
|
+
src.start(at, (it.offset || 0) + Math.max(0, -start));
|
|
529
|
+
src.stop(start + len);
|
|
530
|
+
}
|
|
531
|
+
return oc.startRendering();
|
|
532
|
+
};
|
|
533
|
+
S.wav = function(buf){
|
|
534
|
+
var ch, n, dv, w, data, res$, i$, c, o, i, j$, v;
|
|
535
|
+
ch = buf.numberOfChannels;
|
|
536
|
+
n = buf.length;
|
|
537
|
+
dv = new DataView(new ArrayBuffer(44 + n * ch * 2));
|
|
538
|
+
w = function(o, s){
|
|
539
|
+
var i$, to$, i, results$ = [];
|
|
540
|
+
for (i$ = 0, to$ = s.length; i$ < to$; ++i$) {
|
|
541
|
+
i = i$;
|
|
542
|
+
results$.push(dv.setUint8(o + i, s.charCodeAt(i)));
|
|
543
|
+
}
|
|
544
|
+
return results$;
|
|
545
|
+
};
|
|
546
|
+
w(0, 'RIFF');
|
|
547
|
+
dv.setUint32(4, 36 + n * ch * 2, true);
|
|
548
|
+
w(8, 'WAVE');
|
|
549
|
+
w(12, 'fmt ');
|
|
550
|
+
dv.setUint32(16, 16, true);
|
|
551
|
+
dv.setUint16(20, 1, true);
|
|
552
|
+
dv.setUint16(22, ch, true);
|
|
553
|
+
dv.setUint32(24, buf.sampleRate, true);
|
|
554
|
+
dv.setUint32(28, buf.sampleRate * ch * 2, true);
|
|
555
|
+
dv.setUint16(32, ch * 2, true);
|
|
556
|
+
dv.setUint16(34, 16, true);
|
|
557
|
+
w(36, 'data');
|
|
558
|
+
dv.setUint32(40, n * ch * 2, true);
|
|
559
|
+
res$ = [];
|
|
560
|
+
for (i$ = 0; i$ < ch; ++i$) {
|
|
561
|
+
c = i$;
|
|
562
|
+
res$.push(buf.getChannelData(c));
|
|
563
|
+
}
|
|
564
|
+
data = res$;
|
|
565
|
+
o = 44;
|
|
566
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
567
|
+
i = i$;
|
|
568
|
+
for (j$ = 0; j$ < ch; ++j$) {
|
|
569
|
+
c = j$;
|
|
570
|
+
v = Math.max(-1, Math.min(1, data[c][i]));
|
|
571
|
+
dv.setInt16(o, v < 0
|
|
572
|
+
? v * 0x8000
|
|
573
|
+
: v * 0x7fff, true);
|
|
574
|
+
o += 2;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
return new Blob([dv], {
|
|
578
|
+
type: 'audio/wav'
|
|
579
|
+
});
|
|
580
|
+
};
|
|
581
|
+
S.report = function(){
|
|
582
|
+
return {
|
|
583
|
+
loaded: Object.keys(S.buffers).map(function(k){
|
|
584
|
+
return {
|
|
585
|
+
name: k,
|
|
586
|
+
duration: +S.buffers[k].duration.toFixed(2),
|
|
587
|
+
peak: +S.peak(S.buffers[k]).toFixed(3)
|
|
588
|
+
};
|
|
589
|
+
}),
|
|
590
|
+
timeline: S.items.length,
|
|
591
|
+
playing: S.playing,
|
|
592
|
+
context: ctx ? ctx.state : null,
|
|
593
|
+
errors: S.errors.slice(-10)
|
|
594
|
+
};
|
|
595
|
+
};
|
|
596
|
+
NOTES = {
|
|
597
|
+
C: -9,
|
|
598
|
+
D: -7,
|
|
599
|
+
E: -5,
|
|
600
|
+
F: -4,
|
|
601
|
+
G: -2,
|
|
602
|
+
A: 0,
|
|
603
|
+
B: 2
|
|
604
|
+
};
|
|
605
|
+
S.freq = function(n){
|
|
606
|
+
var m, semi;
|
|
607
|
+
if (typeof n === 'number') {
|
|
608
|
+
return n;
|
|
609
|
+
}
|
|
610
|
+
m = /^([A-G])(#|b)?(-?\d)$/.exec(n);
|
|
611
|
+
if (!m) {
|
|
612
|
+
return 440;
|
|
613
|
+
}
|
|
614
|
+
semi = NOTES[m[1]] + (m[2] === '#'
|
|
615
|
+
? 1
|
|
616
|
+
: m[2] === 'b' ? -1 : 0) + (+m[3] - 4) * 12;
|
|
617
|
+
return 440 * Math.pow(2, semi / 12);
|
|
618
|
+
};
|
|
619
|
+
rng = function(seed){
|
|
620
|
+
var s;
|
|
621
|
+
seed == null && (seed = 1);
|
|
622
|
+
s = seed >>> 0 || 1;
|
|
623
|
+
return function(){
|
|
624
|
+
s = s * 1664525 + 1013904223 >>> 0;
|
|
625
|
+
return s / 4294967296;
|
|
626
|
+
};
|
|
627
|
+
};
|
|
628
|
+
make = function(dur, fn, opt){
|
|
629
|
+
var n, L, R, max, i$, i, k, buf;
|
|
630
|
+
opt == null && (opt = {});
|
|
631
|
+
n = Math.max(1, Math.round(dur * SR));
|
|
632
|
+
L = new Float32Array(n);
|
|
633
|
+
R = new Float32Array(n);
|
|
634
|
+
fn(L, R, n);
|
|
635
|
+
max = 0;
|
|
636
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
637
|
+
i = i$;
|
|
638
|
+
max = Math.max(max, Math.abs(L[i]), Math.abs(R[i]));
|
|
639
|
+
}
|
|
640
|
+
k = max > 0 ? (opt.peak || 0.9) / max : 1;
|
|
641
|
+
buf = new AudioBuffer({
|
|
642
|
+
length: n,
|
|
643
|
+
sampleRate: SR,
|
|
644
|
+
numberOfChannels: 2
|
|
645
|
+
});
|
|
646
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
647
|
+
i = i$;
|
|
648
|
+
L[i] *= k;
|
|
649
|
+
R[i] *= k;
|
|
650
|
+
}
|
|
651
|
+
buf.copyToChannel(L, 0);
|
|
652
|
+
buf.copyToChannel(R, 1);
|
|
653
|
+
return buf;
|
|
654
|
+
};
|
|
655
|
+
coef = function(type, f, q){
|
|
656
|
+
var w, cs, al;
|
|
657
|
+
w = 2 * Math.PI * Math.min(f, SR * 0.49) / SR;
|
|
658
|
+
cs = Math.cos(w);
|
|
659
|
+
al = Math.sin(w) / (2 * q);
|
|
660
|
+
switch (type) {
|
|
661
|
+
case 'lp':
|
|
662
|
+
return [(1 - cs) / 2, 1 - cs, (1 - cs) / 2, 1 + al, -2 * cs, 1 - al];
|
|
663
|
+
case 'hp':
|
|
664
|
+
return [(1 + cs) / 2, -(1 + cs), (1 + cs) / 2, 1 + al, -2 * cs, 1 - al];
|
|
665
|
+
default:
|
|
666
|
+
return [al, 0, -al, 1 + al, -2 * cs, 1 - al];
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
biquad = function(d, type, f, q){
|
|
670
|
+
var ref$, b0, b1, b2, a0, a1, a2, x1, x2, y1, y2, i$, to$, i, x, y;
|
|
671
|
+
q == null && (q = 0.707);
|
|
672
|
+
ref$ = coef(type, f, q), b0 = ref$[0], b1 = ref$[1], b2 = ref$[2], a0 = ref$[3], a1 = ref$[4], a2 = ref$[5];
|
|
673
|
+
x1 = x2 = y1 = y2 = 0;
|
|
674
|
+
for (i$ = 0, to$ = d.length; i$ < to$; ++i$) {
|
|
675
|
+
i = i$;
|
|
676
|
+
x = d[i];
|
|
677
|
+
y = (b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2) / a0;
|
|
678
|
+
x2 = x1;
|
|
679
|
+
x1 = x;
|
|
680
|
+
y2 = y1;
|
|
681
|
+
y1 = y;
|
|
682
|
+
d[i] = y;
|
|
683
|
+
}
|
|
684
|
+
return d;
|
|
685
|
+
};
|
|
686
|
+
biquadTv = function(d, type, fc, q){
|
|
687
|
+
var n, x1, x2, y1, y2, i$, s, ref$, b0, b1, b2, a0, a1, a2, j$, to$, i, x, y;
|
|
688
|
+
q == null && (q = 0.707);
|
|
689
|
+
n = d.length;
|
|
690
|
+
x1 = x2 = y1 = y2 = 0;
|
|
691
|
+
for (i$ = 0; i$ < n; i$ += 32) {
|
|
692
|
+
s = i$;
|
|
693
|
+
ref$ = coef(type, fc(s / n), q), b0 = ref$[0], b1 = ref$[1], b2 = ref$[2], a0 = ref$[3], a1 = ref$[4], a2 = ref$[5];
|
|
694
|
+
for (j$ = s, to$ = Math.min(n, s + 32); j$ < to$; ++j$) {
|
|
695
|
+
i = j$;
|
|
696
|
+
x = d[i];
|
|
697
|
+
y = (b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2) / a0;
|
|
698
|
+
x2 = x1;
|
|
699
|
+
x1 = x;
|
|
700
|
+
y2 = y1;
|
|
701
|
+
y1 = y;
|
|
702
|
+
d[i] = y;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
return d;
|
|
706
|
+
};
|
|
707
|
+
noise = function(n, r){
|
|
708
|
+
var d, i$, i;
|
|
709
|
+
d = new Float32Array(n);
|
|
710
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
711
|
+
i = i$;
|
|
712
|
+
d[i] = r() * 2 - 1;
|
|
713
|
+
}
|
|
714
|
+
return d;
|
|
715
|
+
};
|
|
716
|
+
env = function(t, a, d){
|
|
717
|
+
if (t < a) {
|
|
718
|
+
return t / a;
|
|
719
|
+
} else {
|
|
720
|
+
return Math.exp(-(t - a) / d);
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
pan = function(L, R, src, p, gain){
|
|
724
|
+
var gl, gr, i$, to$, i, results$ = [];
|
|
725
|
+
p == null && (p = 0);
|
|
726
|
+
gain == null && (gain = 1);
|
|
727
|
+
gl = Math.cos((p + 1) * Math.PI / 4) * gain;
|
|
728
|
+
gr = Math.sin((p + 1) * Math.PI / 4) * gain;
|
|
729
|
+
for (i$ = 0, to$ = src.length; i$ < to$; ++i$) {
|
|
730
|
+
i = i$;
|
|
731
|
+
L[i] += src[i] * gl;
|
|
732
|
+
results$.push(R[i] += src[i] * gr);
|
|
733
|
+
}
|
|
734
|
+
return results$;
|
|
735
|
+
};
|
|
736
|
+
synth = S.synth = {};
|
|
737
|
+
synth.click = function(o){
|
|
738
|
+
o == null && (o = {});
|
|
739
|
+
return make(0.05, function(L, R, n){
|
|
740
|
+
var r, nz, d, i$, i, t;
|
|
741
|
+
r = rng(o.seed || 7);
|
|
742
|
+
nz = biquad(noise(n, r), 'hp', 2500);
|
|
743
|
+
d = new Float32Array(n);
|
|
744
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
745
|
+
i = i$;
|
|
746
|
+
t = i / SR;
|
|
747
|
+
d[i] = nz[i] * env(t, 0.0005, 0.004) + 0.5 * Math.sin(2 * Math.PI * (o.freq || 2000) * t) * env(t, 0.0005, 0.012);
|
|
748
|
+
}
|
|
749
|
+
return pan(L, R, d, o.pan);
|
|
750
|
+
});
|
|
751
|
+
};
|
|
752
|
+
synth.tick = function(o){
|
|
753
|
+
o == null && (o = {});
|
|
754
|
+
return make(0.06, function(L, R, n){
|
|
755
|
+
var f, d, i$, i, t;
|
|
756
|
+
f = S.freq(o.note || o.freq || 1800);
|
|
757
|
+
d = new Float32Array(n);
|
|
758
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
759
|
+
i = i$;
|
|
760
|
+
t = i / SR;
|
|
761
|
+
d[i] = Math.sin(2 * Math.PI * f * t) * env(t, 0.001, 0.018);
|
|
762
|
+
}
|
|
763
|
+
return pan(L, R, d, o.pan);
|
|
764
|
+
});
|
|
765
|
+
};
|
|
766
|
+
synth.pop = function(o){
|
|
767
|
+
o == null && (o = {});
|
|
768
|
+
return make(0.15, function(L, R, n){
|
|
769
|
+
var f0, f1, d, ph, i$, i, t, f;
|
|
770
|
+
f0 = o.from || 380;
|
|
771
|
+
f1 = o.to || 900;
|
|
772
|
+
d = new Float32Array(n);
|
|
773
|
+
ph = 0;
|
|
774
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
775
|
+
i = i$;
|
|
776
|
+
t = i / SR;
|
|
777
|
+
f = f0 + (f1 - f0) * Math.min(1, t / 0.03);
|
|
778
|
+
ph += 2 * Math.PI * f / SR;
|
|
779
|
+
d[i] = Math.sin(ph) * env(t, 0.002, 0.04);
|
|
780
|
+
}
|
|
781
|
+
return pan(L, R, d, o.pan);
|
|
782
|
+
});
|
|
783
|
+
};
|
|
784
|
+
synth.toggle = function(o){
|
|
785
|
+
o == null && (o = {});
|
|
786
|
+
return make(0.12, function(L, R, n){
|
|
787
|
+
var d, i$, i, t;
|
|
788
|
+
d = new Float32Array(n);
|
|
789
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
790
|
+
i = i$;
|
|
791
|
+
t = i / SR;
|
|
792
|
+
d[i] = Math.sin(2 * Math.PI * 1500 * t) * env(t, 0.001, 0.012) + (t > 0.05 ? Math.sin(2 * Math.PI * 2200 * (t - 0.05)) * env(t - 0.05, 0.001, 0.015) : 0);
|
|
793
|
+
}
|
|
794
|
+
return pan(L, R, d, o.pan);
|
|
795
|
+
});
|
|
796
|
+
};
|
|
797
|
+
synth.chime = function(o){
|
|
798
|
+
var f, dur;
|
|
799
|
+
o == null && (o = {});
|
|
800
|
+
f = S.freq(o.note || 'E6');
|
|
801
|
+
dur = o.dur || 1.4;
|
|
802
|
+
return make(dur, function(L, R, n){
|
|
803
|
+
var d, i$, i, t;
|
|
804
|
+
d = new Float32Array(n);
|
|
805
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
806
|
+
i = i$;
|
|
807
|
+
t = i / SR;
|
|
808
|
+
d[i] = (Math.sin(2 * Math.PI * f * t) + 0.5 * Math.sin(2 * Math.PI * f * 2.01 * t) * Math.exp(-t * 2) + 0.25 * Math.sin(2 * Math.PI * f * 3.02 * t) * Math.exp(-t * 4)) * env(t, 0.003, dur / 4);
|
|
809
|
+
}
|
|
810
|
+
return pan(L, R, d, o.pan);
|
|
811
|
+
});
|
|
812
|
+
};
|
|
813
|
+
synth.success = function(o){
|
|
814
|
+
o == null && (o = {});
|
|
815
|
+
return make(0.9, function(L, R, n){
|
|
816
|
+
var d, i$, ref$, len$, ref1$, at, note, f, j$, i, t;
|
|
817
|
+
d = new Float32Array(n);
|
|
818
|
+
for (i$ = 0, len$ = (ref$ = [[0, 'C6'], [0.09, 'E6'], [0.18, 'G6']]).length; i$ < len$; ++i$) {
|
|
819
|
+
ref1$ = ref$[i$], at = ref1$[0], note = ref1$[1];
|
|
820
|
+
f = S.freq(note);
|
|
821
|
+
for (j$ = Math.round(at * SR); j$ < n; ++j$) {
|
|
822
|
+
i = j$;
|
|
823
|
+
t = i / SR - at;
|
|
824
|
+
d[i] += (Math.sin(2 * Math.PI * f * t) + 0.4 * Math.sin(2 * Math.PI * f * 2.01 * t)) * env(t, 0.003, 0.25);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
return pan(L, R, d, o.pan);
|
|
828
|
+
});
|
|
829
|
+
};
|
|
830
|
+
synth.notify = function(o){
|
|
831
|
+
o == null && (o = {});
|
|
832
|
+
return make(0.7, function(L, R, n){
|
|
833
|
+
var d, i$, ref$, len$, ref1$, at, note, f, j$, i, t;
|
|
834
|
+
d = new Float32Array(n);
|
|
835
|
+
for (i$ = 0, len$ = (ref$ = [[0, 'A5'], [0.12, 'E6']]).length; i$ < len$; ++i$) {
|
|
836
|
+
ref1$ = ref$[i$], at = ref1$[0], note = ref1$[1];
|
|
837
|
+
f = S.freq(note);
|
|
838
|
+
for (j$ = Math.round(at * SR); j$ < n; ++j$) {
|
|
839
|
+
i = j$;
|
|
840
|
+
t = i / SR - at;
|
|
841
|
+
d[i] += Math.sin(2 * Math.PI * f * t) * env(t, 0.004, 0.18);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
return pan(L, R, d, o.pan);
|
|
845
|
+
});
|
|
846
|
+
};
|
|
847
|
+
synth.whoosh = function(o){
|
|
848
|
+
var dur, f0, f1, f2, at, q;
|
|
849
|
+
o == null && (o = {});
|
|
850
|
+
dur = o.dur || 0.7;
|
|
851
|
+
f0 = o.from || 400;
|
|
852
|
+
f1 = o.peak || 2600;
|
|
853
|
+
f2 = o.to || 600;
|
|
854
|
+
at = o.at || 0.45;
|
|
855
|
+
q = o.q || 1.2;
|
|
856
|
+
return make(dur, function(L, R, n){
|
|
857
|
+
var r, d, i$, i, v, results$ = [];
|
|
858
|
+
r = rng(o.seed || 3);
|
|
859
|
+
d = biquadTv(noise(n, r), 'bp', function(u){
|
|
860
|
+
if (u < at) {
|
|
861
|
+
return f0 + (f1 - f0) * (u / at);
|
|
862
|
+
} else {
|
|
863
|
+
return f1 + (f2 - f1) * ((u - at) / (1 - at));
|
|
864
|
+
}
|
|
865
|
+
}, q);
|
|
866
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
867
|
+
i = i$;
|
|
868
|
+
v = i / n;
|
|
869
|
+
d[i] *= v < at
|
|
870
|
+
? Math.sin(Math.PI / 2 * v / at)
|
|
871
|
+
: Math.cos(Math.PI / 2 * (v - at) / (1 - at));
|
|
872
|
+
}
|
|
873
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
874
|
+
i = i$;
|
|
875
|
+
L[i] = d[i] * (1 - i / n * 0.6);
|
|
876
|
+
results$.push(R[i] = d[i] * (0.4 + i / n * 0.6));
|
|
877
|
+
}
|
|
878
|
+
return results$;
|
|
879
|
+
});
|
|
880
|
+
};
|
|
881
|
+
synth.type = function(o){
|
|
882
|
+
o == null && (o = {});
|
|
883
|
+
return synth.click({
|
|
884
|
+
freq: 1200 + 600 * rng(o.seed || 11)(),
|
|
885
|
+
seed: o.seed
|
|
886
|
+
});
|
|
887
|
+
};
|
|
888
|
+
synth.thump = function(o){
|
|
889
|
+
o == null && (o = {});
|
|
890
|
+
return make(0.35, function(L, R, n){
|
|
891
|
+
var r, nz, d, ph, i$, i, t;
|
|
892
|
+
r = rng(o.seed || 5);
|
|
893
|
+
nz = biquad(noise(n, r), 'bp', 1800, 0.8);
|
|
894
|
+
d = new Float32Array(n);
|
|
895
|
+
ph = 0;
|
|
896
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
897
|
+
i = i$;
|
|
898
|
+
t = i / SR;
|
|
899
|
+
ph += 2 * Math.PI * (70 + 60 * Math.exp(-t / 0.04)) / SR;
|
|
900
|
+
d[i] = Math.sin(ph) * env(t, 0.002, 0.09) + 0.35 * nz[i] * env(t, 0.001, 0.03);
|
|
901
|
+
}
|
|
902
|
+
return pan(L, R, d, o.pan);
|
|
903
|
+
});
|
|
904
|
+
};
|
|
905
|
+
synth.pluck = function(o){
|
|
906
|
+
var f, dur, bright, slide;
|
|
907
|
+
o == null && (o = {});
|
|
908
|
+
f = S.freq(o.note || 'A3');
|
|
909
|
+
dur = o.dur || 2.5;
|
|
910
|
+
bright = o.bright != null ? o.bright : 0.6;
|
|
911
|
+
slide = o.slide != null ? o.slide : 0.6;
|
|
912
|
+
return make(dur, function(L, R, n){
|
|
913
|
+
var r, period, size, buf, i$, to$, k, j$, i, d, line, decay, p, j, j0, fr, a, b;
|
|
914
|
+
r = rng(o.seed || 13);
|
|
915
|
+
period = SR / f;
|
|
916
|
+
size = Math.ceil(period * 2) + 4;
|
|
917
|
+
buf = noise(size, r);
|
|
918
|
+
for (i$ = 0, to$ = Math.round((1 - bright) * 4); i$ < to$; ++i$) {
|
|
919
|
+
k = i$;
|
|
920
|
+
for (j$ = 1; j$ < size; ++j$) {
|
|
921
|
+
i = j$;
|
|
922
|
+
buf[i] = (buf[i] + buf[i - 1]) / 2;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
d = new Float32Array(n);
|
|
926
|
+
line = new Float32Array(n + size);
|
|
927
|
+
for (i$ = 0; i$ < size; ++i$) {
|
|
928
|
+
i = i$;
|
|
929
|
+
line[i] = buf[i];
|
|
930
|
+
}
|
|
931
|
+
decay = Math.pow(0.996, 220 / f);
|
|
932
|
+
for (i$ = size, to$ = n + size; i$ < to$; ++i$) {
|
|
933
|
+
k = i$;
|
|
934
|
+
p = period * Math.pow(2, slide * Math.exp(-(k - size) / SR / 0.09) / 12);
|
|
935
|
+
j = k - p;
|
|
936
|
+
j0 = Math.floor(j);
|
|
937
|
+
fr = j - j0;
|
|
938
|
+
a = line[j0] * (1 - fr) + line[j0 + 1] * fr;
|
|
939
|
+
b = line[j0 - 1] * (1 - fr) + line[j0] * fr;
|
|
940
|
+
line[k] = decay * (a + b) / 2;
|
|
941
|
+
d[k - size] = line[k];
|
|
942
|
+
}
|
|
943
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
944
|
+
i = i$;
|
|
945
|
+
d[i] *= Math.min(1, (n - i) / (0.3 * SR));
|
|
946
|
+
}
|
|
947
|
+
return pan(L, R, d, o.pan);
|
|
948
|
+
});
|
|
949
|
+
};
|
|
950
|
+
synth.drone = function(o){
|
|
951
|
+
var notes, dur, att, rel;
|
|
952
|
+
o == null && (o = {});
|
|
953
|
+
notes = (o.notes || ['A1', 'E2', 'A2']).map(S.freq);
|
|
954
|
+
dur = o.dur || 8;
|
|
955
|
+
att = o.attack || 1.5;
|
|
956
|
+
rel = o.release || 2;
|
|
957
|
+
return make(dur, function(L, R, n){
|
|
958
|
+
var i$, ref$, len$, k, f, d, j$, i, t, a, results$ = [];
|
|
959
|
+
for (i$ = 0, len$ = (ref$ = notes).length; i$ < len$; ++i$) {
|
|
960
|
+
k = i$;
|
|
961
|
+
f = ref$[i$];
|
|
962
|
+
d = new Float32Array(n);
|
|
963
|
+
for (j$ = 0; j$ < n; ++j$) {
|
|
964
|
+
i = j$;
|
|
965
|
+
t = i / SR;
|
|
966
|
+
a = Math.min(1, t / att, (dur - t) / rel);
|
|
967
|
+
d[i] = (Math.sin(2 * Math.PI * f * t) + 0.3 * Math.sin(2 * Math.PI * f * 1.003 * 2 * t)) * a;
|
|
968
|
+
}
|
|
969
|
+
results$.push(pan(L, R, d, (k - (notes.length - 1) / 2) * 0.4, 1 / notes.length));
|
|
970
|
+
}
|
|
971
|
+
return results$;
|
|
972
|
+
});
|
|
973
|
+
};
|
|
974
|
+
synth.wind = function(o){
|
|
975
|
+
var dur;
|
|
976
|
+
o == null && (o = {});
|
|
977
|
+
dur = o.dur || 6;
|
|
978
|
+
return make(dur, function(L, R, n){
|
|
979
|
+
var r, d, lag, i$, i, t, a, results$ = [];
|
|
980
|
+
r = rng(o.seed || 17);
|
|
981
|
+
d = biquad(biquad(noise(n, r), 'hp', 150), 'lp', o.cutoff || 900);
|
|
982
|
+
lag = 2400;
|
|
983
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
984
|
+
i = i$;
|
|
985
|
+
t = i / SR;
|
|
986
|
+
a = (0.6 + 0.4 * Math.sin(2 * Math.PI * 0.13 * t) * Math.sin(2 * Math.PI * 0.071 * t + 1)) * Math.min(1, t, dur - t);
|
|
987
|
+
L[i] = d[i] * a;
|
|
988
|
+
results$.push(R[i] = d[(i + lag) % n] * a);
|
|
989
|
+
}
|
|
990
|
+
return results$;
|
|
991
|
+
});
|
|
992
|
+
};
|
|
993
|
+
synth.rain = function(o){
|
|
994
|
+
var dur, density;
|
|
995
|
+
o == null && (o = {});
|
|
996
|
+
dur = o.dur || 6;
|
|
997
|
+
density = o.density || 0.02;
|
|
998
|
+
return make(dur, function(L, R, n){
|
|
999
|
+
var r, bed, grains, i$, i, a, results$ = [];
|
|
1000
|
+
r = rng(o.seed || 19);
|
|
1001
|
+
bed = biquad(noise(n, r), 'bp', 4000, 0.5);
|
|
1002
|
+
grains = new Float32Array(n);
|
|
1003
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1004
|
+
i = i$;
|
|
1005
|
+
if (r() < density * 0.05) {
|
|
1006
|
+
grains[i] = r() * 2 - 1;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
grains = biquad(biquad(grains, 'hp', 2500), 'lp', 9000);
|
|
1010
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1011
|
+
i = i$;
|
|
1012
|
+
a = Math.min(1, i / SR, (n - i) / SR);
|
|
1013
|
+
L[i] = (bed[i] * 0.15 + grains[i] * 3) * a;
|
|
1014
|
+
results$.push(R[i] = (bed[(i + 1200) % n] * 0.15 + grains[(i + 777) % n] * 3) * a);
|
|
1015
|
+
}
|
|
1016
|
+
return results$;
|
|
1017
|
+
});
|
|
1018
|
+
};
|
|
1019
|
+
synth.buzz = function(o){
|
|
1020
|
+
var dur, f;
|
|
1021
|
+
o == null && (o = {});
|
|
1022
|
+
dur = o.dur || 1.5;
|
|
1023
|
+
f = S.freq(o.freq || 220);
|
|
1024
|
+
return make(dur, function(L, R, n){
|
|
1025
|
+
var d, ph, i$, i, t, ff, saw;
|
|
1026
|
+
d = new Float32Array(n);
|
|
1027
|
+
ph = 0;
|
|
1028
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1029
|
+
i = i$;
|
|
1030
|
+
t = i / SR;
|
|
1031
|
+
ff = f * (1 + 0.03 * Math.sin(2 * Math.PI * 5.3 * t) + 0.015 * Math.sin(2 * Math.PI * 1.7 * t));
|
|
1032
|
+
ph += ff / SR;
|
|
1033
|
+
saw = 2 * (ph - Math.floor(ph + 0.5));
|
|
1034
|
+
d[i] = saw * (0.75 + 0.25 * Math.sin(2 * Math.PI * ff * 0.5 * t)) * Math.min(1, t / 0.08, (dur - t) / 0.15);
|
|
1035
|
+
}
|
|
1036
|
+
biquad(d, 'lp', 2200);
|
|
1037
|
+
biquad(d, 'bp', f * 3, 0.6);
|
|
1038
|
+
return pan(L, R, d, o.pan);
|
|
1039
|
+
});
|
|
1040
|
+
};
|
|
1041
|
+
synth.swell = function(o){
|
|
1042
|
+
var dur;
|
|
1043
|
+
o == null && (o = {});
|
|
1044
|
+
dur = o.dur || 2;
|
|
1045
|
+
return make(dur, function(L, R, n){
|
|
1046
|
+
var r, d, i$, i, u, results$ = [];
|
|
1047
|
+
r = rng(o.seed || 23);
|
|
1048
|
+
d = biquadTv(noise(n, r), 'bp', function(u){
|
|
1049
|
+
return 300 + 3000 * u * u;
|
|
1050
|
+
}, 0.9);
|
|
1051
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1052
|
+
i = i$;
|
|
1053
|
+
u = i / n;
|
|
1054
|
+
results$.push(L[i] = R[i] = d[i] * u * u);
|
|
1055
|
+
}
|
|
1056
|
+
return results$;
|
|
1057
|
+
});
|
|
1058
|
+
};
|
|
1059
|
+
synth.melody = function(o){
|
|
1060
|
+
var seq, dur, inst, voices;
|
|
1061
|
+
o == null && (o = {});
|
|
1062
|
+
seq = o.notes || [];
|
|
1063
|
+
dur = o.dur || Math.max.apply(Math, seq.map(function(x){
|
|
1064
|
+
return x[0] + (x[2] || 1.5);
|
|
1065
|
+
})) + 1;
|
|
1066
|
+
inst = o.instrument || 'pluck';
|
|
1067
|
+
if (!synth[inst]) {
|
|
1068
|
+
inst = 'pluck';
|
|
1069
|
+
}
|
|
1070
|
+
voices = seq.map(function(x, k){
|
|
1071
|
+
var opt;
|
|
1072
|
+
opt = inst === 'pluck'
|
|
1073
|
+
? {
|
|
1074
|
+
bright: o.bright,
|
|
1075
|
+
slide: o.slide
|
|
1076
|
+
}
|
|
1077
|
+
: {};
|
|
1078
|
+
return [
|
|
1079
|
+
x, synth[inst](import$({
|
|
1080
|
+
note: x[1],
|
|
1081
|
+
dur: (x[2] || 1.5) + 0.8,
|
|
1082
|
+
seed: 31 + k
|
|
1083
|
+
}, opt))
|
|
1084
|
+
];
|
|
1085
|
+
});
|
|
1086
|
+
return make(dur, function(L, R, n){
|
|
1087
|
+
var i$, ref$, len$, ref1$, ref2$, t, note, d, vel, b, results$ = [];
|
|
1088
|
+
for (i$ = 0, len$ = (ref$ = voices).length; i$ < len$; ++i$) {
|
|
1089
|
+
ref1$ = ref$[i$], ref2$ = ref1$[0], t = ref2$[0], note = ref2$[1], d = ref2$[2], vel = ref2$[3], b = ref1$[1];
|
|
1090
|
+
results$.push(place(L, R, b, t, vel || 0.8));
|
|
1091
|
+
}
|
|
1092
|
+
return results$;
|
|
1093
|
+
});
|
|
1094
|
+
};
|
|
1095
|
+
place = function(L, R, b, t, g){
|
|
1096
|
+
var l, r_, o0, i$, to$, i, results$ = [];
|
|
1097
|
+
g == null && (g = 1);
|
|
1098
|
+
l = b.getChannelData(0);
|
|
1099
|
+
r_ = b.getChannelData(1);
|
|
1100
|
+
o0 = Math.round(t * SR);
|
|
1101
|
+
for (i$ = Math.max(0, -o0), to$ = Math.min(l.length, L.length - o0); i$ < to$; ++i$) {
|
|
1102
|
+
i = i$;
|
|
1103
|
+
L[o0 + i] += l[i] * g;
|
|
1104
|
+
results$.push(R[o0 + i] += r_[i] * g);
|
|
1105
|
+
}
|
|
1106
|
+
return results$;
|
|
1107
|
+
};
|
|
1108
|
+
partial = function(d, at, f, amp, dec, att){
|
|
1109
|
+
var o0, w, i$, to$, i, k, t, a;
|
|
1110
|
+
att == null && (att = 0.001);
|
|
1111
|
+
if (f >= SR * 0.45) {
|
|
1112
|
+
return d;
|
|
1113
|
+
}
|
|
1114
|
+
o0 = Math.round(at * SR);
|
|
1115
|
+
w = 2 * Math.PI * f / SR;
|
|
1116
|
+
for (i$ = Math.max(0, o0), to$ = d.length; i$ < to$; ++i$) {
|
|
1117
|
+
i = i$;
|
|
1118
|
+
k = i - o0;
|
|
1119
|
+
t = k / SR;
|
|
1120
|
+
a = amp * env(t, att, dec);
|
|
1121
|
+
if (t > att && a < 1e-5) {
|
|
1122
|
+
break;
|
|
1123
|
+
}
|
|
1124
|
+
d[i] += a * Math.sin(w * k);
|
|
1125
|
+
}
|
|
1126
|
+
return d;
|
|
1127
|
+
};
|
|
1128
|
+
fadeOut = function(d, sec){
|
|
1129
|
+
var m, i$, i;
|
|
1130
|
+
sec == null && (sec = 0.02);
|
|
1131
|
+
m = Math.min(d.length, Math.round(sec * SR));
|
|
1132
|
+
for (i$ = 0; i$ < m; ++i$) {
|
|
1133
|
+
i = i$;
|
|
1134
|
+
d[d.length - 1 - i] *= i / m;
|
|
1135
|
+
}
|
|
1136
|
+
return d;
|
|
1137
|
+
};
|
|
1138
|
+
wander = function(n, every, r){
|
|
1139
|
+
var step, pts, res$, i$, to$, k, d, i, u;
|
|
1140
|
+
step = Math.max(1, Math.round(every * SR));
|
|
1141
|
+
res$ = [];
|
|
1142
|
+
for (i$ = 0, to$ = Math.ceil(n / step) + 1; i$ <= to$; ++i$) {
|
|
1143
|
+
k = i$;
|
|
1144
|
+
res$.push(r());
|
|
1145
|
+
}
|
|
1146
|
+
pts = res$;
|
|
1147
|
+
d = new Float32Array(n);
|
|
1148
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1149
|
+
i = i$;
|
|
1150
|
+
k = Math.floor(i / step);
|
|
1151
|
+
u = (i % step) / step;
|
|
1152
|
+
d[i] = pts[k] * (1 - u) + pts[k + 1] * u;
|
|
1153
|
+
}
|
|
1154
|
+
return d;
|
|
1155
|
+
};
|
|
1156
|
+
glideOsc = function(n, f0, f1, harm){
|
|
1157
|
+
var d, ph, i$, i, j$, len$, k, a;
|
|
1158
|
+
harm == null && (harm = [1]);
|
|
1159
|
+
d = new Float32Array(n);
|
|
1160
|
+
ph = 0;
|
|
1161
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1162
|
+
i = i$;
|
|
1163
|
+
ph += 2 * Math.PI * f0 * Math.pow(f1 / f0, i / n) / SR;
|
|
1164
|
+
for (j$ = 0, len$ = harm.length; j$ < len$; ++j$) {
|
|
1165
|
+
k = j$;
|
|
1166
|
+
a = harm[j$];
|
|
1167
|
+
d[i] += a * Math.sin(ph * (k + 1));
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
return d;
|
|
1171
|
+
};
|
|
1172
|
+
COMB = [1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617];
|
|
1173
|
+
ALLPASS = [556, 441, 341, 225];
|
|
1174
|
+
reverb = function(buf, mix, room){
|
|
1175
|
+
var k, src, m;
|
|
1176
|
+
mix == null && (mix = 0.3);
|
|
1177
|
+
room == null && (room = 0.5);
|
|
1178
|
+
k = SR / 44100;
|
|
1179
|
+
src = [buf.getChannelData(0), buf.getChannelData(1)];
|
|
1180
|
+
m = buf.length;
|
|
1181
|
+
return make(buf.duration + 0.4 + room * 3, function(L, R, n){
|
|
1182
|
+
var fb, damp, input, i$, to$, i, ref$, len$, ch, out, lresult$, wet, j$, ref1$, len1$, c, len, line, idx, filt, k$, y, b, v, dry, results$ = [];
|
|
1183
|
+
fb = 0.7 + 0.27 * room;
|
|
1184
|
+
damp = 0.3;
|
|
1185
|
+
input = new Float32Array(n);
|
|
1186
|
+
for (i$ = 0, to$ = m; i$ < to$; ++i$) {
|
|
1187
|
+
i = i$;
|
|
1188
|
+
input[i] = (src[0][i] + src[1][i]) * 0.015;
|
|
1189
|
+
}
|
|
1190
|
+
for (i$ = 0, len$ = (ref$ = [L, R]).length; i$ < len$; ++i$) {
|
|
1191
|
+
ch = i$;
|
|
1192
|
+
out = ref$[i$];
|
|
1193
|
+
lresult$ = [];
|
|
1194
|
+
wet = new Float32Array(n);
|
|
1195
|
+
for (j$ = 0, len1$ = (ref1$ = COMB).length; j$ < len1$; ++j$) {
|
|
1196
|
+
c = ref1$[j$];
|
|
1197
|
+
len = Math.round((c + ch * 23) * k);
|
|
1198
|
+
line = new Float32Array(len);
|
|
1199
|
+
idx = 0;
|
|
1200
|
+
filt = 0;
|
|
1201
|
+
for (k$ = 0; k$ < n; ++k$) {
|
|
1202
|
+
i = k$;
|
|
1203
|
+
y = line[idx];
|
|
1204
|
+
filt = y * (1 - damp) + filt * damp;
|
|
1205
|
+
line[idx] = input[i] + filt * fb;
|
|
1206
|
+
idx = (idx + 1) % len;
|
|
1207
|
+
wet[i] += y;
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
for (j$ = 0, len1$ = (ref1$ = ALLPASS).length; j$ < len1$; ++j$) {
|
|
1211
|
+
c = ref1$[j$];
|
|
1212
|
+
len = Math.round((c + ch * 23) * k);
|
|
1213
|
+
line = new Float32Array(len);
|
|
1214
|
+
idx = 0;
|
|
1215
|
+
for (k$ = 0; k$ < n; ++k$) {
|
|
1216
|
+
i = k$;
|
|
1217
|
+
b = line[idx];
|
|
1218
|
+
v = wet[i];
|
|
1219
|
+
line[idx] = v + b * 0.5;
|
|
1220
|
+
wet[i] = b - v;
|
|
1221
|
+
idx = (idx + 1) % len;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
dry = src[ch];
|
|
1225
|
+
for (j$ = 0; j$ < n; ++j$) {
|
|
1226
|
+
i = j$;
|
|
1227
|
+
lresult$.push(out[i] = (i < m ? dry[i] * (1 - mix * 0.5) : 0) + wet[i] * mix * 3);
|
|
1228
|
+
}
|
|
1229
|
+
results$.push(lresult$);
|
|
1230
|
+
}
|
|
1231
|
+
return results$;
|
|
1232
|
+
});
|
|
1233
|
+
};
|
|
1234
|
+
S.reverb = function(buf, o){
|
|
1235
|
+
o == null && (o = {});
|
|
1236
|
+
return reverb(buf, o.mix != null ? o.mix : 0.3, o.room != null ? o.room : 0.5);
|
|
1237
|
+
};
|
|
1238
|
+
synth.slide = function(o){
|
|
1239
|
+
var dur, f0, f1, q, dir;
|
|
1240
|
+
o == null && (o = {});
|
|
1241
|
+
dur = o.dur || 0.3;
|
|
1242
|
+
f0 = o.from || 900;
|
|
1243
|
+
f1 = o.to || 2600;
|
|
1244
|
+
q = o.q || 0.9;
|
|
1245
|
+
dir = o.dir != null ? o.dir : 1;
|
|
1246
|
+
return make(dur, function(L, R, n){
|
|
1247
|
+
var d, i$, i, u, a, p, results$ = [];
|
|
1248
|
+
d = biquadTv(noise(n, rng(o.seed || 37)), 'bp', function(u){
|
|
1249
|
+
return f0 * Math.pow(f1 / f0, u);
|
|
1250
|
+
}, q);
|
|
1251
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1252
|
+
i = i$;
|
|
1253
|
+
u = i / n;
|
|
1254
|
+
a = u < 0.25
|
|
1255
|
+
? Math.sin(Math.PI / 2 * u / 0.25)
|
|
1256
|
+
: Math.pow(Math.cos(Math.PI / 2 * (u - 0.25) / 0.75), 2);
|
|
1257
|
+
p = (u * 2 - 1) * 0.6 * dir;
|
|
1258
|
+
L[i] = d[i] * a * Math.cos((p + 1) * Math.PI / 4);
|
|
1259
|
+
results$.push(R[i] = d[i] * a * Math.sin((p + 1) * Math.PI / 4));
|
|
1260
|
+
}
|
|
1261
|
+
return results$;
|
|
1262
|
+
});
|
|
1263
|
+
};
|
|
1264
|
+
glide = function(o, d0, d1){
|
|
1265
|
+
var dur, f0, f1;
|
|
1266
|
+
dur = o.dur || 0.6;
|
|
1267
|
+
f0 = S.freq(o.from || d0);
|
|
1268
|
+
f1 = S.freq(o.to || d1);
|
|
1269
|
+
return make(dur, function(L, R, n){
|
|
1270
|
+
var d, i$, i, t;
|
|
1271
|
+
d = glideOsc(n, f0, f1, [1, 0.25, 0.08]);
|
|
1272
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1273
|
+
i = i$;
|
|
1274
|
+
t = i / SR;
|
|
1275
|
+
d[i] *= Math.min(1, t / 0.02) * Math.min(1, (dur - t) / (dur * 0.35));
|
|
1276
|
+
}
|
|
1277
|
+
return pan(L, R, d, o.pan);
|
|
1278
|
+
});
|
|
1279
|
+
};
|
|
1280
|
+
synth.rise = function(o){
|
|
1281
|
+
o == null && (o = {});
|
|
1282
|
+
return glide(o, 300, 900);
|
|
1283
|
+
};
|
|
1284
|
+
synth.fall = function(o){
|
|
1285
|
+
o == null && (o = {});
|
|
1286
|
+
return glide(o, 900, 250);
|
|
1287
|
+
};
|
|
1288
|
+
synth.count = function(o){
|
|
1289
|
+
var cnt, dur, f, climb, ease;
|
|
1290
|
+
o == null && (o = {});
|
|
1291
|
+
cnt = Math.max(2, o.n || 12);
|
|
1292
|
+
dur = o.dur || 1.2;
|
|
1293
|
+
f = S.freq(o.note || 'C6');
|
|
1294
|
+
climb = o.climb != null ? o.climb : 7;
|
|
1295
|
+
ease = (function(){
|
|
1296
|
+
switch (o.ease) {
|
|
1297
|
+
case 'in':
|
|
1298
|
+
return function(u){
|
|
1299
|
+
return u * u;
|
|
1300
|
+
};
|
|
1301
|
+
case 'linear':
|
|
1302
|
+
return function(u){
|
|
1303
|
+
return u;
|
|
1304
|
+
};
|
|
1305
|
+
default:
|
|
1306
|
+
return function(u){
|
|
1307
|
+
return 1 - (1 - u) * (1 - u);
|
|
1308
|
+
};
|
|
1309
|
+
}
|
|
1310
|
+
}());
|
|
1311
|
+
return make(dur + 0.2, function(L, R, n){
|
|
1312
|
+
var d, i$, to$, k, u, last, ff;
|
|
1313
|
+
d = new Float32Array(n);
|
|
1314
|
+
for (i$ = 0, to$ = cnt; i$ < to$; ++i$) {
|
|
1315
|
+
k = i$;
|
|
1316
|
+
u = k / (cnt - 1);
|
|
1317
|
+
last = k === cnt - 1;
|
|
1318
|
+
ff = f * Math.pow(2, climb * u / 12);
|
|
1319
|
+
partial(d, dur * ease(u), ff, last ? 1 : 0.6, last ? 0.09 : 0.02);
|
|
1320
|
+
if (last) {
|
|
1321
|
+
partial(d, dur, ff * 2, 0.3, 0.06);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
return pan(L, R, d, o.pan);
|
|
1325
|
+
});
|
|
1326
|
+
};
|
|
1327
|
+
synth.snap = function(o){
|
|
1328
|
+
o == null && (o = {});
|
|
1329
|
+
return make(0.1, function(L, R, n){
|
|
1330
|
+
var nz, d, i$, i, t;
|
|
1331
|
+
nz = biquad(noise(n, rng(o.seed || 41)), 'lp', 6000);
|
|
1332
|
+
d = new Float32Array(n);
|
|
1333
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1334
|
+
i = i$;
|
|
1335
|
+
t = i / SR;
|
|
1336
|
+
d[i] = 0.8 * nz[i] * env(t, 0.0003, 0.002) + 0.6 * Math.sin(2 * Math.PI * 1400 * t) * env(t, 0.0005, 0.01) + Math.sin(2 * Math.PI * 160 * t) * env(t, 0.001, 0.025);
|
|
1337
|
+
}
|
|
1338
|
+
return pan(L, R, d, o.pan);
|
|
1339
|
+
});
|
|
1340
|
+
};
|
|
1341
|
+
synth.draw = function(o){
|
|
1342
|
+
var dur, rough;
|
|
1343
|
+
o == null && (o = {});
|
|
1344
|
+
dur = o.dur || 1;
|
|
1345
|
+
rough = o.rough != null ? o.rough : 0.5;
|
|
1346
|
+
return make(dur, function(L, R, n){
|
|
1347
|
+
var r, d, speed, grain, i$, i, t, g;
|
|
1348
|
+
r = rng(o.seed || 43);
|
|
1349
|
+
d = biquad(biquad(noise(n, r), 'bp', o.pitch || 2500, 0.8), 'hp', 600);
|
|
1350
|
+
speed = wander(n, 0.06, r);
|
|
1351
|
+
grain = wander(n, 0.004, r);
|
|
1352
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1353
|
+
i = i$;
|
|
1354
|
+
t = i / SR;
|
|
1355
|
+
g = grain[i] * grain[i];
|
|
1356
|
+
d[i] *= (0.3 + 0.7 * speed[i]) * (1 - rough + rough * g * 2) * Math.min(1, t / 0.03, (dur - t) / 0.05);
|
|
1357
|
+
}
|
|
1358
|
+
return pan(L, R, d, o.pan);
|
|
1359
|
+
});
|
|
1360
|
+
};
|
|
1361
|
+
synth.glitch = function(o){
|
|
1362
|
+
var dur;
|
|
1363
|
+
o == null && (o = {});
|
|
1364
|
+
dur = o.dur || 0.5;
|
|
1365
|
+
return make(dur, function(L, R, n){
|
|
1366
|
+
var r, i, len, kind, f, hold, p, gl, gr, v, i$, to$, j, t, x, results$ = [];
|
|
1367
|
+
r = rng(o.seed || 47);
|
|
1368
|
+
i = 0;
|
|
1369
|
+
while (i < n) {
|
|
1370
|
+
len = Math.round((0.015 + 0.05 * r()) * SR);
|
|
1371
|
+
kind = r();
|
|
1372
|
+
f = 100 + 1900 * r() * r();
|
|
1373
|
+
hold = 1 + Math.floor(r() * 40);
|
|
1374
|
+
p = r() * 1.6 - 0.8;
|
|
1375
|
+
gl = Math.cos((p + 1) * Math.PI / 4);
|
|
1376
|
+
gr = Math.sin((p + 1) * Math.PI / 4);
|
|
1377
|
+
v = 0;
|
|
1378
|
+
for (i$ = i, to$ = Math.min(n, i + len); i$ < to$; ++i$) {
|
|
1379
|
+
j = i$;
|
|
1380
|
+
t = (j - i) / SR;
|
|
1381
|
+
x = kind < 0.4
|
|
1382
|
+
? Math.sin(2 * Math.PI * f * t) > 0
|
|
1383
|
+
? 0.6
|
|
1384
|
+
: -0.6
|
|
1385
|
+
: kind < 0.8 ? (j - i) % hold === 0 ? v = r() * 2 - 1 : v : 0;
|
|
1386
|
+
L[j] = x * gl;
|
|
1387
|
+
R[j] = x * gr;
|
|
1388
|
+
}
|
|
1389
|
+
results$.push(i += len);
|
|
1390
|
+
}
|
|
1391
|
+
return results$;
|
|
1392
|
+
});
|
|
1393
|
+
};
|
|
1394
|
+
synth.reveal = function(o){
|
|
1395
|
+
var notes, gap;
|
|
1396
|
+
o == null && (o = {});
|
|
1397
|
+
notes = (o.notes || ['C6', 'E6', 'G6', 'C7', 'E7']).map(S.freq);
|
|
1398
|
+
gap = o.gap != null ? o.gap : 0.06;
|
|
1399
|
+
return make(1.6, function(L, R, n){
|
|
1400
|
+
var d, i$, ref$, len$, k, f, sh, i, t;
|
|
1401
|
+
d = new Float32Array(n);
|
|
1402
|
+
for (i$ = 0, len$ = (ref$ = notes).length; i$ < len$; ++i$) {
|
|
1403
|
+
k = i$;
|
|
1404
|
+
f = ref$[i$];
|
|
1405
|
+
partial(d, k * gap, f, 1, 0.5);
|
|
1406
|
+
partial(d, k * gap, f * 2.76, 0.25, 0.15);
|
|
1407
|
+
}
|
|
1408
|
+
sh = biquad(noise(n, rng(o.seed || 53)), 'hp', 6000);
|
|
1409
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1410
|
+
i = i$;
|
|
1411
|
+
t = i / SR;
|
|
1412
|
+
d[i] += sh[i] * 0.12 * env(t, 0.25, 0.3);
|
|
1413
|
+
}
|
|
1414
|
+
return pan(L, R, d, o.pan);
|
|
1415
|
+
});
|
|
1416
|
+
};
|
|
1417
|
+
synth.reveal.reverb = 0.35;
|
|
1418
|
+
synth.error = function(o){
|
|
1419
|
+
var notes;
|
|
1420
|
+
o == null && (o = {});
|
|
1421
|
+
notes = [S.freq(o.from || 'B3'), S.freq(o.to || 'F3')];
|
|
1422
|
+
return make(0.5, function(L, R, n){
|
|
1423
|
+
var d, i$, ref$, len$, k, f, j$, h;
|
|
1424
|
+
d = new Float32Array(n);
|
|
1425
|
+
for (i$ = 0, len$ = (ref$ = notes).length; i$ < len$; ++i$) {
|
|
1426
|
+
k = i$;
|
|
1427
|
+
f = ref$[i$];
|
|
1428
|
+
for (j$ = 1; j$ <= 7; j$ += 2) {
|
|
1429
|
+
h = j$;
|
|
1430
|
+
partial(d, k * 0.16, f * h, 1 / h, 0.12, 0.005);
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
fadeOut(biquad(d, 'lp', 2000));
|
|
1434
|
+
return pan(L, R, d, o.pan);
|
|
1435
|
+
});
|
|
1436
|
+
};
|
|
1437
|
+
synth.tension = function(o){
|
|
1438
|
+
var dur, f;
|
|
1439
|
+
o == null && (o = {});
|
|
1440
|
+
dur = o.dur || 6;
|
|
1441
|
+
f = S.freq(o.note || 'A2');
|
|
1442
|
+
return make(dur, function(L, R, n){
|
|
1443
|
+
var i$, ref$, len$, k, ratio, d, ph, tp, j$, i, t, u, results$ = [];
|
|
1444
|
+
for (i$ = 0, len$ = (ref$ = [1, Math.pow(2, 1 / 12), Math.pow(2, 6 / 12), 2]).length; i$ < len$; ++i$) {
|
|
1445
|
+
k = i$;
|
|
1446
|
+
ratio = ref$[i$];
|
|
1447
|
+
d = new Float32Array(n);
|
|
1448
|
+
ph = 0;
|
|
1449
|
+
tp = 0;
|
|
1450
|
+
for (j$ = 0; j$ < n; ++j$) {
|
|
1451
|
+
i = j$;
|
|
1452
|
+
t = i / SR;
|
|
1453
|
+
u = t / dur;
|
|
1454
|
+
tp += 2 * Math.PI * (3 + 5 * u) / SR;
|
|
1455
|
+
ph += 2 * Math.PI * f * ratio / SR;
|
|
1456
|
+
d[i] = (Math.sin(ph) + 0.3 * Math.sin(ph * 2) + 0.15 * Math.sin(ph * 3)) * (1 - 0.35 * (0.5 + 0.5 * Math.sin(tp + k))) * Math.pow(u, 1.5) * Math.min(1, (dur - t) / 0.3);
|
|
1457
|
+
}
|
|
1458
|
+
results$.push(pan(L, R, d, (k - 1.5) * 0.4, 0.5));
|
|
1459
|
+
}
|
|
1460
|
+
return results$;
|
|
1461
|
+
});
|
|
1462
|
+
};
|
|
1463
|
+
synth.heartbeat = function(o){
|
|
1464
|
+
var dur, period;
|
|
1465
|
+
o == null && (o = {});
|
|
1466
|
+
dur = o.dur || 4;
|
|
1467
|
+
period = 60 / (o.bpm || 70);
|
|
1468
|
+
return make(dur, function(L, R, n){
|
|
1469
|
+
var d, t, i$, ref$, len$, ref1$, at, f0, f1, a, m, o0, b, j$, to$, i;
|
|
1470
|
+
d = new Float32Array(n);
|
|
1471
|
+
t = 0.05;
|
|
1472
|
+
while (t < dur - 0.2) {
|
|
1473
|
+
for (i$ = 0, len$ = (ref$ = [[0, 75, 45, 1], [Math.min(0.3, period * 0.35), 85, 55, 0.7]]).length; i$ < len$; ++i$) {
|
|
1474
|
+
ref1$ = ref$[i$], at = ref1$[0], f0 = ref1$[1], f1 = ref1$[2], a = ref1$[3];
|
|
1475
|
+
m = Math.round(0.25 * SR);
|
|
1476
|
+
o0 = Math.round((t + at) * SR);
|
|
1477
|
+
b = glideOsc(m, f0, f1);
|
|
1478
|
+
for (j$ = 0, to$ = Math.min(m, n - o0); j$ < to$; ++j$) {
|
|
1479
|
+
i = j$;
|
|
1480
|
+
d[o0 + i] += b[i] * a * env(i / SR, 0.008, 0.06);
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
t += period;
|
|
1484
|
+
}
|
|
1485
|
+
return pan(L, R, biquad(d, 'lp', 300), o.pan);
|
|
1486
|
+
});
|
|
1487
|
+
};
|
|
1488
|
+
synth.clock = function(o){
|
|
1489
|
+
var dur, period;
|
|
1490
|
+
o == null && (o = {});
|
|
1491
|
+
dur = o.dur || 4;
|
|
1492
|
+
period = 60 / (o.bpm || 60);
|
|
1493
|
+
return make(dur, function(L, R, n){
|
|
1494
|
+
var d, nz, k, t, f, o0, i$, to$, i;
|
|
1495
|
+
d = new Float32Array(n);
|
|
1496
|
+
nz = biquad(noise(n, rng(o.seed || 59)), 'hp', 2000);
|
|
1497
|
+
k = 0;
|
|
1498
|
+
t = 0.02;
|
|
1499
|
+
while (t < dur - 0.05) {
|
|
1500
|
+
f = k % 2 ? 2400 : 3200;
|
|
1501
|
+
partial(d, t, f, 0.6, 0.012);
|
|
1502
|
+
partial(d, t, f * 1.5, 0.3, 0.006);
|
|
1503
|
+
o0 = Math.round(t * SR);
|
|
1504
|
+
for (i$ = 0, to$ = Math.min(Math.round(0.002 * SR), n - o0); i$ < to$; ++i$) {
|
|
1505
|
+
i = i$;
|
|
1506
|
+
d[o0 + i] += nz[o0 + i] * 0.8;
|
|
1507
|
+
}
|
|
1508
|
+
t += period;
|
|
1509
|
+
k++;
|
|
1510
|
+
}
|
|
1511
|
+
return pan(L, R, d, o.pan);
|
|
1512
|
+
});
|
|
1513
|
+
};
|
|
1514
|
+
grain = function(L, R, r, at, len, fc, q, amp, p){
|
|
1515
|
+
var m, g, o0, gl, gr, i$, to$, i, e, results$ = [];
|
|
1516
|
+
p == null && (p = 0);
|
|
1517
|
+
m = Math.max(4, Math.round(len * SR));
|
|
1518
|
+
g = noise(m, r);
|
|
1519
|
+
biquad(g, 'bp', fc, q);
|
|
1520
|
+
o0 = Math.round(at * SR);
|
|
1521
|
+
gl = Math.cos((p + 1) * Math.PI / 4) * amp;
|
|
1522
|
+
gr = Math.sin((p + 1) * Math.PI / 4) * amp;
|
|
1523
|
+
for (i$ = 0, to$ = Math.min(m, L.length - o0); i$ < to$; ++i$) {
|
|
1524
|
+
i = i$;
|
|
1525
|
+
e = Math.exp(-4 * i / m) * Math.min(1, i / 8);
|
|
1526
|
+
L[o0 + i] += g[i] * e * gl;
|
|
1527
|
+
results$.push(R[o0 + i] += g[i] * e * gr);
|
|
1528
|
+
}
|
|
1529
|
+
return results$;
|
|
1530
|
+
};
|
|
1531
|
+
pick = function(r, w){
|
|
1532
|
+
var i$, k, u;
|
|
1533
|
+
for (i$ = 0; i$ < 50; ++i$) {
|
|
1534
|
+
k = i$;
|
|
1535
|
+
u = r();
|
|
1536
|
+
if (r() < w(u)) {
|
|
1537
|
+
return u;
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
return r();
|
|
1541
|
+
};
|
|
1542
|
+
synth.paper = function(o){
|
|
1543
|
+
var dur, crisp, flutter, lift, land;
|
|
1544
|
+
o == null && (o = {});
|
|
1545
|
+
dur = o.dur || 1.2;
|
|
1546
|
+
crisp = o.crisp != null ? o.crisp : 1;
|
|
1547
|
+
flutter = o.flutter != null ? o.flutter : 0.6;
|
|
1548
|
+
lift = dur * 0.2;
|
|
1549
|
+
land = dur * 0.8;
|
|
1550
|
+
return make(dur, function(L, R, n){
|
|
1551
|
+
var r, flip, fl, fl2, i$, ref$, len$, c, ch, p, sl, j$, i, t, shake, a, s, d, to$, k, results$ = [];
|
|
1552
|
+
r = rng(o.seed || 61);
|
|
1553
|
+
flip = function(t){
|
|
1554
|
+
if (t < lift * 0.5 || t > land + 0.02) {
|
|
1555
|
+
return 0;
|
|
1556
|
+
} else {
|
|
1557
|
+
return Math.pow(Math.min(1, (t - lift * 0.5) / (land - lift * 0.5)), 0.7);
|
|
1558
|
+
}
|
|
1559
|
+
};
|
|
1560
|
+
fl = wander(n, 0.035, r);
|
|
1561
|
+
fl2 = wander(n, 0.09, r);
|
|
1562
|
+
for (i$ = 0, len$ = (ref$ = [L, R]).length; i$ < len$; ++i$) {
|
|
1563
|
+
c = i$;
|
|
1564
|
+
ch = ref$[i$];
|
|
1565
|
+
p = pink(n, r);
|
|
1566
|
+
sl = biquad(noise(n, r), 'bp', 4000, 0.7);
|
|
1567
|
+
for (j$ = 0; j$ < n; ++j$) {
|
|
1568
|
+
i = j$;
|
|
1569
|
+
t = i / SR;
|
|
1570
|
+
shake = 1 - flutter + flutter * (fl[i] * 0.7 + fl2[i] * 0.6);
|
|
1571
|
+
a = flip(t) * shake;
|
|
1572
|
+
s = t < lift
|
|
1573
|
+
? Math.sin(Math.PI / 2 * t / lift) * 0.25
|
|
1574
|
+
: t < land ? 0.25 * Math.max(0, 1 - (t - lift) / lift) : 0;
|
|
1575
|
+
d = t >= land ? env(t - land, 0.006, 0.07) * 1.1 + 0.25 * Math.max(0, 1 - (t - land) / (dur - land)) : 0;
|
|
1576
|
+
ch[i] = p[i] * (a * 0.8 + d) + sl[i] * s;
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
for (i$ = 0, to$ = Math.round(50 * dur * crisp); i$ < to$; ++i$) {
|
|
1580
|
+
k = i$;
|
|
1581
|
+
t = lift * 0.5 + (land - lift * 0.5) * pick(r, fn$);
|
|
1582
|
+
grain(L, R, r, t, 0.0002 + 0.0008 * r(), 1500 * Math.pow(5, r()), 0.5, (0.1 + r() * r()) * 8, r() * 0.6 - 0.3);
|
|
1583
|
+
}
|
|
1584
|
+
for (i$ = 0, len$ = (ref$ = [L, R]).length; i$ < len$; ++i$) {
|
|
1585
|
+
ch = ref$[i$];
|
|
1586
|
+
biquad(ch, 'hp', 150);
|
|
1587
|
+
biquad(ch, 'lp', 7500, 0.6);
|
|
1588
|
+
results$.push(fadeOut(ch, 0.05));
|
|
1589
|
+
}
|
|
1590
|
+
return results$;
|
|
1591
|
+
function fn$(u){
|
|
1592
|
+
return 0.3 + 0.7 * u;
|
|
1593
|
+
}
|
|
1594
|
+
});
|
|
1595
|
+
};
|
|
1596
|
+
bubble = function(L, R, at, radius, amp, rise, p, damp){
|
|
1597
|
+
var f0, d, m, o0, gl, gr, ph, i$, i, t, v, results$ = [];
|
|
1598
|
+
damp == null && (damp = 1);
|
|
1599
|
+
f0 = 3000 / radius;
|
|
1600
|
+
d = (0.043 * f0 + 0.0014 * Math.pow(f0, 1.5)) * damp;
|
|
1601
|
+
m = Math.min(Math.round(6 / d * SR), L.length - Math.round(at * SR));
|
|
1602
|
+
o0 = Math.round(at * SR);
|
|
1603
|
+
gl = Math.cos((p + 1) * Math.PI / 4) * amp;
|
|
1604
|
+
gr = Math.sin((p + 1) * Math.PI / 4) * amp;
|
|
1605
|
+
ph = 0;
|
|
1606
|
+
for (i$ = 0; i$ < m; ++i$) {
|
|
1607
|
+
i = i$;
|
|
1608
|
+
t = i / SR;
|
|
1609
|
+
ph += 2 * Math.PI * f0 * (1 + rise * d * t) / SR;
|
|
1610
|
+
v = Math.sin(ph) * Math.exp(-d * t) * Math.min(1, i / 24);
|
|
1611
|
+
L[o0 + i] += v * gl;
|
|
1612
|
+
results$.push(R[o0 + i] += v * gr);
|
|
1613
|
+
}
|
|
1614
|
+
return results$;
|
|
1615
|
+
};
|
|
1616
|
+
synth.water = function(o){
|
|
1617
|
+
var cnt, rise, size, dur;
|
|
1618
|
+
o == null && (o = {});
|
|
1619
|
+
cnt = o.n || 1;
|
|
1620
|
+
rise = o.rise != null
|
|
1621
|
+
? o.rise
|
|
1622
|
+
: cnt === 1 ? 0.05 : 0.1;
|
|
1623
|
+
size = o.size || (o.freq
|
|
1624
|
+
? 3000 / S.freq(o.freq)
|
|
1625
|
+
: cnt === 1 ? 3 : 2.5);
|
|
1626
|
+
dur = o.dur || (cnt === 1
|
|
1627
|
+
? 0.4
|
|
1628
|
+
: Math.max(1, cnt * 0.04));
|
|
1629
|
+
return make(dur, function(L, R, n){
|
|
1630
|
+
var r, i$, to$, k, radius, at, results$ = [];
|
|
1631
|
+
r = rng(o.seed || 67);
|
|
1632
|
+
if (cnt === 1) {
|
|
1633
|
+
grain(L, R, r, 0.005, 0.001, 3000, 0.8, 0.25);
|
|
1634
|
+
bubble(L, R, 0.007, size, 1, rise, 0, 0.4);
|
|
1635
|
+
bubble(L, R, 0.012, size * 0.4, 0.12, rise, 0.1);
|
|
1636
|
+
return;
|
|
1637
|
+
}
|
|
1638
|
+
for (i$ = 0, to$ = cnt; i$ < to$; ++i$) {
|
|
1639
|
+
k = i$;
|
|
1640
|
+
radius = size * (0.25 + 1.75 * Math.pow(r(), 2.5));
|
|
1641
|
+
at = r() * (dur - 0.1);
|
|
1642
|
+
results$.push(bubble(L, R, at, radius, Math.pow(radius / size, 0.7) * (0.3 + 0.7 * r()), rise * (0.5 + r()), r() * 1.4 - 0.7));
|
|
1643
|
+
}
|
|
1644
|
+
return results$;
|
|
1645
|
+
});
|
|
1646
|
+
};
|
|
1647
|
+
synth.fire = function(o){
|
|
1648
|
+
var dur, density;
|
|
1649
|
+
o == null && (o = {});
|
|
1650
|
+
dur = o.dur || 6;
|
|
1651
|
+
density = o.density != null ? o.density : 1;
|
|
1652
|
+
return make(dur, function(L, R, n){
|
|
1653
|
+
var r, bed, hiss, sw, i$, i, a, cnt, k, lresult$, at, amp, len, p, gl, gr, j$, v, results$ = [];
|
|
1654
|
+
r = rng(o.seed || 71);
|
|
1655
|
+
bed = biquad(noise(n, r), 'lp', 300);
|
|
1656
|
+
hiss = biquad(noise(n, r), 'hp', 3000);
|
|
1657
|
+
sw = wander(n, 0.25, r);
|
|
1658
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1659
|
+
i = i$;
|
|
1660
|
+
a = (0.4 + 0.6 * sw[i]) * Math.min(1, i / SR / 0.3, (n - i) / SR / 0.3);
|
|
1661
|
+
L[i] = R[i] = (bed[i] * 0.5 + hiss[i] * 0.04) * a;
|
|
1662
|
+
}
|
|
1663
|
+
cnt = Math.round(dur * 10 * density);
|
|
1664
|
+
for (i$ = 0; i$ < cnt; ++i$) {
|
|
1665
|
+
k = i$;
|
|
1666
|
+
lresult$ = [];
|
|
1667
|
+
at = Math.round(r() * (n - 0.01 * SR));
|
|
1668
|
+
amp = r() * r() * 1.5;
|
|
1669
|
+
len = Math.round((0.0005 + 0.003 * r()) * SR);
|
|
1670
|
+
p = r() * 1.6 - 0.8;
|
|
1671
|
+
gl = Math.cos((p + 1) * Math.PI / 4);
|
|
1672
|
+
gr = Math.sin((p + 1) * Math.PI / 4);
|
|
1673
|
+
for (j$ = 0; j$ < len; ++j$) {
|
|
1674
|
+
i = j$;
|
|
1675
|
+
v = (r() * 2 - 1) * amp * (1 - i / len);
|
|
1676
|
+
L[at + i] += v * gl;
|
|
1677
|
+
lresult$.push(R[at + i] += v * gr);
|
|
1678
|
+
}
|
|
1679
|
+
results$.push(lresult$);
|
|
1680
|
+
}
|
|
1681
|
+
return results$;
|
|
1682
|
+
});
|
|
1683
|
+
};
|
|
1684
|
+
SURFACE = {
|
|
1685
|
+
wood: {
|
|
1686
|
+
thud: 1,
|
|
1687
|
+
tones: [140, 380, 620],
|
|
1688
|
+
click: [[2200, 1.2, 0.012, 0.5]]
|
|
1689
|
+
},
|
|
1690
|
+
concrete: {
|
|
1691
|
+
thud: 0.04,
|
|
1692
|
+
tones: [],
|
|
1693
|
+
click: [[700, 0.8, 0.003, 1.6], [2600, 1.2, 0.002, 0.15]],
|
|
1694
|
+
scuff: 0.06
|
|
1695
|
+
},
|
|
1696
|
+
gravel: {
|
|
1697
|
+
thud: 0.45,
|
|
1698
|
+
grains: 90,
|
|
1699
|
+
band: [1200, 6000],
|
|
1700
|
+
len: [0.0004, 0.002],
|
|
1701
|
+
q: 1.5
|
|
1702
|
+
},
|
|
1703
|
+
snow: {
|
|
1704
|
+
thud: 0.35,
|
|
1705
|
+
grains: 70,
|
|
1706
|
+
band: [500, 2200],
|
|
1707
|
+
len: [0.002, 0.007],
|
|
1708
|
+
q: 0.8
|
|
1709
|
+
},
|
|
1710
|
+
grass: {
|
|
1711
|
+
thud: 0.25,
|
|
1712
|
+
grains: 90,
|
|
1713
|
+
band: [2500, 8000],
|
|
1714
|
+
len: [0.0005, 0.003],
|
|
1715
|
+
q: 1.2
|
|
1716
|
+
}
|
|
1717
|
+
};
|
|
1718
|
+
synth.steps = function(o){
|
|
1719
|
+
var run, cnt, pace, sf;
|
|
1720
|
+
o == null && (o = {});
|
|
1721
|
+
run = o.gait === 'run';
|
|
1722
|
+
cnt = o.n || 4;
|
|
1723
|
+
pace = o.pace || (run ? 0.3 : 0.5);
|
|
1724
|
+
sf = SURFACE[o.surface] || SURFACE.wood;
|
|
1725
|
+
return make(cnt * pace + 0.35, function(L, R, n){
|
|
1726
|
+
var r, lp, i$, to$, k, lresult$, T, w, p, gl, gr, toe, j$, ref$, len$, ref1$, at, a, o0, m, d, k$, i, t, len1$, f, ref2$, fc, q, dec, amp, c, l$, sc, s, to1$, e, j, f0, f1, l0, l1, results$ = [];
|
|
1727
|
+
r = rng(o.seed || 73);
|
|
1728
|
+
lp = biquad(noise(n, r), 'lp', 260);
|
|
1729
|
+
for (i$ = 0, to$ = cnt; i$ < to$; ++i$) {
|
|
1730
|
+
k = i$;
|
|
1731
|
+
lresult$ = [];
|
|
1732
|
+
T = 0.02 + k * pace + (r() - 0.5) * (run ? 0.01 : 0.02);
|
|
1733
|
+
w = (run ? 1.15 : 0.85) + 0.3 * r();
|
|
1734
|
+
p = k % 2
|
|
1735
|
+
? 0.12
|
|
1736
|
+
: -0.12;
|
|
1737
|
+
gl = Math.cos((p + 1) * Math.PI / 4);
|
|
1738
|
+
gr = Math.sin((p + 1) * Math.PI / 4);
|
|
1739
|
+
toe = run
|
|
1740
|
+
? 0.025 + 0.015 * r()
|
|
1741
|
+
: 0.09 + 0.04 * r();
|
|
1742
|
+
for (j$ = 0, len$ = (ref$ = run
|
|
1743
|
+
? [[0, w * 0.8], [toe, w]]
|
|
1744
|
+
: [[0, w], [toe, w * 0.55]]).length; j$ < len$; ++j$) {
|
|
1745
|
+
ref1$ = ref$[j$], at = ref1$[0], a = ref1$[1];
|
|
1746
|
+
o0 = Math.round((T + at) * SR);
|
|
1747
|
+
m = Math.min(Math.round(0.15 * SR), n - o0);
|
|
1748
|
+
d = new Float32Array(m);
|
|
1749
|
+
for (k$ = 0; k$ < m; ++k$) {
|
|
1750
|
+
i = k$;
|
|
1751
|
+
t = i / SR;
|
|
1752
|
+
d[i] = lp[o0 + i] * 2.5 * sf.thud * env(t, 0.003, 0.025) + 0.5 * sf.thud * Math.sin(2 * Math.PI * (75 + 20 * a) * t) * env(t, 0.002, 0.03);
|
|
1753
|
+
}
|
|
1754
|
+
for (k$ = 0, len1$ = (ref1$ = sf.tones || []).length; k$ < len1$; ++k$) {
|
|
1755
|
+
f = ref1$[k$];
|
|
1756
|
+
partial(d, 0, f * (0.95 + 0.1 * r()), 0.12, 0.035);
|
|
1757
|
+
}
|
|
1758
|
+
for (k$ = 0, len1$ = (ref1$ = sf.click || []).length; k$ < len1$; ++k$) {
|
|
1759
|
+
ref2$ = ref1$[k$], fc = ref2$[0], q = ref2$[1], dec = ref2$[2], amp = ref2$[3];
|
|
1760
|
+
c = biquad(noise(m, r), 'bp', fc * (0.85 + 0.3 * r()), q);
|
|
1761
|
+
for (l$ = 0; l$ < m; ++l$) {
|
|
1762
|
+
i = l$;
|
|
1763
|
+
d[i] += c[i] * amp * env(i / SR, 0.0004, dec);
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
for (k$ = 0; k$ < m; ++k$) {
|
|
1767
|
+
i = k$;
|
|
1768
|
+
L[o0 + i] += d[i] * a * gl;
|
|
1769
|
+
R[o0 + i] += d[i] * a * gr;
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
sc = (sf.scuff || 0.1) * (run ? 2.5 : 1);
|
|
1773
|
+
if (sf.scuff || run) {
|
|
1774
|
+
o0 = Math.round((T + (run ? toe + 0.03 : 0.02)) * SR);
|
|
1775
|
+
s = biquad(noise(Math.round((run ? 0.07 : 0.12) * SR), r), 'bp', 2800, 0.8);
|
|
1776
|
+
for (j$ = 0, to1$ = Math.min(s.length, n - o0); j$ < to1$; ++j$) {
|
|
1777
|
+
i = j$;
|
|
1778
|
+
e = Math.sin(Math.PI * i / s.length) * sc * w * 0.3;
|
|
1779
|
+
L[o0 + i] += s[i] * e * gl;
|
|
1780
|
+
R[o0 + i] += s[i] * e * gr;
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
if (sf.grains) {
|
|
1784
|
+
for (j$ = 0, to1$ = Math.round(sf.grains * w); j$ < to1$; ++j$) {
|
|
1785
|
+
j = j$;
|
|
1786
|
+
at = r() < 0.6
|
|
1787
|
+
? 0.07 * Math.pow(r(), 1.5)
|
|
1788
|
+
: toe + 0.09 * Math.pow(r(), 1.5);
|
|
1789
|
+
ref$ = sf.band, f0 = ref$[0], f1 = ref$[1];
|
|
1790
|
+
ref$ = sf.len, l0 = ref$[0], l1 = ref$[1];
|
|
1791
|
+
lresult$.push(grain(L, R, r, T + at, l0 + (l1 - l0) * r(), f0 * Math.pow(f1 / f0, r()), sf.q, (0.15 + r() * r()) * 0.8 * w, p + r() * 0.3 - 0.15));
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
results$.push(lresult$);
|
|
1795
|
+
}
|
|
1796
|
+
return results$;
|
|
1797
|
+
});
|
|
1798
|
+
};
|
|
1799
|
+
synth.bell = function(o){
|
|
1800
|
+
var f, dur;
|
|
1801
|
+
o == null && (o = {});
|
|
1802
|
+
f = S.freq(o.note || 'C5');
|
|
1803
|
+
dur = o.dur || 5;
|
|
1804
|
+
return make(dur, function(L, R, n){
|
|
1805
|
+
var d, i$, ref$, len$, ref1$, ratio, amp, dec;
|
|
1806
|
+
d = new Float32Array(n);
|
|
1807
|
+
for (i$ = 0, len$ = (ref$ = [[0.5, 0.5, 1], [1, 1, 0.7], [1.2, 0.55, 0.5], [1.5, 0.35, 0.4], [2, 0.6, 0.35], [2.51, 0.25, 0.25], [2.66, 0.2, 0.22], [3.01, 0.18, 0.18], [4.17, 0.1, 0.12], [5.43, 0.06, 0.08]]).length; i$ < len$; ++i$) {
|
|
1808
|
+
ref1$ = ref$[i$], ratio = ref1$[0], amp = ref1$[1], dec = ref1$[2];
|
|
1809
|
+
partial(d, 0, f * ratio, amp, dec * dur * 0.45, 0.002);
|
|
1810
|
+
partial(d, 0, f * ratio * 1.0015, amp * 0.5, dec * dur * 0.45, 0.002);
|
|
1811
|
+
}
|
|
1812
|
+
return pan(L, R, fadeOut(d, 0.1), o.pan);
|
|
1813
|
+
});
|
|
1814
|
+
};
|
|
1815
|
+
synth.bell.reverb = 0.2;
|
|
1816
|
+
pink = function(n, r){
|
|
1817
|
+
var d, b0, b1, b2, b3, b4, b5, b6, i$, i, w;
|
|
1818
|
+
d = new Float32Array(n);
|
|
1819
|
+
b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0;
|
|
1820
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1821
|
+
i = i$;
|
|
1822
|
+
w = r() * 2 - 1;
|
|
1823
|
+
b0 = 0.99886 * b0 + w * 0.0555179;
|
|
1824
|
+
b1 = 0.99332 * b1 + w * 0.0750759;
|
|
1825
|
+
b2 = 0.969 * b2 + w * 0.153852;
|
|
1826
|
+
b3 = 0.8665 * b3 + w * 0.3104856;
|
|
1827
|
+
b4 = 0.55 * b4 + w * 0.5329522;
|
|
1828
|
+
b5 = -0.7616 * b5 - w * 0.016898;
|
|
1829
|
+
d[i] = (b0 + b1 + b2 + b3 + b4 + b5 + b6 + w * 0.5362) * 0.11;
|
|
1830
|
+
b6 = w * 0.115926;
|
|
1831
|
+
}
|
|
1832
|
+
return d;
|
|
1833
|
+
};
|
|
1834
|
+
synth.thunder = function(o){
|
|
1835
|
+
var dur, dist, near;
|
|
1836
|
+
o == null && (o = {});
|
|
1837
|
+
dur = o.dur || 6;
|
|
1838
|
+
dist = o.dist != null ? o.dist : 0.5;
|
|
1839
|
+
near = 1 - dist;
|
|
1840
|
+
return make(dur, function(L, R, n){
|
|
1841
|
+
var r, t0, cracks, k, rolls, res$, i$, ca, ra, i, t, j$, len$, ref$, at, g, fo, lpf, ch, p, b, to$, results$ = [];
|
|
1842
|
+
r = rng(o.seed || 79);
|
|
1843
|
+
t0 = 0.02 + dist * 0.4;
|
|
1844
|
+
cracks = [[t0, 1]].concat((function(){
|
|
1845
|
+
var i$, to$, results$ = [];
|
|
1846
|
+
for (i$ = 0, to$ = Math.round(2 + 5 * near); i$ < to$; ++i$) {
|
|
1847
|
+
k = i$;
|
|
1848
|
+
results$.push([t0 + 0.7 * Math.pow(r(), 1.5), 0.4 + 0.6 * r()]);
|
|
1849
|
+
}
|
|
1850
|
+
return results$;
|
|
1851
|
+
}()));
|
|
1852
|
+
res$ = [];
|
|
1853
|
+
for (i$ = 0; i$ < 5; ++i$) {
|
|
1854
|
+
k = i$;
|
|
1855
|
+
res$.push([t0 + 0.3 + r() * dur * 0.5, 0.3 + 0.7 * r()]);
|
|
1856
|
+
}
|
|
1857
|
+
rolls = res$;
|
|
1858
|
+
ca = new Float32Array(n);
|
|
1859
|
+
ra = new Float32Array(n);
|
|
1860
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1861
|
+
i = i$;
|
|
1862
|
+
t = i / SR;
|
|
1863
|
+
for (j$ = 0, len$ = cracks.length; j$ < len$; ++j$) {
|
|
1864
|
+
ref$ = cracks[j$], at = ref$[0], g = ref$[1];
|
|
1865
|
+
if (t > at) {
|
|
1866
|
+
ca[i] += g * env(t - at, 0.004, 0.1 + 0.25 * dist);
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
for (j$ = 0, len$ = rolls.length; j$ < len$; ++j$) {
|
|
1870
|
+
ref$ = rolls[j$], at = ref$[0], g = ref$[1];
|
|
1871
|
+
if (t > at) {
|
|
1872
|
+
ra[i] += g * env(t - at, 0.15 + 0.4 * dist, 0.7 + dist);
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
fo = Math.min(1, (dur - t) / 0.6);
|
|
1876
|
+
ca[i] *= fo;
|
|
1877
|
+
ra[i] *= fo;
|
|
1878
|
+
}
|
|
1879
|
+
lpf = 400 + 11000 * near * near;
|
|
1880
|
+
for (i$ = 0, len$ = (ref$ = [L, R]).length; i$ < len$; ++i$) {
|
|
1881
|
+
ch = ref$[i$];
|
|
1882
|
+
p = biquad(biquad(pink(n, r), 'lp', lpf), 'hp', 30);
|
|
1883
|
+
b = biquad(biquad(noise(n, r), 'lp', 140), 'lp', 140);
|
|
1884
|
+
for (j$ = 0; j$ < n; ++j$) {
|
|
1885
|
+
i = j$;
|
|
1886
|
+
ch[i] = p[i] * (ca[i] * (0.4 + 0.6 * near) + ra[i] * 0.8 * near) + b[i] * ra[i] * (0.6 + 0.4 * dist) * 3 + b[i] * ca[i] * 2;
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
for (i$ = 0, to$ = Math.round(300 * near * near); i$ < to$; ++i$) {
|
|
1890
|
+
k = i$;
|
|
1891
|
+
at = t0 + 1.2 * Math.pow(r(), 2);
|
|
1892
|
+
results$.push(grain(L, R, r, at, 0.0003 + 0.002 * r(), 800 + 5000 * r(), 1, (0.1 + r() * r()) * near * 0.8, r() * 1.4 - 0.7));
|
|
1893
|
+
}
|
|
1894
|
+
return results$;
|
|
1895
|
+
});
|
|
1896
|
+
};
|
|
1897
|
+
synth.fingersnap = function(o){
|
|
1898
|
+
o == null && (o = {});
|
|
1899
|
+
return make(0.12, function(L, R, n){
|
|
1900
|
+
var r, tone, d, nz, crack, res, i$, i, t;
|
|
1901
|
+
r = rng(o.seed || 137);
|
|
1902
|
+
tone = o.tone || 3200;
|
|
1903
|
+
d = new Float32Array(n);
|
|
1904
|
+
nz = noise(n, r);
|
|
1905
|
+
crack = biquad(Float32Array.from(nz), 'hp', 5000);
|
|
1906
|
+
res = biquad(Float32Array.from(nz), 'bp', tone, 5);
|
|
1907
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1908
|
+
i = i$;
|
|
1909
|
+
t = i / SR;
|
|
1910
|
+
d[i] = crack[i] * 2.5 * env(t, 0.0001, 0.0015) + res[i] * 2.2 * env(t, 0.0002, 0.0025);
|
|
1911
|
+
}
|
|
1912
|
+
partial(d, 0, tone * 1.1, 0.12, 0.004);
|
|
1913
|
+
partial(d, 0.0005, 200 + 30 * r(), 0.02, 0.008, 0.001);
|
|
1914
|
+
return pan(L, R, d, o.pan);
|
|
1915
|
+
});
|
|
1916
|
+
};
|
|
1917
|
+
formantVoice = function(n, r, size, track){
|
|
1918
|
+
var src, ph, jit, tr, i$, s, i, p, f0, v, K, j$, k, a, j, y1, y2, F, B, rr, c, b, k$, to$, y;
|
|
1919
|
+
src = new Float32Array(n);
|
|
1920
|
+
ph = 0;
|
|
1921
|
+
jit = 0;
|
|
1922
|
+
tr = [];
|
|
1923
|
+
for (i$ = 0; i$ < n; i$ += 32) {
|
|
1924
|
+
s = i$;
|
|
1925
|
+
tr.push(track(s / n));
|
|
1926
|
+
}
|
|
1927
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
1928
|
+
i = i$;
|
|
1929
|
+
p = tr[i >> 5];
|
|
1930
|
+
jit = jit * 0.999 + (r() - 0.5) * 0.002;
|
|
1931
|
+
f0 = p.f0 * (1 + 0.006 * Math.sin(2 * Math.PI * 5.2 * i / SR) + jit);
|
|
1932
|
+
ph += f0 / SR;
|
|
1933
|
+
ph -= Math.floor(ph);
|
|
1934
|
+
v = 0;
|
|
1935
|
+
if (p.voice > 0) {
|
|
1936
|
+
K = Math.min(40, Math.floor(5000 / f0));
|
|
1937
|
+
for (j$ = 1; j$ <= K; ++j$) {
|
|
1938
|
+
k = j$;
|
|
1939
|
+
v += Math.sin(2 * Math.PI * k * ph) / k;
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
a = (r() * 2 - 1) * p.asp * (p.voice > 0 ? 0.6 + 0.4 * Math.sin(2 * Math.PI * ph) : 1);
|
|
1943
|
+
src[i] = (v * p.voice * 0.35 + a) * p.amp;
|
|
1944
|
+
}
|
|
1945
|
+
for (i$ = 0; i$ < 4; ++i$) {
|
|
1946
|
+
j = i$;
|
|
1947
|
+
y1 = y2 = 0;
|
|
1948
|
+
for (j$ = 0; j$ < n; j$ += 32) {
|
|
1949
|
+
s = j$;
|
|
1950
|
+
F = tr[s >> 5].F[j] * size;
|
|
1951
|
+
B = 60 + F * 0.06;
|
|
1952
|
+
rr = Math.exp(-Math.PI * B / SR);
|
|
1953
|
+
c = -rr * rr;
|
|
1954
|
+
b = 2 * rr * Math.cos(2 * Math.PI * F / SR);
|
|
1955
|
+
a = 1 - b - c;
|
|
1956
|
+
for (k$ = s, to$ = Math.min(n, s + 32); k$ < to$; ++k$) {
|
|
1957
|
+
i = k$;
|
|
1958
|
+
y = a * src[i] + b * y1 + c * y2;
|
|
1959
|
+
y2 = y1;
|
|
1960
|
+
y1 = y;
|
|
1961
|
+
src[i] = y;
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
return src;
|
|
1966
|
+
};
|
|
1967
|
+
mix = function(a, b, u){
|
|
1968
|
+
return a + (b - a) * u;
|
|
1969
|
+
};
|
|
1970
|
+
ease = function(u){
|
|
1971
|
+
return u * u * (3 - 2 * u);
|
|
1972
|
+
};
|
|
1973
|
+
synth.huh = function(o){
|
|
1974
|
+
var dur, f0, rise, size, h;
|
|
1975
|
+
o == null && (o = {});
|
|
1976
|
+
dur = o.dur || 0.45;
|
|
1977
|
+
f0 = o.pitch || 200;
|
|
1978
|
+
rise = o.rise || 1.9;
|
|
1979
|
+
size = o.size || 1;
|
|
1980
|
+
h = 0.08 / dur;
|
|
1981
|
+
return make(dur, function(L, R, n){
|
|
1982
|
+
var r, d;
|
|
1983
|
+
r = rng(o.seed || 151);
|
|
1984
|
+
d = formantVoice(n, r, size, function(u){
|
|
1985
|
+
var v, w, amp;
|
|
1986
|
+
v = Math.max(0, Math.min(1, (u - h) / 0.08));
|
|
1987
|
+
w = Math.max(0, (u - h) / (1 - h));
|
|
1988
|
+
amp = Math.min(1, u / 0.06) * (u > 0.75 ? Math.max(0, 1 - (u - 0.75) / 0.25) : 1);
|
|
1989
|
+
return {
|
|
1990
|
+
f0: f0 * mix(1, rise, Math.pow(w, 1.6)),
|
|
1991
|
+
voice: v,
|
|
1992
|
+
asp: 0.35 * (1 - v) + 0.06,
|
|
1993
|
+
amp: amp,
|
|
1994
|
+
F: [mix(700, 850, v), 1250, 2700, 3600]
|
|
1995
|
+
};
|
|
1996
|
+
});
|
|
1997
|
+
fadeOut(d, 0.03);
|
|
1998
|
+
return pan(L, R, d, o.pan);
|
|
1999
|
+
});
|
|
2000
|
+
};
|
|
2001
|
+
synth.yay = function(o){
|
|
2002
|
+
var dur, f0, size;
|
|
2003
|
+
o == null && (o = {});
|
|
2004
|
+
dur = o.dur || 0.5;
|
|
2005
|
+
f0 = o.pitch || 300;
|
|
2006
|
+
size = o.size || 1;
|
|
2007
|
+
return make(dur, function(L, R, n){
|
|
2008
|
+
var r, d;
|
|
2009
|
+
r = rng(o.seed || 157);
|
|
2010
|
+
d = formantVoice(n, r, size, function(u){
|
|
2011
|
+
var g, amp, pc;
|
|
2012
|
+
g = ease(Math.min(1, u / 0.25));
|
|
2013
|
+
amp = Math.min(1, u / 0.04) * (u > 0.7 ? Math.max(0, 1 - (u - 0.7) / 0.3) : 1);
|
|
2014
|
+
pc = u < 0.35
|
|
2015
|
+
? mix(0.88, 1.12, ease(u / 0.35))
|
|
2016
|
+
: mix(1.12, 0.85, ease((u - 0.35) / 0.65));
|
|
2017
|
+
return {
|
|
2018
|
+
f0: f0 * pc,
|
|
2019
|
+
voice: 1,
|
|
2020
|
+
asp: 0.05,
|
|
2021
|
+
amp: amp,
|
|
2022
|
+
F: [mix(320, 660, g), mix(2600, 1850, g), mix(3200, 2650, g), 3800]
|
|
2023
|
+
};
|
|
2024
|
+
});
|
|
2025
|
+
fadeOut(d, 0.03);
|
|
2026
|
+
return pan(L, R, d, o.pan);
|
|
2027
|
+
});
|
|
2028
|
+
};
|
|
2029
|
+
synth.correct = function(o){
|
|
2030
|
+
var arp, notes, gap;
|
|
2031
|
+
o == null && (o = {});
|
|
2032
|
+
arp = o.style === 'arp';
|
|
2033
|
+
notes = (o.notes || (arp
|
|
2034
|
+
? ['C6', 'E6', 'G6', 'C7']
|
|
2035
|
+
: ['B5', 'G5'])).map(S.freq);
|
|
2036
|
+
gap = o.gap || (arp ? 0.07 : 0.2);
|
|
2037
|
+
return make(notes.length * gap + 1.1, function(L, R, n){
|
|
2038
|
+
var d, i$, ref$, len$, k, f, last, dec, sh, i;
|
|
2039
|
+
d = new Float32Array(n);
|
|
2040
|
+
for (i$ = 0, len$ = (ref$ = notes).length; i$ < len$; ++i$) {
|
|
2041
|
+
k = i$;
|
|
2042
|
+
f = ref$[i$];
|
|
2043
|
+
last = k === notes.length - 1;
|
|
2044
|
+
dec = last
|
|
2045
|
+
? 0.45
|
|
2046
|
+
: arp ? 0.15 : 0.25;
|
|
2047
|
+
partial(d, k * gap, f, 1, dec, 0.002);
|
|
2048
|
+
partial(d, k * gap, f * 2, 0.25, dec * 0.4, 0.002);
|
|
2049
|
+
partial(d, k * gap, f * 3.01, 0.08, dec * 0.25, 0.002);
|
|
2050
|
+
}
|
|
2051
|
+
if (arp) {
|
|
2052
|
+
sh = biquad(noise(n, rng(o.seed || 163)), 'hp', 7000);
|
|
2053
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
2054
|
+
i = i$;
|
|
2055
|
+
d[i] += sh[i] * 0.08 * env(i / SR - notes.length * gap * 0.6, 0.1, 0.25) * (i / SR > notes.length * gap * 0.6 - 0.1 ? 1 : 0);
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
return pan(L, R, fadeOut(d, 0.05), o.pan);
|
|
2059
|
+
});
|
|
2060
|
+
};
|
|
2061
|
+
synth.correct.reverb = 0.15;
|
|
2062
|
+
synth.wrong = function(o){
|
|
2063
|
+
var notes, f;
|
|
2064
|
+
o == null && (o = {});
|
|
2065
|
+
if (o.style === 'trombone') {
|
|
2066
|
+
notes = ['D4', 'C#4', 'C4', 'B3'].map(S.freq);
|
|
2067
|
+
return make(2.2, function(L, R, n){
|
|
2068
|
+
var d, ph, i$, i, t, k, lt, f, p, a, b2;
|
|
2069
|
+
d = new Float32Array(n);
|
|
2070
|
+
ph = 0;
|
|
2071
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
2072
|
+
i = i$;
|
|
2073
|
+
t = i / SR;
|
|
2074
|
+
k = Math.min(3, Math.floor(t / 0.42));
|
|
2075
|
+
lt = t - k * 0.42;
|
|
2076
|
+
f = notes[k] * (k === 3 ? 1 + 0.025 * Math.sin(2 * Math.PI * 5.5 * Math.max(0, lt - 0.15)) : 1) * (1 - 0.03 * Math.min(1, lt / 0.3));
|
|
2077
|
+
ph += f / SR;
|
|
2078
|
+
p = ph % 1;
|
|
2079
|
+
a = k < 3
|
|
2080
|
+
? Math.min(1, lt / 0.04) * Math.max(0, 1 - Math.max(0, lt - 0.3) / 0.08)
|
|
2081
|
+
: Math.min(1, lt / 0.04) * Math.max(0, 1 - lt / 0.95);
|
|
2082
|
+
d[i] = (2 * p - 1) * a;
|
|
2083
|
+
}
|
|
2084
|
+
biquad(d, 'lp', 1400, 0.9);
|
|
2085
|
+
b2 = biquad(Float32Array.from(d), 'bp', 1200, 2);
|
|
2086
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
2087
|
+
i = i$;
|
|
2088
|
+
d[i] += b2[i] * 0.5;
|
|
2089
|
+
}
|
|
2090
|
+
return pan(L, R, fadeOut(d, 0.05), o.pan);
|
|
2091
|
+
});
|
|
2092
|
+
}
|
|
2093
|
+
f = o.pitch || 140;
|
|
2094
|
+
return make(0.75, function(L, R, n){
|
|
2095
|
+
var d, p1, p2, i$, i, t, a;
|
|
2096
|
+
d = new Float32Array(n);
|
|
2097
|
+
p1 = 0;
|
|
2098
|
+
p2 = 0;
|
|
2099
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
2100
|
+
i = i$;
|
|
2101
|
+
t = i / SR;
|
|
2102
|
+
a = t < 0.13
|
|
2103
|
+
? Math.min(1, t / 0.005) * Math.min(1, (0.13 - t) / 0.01)
|
|
2104
|
+
: t > 0.19 ? Math.min(1, (t - 0.19) / 0.005) * Math.min(1, (0.72 - t) / 0.03) : 0;
|
|
2105
|
+
p1 += f / SR;
|
|
2106
|
+
p2 += f * 1.012 / SR;
|
|
2107
|
+
d[i] = ((p1 % 1 < 0.5
|
|
2108
|
+
? 1
|
|
2109
|
+
: -1) + (p2 % 1 < 0.5
|
|
2110
|
+
? 1
|
|
2111
|
+
: -1)) * 0.5 * Math.max(0, a);
|
|
2112
|
+
}
|
|
2113
|
+
biquad(d, 'lp', 2500);
|
|
2114
|
+
return pan(L, R, d, o.pan);
|
|
2115
|
+
});
|
|
2116
|
+
};
|
|
2117
|
+
bar = function(o, cfg){
|
|
2118
|
+
var f, dur, hard, base;
|
|
2119
|
+
f = S.freq(o.note || cfg.note);
|
|
2120
|
+
dur = o.dur || cfg.dur;
|
|
2121
|
+
hard = o.hard != null ? o.hard : 0.5;
|
|
2122
|
+
base = cfg.decay * Math.pow(S.freq(cfg.note) / f, 0.4);
|
|
2123
|
+
return make(dur, function(L, R, n){
|
|
2124
|
+
var d, i$, ref$, len$, k, ratio, depth, i, m, to$;
|
|
2125
|
+
d = new Float32Array(n);
|
|
2126
|
+
for (i$ = 0, len$ = (ref$ = cfg.ratios).length; i$ < len$; ++i$) {
|
|
2127
|
+
k = i$;
|
|
2128
|
+
ratio = ref$[i$];
|
|
2129
|
+
partial(d, 0, f * ratio, cfg.amps[k] * (k ? 0.3 + 1.4 * hard : 1), base / (1 + k * cfg.damp), 0.0015);
|
|
2130
|
+
}
|
|
2131
|
+
if (cfg.trem) {
|
|
2132
|
+
depth = o.trem != null ? o.trem : 0.35;
|
|
2133
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
2134
|
+
i = i$;
|
|
2135
|
+
d[i] *= 1 - depth * (0.5 + 0.5 * Math.sin(2 * Math.PI * 5.5 * i / SR));
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
m = biquad(noise(Math.round(0.008 * SR), rng(o.seed || 83)), 'lp', 2000 + 6000 * hard);
|
|
2139
|
+
for (i$ = 0, to$ = m.length; i$ < to$; ++i$) {
|
|
2140
|
+
i = i$;
|
|
2141
|
+
d[i] += m[i] * 0.4 * hard * (1 - i / m.length);
|
|
2142
|
+
}
|
|
2143
|
+
return pan(L, R, fadeOut(d), o.pan);
|
|
2144
|
+
});
|
|
2145
|
+
};
|
|
2146
|
+
synth.marimba = function(o){
|
|
2147
|
+
o == null && (o = {});
|
|
2148
|
+
return bar(o, {
|
|
2149
|
+
note: 'C4',
|
|
2150
|
+
dur: 1.5,
|
|
2151
|
+
ratios: [1, 3.93, 9.24],
|
|
2152
|
+
amps: [1, 0.3, 0.1],
|
|
2153
|
+
decay: 0.45,
|
|
2154
|
+
damp: 2.5
|
|
2155
|
+
});
|
|
2156
|
+
};
|
|
2157
|
+
synth.xylophone = function(o){
|
|
2158
|
+
o == null && (o = {});
|
|
2159
|
+
return bar(o, {
|
|
2160
|
+
note: 'C5',
|
|
2161
|
+
dur: 0.8,
|
|
2162
|
+
ratios: [1, 3, 6.1],
|
|
2163
|
+
amps: [1, 0.5, 0.2],
|
|
2164
|
+
decay: 0.2,
|
|
2165
|
+
damp: 1.5
|
|
2166
|
+
});
|
|
2167
|
+
};
|
|
2168
|
+
synth.vibraphone = function(o){
|
|
2169
|
+
o == null && (o = {});
|
|
2170
|
+
return bar(o, {
|
|
2171
|
+
note: 'F4',
|
|
2172
|
+
dur: 3,
|
|
2173
|
+
ratios: [1, 4, 10],
|
|
2174
|
+
amps: [1, 0.25, 0.08],
|
|
2175
|
+
decay: 1.4,
|
|
2176
|
+
damp: 3,
|
|
2177
|
+
trem: true
|
|
2178
|
+
});
|
|
2179
|
+
};
|
|
2180
|
+
synth.glockenspiel = function(o){
|
|
2181
|
+
o == null && (o = {});
|
|
2182
|
+
return bar(o, {
|
|
2183
|
+
note: 'C6',
|
|
2184
|
+
dur: 2,
|
|
2185
|
+
ratios: [1, 2.76, 5.4, 8.93],
|
|
2186
|
+
amps: [1, 0.4, 0.2, 0.08],
|
|
2187
|
+
decay: 0.9,
|
|
2188
|
+
damp: 1.2
|
|
2189
|
+
});
|
|
2190
|
+
};
|
|
2191
|
+
CHORDS = {
|
|
2192
|
+
C: ['C3', 'E3', 'G3', 'C4', 'E4'],
|
|
2193
|
+
D: ['D3', 'A3', 'D4', 'F#4'],
|
|
2194
|
+
Dm: ['D3', 'A3', 'D4', 'F4'],
|
|
2195
|
+
E: ['E2', 'B2', 'E3', 'G#3', 'B3', 'E4'],
|
|
2196
|
+
Em: ['E2', 'B2', 'E3', 'G3', 'B3', 'E4'],
|
|
2197
|
+
F: ['F2', 'C3', 'F3', 'A3', 'C4', 'F4'],
|
|
2198
|
+
G: ['G2', 'B2', 'D3', 'G3', 'B3', 'G4'],
|
|
2199
|
+
A: ['A2', 'E3', 'A3', 'C#4', 'E4'],
|
|
2200
|
+
Am: ['A2', 'E3', 'A3', 'C4', 'E4']
|
|
2201
|
+
};
|
|
2202
|
+
string = function(f, n, o, r){
|
|
2203
|
+
var bright, mute, s, period, size, exc, p, i$, i, a, y, sustain, g, line, d, to$, k, j, j0, fr, a1, b1;
|
|
2204
|
+
bright = o.bright != null ? o.bright : 0.5;
|
|
2205
|
+
mute = o.mute || 0;
|
|
2206
|
+
s = 0.5 + 0.45 * bright * (1 - mute);
|
|
2207
|
+
period = SR / f - (1 - s);
|
|
2208
|
+
size = Math.ceil(period) + 3;
|
|
2209
|
+
exc = noise(size, r);
|
|
2210
|
+
p = Math.max(1, Math.round(period * (o.pos || 0.2)));
|
|
2211
|
+
for (i$ = size - 1; i$ >= p; --i$) {
|
|
2212
|
+
i = i$;
|
|
2213
|
+
exc[i] -= exc[i - p];
|
|
2214
|
+
}
|
|
2215
|
+
a = 0.15 + 0.8 * bright * (1 - mute * 0.7);
|
|
2216
|
+
y = 0;
|
|
2217
|
+
for (i$ = 0; i$ < size; ++i$) {
|
|
2218
|
+
i = i$;
|
|
2219
|
+
y = a * exc[i] + (1 - a) * y;
|
|
2220
|
+
exc[i] = y;
|
|
2221
|
+
}
|
|
2222
|
+
sustain = (o.sustain || 4) * (1 - 0.92 * mute);
|
|
2223
|
+
g = Math.pow(0.001, 1 / (f * sustain));
|
|
2224
|
+
line = new Float32Array(n + size);
|
|
2225
|
+
for (i$ = 0; i$ < size; ++i$) {
|
|
2226
|
+
i = i$;
|
|
2227
|
+
line[i] = exc[i];
|
|
2228
|
+
}
|
|
2229
|
+
d = new Float32Array(n);
|
|
2230
|
+
for (i$ = size, to$ = n + size; i$ < to$; ++i$) {
|
|
2231
|
+
k = i$;
|
|
2232
|
+
j = k - period;
|
|
2233
|
+
j0 = Math.floor(j);
|
|
2234
|
+
fr = j - j0;
|
|
2235
|
+
a1 = line[j0] * (1 - fr) + line[j0 + 1] * fr;
|
|
2236
|
+
b1 = line[j0 - 1] * (1 - fr) + line[j0] * fr;
|
|
2237
|
+
line[k] = g * (s * a1 + (1 - s) * b1);
|
|
2238
|
+
d[k - size] = line[k];
|
|
2239
|
+
}
|
|
2240
|
+
return d;
|
|
2241
|
+
};
|
|
2242
|
+
synth.guitar = function(o){
|
|
2243
|
+
var notes, dur, gap;
|
|
2244
|
+
o == null && (o = {});
|
|
2245
|
+
notes = o.notes || CHORDS[o.chord] || [o.note || 'E3'];
|
|
2246
|
+
if (o.dir === 'up') {
|
|
2247
|
+
notes = notes.slice().reverse();
|
|
2248
|
+
}
|
|
2249
|
+
dur = o.dur || 3;
|
|
2250
|
+
gap = o.strum != null ? o.strum : 0.03;
|
|
2251
|
+
return make(dur, function(L, R, n){
|
|
2252
|
+
var r, i$, ref$, len$, k, note, lresult$, at, d, body, body2, j$, to$, i, p, gl, gr, results$ = [];
|
|
2253
|
+
r = rng(o.seed || 89);
|
|
2254
|
+
for (i$ = 0, len$ = (ref$ = notes).length; i$ < len$; ++i$) {
|
|
2255
|
+
k = i$;
|
|
2256
|
+
note = ref$[i$];
|
|
2257
|
+
lresult$ = [];
|
|
2258
|
+
at = Math.round(k * gap * SR);
|
|
2259
|
+
d = string(S.freq(note), n - at, o, r);
|
|
2260
|
+
body = biquad(Float32Array.from(d), 'bp', 105, 1.5);
|
|
2261
|
+
body2 = biquad(Float32Array.from(d), 'bp', 220, 2);
|
|
2262
|
+
for (j$ = 0, to$ = d.length; j$ < to$; ++j$) {
|
|
2263
|
+
i = j$;
|
|
2264
|
+
d[i] = d[i] + body[i] * 0.6 + body2[i] * 0.3;
|
|
2265
|
+
}
|
|
2266
|
+
fadeOut(d, 0.05);
|
|
2267
|
+
p = (o.pan || 0) + (k / Math.max(1, notes.length - 1) - 0.5) * 0.3;
|
|
2268
|
+
gl = Math.cos((p + 1) * Math.PI / 4);
|
|
2269
|
+
gr = Math.sin((p + 1) * Math.PI / 4);
|
|
2270
|
+
for (j$ = 0, to$ = d.length; j$ < to$; ++j$) {
|
|
2271
|
+
i = j$;
|
|
2272
|
+
L[at + i] += d[i] * gl;
|
|
2273
|
+
lresult$.push(R[at + i] += d[i] * gr);
|
|
2274
|
+
}
|
|
2275
|
+
results$.push(lresult$);
|
|
2276
|
+
}
|
|
2277
|
+
return results$;
|
|
2278
|
+
});
|
|
2279
|
+
};
|
|
2280
|
+
synth.kick = function(o){
|
|
2281
|
+
var f1, dec, punch;
|
|
2282
|
+
o == null && (o = {});
|
|
2283
|
+
f1 = o.tune || 50;
|
|
2284
|
+
dec = o.decay || 0.3;
|
|
2285
|
+
punch = o.punch != null ? o.punch : 0.5;
|
|
2286
|
+
return make(dec * 2 + 0.05, function(L, R, n){
|
|
2287
|
+
var d, ph, ck, i$, i, t;
|
|
2288
|
+
d = new Float32Array(n);
|
|
2289
|
+
ph = 0;
|
|
2290
|
+
ck = biquad(noise(n, rng(o.seed || 97)), 'lp', 4000);
|
|
2291
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
2292
|
+
i = i$;
|
|
2293
|
+
t = i / SR;
|
|
2294
|
+
ph += 2 * Math.PI * (f1 + f1 * 2 * Math.exp(-t / 0.03)) / SR;
|
|
2295
|
+
d[i] = Math.tanh((Math.sin(ph) * env(t, 0.001, dec) + ck[i] * punch * 0.6 * env(t, 0.0002, 0.003)) * (1 + 2 * punch));
|
|
2296
|
+
}
|
|
2297
|
+
return pan(L, R, fadeOut(d), o.pan);
|
|
2298
|
+
});
|
|
2299
|
+
};
|
|
2300
|
+
synth.snare = function(o){
|
|
2301
|
+
var f, dec, snappy;
|
|
2302
|
+
o == null && (o = {});
|
|
2303
|
+
f = o.tune || 180;
|
|
2304
|
+
dec = o.decay || 0.15;
|
|
2305
|
+
snappy = o.snappy != null ? o.snappy : 0.6;
|
|
2306
|
+
return make(dec * 2 + 0.05, function(L, R, n){
|
|
2307
|
+
var d, nz, i$, i;
|
|
2308
|
+
d = new Float32Array(n);
|
|
2309
|
+
partial(d, 0, f, 0.8, 0.05);
|
|
2310
|
+
partial(d, 0, f * 1.83, 0.4, 0.035);
|
|
2311
|
+
nz = biquad(biquad(noise(n, rng(o.seed || 101)), 'hp', 1200), 'lp', 9000);
|
|
2312
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
2313
|
+
i = i$;
|
|
2314
|
+
d[i] += nz[i] * snappy * 1.2 * env(i / SR, 0.001, dec * 0.8);
|
|
2315
|
+
}
|
|
2316
|
+
return pan(L, R, fadeOut(d), o.pan);
|
|
2317
|
+
});
|
|
2318
|
+
};
|
|
2319
|
+
metal = function(n, scale){
|
|
2320
|
+
var d, i$, ref$, len$, f, w, ph, j$, i;
|
|
2321
|
+
scale == null && (scale = 1);
|
|
2322
|
+
d = new Float32Array(n);
|
|
2323
|
+
for (i$ = 0, len$ = (ref$ = [205.3, 304.4, 369.6, 522.7, 540, 800]).length; i$ < len$; ++i$) {
|
|
2324
|
+
f = ref$[i$];
|
|
2325
|
+
w = f * scale / SR;
|
|
2326
|
+
ph = 0;
|
|
2327
|
+
for (j$ = 0; j$ < n; ++j$) {
|
|
2328
|
+
i = j$;
|
|
2329
|
+
ph += w;
|
|
2330
|
+
d[i] += ph % 1 < 0.5
|
|
2331
|
+
? 1
|
|
2332
|
+
: -1;
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
return d;
|
|
2336
|
+
};
|
|
2337
|
+
synth.hihat = function(o){
|
|
2338
|
+
var open, dec;
|
|
2339
|
+
o == null && (o = {});
|
|
2340
|
+
open = o.open || 0;
|
|
2341
|
+
dec = 0.04 + open * 0.5;
|
|
2342
|
+
return make(dec * 2.5 + 0.02, function(L, R, n){
|
|
2343
|
+
var m, nz, d, i$, i;
|
|
2344
|
+
m = metal(n, o.tune || 1);
|
|
2345
|
+
nz = noise(n, rng(o.seed || 103));
|
|
2346
|
+
d = new Float32Array(n);
|
|
2347
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
2348
|
+
i = i$;
|
|
2349
|
+
d[i] = m[i] * 0.15 + nz[i] * 0.5;
|
|
2350
|
+
}
|
|
2351
|
+
biquad(biquad(d, 'hp', 7000), 'bp', 10000, 0.8);
|
|
2352
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
2353
|
+
i = i$;
|
|
2354
|
+
d[i] *= env(i / SR, 0.0008, dec);
|
|
2355
|
+
}
|
|
2356
|
+
return pan(L, R, fadeOut(d), o.pan);
|
|
2357
|
+
});
|
|
2358
|
+
};
|
|
2359
|
+
synth.tom = function(o){
|
|
2360
|
+
var f, dec;
|
|
2361
|
+
o == null && (o = {});
|
|
2362
|
+
f = S.freq(o.note || 'A2');
|
|
2363
|
+
dec = o.decay || 0.35;
|
|
2364
|
+
return make(dec * 2 + 0.05, function(L, R, n){
|
|
2365
|
+
var d, ph, nz, i$, i, t;
|
|
2366
|
+
d = new Float32Array(n);
|
|
2367
|
+
ph = 0;
|
|
2368
|
+
nz = biquad(noise(n, rng(o.seed || 107)), 'bp', f * 4, 1);
|
|
2369
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
2370
|
+
i = i$;
|
|
2371
|
+
t = i / SR;
|
|
2372
|
+
ph += 2 * Math.PI * f * (1 + 0.5 * Math.exp(-t / 0.04)) / SR;
|
|
2373
|
+
d[i] = Math.sin(ph) * env(t, 0.002, dec) + nz[i] * 0.3 * env(t, 0.001, 0.02);
|
|
2374
|
+
}
|
|
2375
|
+
return pan(L, R, fadeOut(d), o.pan);
|
|
2376
|
+
});
|
|
2377
|
+
};
|
|
2378
|
+
synth.clap = function(o){
|
|
2379
|
+
var dec;
|
|
2380
|
+
o == null && (o = {});
|
|
2381
|
+
dec = o.decay || 0.12;
|
|
2382
|
+
return make(dec * 2.5 + 0.06, function(L, R, n){
|
|
2383
|
+
var nz, d, i$, i, t, a, j$, ref$, len$, at;
|
|
2384
|
+
nz = biquad(noise(n, rng(o.seed || 109)), 'bp', 1100, 1.2);
|
|
2385
|
+
d = new Float32Array(n);
|
|
2386
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
2387
|
+
i = i$;
|
|
2388
|
+
t = i / SR;
|
|
2389
|
+
a = 0;
|
|
2390
|
+
for (j$ = 0, len$ = (ref$ = [0, 0.011, 0.022]).length; j$ < len$; ++j$) {
|
|
2391
|
+
at = ref$[j$];
|
|
2392
|
+
if (t >= at) {
|
|
2393
|
+
a += env(t - at, 0.0005, 0.006);
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
if (t >= 0.031) {
|
|
2397
|
+
a += env(t - 0.031, 0.001, dec);
|
|
2398
|
+
}
|
|
2399
|
+
d[i] = nz[i] * a;
|
|
2400
|
+
}
|
|
2401
|
+
L.set(d);
|
|
2402
|
+
return R.set(biquad(Float32Array.from(d), 'bp', 1300, 1.5));
|
|
2403
|
+
});
|
|
2404
|
+
};
|
|
2405
|
+
ring = function(d, at, f, a, tau, att){
|
|
2406
|
+
var o0, g, w, c, s, x, y, A, an, i$, to$, i, k, t, results$ = [];
|
|
2407
|
+
att == null && (att = 0.0005);
|
|
2408
|
+
if (f >= SR * 0.45) {
|
|
2409
|
+
return;
|
|
2410
|
+
}
|
|
2411
|
+
o0 = Math.round(at * SR);
|
|
2412
|
+
g = Math.exp(-1 / (tau * SR));
|
|
2413
|
+
w = 2 * Math.PI * f / SR;
|
|
2414
|
+
c = Math.cos(w);
|
|
2415
|
+
s = Math.sin(w);
|
|
2416
|
+
x = 1;
|
|
2417
|
+
y = 0;
|
|
2418
|
+
A = a;
|
|
2419
|
+
an = Math.max(1, Math.round(att * SR));
|
|
2420
|
+
for (i$ = o0, to$ = d.length; i$ < to$; ++i$) {
|
|
2421
|
+
i = i$;
|
|
2422
|
+
k = i - o0;
|
|
2423
|
+
d[i] += y * A * (k < an ? k / an : 1);
|
|
2424
|
+
t = x * c - y * s;
|
|
2425
|
+
y = x * s + y * c;
|
|
2426
|
+
x = t;
|
|
2427
|
+
A *= g;
|
|
2428
|
+
if (A < 1e-5) {
|
|
2429
|
+
break;
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
return results$;
|
|
2433
|
+
};
|
|
2434
|
+
gauss = function(r){
|
|
2435
|
+
return Math.sqrt(-2 * Math.log(r() + 1e-12)) * Math.cos(2 * Math.PI * r());
|
|
2436
|
+
};
|
|
2437
|
+
synth.crash = function(o){
|
|
2438
|
+
var dec, tune;
|
|
2439
|
+
o == null && (o = {});
|
|
2440
|
+
dec = o.decay || 1;
|
|
2441
|
+
tune = o.tune || 1;
|
|
2442
|
+
return make(2.4 * dec + 0.1, function(L, R, n){
|
|
2443
|
+
var r, i$, ref$, len$, ch, j$, k, f, nz, sh, i, t, results$ = [];
|
|
2444
|
+
r = rng(o.seed || 113);
|
|
2445
|
+
for (i$ = 0, len$ = (ref$ = [L, R]).length; i$ < len$; ++i$) {
|
|
2446
|
+
ch = ref$[i$];
|
|
2447
|
+
for (j$ = 0; j$ < 260; ++j$) {
|
|
2448
|
+
k = j$;
|
|
2449
|
+
f = Math.max(1200, Math.min(14000, 4200 * Math.pow(2, 0.55 * gauss(r)))) * tune;
|
|
2450
|
+
ring(ch, 0, f, (0.4 + r()) / 16, 0.3 * dec * Math.pow(f / 4200 / tune, -0.8) * (0.6 + 0.8 * r()), 0.002 + 0.07 * r() * Math.min(1, f / 4200 / tune));
|
|
2451
|
+
}
|
|
2452
|
+
for (j$ = 0; j$ < 30; ++j$) {
|
|
2453
|
+
k = j$;
|
|
2454
|
+
ring(ch, 0, 350 * tune * Math.pow(3, r()), (0.3 + r()) / 14, 0.5 * dec * (0.6 + 0.8 * r()), 0.003);
|
|
2455
|
+
}
|
|
2456
|
+
nz = biquad(noise(n, r), 'lp', 9000);
|
|
2457
|
+
sh = biquad(noise(n, r), 'bp', 4200 * tune, 0.8);
|
|
2458
|
+
for (j$ = 0; j$ < n; ++j$) {
|
|
2459
|
+
i = j$;
|
|
2460
|
+
t = i / SR;
|
|
2461
|
+
ch[i] += nz[i] * 0.4 * env(t, 0.0005, 0.008) + sh[i] * 0.1 * env(t, 0.03, 0.3 * dec);
|
|
2462
|
+
}
|
|
2463
|
+
biquad(ch, 'hp', 250);
|
|
2464
|
+
results$.push(fadeOut(ch, 0.1));
|
|
2465
|
+
}
|
|
2466
|
+
return results$;
|
|
2467
|
+
});
|
|
2468
|
+
};
|
|
2469
|
+
synth.ride = function(o){
|
|
2470
|
+
var dec, tune, bell;
|
|
2471
|
+
o == null && (o = {});
|
|
2472
|
+
dec = o.decay || 1;
|
|
2473
|
+
tune = o.tune || 1;
|
|
2474
|
+
bell = o.bell || 0;
|
|
2475
|
+
return make(4 * dec + 0.1, function(L, R, n){
|
|
2476
|
+
var r, st, i$, ref$, len$, ch, j$, to$, i, k, f, sh, results$ = [];
|
|
2477
|
+
r = rng(o.seed || 127);
|
|
2478
|
+
st = biquad(noise(n, r), 'bp', 4800 * tune, 0.7);
|
|
2479
|
+
for (i$ = 0, len$ = (ref$ = [L, R]).length; i$ < len$; ++i$) {
|
|
2480
|
+
ch = ref$[i$];
|
|
2481
|
+
for (j$ = 0, to$ = Math.round(0.05 * SR); j$ < to$; ++j$) {
|
|
2482
|
+
i = j$;
|
|
2483
|
+
ch[i] += st[i] * 0.9 * env(i / SR, 0.0003, 0.006);
|
|
2484
|
+
}
|
|
2485
|
+
for (j$ = 0; j$ < 40; ++j$) {
|
|
2486
|
+
k = j$;
|
|
2487
|
+
ring(ch, 0, (5000 + 4000 * r()) * tune, 0.04, 0.015 + 0.03 * r());
|
|
2488
|
+
}
|
|
2489
|
+
for (j$ = 0; j$ < 180; ++j$) {
|
|
2490
|
+
k = j$;
|
|
2491
|
+
f = Math.max(700, Math.min(10000, 2600 * Math.pow(2, 0.55 * gauss(r)))) * tune;
|
|
2492
|
+
ring(ch, 0, f, (0.4 + r()) / 80, 0.9 * dec * Math.pow(f / 2600 / tune, -0.3) * (0.6 + 0.8 * r()), 0.001);
|
|
2493
|
+
}
|
|
2494
|
+
sh = biquad(noise(n, r), 'bp', 3000 * tune, 0.7);
|
|
2495
|
+
for (j$ = 0; j$ < n; ++j$) {
|
|
2496
|
+
i = j$;
|
|
2497
|
+
ch[i] += sh[i] * 0.05 * env(i / SR, 0.002, 0.35 * dec);
|
|
2498
|
+
}
|
|
2499
|
+
if (bell) {
|
|
2500
|
+
for (j$ = 0; j$ < 14; ++j$) {
|
|
2501
|
+
k = j$;
|
|
2502
|
+
f = 2800 * tune * Math.pow(2, 0.4 * gauss(r));
|
|
2503
|
+
ring(ch, 0, f, bell * (0.5 + r()) / 6, 0.5 * dec * (0.6 + 0.8 * r()), 0.001);
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2506
|
+
biquad(ch, 'hp', 400);
|
|
2507
|
+
results$.push(fadeOut(ch, 0.1));
|
|
2508
|
+
}
|
|
2509
|
+
return results$;
|
|
2510
|
+
});
|
|
2511
|
+
};
|
|
2512
|
+
KIT = {
|
|
2513
|
+
kick: ['kick', {}, 1],
|
|
2514
|
+
snare: ['snare', {}, 0.9],
|
|
2515
|
+
hihat: ['hihat', {}, 0.45],
|
|
2516
|
+
ohat: [
|
|
2517
|
+
'hihat', {
|
|
2518
|
+
open: 0.6
|
|
2519
|
+
}, 0.45
|
|
2520
|
+
],
|
|
2521
|
+
tom: ['tom', {}, 0.8],
|
|
2522
|
+
ltom: [
|
|
2523
|
+
'tom', {
|
|
2524
|
+
note: 'E2'
|
|
2525
|
+
}, 0.8
|
|
2526
|
+
],
|
|
2527
|
+
htom: [
|
|
2528
|
+
'tom', {
|
|
2529
|
+
note: 'D3'
|
|
2530
|
+
}, 0.8
|
|
2531
|
+
],
|
|
2532
|
+
clap: ['clap', {}, 0.8],
|
|
2533
|
+
crash: ['crash', {}, 0.55],
|
|
2534
|
+
ride: ['ride', {}, 0.4]
|
|
2535
|
+
};
|
|
2536
|
+
VEL = {
|
|
2537
|
+
X: 1,
|
|
2538
|
+
x: 0.75,
|
|
2539
|
+
o: 0.4
|
|
2540
|
+
};
|
|
2541
|
+
synth.beat = function(o){
|
|
2542
|
+
var step, bars, swing, pat, hits, steps, tail, name, def, ref$, str, opt, kind, base, g, b, s, total;
|
|
2543
|
+
o == null && (o = {});
|
|
2544
|
+
step = 60 / (o.bpm || 100) / 4;
|
|
2545
|
+
bars = o.bars || 1;
|
|
2546
|
+
swing = o.swing || 0;
|
|
2547
|
+
pat = o.pattern || {
|
|
2548
|
+
kick: 'x...x...x...x...',
|
|
2549
|
+
snare: '....x.......x...',
|
|
2550
|
+
hihat: 'x.x.x.x.x.x.x.x.'
|
|
2551
|
+
};
|
|
2552
|
+
hits = [];
|
|
2553
|
+
steps = 0;
|
|
2554
|
+
tail = 0;
|
|
2555
|
+
for (name in pat) {
|
|
2556
|
+
def = pat[name];
|
|
2557
|
+
ref$ = Array.isArray(def)
|
|
2558
|
+
? def
|
|
2559
|
+
: [def], str = ref$[0], opt = ref$[1];
|
|
2560
|
+
opt = opt || {};
|
|
2561
|
+
ref$ = KIT[name] || [name, {}, 0.8], kind = ref$[0], base = ref$[1], g = ref$[2];
|
|
2562
|
+
if (!synth[kind]) {
|
|
2563
|
+
continue;
|
|
2564
|
+
}
|
|
2565
|
+
b = synth[kind](import$(import$({}, base), opt));
|
|
2566
|
+
tail = Math.max(tail, b.duration);
|
|
2567
|
+
s = (str || '').replace(/[\s|]/g, '');
|
|
2568
|
+
steps = Math.max(steps, s.length);
|
|
2569
|
+
hits.push({
|
|
2570
|
+
b: b,
|
|
2571
|
+
s: s,
|
|
2572
|
+
g: opt.gain != null ? opt.gain : g
|
|
2573
|
+
});
|
|
2574
|
+
}
|
|
2575
|
+
total = steps * bars;
|
|
2576
|
+
return make(Math.max(0.1, total * step + tail), function(L, R, n){
|
|
2577
|
+
var i$, ref$, len$, ref1$, b, s, g, lresult$, j$, to$, k, v, results$ = [];
|
|
2578
|
+
for (i$ = 0, len$ = (ref$ = hits).length; i$ < len$; ++i$) {
|
|
2579
|
+
ref1$ = ref$[i$], b = ref1$.b, s = ref1$.s, g = ref1$.g;
|
|
2580
|
+
lresult$ = [];
|
|
2581
|
+
for (j$ = 0, to$ = total; j$ < to$; ++j$) {
|
|
2582
|
+
k = j$;
|
|
2583
|
+
v = VEL[s[k % steps]];
|
|
2584
|
+
if (!v) {
|
|
2585
|
+
continue;
|
|
2586
|
+
}
|
|
2587
|
+
lresult$.push(place(L, R, b, k * step + (k % 2 ? swing * step * 0.5 : 0), v * g));
|
|
2588
|
+
}
|
|
2589
|
+
results$.push(lresult$);
|
|
2590
|
+
}
|
|
2591
|
+
return results$;
|
|
2592
|
+
});
|
|
2593
|
+
};
|
|
2594
|
+
synth.sweep = function(o){
|
|
2595
|
+
var dur, f0, f1, att, rel, fu;
|
|
2596
|
+
o == null && (o = {});
|
|
2597
|
+
dur = o.dur || 1;
|
|
2598
|
+
f0 = S.freq(o.from || 200);
|
|
2599
|
+
f1 = S.freq(o.to || 2000);
|
|
2600
|
+
att = o.attack != null ? o.attack : 0.01;
|
|
2601
|
+
rel = o.release != null ? o.release : 0.1;
|
|
2602
|
+
fu = o.curve === 'lin'
|
|
2603
|
+
? function(u){
|
|
2604
|
+
return f0 + (f1 - f0) * u;
|
|
2605
|
+
}
|
|
2606
|
+
: function(u){
|
|
2607
|
+
return f0 * Math.pow(f1 / f0, u);
|
|
2608
|
+
};
|
|
2609
|
+
return make(dur, function(L, R, n){
|
|
2610
|
+
var d, x, ph, i, p, i$, t;
|
|
2611
|
+
d = o.wave === 'noise'
|
|
2612
|
+
? biquadTv(noise(n, rng(o.seed || 131)), 'bp', fu, o.q || 2)
|
|
2613
|
+
: (x = new Float32Array(n), ph = 0, (function(){
|
|
2614
|
+
var i$, to$, results$ = [];
|
|
2615
|
+
for (i$ = 0, to$ = n; i$ < to$; ++i$) {
|
|
2616
|
+
i = i$;
|
|
2617
|
+
ph += fu(i / n) / SR;
|
|
2618
|
+
p = ph % 1;
|
|
2619
|
+
results$.push(x[i] = (fn$()));
|
|
2620
|
+
}
|
|
2621
|
+
return results$;
|
|
2622
|
+
function fn$(){
|
|
2623
|
+
switch (o.wave) {
|
|
2624
|
+
case 'square':
|
|
2625
|
+
if (p < 0.5) {
|
|
2626
|
+
return 0.6;
|
|
2627
|
+
} else {
|
|
2628
|
+
return -0.6;
|
|
2629
|
+
}
|
|
2630
|
+
case 'saw':
|
|
2631
|
+
return (2 * p - 1) * 0.6;
|
|
2632
|
+
case 'triangle':
|
|
2633
|
+
return 1 - 4 * Math.abs(p - 0.5);
|
|
2634
|
+
default:
|
|
2635
|
+
return Math.sin(2 * Math.PI * p);
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
}()), x);
|
|
2639
|
+
for (i$ = 0; i$ < n; ++i$) {
|
|
2640
|
+
i = i$;
|
|
2641
|
+
t = i / SR;
|
|
2642
|
+
d[i] *= Math.min(1, t / Math.max(0.001, att), (dur - t) / Math.max(0.001, rel));
|
|
2643
|
+
}
|
|
2644
|
+
return pan(L, R, d, o.pan);
|
|
2645
|
+
});
|
|
2646
|
+
};
|
|
2647
|
+
wrap = function(fn){
|
|
2648
|
+
return function(o){
|
|
2649
|
+
var b, mix;
|
|
2650
|
+
o == null && (o = {});
|
|
2651
|
+
b = fn(o);
|
|
2652
|
+
mix = o.reverb != null
|
|
2653
|
+
? o.reverb
|
|
2654
|
+
: fn.reverb || 0;
|
|
2655
|
+
if (mix > 0) {
|
|
2656
|
+
return reverb(b, mix, o.room != null ? o.room : 0.5);
|
|
2657
|
+
} else {
|
|
2658
|
+
return b;
|
|
2659
|
+
}
|
|
2660
|
+
};
|
|
2661
|
+
};
|
|
2662
|
+
for (k in synth) {
|
|
2663
|
+
synth[k] = wrap(synth[k]);
|
|
2664
|
+
}
|
|
2665
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
2666
|
+
module.exports = S;
|
|
2667
|
+
}
|
|
2668
|
+
if (typeof window !== 'undefined') {
|
|
2669
|
+
return window.sfx = S;
|
|
2670
|
+
}
|
|
2671
|
+
})();
|
|
2672
|
+
function import$(obj, src){
|
|
2673
|
+
var own = {}.hasOwnProperty;
|
|
2674
|
+
for (var key in src) if (own.call(src, key)) obj[key] = src[key];
|
|
2675
|
+
return obj;
|
|
2676
|
+
}
|
|
2677
|
+
}).call(this);
|