waa-play 0.1.1 → 0.2.1
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/README.md +40 -123
- package/dist/adapters.cjs +6 -6
- package/dist/adapters.d.cts +15 -3
- package/dist/adapters.d.ts +15 -3
- package/dist/adapters.js +1 -1
- package/dist/buffer.cjs +5 -5
- package/dist/buffer.d.cts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/buffer.js +1 -1
- package/dist/{chunk-T74FBKTY.js → chunk-2FGUFHZM.js} +2 -2
- package/dist/chunk-2FGUFHZM.js.map +1 -0
- package/dist/{chunk-CPAT75WD.cjs → chunk-3VTU5OX5.cjs} +2 -2
- package/dist/chunk-3VTU5OX5.cjs.map +1 -0
- package/dist/{chunk-2DL7CAEP.js → chunk-7JUVBZ6B.js} +2 -2
- package/dist/chunk-7JUVBZ6B.js.map +1 -0
- package/dist/{chunk-D5CD5KQZ.cjs → chunk-BRS7LZVH.cjs} +2 -2
- package/dist/chunk-BRS7LZVH.cjs.map +1 -0
- package/dist/{chunk-QWNV2BZ5.cjs → chunk-F6WXD3XW.cjs} +2 -2
- package/dist/chunk-F6WXD3XW.cjs.map +1 -0
- package/dist/{chunk-C2ASIYN5.js → chunk-FESPIMZM.js} +3 -7
- package/dist/chunk-FESPIMZM.js.map +1 -0
- package/dist/{chunk-GYH2JSCY.js → chunk-FY273Z3I.js} +2 -2
- package/dist/chunk-FY273Z3I.js.map +1 -0
- package/dist/{chunk-TULV7V5M.cjs → chunk-G37HMZEX.cjs} +1075 -982
- package/dist/chunk-G37HMZEX.cjs.map +1 -0
- package/dist/{chunk-V2QX5K42.js → chunk-GDBOHOGF.js} +1074 -982
- package/dist/chunk-GDBOHOGF.js.map +1 -0
- package/dist/{chunk-5J7S6QV3.cjs → chunk-HIF3UAF3.cjs} +2 -2
- package/dist/chunk-HIF3UAF3.cjs.map +1 -0
- package/dist/{chunk-CRODJ4KS.js → chunk-HTN52U23.js} +13 -6
- package/dist/chunk-HTN52U23.js.map +1 -0
- package/dist/{chunk-RWJ4EWJT.js → chunk-HYRDCTBO.js} +152 -116
- package/dist/chunk-HYRDCTBO.js.map +1 -0
- package/dist/chunk-JIHPQAEA.js +90 -0
- package/dist/chunk-JIHPQAEA.js.map +1 -0
- package/dist/chunk-KVKW7W66.cjs +148 -0
- package/dist/chunk-KVKW7W66.cjs.map +1 -0
- package/dist/{chunk-4LNVRSTM.cjs → chunk-OIY6I4TU.cjs} +3 -7
- package/dist/chunk-OIY6I4TU.cjs.map +1 -0
- package/dist/chunk-OZN5X4N6.cjs +96 -0
- package/dist/chunk-OZN5X4N6.cjs.map +1 -0
- package/dist/{chunk-CJJC6ASU.js → chunk-PL4J3NR7.js} +2 -2
- package/dist/chunk-PL4J3NR7.js.map +1 -0
- package/dist/chunk-QFJQU7TQ.js +146 -0
- package/dist/chunk-QFJQU7TQ.js.map +1 -0
- package/dist/{chunk-M5PDY5EZ.cjs → chunk-QGZGERGK.cjs} +2 -2
- package/dist/chunk-QGZGERGK.cjs.map +1 -0
- package/dist/{chunk-QFFQQMU4.cjs → chunk-VOSIA3GF.cjs} +13 -6
- package/dist/chunk-VOSIA3GF.cjs.map +1 -0
- package/dist/{chunk-PZE6HTZR.cjs → chunk-VY4UMZMJ.cjs} +154 -118
- package/dist/chunk-VY4UMZMJ.cjs.map +1 -0
- package/dist/{chunk-LETS7FKB.js → chunk-YFK7ETCF.js} +2 -2
- package/dist/chunk-YFK7ETCF.js.map +1 -0
- package/dist/context.d.cts +1 -1
- package/dist/context.d.ts +1 -1
- package/dist/emitter.cjs +2 -2
- package/dist/emitter.js +1 -1
- package/dist/engine-7DCOERRN.js +4 -0
- package/dist/{engine-M2U4LE3F.js.map → engine-7DCOERRN.js.map} +1 -1
- package/dist/engine-ALWPAIX6.cjs +17 -0
- package/dist/{engine-5JK2FCNL.cjs.map → engine-ALWPAIX6.cjs.map} +1 -1
- package/dist/fade.cjs +5 -5
- package/dist/fade.d.cts +1 -1
- package/dist/fade.d.ts +1 -1
- package/dist/fade.js +1 -1
- package/dist/index.cjs +47 -42
- package/dist/index.d.cts +7 -6
- package/dist/index.d.ts +7 -6
- package/dist/index.js +10 -9
- package/dist/nodes.cjs +11 -11
- package/dist/nodes.js +1 -1
- package/dist/play.cjs +3 -3
- package/dist/play.d.cts +1 -1
- package/dist/play.d.ts +1 -1
- package/dist/play.js +2 -2
- package/dist/player.cjs +22 -0
- package/dist/player.cjs.map +1 -0
- package/dist/player.d.cts +64 -0
- package/dist/player.d.ts +64 -0
- package/dist/player.js +13 -0
- package/dist/player.js.map +1 -0
- package/dist/scheduler.cjs +3 -3
- package/dist/scheduler.d.cts +1 -1
- package/dist/scheduler.d.ts +1 -1
- package/dist/scheduler.js +1 -1
- package/dist/stretcher.cjs +3 -3
- package/dist/stretcher.d.cts +5 -3
- package/dist/stretcher.d.ts +5 -3
- package/dist/stretcher.js +2 -2
- package/dist/synth.cjs +4 -4
- package/dist/synth.js +1 -1
- package/dist/{types-DUrbEbPl.d.cts → types-BYC6m7Q0.d.cts} +6 -6
- package/dist/{types-DUrbEbPl.d.ts → types-BYC6m7Q0.d.ts} +6 -6
- package/dist/waveform.cjs +4 -4
- package/dist/waveform.d.cts +1 -1
- package/dist/waveform.d.ts +1 -1
- package/dist/waveform.js +1 -1
- package/package.json +19 -7
- package/dist/chunk-2DL7CAEP.js.map +0 -1
- package/dist/chunk-4LNVRSTM.cjs.map +0 -1
- package/dist/chunk-5J7S6QV3.cjs.map +0 -1
- package/dist/chunk-AGP2IRC6.js +0 -63
- package/dist/chunk-AGP2IRC6.js.map +0 -1
- package/dist/chunk-C2ASIYN5.js.map +0 -1
- package/dist/chunk-CJJC6ASU.js.map +0 -1
- package/dist/chunk-CPAT75WD.cjs.map +0 -1
- package/dist/chunk-CRODJ4KS.js.map +0 -1
- package/dist/chunk-D5CD5KQZ.cjs.map +0 -1
- package/dist/chunk-GYH2JSCY.js.map +0 -1
- package/dist/chunk-HTGOHC73.cjs +0 -69
- package/dist/chunk-HTGOHC73.cjs.map +0 -1
- package/dist/chunk-LETS7FKB.js.map +0 -1
- package/dist/chunk-M5PDY5EZ.cjs.map +0 -1
- package/dist/chunk-PZE6HTZR.cjs.map +0 -1
- package/dist/chunk-QFFQQMU4.cjs.map +0 -1
- package/dist/chunk-QWNV2BZ5.cjs.map +0 -1
- package/dist/chunk-RWJ4EWJT.js.map +0 -1
- package/dist/chunk-T74FBKTY.js.map +0 -1
- package/dist/chunk-TULV7V5M.cjs.map +0 -1
- package/dist/chunk-V2QX5K42.js.map +0 -1
- package/dist/engine-5JK2FCNL.cjs +0 -13
- package/dist/engine-M2U4LE3F.js +0 -4
|
@@ -1,6 +1,60 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkHIF3UAF3_cjs = require('./chunk-HIF3UAF3.cjs');
|
|
4
|
+
|
|
5
|
+
// src/playback-position.ts
|
|
6
|
+
function calcLoopPosition(elapsed, loopStart, loopEnd) {
|
|
7
|
+
const loopDur = loopEnd - loopStart;
|
|
8
|
+
if (loopDur <= 0) return null;
|
|
9
|
+
const offset = elapsed - loopStart;
|
|
10
|
+
return (offset % loopDur + loopDur) % loopDur + loopStart;
|
|
11
|
+
}
|
|
12
|
+
function calcPlaybackPosition(state, elapsed, duration, pausedAt, isLooping, loopStart, loopEnd) {
|
|
13
|
+
if (state === "paused") return pausedAt;
|
|
14
|
+
if (state === "stopped") return 0;
|
|
15
|
+
if (isLooping) {
|
|
16
|
+
const looped = calcLoopPosition(elapsed, loopStart ?? 0, loopEnd ?? duration);
|
|
17
|
+
if (looped !== null) return looped;
|
|
18
|
+
}
|
|
19
|
+
return Math.min(Math.max(elapsed, 0), duration);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// src/playback-state.ts
|
|
23
|
+
function createPlaybackStateManager(opts) {
|
|
24
|
+
let state = opts.initialState;
|
|
25
|
+
let timerId = null;
|
|
26
|
+
let disposed = false;
|
|
27
|
+
function getState() {
|
|
28
|
+
return state;
|
|
29
|
+
}
|
|
30
|
+
function setState(next) {
|
|
31
|
+
if (state === next) return false;
|
|
32
|
+
state = next;
|
|
33
|
+
opts.onStateChange(next);
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
function startTimer() {
|
|
37
|
+
if (timerId !== null) return;
|
|
38
|
+
timerId = setInterval(() => {
|
|
39
|
+
if (state !== "playing" || disposed) return;
|
|
40
|
+
opts.onTimerTick();
|
|
41
|
+
}, opts.timerInterval);
|
|
42
|
+
}
|
|
43
|
+
function stopTimer() {
|
|
44
|
+
if (timerId !== null) {
|
|
45
|
+
clearInterval(timerId);
|
|
46
|
+
timerId = null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function isDisposed() {
|
|
50
|
+
return disposed;
|
|
51
|
+
}
|
|
52
|
+
function markDisposed() {
|
|
53
|
+
disposed = true;
|
|
54
|
+
stopTimer();
|
|
55
|
+
}
|
|
56
|
+
return { getState, setState, startTimer, stopTimer, isDisposed, markDisposed };
|
|
57
|
+
}
|
|
4
58
|
|
|
5
59
|
// src/play.ts
|
|
6
60
|
function play(ctx, buffer, options) {
|
|
@@ -18,16 +72,24 @@ function play(ctx, buffer, options) {
|
|
|
18
72
|
destination = ctx.destination,
|
|
19
73
|
timeupdateInterval = 50
|
|
20
74
|
} = options ?? {};
|
|
21
|
-
const emitter =
|
|
75
|
+
const emitter = chunkHIF3UAF3_cjs.createEmitter();
|
|
22
76
|
const duration = buffer.duration;
|
|
23
|
-
let state = "stopped";
|
|
24
77
|
let sourceNode = null;
|
|
25
78
|
let startedAt = 0;
|
|
26
79
|
let pausedAt = initialOffset;
|
|
27
|
-
let currentRate = initialRate;
|
|
80
|
+
let currentRate = initialRate > 0 ? initialRate : 1;
|
|
28
81
|
let isLooping = loop;
|
|
29
|
-
|
|
30
|
-
|
|
82
|
+
const sm = createPlaybackStateManager({
|
|
83
|
+
initialState: "stopped",
|
|
84
|
+
onStateChange: (next) => emitter.emit("statechange", { state: next }),
|
|
85
|
+
onTimerTick: () => {
|
|
86
|
+
emitter.emit("timeupdate", {
|
|
87
|
+
position: getCurrentTime(),
|
|
88
|
+
duration
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
timerInterval: timeupdateInterval
|
|
92
|
+
});
|
|
31
93
|
function createSource() {
|
|
32
94
|
const src = ctx.createBufferSource();
|
|
33
95
|
src.buffer = buffer;
|
|
@@ -64,90 +126,63 @@ function play(ctx, buffer, options) {
|
|
|
64
126
|
}
|
|
65
127
|
}
|
|
66
128
|
function handleEnded() {
|
|
67
|
-
if (
|
|
129
|
+
if (sm.getState() !== "playing") return;
|
|
68
130
|
if (isLooping) {
|
|
69
131
|
emitter.emit("loop", void 0);
|
|
70
132
|
return;
|
|
71
133
|
}
|
|
72
|
-
setState("stopped");
|
|
134
|
+
sm.setState("stopped");
|
|
73
135
|
pausedAt = 0;
|
|
74
|
-
stopTimer();
|
|
136
|
+
sm.stopTimer();
|
|
75
137
|
emitter.emit("ended", void 0);
|
|
76
138
|
}
|
|
77
|
-
function setState(next) {
|
|
78
|
-
if (state === next) return;
|
|
79
|
-
state = next;
|
|
80
|
-
emitter.emit("statechange", { state: next });
|
|
81
|
-
}
|
|
82
|
-
function startTimer() {
|
|
83
|
-
if (timerId !== null) return;
|
|
84
|
-
timerId = setInterval(() => {
|
|
85
|
-
if (state !== "playing") return;
|
|
86
|
-
emitter.emit("timeupdate", {
|
|
87
|
-
position: getCurrentTime(),
|
|
88
|
-
duration
|
|
89
|
-
});
|
|
90
|
-
}, timeupdateInterval);
|
|
91
|
-
}
|
|
92
|
-
function stopTimer() {
|
|
93
|
-
if (timerId !== null) {
|
|
94
|
-
clearInterval(timerId);
|
|
95
|
-
timerId = null;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
139
|
function getCurrentTime() {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const loopDur = (loopEnd ?? duration) - (loopStart ?? 0);
|
|
103
|
-
return (elapsed - (loopStart ?? 0)) % loopDur + (loopStart ?? 0);
|
|
104
|
-
}
|
|
105
|
-
return Math.min(elapsed, duration);
|
|
106
|
-
}
|
|
107
|
-
if (state === "paused") return pausedAt;
|
|
108
|
-
return 0;
|
|
140
|
+
const state = sm.getState();
|
|
141
|
+
const elapsed = state === "playing" ? (ctx.currentTime - startedAt) * currentRate : 0;
|
|
142
|
+
return calcPlaybackPosition(state, elapsed, duration, pausedAt, isLooping, loopStart, loopEnd);
|
|
109
143
|
}
|
|
110
144
|
function pause() {
|
|
111
|
-
if (
|
|
145
|
+
if (sm.getState() !== "playing" || sm.isDisposed()) return;
|
|
112
146
|
pausedAt = getCurrentTime();
|
|
113
147
|
stopSource();
|
|
114
|
-
stopTimer();
|
|
115
|
-
setState("paused");
|
|
148
|
+
sm.stopTimer();
|
|
149
|
+
sm.setState("paused");
|
|
116
150
|
emitter.emit("pause", void 0);
|
|
117
151
|
}
|
|
118
152
|
function resume() {
|
|
119
|
-
if (
|
|
153
|
+
if (sm.getState() !== "paused" || sm.isDisposed()) return;
|
|
120
154
|
startSource(pausedAt);
|
|
121
|
-
setState("playing");
|
|
122
|
-
startTimer();
|
|
155
|
+
sm.setState("playing");
|
|
156
|
+
sm.startTimer();
|
|
123
157
|
emitter.emit("resume", void 0);
|
|
124
158
|
}
|
|
125
159
|
function togglePlayPause() {
|
|
126
|
-
if (
|
|
127
|
-
else if (
|
|
160
|
+
if (sm.getState() === "playing") pause();
|
|
161
|
+
else if (sm.getState() === "paused") resume();
|
|
128
162
|
}
|
|
129
163
|
function seek(position) {
|
|
130
|
-
if (
|
|
164
|
+
if (sm.isDisposed()) return;
|
|
131
165
|
const clamped = Math.max(0, Math.min(position, duration));
|
|
132
|
-
const wasPlaying =
|
|
166
|
+
const wasPlaying = sm.getState() === "playing";
|
|
133
167
|
stopSource();
|
|
134
|
-
stopTimer();
|
|
168
|
+
sm.stopTimer();
|
|
135
169
|
pausedAt = clamped;
|
|
136
170
|
if (wasPlaying) {
|
|
137
171
|
startSource(clamped);
|
|
138
|
-
startTimer();
|
|
172
|
+
sm.startTimer();
|
|
139
173
|
}
|
|
140
174
|
emitter.emit("seek", { position: clamped });
|
|
141
175
|
}
|
|
142
176
|
function stop() {
|
|
143
|
-
if (
|
|
177
|
+
if (sm.getState() === "stopped" || sm.isDisposed()) return;
|
|
144
178
|
stopSource();
|
|
145
|
-
stopTimer();
|
|
179
|
+
sm.stopTimer();
|
|
146
180
|
pausedAt = 0;
|
|
147
|
-
setState("stopped");
|
|
181
|
+
sm.setState("stopped");
|
|
148
182
|
emitter.emit("stop", void 0);
|
|
149
183
|
}
|
|
150
184
|
function setPlaybackRate(rate) {
|
|
185
|
+
if (rate <= 0) return;
|
|
151
186
|
const position = getCurrentTime();
|
|
152
187
|
currentRate = rate;
|
|
153
188
|
if (sourceNode) {
|
|
@@ -162,18 +197,17 @@ function play(ctx, buffer, options) {
|
|
|
162
197
|
}
|
|
163
198
|
}
|
|
164
199
|
function dispose() {
|
|
165
|
-
if (
|
|
166
|
-
|
|
200
|
+
if (sm.isDisposed()) return;
|
|
201
|
+
sm.markDisposed();
|
|
167
202
|
stopSource();
|
|
168
|
-
stopTimer();
|
|
169
203
|
emitter.clear();
|
|
170
204
|
}
|
|
171
205
|
startSource(initialOffset);
|
|
172
|
-
setState("playing");
|
|
173
|
-
startTimer();
|
|
206
|
+
sm.setState("playing");
|
|
207
|
+
sm.startTimer();
|
|
174
208
|
emitter.emit("play", void 0);
|
|
175
209
|
return {
|
|
176
|
-
getState: () =>
|
|
210
|
+
getState: () => sm.getState(),
|
|
177
211
|
getCurrentTime,
|
|
178
212
|
getDuration: () => duration,
|
|
179
213
|
getProgress: () => duration > 0 ? getCurrentTime() / duration : 0,
|
|
@@ -192,81 +226,84 @@ function play(ctx, buffer, options) {
|
|
|
192
226
|
function createStretchedPlayback(ctx, buffer, options) {
|
|
193
227
|
const {
|
|
194
228
|
offset: initialOffset = 0,
|
|
229
|
+
loop = false,
|
|
195
230
|
playbackRate: initialRate = 1,
|
|
196
231
|
through = [],
|
|
197
232
|
destination = ctx.destination,
|
|
198
233
|
timeupdateInterval = 50
|
|
199
234
|
} = options;
|
|
200
|
-
const emitter =
|
|
235
|
+
const emitter = chunkHIF3UAF3_cjs.createEmitter();
|
|
201
236
|
const duration = buffer.duration;
|
|
202
|
-
let state = "playing";
|
|
203
237
|
let engineInstance = null;
|
|
204
|
-
let
|
|
205
|
-
let
|
|
206
|
-
let currentRate = initialRate;
|
|
238
|
+
let currentRate = initialRate > 0 ? initialRate : 1;
|
|
239
|
+
let isLooping = loop;
|
|
207
240
|
let pendingSeek = null;
|
|
241
|
+
const sm = createPlaybackStateManager({
|
|
242
|
+
initialState: "playing",
|
|
243
|
+
onStateChange: (next) => emitter.emit("statechange", { state: next }),
|
|
244
|
+
onTimerTick: () => {
|
|
245
|
+
emitter.emit("timeupdate", {
|
|
246
|
+
position: getCurrentTime(),
|
|
247
|
+
duration
|
|
248
|
+
});
|
|
249
|
+
},
|
|
250
|
+
timerInterval: timeupdateInterval
|
|
251
|
+
});
|
|
208
252
|
emitter.emit("statechange", { state: "playing" });
|
|
209
253
|
emitter.emit("play", void 0);
|
|
210
|
-
import('./engine-
|
|
211
|
-
if (
|
|
254
|
+
import('./engine-ALWPAIX6.cjs').then(({ createStretcherEngine }) => {
|
|
255
|
+
if (sm.isDisposed()) return;
|
|
212
256
|
engineInstance = createStretcherEngine(ctx, buffer, {
|
|
213
257
|
tempo: currentRate,
|
|
214
258
|
offset: initialOffset,
|
|
259
|
+
loop: isLooping,
|
|
215
260
|
through,
|
|
216
261
|
destination,
|
|
217
262
|
timeupdateInterval
|
|
218
263
|
});
|
|
219
264
|
engineInstance.on("buffering", (data) => {
|
|
220
|
-
if (
|
|
265
|
+
if (sm.isDisposed()) return;
|
|
221
266
|
emitter.emit("buffering", data);
|
|
222
267
|
});
|
|
223
268
|
engineInstance.on("buffered", (data) => {
|
|
224
|
-
if (
|
|
269
|
+
if (sm.isDisposed()) return;
|
|
225
270
|
emitter.emit("buffered", data);
|
|
226
271
|
});
|
|
272
|
+
engineInstance.on("loop", () => {
|
|
273
|
+
if (sm.isDisposed()) return;
|
|
274
|
+
emitter.emit("loop", void 0);
|
|
275
|
+
});
|
|
227
276
|
engineInstance.on("ended", () => {
|
|
228
|
-
if (
|
|
229
|
-
|
|
230
|
-
stopTimer();
|
|
231
|
-
|
|
277
|
+
if (sm.isDisposed()) return;
|
|
278
|
+
if (sm.getState() === "stopped") return;
|
|
279
|
+
sm.stopTimer();
|
|
280
|
+
sm.setState("stopped");
|
|
232
281
|
emitter.emit("ended", void 0);
|
|
233
282
|
});
|
|
234
283
|
engineInstance.on("error", (data) => {
|
|
235
|
-
if (
|
|
284
|
+
if (sm.isDisposed()) return;
|
|
236
285
|
if (data.fatal) {
|
|
237
|
-
|
|
238
|
-
emitter.emit("statechange", { state: "stopped" });
|
|
286
|
+
sm.setState("stopped");
|
|
239
287
|
emitter.emit("ended", void 0);
|
|
240
288
|
}
|
|
241
289
|
});
|
|
242
290
|
engineInstance.start();
|
|
243
|
-
startTimer();
|
|
291
|
+
sm.startTimer();
|
|
244
292
|
if (pendingSeek !== null) {
|
|
245
293
|
engineInstance.seek(pendingSeek);
|
|
246
294
|
pendingSeek = null;
|
|
247
295
|
}
|
|
248
|
-
if (
|
|
296
|
+
if (sm.getState() === "paused") {
|
|
249
297
|
engineInstance.pause();
|
|
250
|
-
} else if (
|
|
298
|
+
} else if (sm.getState() === "stopped") {
|
|
251
299
|
engineInstance.stop();
|
|
252
300
|
}
|
|
301
|
+
}).catch(() => {
|
|
302
|
+
if (sm.isDisposed()) return;
|
|
303
|
+
sm.stopTimer();
|
|
304
|
+
sm.setState("stopped");
|
|
305
|
+
emitter.emit("ended", void 0);
|
|
253
306
|
});
|
|
254
|
-
function startTimer() {
|
|
255
|
-
if (timerId !== null) return;
|
|
256
|
-
timerId = setInterval(() => {
|
|
257
|
-
if (state !== "playing" || disposed) return;
|
|
258
|
-
emitter.emit("timeupdate", {
|
|
259
|
-
position: getCurrentTime(),
|
|
260
|
-
duration
|
|
261
|
-
});
|
|
262
|
-
}, timeupdateInterval);
|
|
263
|
-
}
|
|
264
|
-
function stopTimer() {
|
|
265
|
-
if (timerId !== null) {
|
|
266
|
-
clearInterval(timerId);
|
|
267
|
-
timerId = null;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
307
|
function getCurrentTime() {
|
|
271
308
|
if (pendingSeek !== null) {
|
|
272
309
|
return pendingSeek;
|
|
@@ -277,27 +314,25 @@ function createStretchedPlayback(ctx, buffer, options) {
|
|
|
277
314
|
return initialOffset;
|
|
278
315
|
}
|
|
279
316
|
function pause() {
|
|
280
|
-
if (
|
|
281
|
-
state = "paused";
|
|
317
|
+
if (sm.getState() !== "playing" || sm.isDisposed()) return;
|
|
282
318
|
engineInstance?.pause();
|
|
283
|
-
stopTimer();
|
|
284
|
-
|
|
319
|
+
sm.stopTimer();
|
|
320
|
+
sm.setState("paused");
|
|
285
321
|
emitter.emit("pause", void 0);
|
|
286
322
|
}
|
|
287
323
|
function resume() {
|
|
288
|
-
if (
|
|
289
|
-
state = "playing";
|
|
324
|
+
if (sm.getState() !== "paused" || sm.isDisposed()) return;
|
|
290
325
|
engineInstance?.resume();
|
|
291
|
-
startTimer();
|
|
292
|
-
|
|
326
|
+
sm.startTimer();
|
|
327
|
+
sm.setState("playing");
|
|
293
328
|
emitter.emit("resume", void 0);
|
|
294
329
|
}
|
|
295
330
|
function togglePlayPause() {
|
|
296
|
-
if (
|
|
297
|
-
else if (
|
|
331
|
+
if (sm.getState() === "playing") pause();
|
|
332
|
+
else if (sm.getState() === "paused") resume();
|
|
298
333
|
}
|
|
299
334
|
function seek(position) {
|
|
300
|
-
if (
|
|
335
|
+
if (sm.isDisposed()) return;
|
|
301
336
|
const clamped = Math.max(0, Math.min(position, duration));
|
|
302
337
|
if (engineInstance) {
|
|
303
338
|
engineInstance.seek(clamped);
|
|
@@ -307,25 +342,26 @@ function createStretchedPlayback(ctx, buffer, options) {
|
|
|
307
342
|
emitter.emit("seek", { position: clamped });
|
|
308
343
|
}
|
|
309
344
|
function stop() {
|
|
310
|
-
if (
|
|
311
|
-
state = "stopped";
|
|
345
|
+
if (sm.getState() === "stopped" || sm.isDisposed()) return;
|
|
312
346
|
engineInstance?.stop();
|
|
313
|
-
stopTimer();
|
|
314
|
-
|
|
347
|
+
sm.stopTimer();
|
|
348
|
+
sm.setState("stopped");
|
|
315
349
|
emitter.emit("stop", void 0);
|
|
316
350
|
}
|
|
317
351
|
function setPlaybackRate(rate) {
|
|
352
|
+
if (rate <= 0) return;
|
|
318
353
|
currentRate = rate;
|
|
319
354
|
if (engineInstance) {
|
|
320
355
|
engineInstance.setTempo(rate);
|
|
321
356
|
}
|
|
322
357
|
}
|
|
323
|
-
function setLoop(
|
|
358
|
+
function setLoop(value) {
|
|
359
|
+
isLooping = value;
|
|
360
|
+
engineInstance?.setLoop(value);
|
|
324
361
|
}
|
|
325
362
|
function dispose() {
|
|
326
|
-
if (
|
|
327
|
-
|
|
328
|
-
stopTimer();
|
|
363
|
+
if (sm.isDisposed()) return;
|
|
364
|
+
sm.markDisposed();
|
|
329
365
|
engineInstance?.dispose();
|
|
330
366
|
emitter.clear();
|
|
331
367
|
}
|
|
@@ -334,7 +370,7 @@ function createStretchedPlayback(ctx, buffer, options) {
|
|
|
334
370
|
return engineInstance.getSnapshot();
|
|
335
371
|
}
|
|
336
372
|
const playback = {
|
|
337
|
-
getState: () =>
|
|
373
|
+
getState: () => sm.getState(),
|
|
338
374
|
getCurrentTime,
|
|
339
375
|
getDuration: () => duration,
|
|
340
376
|
getProgress: () => duration > 0 ? getCurrentTime() / duration : 0,
|
|
@@ -354,5 +390,5 @@ function createStretchedPlayback(ctx, buffer, options) {
|
|
|
354
390
|
}
|
|
355
391
|
|
|
356
392
|
exports.play = play;
|
|
357
|
-
//# sourceMappingURL=chunk-
|
|
358
|
-
//# sourceMappingURL=chunk-
|
|
393
|
+
//# sourceMappingURL=chunk-VY4UMZMJ.cjs.map
|
|
394
|
+
//# sourceMappingURL=chunk-VY4UMZMJ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/playback-position.ts","../src/playback-state.ts","../src/play.ts"],"names":["createEmitter"],"mappings":"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","file":"chunk-VY4UMZMJ.cjs","sourcesContent":["// ---------------------------------------------------------------------------\n// Pure functions for playback position calculation\n// ---------------------------------------------------------------------------\n\n/**\n * Calculate the current position within a loop region.\n *\n * Uses a true modulo (always non-negative) to avoid the JS `%` sign-preservation\n * issue where `elapsed < loopStart` would produce a value outside the loop region.\n *\n * Returns `null` when the loop region is invalid (loopDur <= 0) so the caller\n * can fall back to non-loop behaviour.\n */\nexport function calcLoopPosition(\n elapsed: number,\n loopStart: number,\n loopEnd: number,\n): number | null {\n const loopDur = loopEnd - loopStart;\n if (loopDur <= 0) return null;\n const offset = elapsed - loopStart;\n return (((offset % loopDur) + loopDur) % loopDur) + loopStart;\n}\n\n/**\n * Calculate the playback position for a given state.\n *\n * Pure function — no side effects, no dependency on AudioContext.\n */\nexport function calcPlaybackPosition(\n state: \"playing\" | \"paused\" | \"stopped\",\n elapsed: number,\n duration: number,\n pausedAt: number,\n isLooping: boolean,\n loopStart: number | undefined,\n loopEnd: number | undefined,\n): number {\n if (state === \"paused\") return pausedAt;\n if (state === \"stopped\") return 0;\n\n // state === \"playing\"\n if (isLooping) {\n const looped = calcLoopPosition(elapsed, loopStart ?? 0, loopEnd ?? duration);\n // Invalid loop region → fall back to non-loop clamping\n if (looped !== null) return looped;\n }\n return Math.min(Math.max(elapsed, 0), duration);\n}\n","// ---------------------------------------------------------------------------\n// Shared playback state management (used by both normal and stretched modes)\n// ---------------------------------------------------------------------------\n\nimport type { PlaybackState } from \"./types.js\";\n\nexport interface PlaybackStateManager {\n getState(): PlaybackState;\n setState(next: PlaybackState): boolean;\n startTimer(): void;\n stopTimer(): void;\n isDisposed(): boolean;\n markDisposed(): void;\n}\n\n/**\n * Create a reusable state manager that encapsulates the setState / startTimer /\n * stopTimer / dispose pattern shared between normal and stretched playback.\n */\nexport function createPlaybackStateManager(opts: {\n initialState: PlaybackState;\n onStateChange: (state: PlaybackState) => void;\n onTimerTick: () => void;\n timerInterval: number;\n}): PlaybackStateManager {\n let state: PlaybackState = opts.initialState;\n let timerId: ReturnType<typeof setInterval> | null = null;\n let disposed = false;\n\n function getState(): PlaybackState {\n return state;\n }\n\n /** Returns `true` if state actually changed. */\n function setState(next: PlaybackState): boolean {\n if (state === next) return false;\n state = next;\n opts.onStateChange(next);\n return true;\n }\n\n function startTimer(): void {\n if (timerId !== null) return;\n timerId = setInterval(() => {\n if (state !== \"playing\" || disposed) return;\n opts.onTimerTick();\n }, opts.timerInterval);\n }\n\n function stopTimer(): void {\n if (timerId !== null) {\n clearInterval(timerId);\n timerId = null;\n }\n }\n\n function isDisposed(): boolean {\n return disposed;\n }\n\n function markDisposed(): void {\n disposed = true;\n stopTimer();\n }\n\n return { getState, setState, startTimer, stopTimer, isDisposed, markDisposed };\n}\n","// ---------------------------------------------------------------------------\n// M3: Playback engine\n// ---------------------------------------------------------------------------\n\nimport { createEmitter } from \"./emitter.js\";\nimport { calcPlaybackPosition } from \"./playback-position.js\";\nimport { createPlaybackStateManager } from \"./playback-state.js\";\nimport type {\n Playback,\n PlaybackEventMap,\n PlayOptions,\n StretcherSnapshotExtension,\n} from \"./types.js\";\n\n/**\n * Play an `AudioBuffer` through an `AudioContext` and return a controllable\n * `Playback` handle.\n *\n * ```ts\n * const pb = play(ctx, buffer, { loop: true });\n * pb.on(\"timeupdate\", ({ position }) => console.log(position));\n * pb.pause();\n * pb.resume();\n * pb.seek(10);\n * pb.stop();\n * pb.dispose();\n * ```\n */\nexport function play(ctx: AudioContext, buffer: AudioBuffer, options?: PlayOptions): Playback {\n const { preservePitch = true } = options ?? {};\n\n // ----- Pitch-preserving mode (WSOLA-based time-stretch) -----\n if (preservePitch) {\n return createStretchedPlayback(ctx, buffer, options ?? {});\n }\n\n const {\n offset: initialOffset = 0,\n loop = false,\n loopStart,\n loopEnd,\n playbackRate: initialRate = 1,\n through = [],\n destination = ctx.destination,\n timeupdateInterval = 50,\n } = options ?? {};\n\n const emitter = createEmitter<PlaybackEventMap>();\n const duration = buffer.duration;\n\n // ----- mutable internal state -----\n let sourceNode: AudioBufferSourceNode | null = null;\n let startedAt = 0; // ctx.currentTime when playback last started/resumed\n let pausedAt = initialOffset; // position in the buffer (seconds)\n let currentRate = initialRate > 0 ? initialRate : 1;\n let isLooping = loop;\n\n const sm = createPlaybackStateManager({\n initialState: \"stopped\",\n onStateChange: (next) => emitter.emit(\"statechange\", { state: next }),\n onTimerTick: () => {\n emitter.emit(\"timeupdate\", {\n position: getCurrentTime(),\n duration,\n });\n },\n timerInterval: timeupdateInterval,\n });\n\n // ----- helpers -----\n\n function createSource(): AudioBufferSourceNode {\n const src = ctx.createBufferSource();\n src.buffer = buffer;\n src.playbackRate.value = currentRate;\n src.loop = isLooping;\n if (loopStart !== undefined) src.loopStart = loopStart;\n if (loopEnd !== undefined) src.loopEnd = loopEnd;\n\n // Connect through the node chain (or directly to destination).\n if (through.length > 0) {\n src.connect(through[0]!);\n for (let i = 0; i < through.length - 1; i++) {\n through[i]!.connect(through[i + 1]!);\n }\n through[through.length - 1]!.connect(destination);\n } else {\n src.connect(destination);\n }\n\n src.onended = handleEnded;\n return src;\n }\n\n function startSource(positionInBuffer: number) {\n sourceNode = createSource();\n sourceNode.start(0, positionInBuffer);\n startedAt = ctx.currentTime - positionInBuffer / currentRate;\n }\n\n function stopSource() {\n if (sourceNode) {\n sourceNode.onended = null;\n try {\n sourceNode.stop();\n } catch {\n // Already stopped — safe to ignore.\n }\n sourceNode.disconnect();\n sourceNode = null;\n }\n }\n\n function handleEnded() {\n // If we manually stopped / paused, the handler was already removed.\n if (sm.getState() !== \"playing\") return;\n if (isLooping) {\n emitter.emit(\"loop\", undefined as never);\n return;\n }\n sm.setState(\"stopped\");\n pausedAt = 0;\n sm.stopTimer();\n emitter.emit(\"ended\", undefined as never);\n }\n\n // ----- public API -----\n\n function getCurrentTime(): number {\n const state = sm.getState();\n const elapsed = state === \"playing\" ? (ctx.currentTime - startedAt) * currentRate : 0;\n return calcPlaybackPosition(state, elapsed, duration, pausedAt, isLooping, loopStart, loopEnd);\n }\n\n function pause() {\n if (sm.getState() !== \"playing\" || sm.isDisposed()) return;\n pausedAt = getCurrentTime();\n stopSource();\n sm.stopTimer();\n sm.setState(\"paused\");\n emitter.emit(\"pause\", undefined as never);\n }\n\n function resume() {\n if (sm.getState() !== \"paused\" || sm.isDisposed()) return;\n startSource(pausedAt);\n sm.setState(\"playing\");\n sm.startTimer();\n emitter.emit(\"resume\", undefined as never);\n }\n\n function togglePlayPause() {\n if (sm.getState() === \"playing\") pause();\n else if (sm.getState() === \"paused\") resume();\n }\n\n function seek(position: number) {\n if (sm.isDisposed()) return;\n const clamped = Math.max(0, Math.min(position, duration));\n const wasPlaying = sm.getState() === \"playing\";\n\n stopSource();\n sm.stopTimer();\n\n pausedAt = clamped;\n\n if (wasPlaying) {\n startSource(clamped);\n sm.startTimer();\n }\n\n emitter.emit(\"seek\", { position: clamped });\n }\n\n function stop() {\n if (sm.getState() === \"stopped\" || sm.isDisposed()) return;\n stopSource();\n sm.stopTimer();\n pausedAt = 0;\n sm.setState(\"stopped\");\n emitter.emit(\"stop\", undefined as never);\n }\n\n function setPlaybackRate(rate: number) {\n if (rate <= 0) return;\n const position = getCurrentTime();\n currentRate = rate;\n if (sourceNode) {\n sourceNode.playbackRate.value = rate;\n startedAt = ctx.currentTime - position / rate;\n }\n }\n\n function setLoop(value: boolean) {\n isLooping = value;\n if (sourceNode) {\n sourceNode.loop = value;\n }\n }\n\n function dispose() {\n if (sm.isDisposed()) return;\n sm.markDisposed();\n stopSource();\n emitter.clear();\n }\n\n // ----- kick off initial playback -----\n\n startSource(initialOffset);\n sm.setState(\"playing\");\n sm.startTimer();\n emitter.emit(\"play\", undefined as never);\n\n return {\n getState: () => sm.getState(),\n getCurrentTime,\n getDuration: () => duration,\n getProgress: () => (duration > 0 ? getCurrentTime() / duration : 0),\n pause,\n resume,\n togglePlayPause,\n seek,\n stop,\n setPlaybackRate,\n setLoop,\n on: emitter.on.bind(emitter) as Playback[\"on\"],\n off: emitter.off.bind(emitter) as Playback[\"off\"],\n dispose,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Stretched playback (preservePitch: true)\n// ---------------------------------------------------------------------------\n\nfunction createStretchedPlayback(\n ctx: AudioContext,\n buffer: AudioBuffer,\n options: PlayOptions,\n): Playback {\n const {\n offset: initialOffset = 0,\n loop = false,\n playbackRate: initialRate = 1,\n through = [],\n destination = ctx.destination,\n timeupdateInterval = 50,\n } = options;\n\n const emitter = createEmitter<PlaybackEventMap>();\n const duration = buffer.duration;\n\n let engineInstance: import(\"./stretcher/types.js\").StretcherEngine | null = null;\n let currentRate = initialRate > 0 ? initialRate : 1;\n let isLooping = loop;\n let pendingSeek: number | null = null;\n\n const sm = createPlaybackStateManager({\n initialState: \"playing\",\n onStateChange: (next) => emitter.emit(\"statechange\", { state: next }),\n onTimerTick: () => {\n emitter.emit(\"timeupdate\", {\n position: getCurrentTime(),\n duration,\n });\n },\n timerInterval: timeupdateInterval,\n });\n\n // Emit initial play event\n emitter.emit(\"statechange\", { state: \"playing\" });\n emitter.emit(\"play\", undefined as never);\n\n // Fire-and-forget dynamic import of the stretcher engine\n import(\"./stretcher/engine.js\")\n .then(({ createStretcherEngine }) => {\n if (sm.isDisposed()) return;\n\n engineInstance = createStretcherEngine(ctx, buffer, {\n tempo: currentRate,\n offset: initialOffset,\n loop: isLooping,\n through,\n destination,\n timeupdateInterval,\n });\n\n // Wire stretcher events to playback events\n engineInstance.on(\"buffering\", (data) => {\n if (sm.isDisposed()) return;\n emitter.emit(\"buffering\", data);\n });\n\n engineInstance.on(\"buffered\", (data) => {\n if (sm.isDisposed()) return;\n emitter.emit(\"buffered\", data);\n });\n\n engineInstance.on(\"loop\", () => {\n if (sm.isDisposed()) return;\n emitter.emit(\"loop\", undefined as never);\n });\n\n engineInstance.on(\"ended\", () => {\n if (sm.isDisposed()) return;\n if (sm.getState() === \"stopped\") return;\n sm.stopTimer();\n sm.setState(\"stopped\");\n emitter.emit(\"ended\", undefined as never);\n });\n\n engineInstance.on(\"error\", (data) => {\n if (sm.isDisposed()) return;\n if (data.fatal) {\n sm.setState(\"stopped\");\n emitter.emit(\"ended\", undefined as never);\n }\n });\n\n // Start engine and timeupdate timer\n engineInstance.start();\n sm.startTimer();\n\n // Apply pending seek if any\n if (pendingSeek !== null) {\n engineInstance.seek(pendingSeek);\n pendingSeek = null;\n }\n\n // If we were paused before the engine loaded, pause it\n if (sm.getState() === \"paused\") {\n engineInstance.pause();\n } else if (sm.getState() === \"stopped\") {\n engineInstance.stop();\n }\n })\n .catch(() => {\n if (sm.isDisposed()) return;\n sm.stopTimer();\n sm.setState(\"stopped\");\n emitter.emit(\"ended\", undefined as never);\n });\n\n function getCurrentTime(): number {\n if (pendingSeek !== null) {\n return pendingSeek;\n }\n if (engineInstance) {\n return engineInstance.getCurrentPosition();\n }\n return initialOffset;\n }\n\n function pause() {\n if (sm.getState() !== \"playing\" || sm.isDisposed()) return;\n engineInstance?.pause();\n sm.stopTimer();\n sm.setState(\"paused\");\n emitter.emit(\"pause\", undefined as never);\n }\n\n function resume() {\n if (sm.getState() !== \"paused\" || sm.isDisposed()) return;\n engineInstance?.resume();\n sm.startTimer();\n sm.setState(\"playing\");\n emitter.emit(\"resume\", undefined as never);\n }\n\n function togglePlayPause() {\n if (sm.getState() === \"playing\") pause();\n else if (sm.getState() === \"paused\") resume();\n }\n\n function seek(position: number) {\n if (sm.isDisposed()) return;\n const clamped = Math.max(0, Math.min(position, duration));\n if (engineInstance) {\n engineInstance.seek(clamped);\n } else {\n pendingSeek = clamped;\n }\n emitter.emit(\"seek\", { position: clamped });\n }\n\n function stop() {\n if (sm.getState() === \"stopped\" || sm.isDisposed()) return;\n engineInstance?.stop();\n sm.stopTimer();\n sm.setState(\"stopped\");\n emitter.emit(\"stop\", undefined as never);\n }\n\n function setPlaybackRate(rate: number) {\n if (rate <= 0) return;\n currentRate = rate;\n if (engineInstance) {\n engineInstance.setTempo(rate);\n }\n }\n\n function setLoop(value: boolean) {\n isLooping = value;\n engineInstance?.setLoop(value);\n }\n\n function dispose() {\n if (sm.isDisposed()) return;\n sm.markDisposed();\n engineInstance?.dispose();\n emitter.clear();\n }\n\n function _getStretcherSnapshot(): StretcherSnapshotExtension | null {\n if (!engineInstance) return null;\n return engineInstance.getSnapshot();\n }\n\n const playback: Playback & {\n _getStretcherSnapshot: typeof _getStretcherSnapshot;\n } = {\n getState: () => sm.getState(),\n getCurrentTime,\n getDuration: () => duration,\n getProgress: () => (duration > 0 ? getCurrentTime() / duration : 0),\n pause,\n resume,\n togglePlayPause,\n seek,\n stop,\n setPlaybackRate,\n setLoop,\n on: emitter.on.bind(emitter) as Playback[\"on\"],\n off: emitter.off.bind(emitter) as Playback[\"off\"],\n dispose,\n _getStretcherSnapshot,\n };\n\n return playback;\n}\n"]}
|
|
@@ -29,5 +29,5 @@ function createClickBuffer(ctx, frequency, duration) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export { createClickBuffer, createNoiseBuffer, createSineBuffer };
|
|
32
|
-
//# sourceMappingURL=chunk-
|
|
33
|
-
//# sourceMappingURL=chunk-
|
|
32
|
+
//# sourceMappingURL=chunk-YFK7ETCF.js.map
|
|
33
|
+
//# sourceMappingURL=chunk-YFK7ETCF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/synth.ts"],"names":[],"mappings":";AAQO,SAAS,gBAAA,CACd,GAAA,EACA,SAAA,EACA,QAAA,EACa;AACb,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,aAAa,QAAQ,CAAA;AAClD,EAAA,MAAM,SAAS,GAAA,CAAI,YAAA,CAAa,CAAA,EAAG,MAAA,EAAQ,IAAI,UAAU,CAAA;AACzD,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,cAAA,CAAe,CAAC,CAAA;AAEpC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAC/B,IAAA,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,CAAK,GAAA,CAAK,CAAA,GAAI,KAAK,EAAA,GAAK,SAAA,GAAY,CAAA,GAAK,GAAA,CAAI,UAAU,CAAA;AAAA,EACnE;AAEA,EAAA,OAAO,MAAA;AACT;AAKO,SAAS,iBAAA,CAAkB,KAAmB,QAAA,EAA+B;AAClF,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,aAAa,QAAQ,CAAA;AAClD,EAAA,MAAM,SAAS,GAAA,CAAI,YAAA,CAAa,CAAA,EAAG,MAAA,EAAQ,IAAI,UAAU,CAAA;AACzD,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,cAAA,CAAe,CAAC,CAAA;AAEpC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAC/B,IAAA,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,CAAK,MAAA,KAAW,CAAA,GAAI,CAAA;AAAA,EAChC;AAEA,EAAA,OAAO,MAAA;AACT;AAKO,SAAS,iBAAA,CACd,GAAA,EACA,SAAA,EACA,QAAA,EACa;AACb,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,aAAa,QAAQ,CAAA;AAClD,EAAA,MAAM,SAAS,GAAA,CAAI,YAAA,CAAa,CAAA,EAAG,MAAA,EAAQ,IAAI,UAAU,CAAA;AACzD,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,cAAA,CAAe,CAAC,CAAA;AAEpC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAE/B,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAK,EAAA,GAAK,IAAK,MAAM,CAAA;AAC3C,IAAA,IAAA,CAAK,CAAC,CAAA,GAAI,QAAA,GAAW,IAAA,CAAK,GAAA,CAAK,CAAA,GAAI,IAAA,CAAK,EAAA,GAAK,SAAA,GAAY,CAAA,GAAK,GAAA,CAAI,UAAU,CAAA;AAAA,EAC9E;AAEA,EAAA,OAAO,MAAA;AACT","file":"chunk-YFK7ETCF.js","sourcesContent":["// ---------------------------------------------------------------------------\n// M9: Buffer synthesis\n// ---------------------------------------------------------------------------\n\n/**\n * Create an `AudioBuffer` containing a sine wave.\n * Useful for test tones and debugging.\n */\nexport function createSineBuffer(\n ctx: AudioContext,\n frequency: number,\n duration: number,\n): AudioBuffer {\n const length = Math.ceil(ctx.sampleRate * duration);\n const buffer = ctx.createBuffer(1, length, ctx.sampleRate);\n const data = buffer.getChannelData(0);\n\n for (let i = 0; i < length; i++) {\n data[i] = Math.sin((2 * Math.PI * frequency * i) / ctx.sampleRate);\n }\n\n return buffer;\n}\n\n/**\n * Create an `AudioBuffer` containing white noise.\n */\nexport function createNoiseBuffer(ctx: AudioContext, duration: number): AudioBuffer {\n const length = Math.ceil(ctx.sampleRate * duration);\n const buffer = ctx.createBuffer(1, length, ctx.sampleRate);\n const data = buffer.getChannelData(0);\n\n for (let i = 0; i < length; i++) {\n data[i] = Math.random() * 2 - 1;\n }\n\n return buffer;\n}\n\n/**\n * Create an `AudioBuffer` containing a short click/impulse.\n */\nexport function createClickBuffer(\n ctx: AudioContext,\n frequency: number,\n duration: number,\n): AudioBuffer {\n const length = Math.ceil(ctx.sampleRate * duration);\n const buffer = ctx.createBuffer(1, length, ctx.sampleRate);\n const data = buffer.getChannelData(0);\n\n for (let i = 0; i < length; i++) {\n // Exponential decay envelope.\n const envelope = Math.exp((-5 * i) / length);\n data[i] = envelope * Math.sin((2 * Math.PI * frequency * i) / ctx.sampleRate);\n }\n\n return buffer;\n}\n"]}
|
package/dist/context.d.cts
CHANGED
package/dist/context.d.ts
CHANGED
package/dist/emitter.cjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkHIF3UAF3_cjs = require('./chunk-HIF3UAF3.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
Object.defineProperty(exports, "createEmitter", {
|
|
8
8
|
enumerable: true,
|
|
9
|
-
get: function () { return
|
|
9
|
+
get: function () { return chunkHIF3UAF3_cjs.createEmitter; }
|
|
10
10
|
});
|
|
11
11
|
//# sourceMappingURL=emitter.cjs.map
|
|
12
12
|
//# sourceMappingURL=emitter.cjs.map
|
package/dist/emitter.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"engine-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"engine-7DCOERRN.js"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkG37HMZEX_cjs = require('./chunk-G37HMZEX.cjs');
|
|
4
|
+
require('./chunk-HIF3UAF3.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "createStretcherEngine", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunkG37HMZEX_cjs.createStretcherEngine; }
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "trimOverlap", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunkG37HMZEX_cjs.trimOverlap; }
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=engine-ALWPAIX6.cjs.map
|
|
17
|
+
//# sourceMappingURL=engine-ALWPAIX6.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"engine-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"engine-ALWPAIX6.cjs"}
|
package/dist/fade.cjs
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkOIY6I4TU_cjs = require('./chunk-OIY6I4TU.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
Object.defineProperty(exports, "autoFade", {
|
|
8
8
|
enumerable: true,
|
|
9
|
-
get: function () { return
|
|
9
|
+
get: function () { return chunkOIY6I4TU_cjs.autoFade; }
|
|
10
10
|
});
|
|
11
11
|
Object.defineProperty(exports, "crossfade", {
|
|
12
12
|
enumerable: true,
|
|
13
|
-
get: function () { return
|
|
13
|
+
get: function () { return chunkOIY6I4TU_cjs.crossfade; }
|
|
14
14
|
});
|
|
15
15
|
Object.defineProperty(exports, "fadeIn", {
|
|
16
16
|
enumerable: true,
|
|
17
|
-
get: function () { return
|
|
17
|
+
get: function () { return chunkOIY6I4TU_cjs.fadeIn; }
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports, "fadeOut", {
|
|
20
20
|
enumerable: true,
|
|
21
|
-
get: function () { return
|
|
21
|
+
get: function () { return chunkOIY6I4TU_cjs.fadeOut; }
|
|
22
22
|
});
|
|
23
23
|
//# sourceMappingURL=fade.cjs.map
|
|
24
24
|
//# sourceMappingURL=fade.cjs.map
|
package/dist/fade.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { e as Playback, A as AutoFadeOptions, b as CrossfadeOptions, c as FadeOptions } from './types-
|
|
1
|
+
import { e as Playback, A as AutoFadeOptions, b as CrossfadeOptions, c as FadeOptions } from './types-BYC6m7Q0.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Fade a `GainNode` in from 0 to `target`.
|
package/dist/fade.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { e as Playback, A as AutoFadeOptions, b as CrossfadeOptions, c as FadeOptions } from './types-
|
|
1
|
+
import { e as Playback, A as AutoFadeOptions, b as CrossfadeOptions, c as FadeOptions } from './types-BYC6m7Q0.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Fade a `GainNode` in from 0 to `target`.
|
package/dist/fade.js
CHANGED