waa-play 0.2.0 → 0.2.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/README.md +41 -89
- package/dist/adapters.cjs +6 -6
- package/dist/adapters.d.cts +1 -1
- package/dist/adapters.d.ts +1 -1
- 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-CPAT75WD.cjs → chunk-3VTU5OX5.cjs} +2 -2
- package/dist/{chunk-2DL7CAEP.js → chunk-7JUVBZ6B.js} +2 -2
- package/dist/{chunk-D5CD5KQZ.cjs → chunk-BRS7LZVH.cjs} +2 -2
- package/dist/{chunk-QWNV2BZ5.cjs → chunk-F6WXD3XW.cjs} +2 -2
- package/dist/{chunk-C2ASIYN5.js → chunk-FESPIMZM.js} +3 -7
- package/dist/{chunk-GYH2JSCY.js → chunk-FY273Z3I.js} +2 -2
- package/dist/{chunk-SIMLANWE.cjs → chunk-G37HMZEX.cjs} +1028 -955
- package/dist/{chunk-2FFORBOP.js → chunk-GDBOHOGF.js} +1027 -955
- package/dist/{chunk-5J7S6QV3.cjs → chunk-HIF3UAF3.cjs} +2 -2
- package/dist/{chunk-CRODJ4KS.js → chunk-HTN52U23.js} +13 -6
- package/dist/{chunk-X4IFO7U7.js → chunk-HYRDCTBO.js} +143 -116
- package/dist/{chunk-VKT7YCWK.js → chunk-JIHPQAEA.js} +6 -3
- package/dist/chunk-KVKW7W66.cjs +148 -0
- package/dist/{chunk-4LNVRSTM.cjs → chunk-OIY6I4TU.cjs} +3 -7
- package/dist/{chunk-7S5KWTZ6.cjs → chunk-OZN5X4N6.cjs} +6 -3
- package/dist/{chunk-CJJC6ASU.js → chunk-PL4J3NR7.js} +2 -2
- package/dist/{chunk-IMNRPYBM.js → chunk-QFJQU7TQ.js} +10 -10
- package/dist/{chunk-M5PDY5EZ.cjs → chunk-QGZGERGK.cjs} +2 -2
- package/dist/{chunk-QFFQQMU4.cjs → chunk-VOSIA3GF.cjs} +13 -6
- package/dist/{chunk-CTUCTTIE.cjs → chunk-VY4UMZMJ.cjs} +145 -118
- package/dist/{chunk-LETS7FKB.js → chunk-YFK7ETCF.js} +2 -2
- 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-ALWPAIX6.cjs +17 -0
- 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 +44 -44
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +10 -10
- 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 +11 -11
- package/dist/player.d.cts +1 -1
- package/dist/player.d.ts +1 -1
- package/dist/player.js +10 -10
- 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 +4 -4
- package/dist/stretcher.d.ts +4 -4
- 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 +14 -6
- package/dist/adapters.cjs.map +0 -1
- package/dist/adapters.js.map +0 -1
- package/dist/buffer.cjs.map +0 -1
- package/dist/buffer.js.map +0 -1
- package/dist/chunk-2DL7CAEP.js.map +0 -1
- package/dist/chunk-2FFORBOP.js.map +0 -1
- package/dist/chunk-37CPPRLV.js.map +0 -1
- package/dist/chunk-4LNVRSTM.cjs.map +0 -1
- package/dist/chunk-5J7S6QV3.cjs.map +0 -1
- package/dist/chunk-6UTN73HG.cjs.map +0 -1
- package/dist/chunk-7S5KWTZ6.cjs.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-CTUCTTIE.cjs.map +0 -1
- package/dist/chunk-D5CD5KQZ.cjs.map +0 -1
- package/dist/chunk-GYH2JSCY.js.map +0 -1
- package/dist/chunk-IMNRPYBM.js.map +0 -1
- package/dist/chunk-LETS7FKB.js.map +0 -1
- package/dist/chunk-M5PDY5EZ.cjs.map +0 -1
- package/dist/chunk-QFFQQMU4.cjs.map +0 -1
- package/dist/chunk-QWNV2BZ5.cjs.map +0 -1
- package/dist/chunk-SIMLANWE.cjs.map +0 -1
- package/dist/chunk-T74FBKTY.js.map +0 -1
- package/dist/chunk-VKT7YCWK.js.map +0 -1
- package/dist/chunk-X4IFO7U7.js.map +0 -1
- package/dist/chunk-XZBMBZA3.cjs +0 -148
- package/dist/chunk-XZBMBZA3.cjs.map +0 -1
- package/dist/context.cjs.map +0 -1
- package/dist/context.js.map +0 -1
- package/dist/emitter.cjs.map +0 -1
- package/dist/emitter.js.map +0 -1
- package/dist/engine-QUMYW73L.cjs +0 -13
- package/dist/engine-QUMYW73L.cjs.map +0 -1
- package/dist/engine-TYI7OX7O.js +0 -4
- package/dist/engine-TYI7OX7O.js.map +0 -1
- package/dist/fade.cjs.map +0 -1
- package/dist/fade.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/nodes.cjs.map +0 -1
- package/dist/nodes.js.map +0 -1
- package/dist/play.cjs.map +0 -1
- package/dist/play.js.map +0 -1
- package/dist/player.cjs.map +0 -1
- package/dist/player.js.map +0 -1
- package/dist/scheduler.cjs.map +0 -1
- package/dist/scheduler.js.map +0 -1
- package/dist/stretcher.cjs.map +0 -1
- package/dist/stretcher.js.map +0 -1
- package/dist/synth.cjs.map +0 -1
- package/dist/synth.js.map +0 -1
- package/dist/waveform.cjs.map +0 -1
- package/dist/waveform.js.map +0 -1
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
// src/waveform.ts
|
|
2
|
+
function calcBlockSize(dataLength, resolution) {
|
|
3
|
+
return Math.max(1, Math.floor(dataLength / resolution));
|
|
4
|
+
}
|
|
2
5
|
function extractPeaks(buffer, options) {
|
|
3
6
|
const { resolution = 200, channel = 0 } = options ?? {};
|
|
4
7
|
const data = buffer.getChannelData(channel);
|
|
5
|
-
const blockSize =
|
|
8
|
+
const blockSize = calcBlockSize(data.length, resolution);
|
|
6
9
|
const peaks = [];
|
|
7
10
|
for (let i = 0; i < resolution; i++) {
|
|
8
11
|
const start = i * blockSize;
|
|
@@ -19,7 +22,7 @@ function extractPeaks(buffer, options) {
|
|
|
19
22
|
function extractPeakPairs(buffer, options) {
|
|
20
23
|
const { resolution = 200, channel = 0 } = options ?? {};
|
|
21
24
|
const data = buffer.getChannelData(channel);
|
|
22
|
-
const blockSize =
|
|
25
|
+
const blockSize = calcBlockSize(data.length, resolution);
|
|
23
26
|
const pairs = [];
|
|
24
27
|
for (let i = 0; i < resolution; i++) {
|
|
25
28
|
const start = i * blockSize;
|
|
@@ -38,6 +41,9 @@ function extractPeakPairs(buffer, options) {
|
|
|
38
41
|
function extractRMS(buffer, options) {
|
|
39
42
|
const { resolution = 200, channel = 0 } = options ?? {};
|
|
40
43
|
if (channel === -1) {
|
|
44
|
+
if (buffer.numberOfChannels === 0) {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
41
47
|
const allChannels = [];
|
|
42
48
|
for (let ch = 0; ch < buffer.numberOfChannels; ch++) {
|
|
43
49
|
allChannels.push(extractRMS(buffer, { resolution, channel: ch }));
|
|
@@ -51,21 +57,22 @@ function extractRMS(buffer, options) {
|
|
|
51
57
|
});
|
|
52
58
|
}
|
|
53
59
|
const data = buffer.getChannelData(channel);
|
|
54
|
-
const blockSize =
|
|
60
|
+
const blockSize = calcBlockSize(data.length, resolution);
|
|
55
61
|
const rms = [];
|
|
56
62
|
for (let i = 0; i < resolution; i++) {
|
|
57
63
|
const start = i * blockSize;
|
|
58
64
|
const end = Math.min(start + blockSize, data.length);
|
|
59
65
|
let sumSq = 0;
|
|
66
|
+
const count = end - start;
|
|
60
67
|
for (let j = start; j < end; j++) {
|
|
61
68
|
const s = data[j];
|
|
62
69
|
sumSq += s * s;
|
|
63
70
|
}
|
|
64
|
-
rms.push(Math.sqrt(sumSq /
|
|
71
|
+
rms.push(count > 0 ? Math.sqrt(sumSq / count) : 0);
|
|
65
72
|
}
|
|
66
73
|
return rms;
|
|
67
74
|
}
|
|
68
75
|
|
|
69
76
|
export { extractPeakPairs, extractPeaks, extractRMS };
|
|
70
|
-
//# sourceMappingURL=chunk-
|
|
71
|
-
//# sourceMappingURL=chunk-
|
|
77
|
+
//# sourceMappingURL=chunk-HTN52U23.js.map
|
|
78
|
+
//# sourceMappingURL=chunk-HTN52U23.js.map
|
|
@@ -1,4 +1,58 @@
|
|
|
1
|
-
import { createEmitter } from './chunk-
|
|
1
|
+
import { createEmitter } from './chunk-FY273Z3I.js';
|
|
2
|
+
|
|
3
|
+
// src/playback-position.ts
|
|
4
|
+
function calcLoopPosition(elapsed, loopStart, loopEnd) {
|
|
5
|
+
const loopDur = loopEnd - loopStart;
|
|
6
|
+
if (loopDur <= 0) return null;
|
|
7
|
+
const offset = elapsed - loopStart;
|
|
8
|
+
return (offset % loopDur + loopDur) % loopDur + loopStart;
|
|
9
|
+
}
|
|
10
|
+
function calcPlaybackPosition(state, elapsed, duration, pausedAt, isLooping, loopStart, loopEnd) {
|
|
11
|
+
if (state === "paused") return pausedAt;
|
|
12
|
+
if (state === "stopped") return 0;
|
|
13
|
+
if (isLooping) {
|
|
14
|
+
const looped = calcLoopPosition(elapsed, loopStart ?? 0, loopEnd ?? duration);
|
|
15
|
+
if (looped !== null) return looped;
|
|
16
|
+
}
|
|
17
|
+
return Math.min(Math.max(elapsed, 0), duration);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// src/playback-state.ts
|
|
21
|
+
function createPlaybackStateManager(opts) {
|
|
22
|
+
let state = opts.initialState;
|
|
23
|
+
let timerId = null;
|
|
24
|
+
let disposed = false;
|
|
25
|
+
function getState() {
|
|
26
|
+
return state;
|
|
27
|
+
}
|
|
28
|
+
function setState(next) {
|
|
29
|
+
if (state === next) return false;
|
|
30
|
+
state = next;
|
|
31
|
+
opts.onStateChange(next);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
function startTimer() {
|
|
35
|
+
if (timerId !== null) return;
|
|
36
|
+
timerId = setInterval(() => {
|
|
37
|
+
if (state !== "playing" || disposed) return;
|
|
38
|
+
opts.onTimerTick();
|
|
39
|
+
}, opts.timerInterval);
|
|
40
|
+
}
|
|
41
|
+
function stopTimer() {
|
|
42
|
+
if (timerId !== null) {
|
|
43
|
+
clearInterval(timerId);
|
|
44
|
+
timerId = null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function isDisposed() {
|
|
48
|
+
return disposed;
|
|
49
|
+
}
|
|
50
|
+
function markDisposed() {
|
|
51
|
+
disposed = true;
|
|
52
|
+
stopTimer();
|
|
53
|
+
}
|
|
54
|
+
return { getState, setState, startTimer, stopTimer, isDisposed, markDisposed };
|
|
55
|
+
}
|
|
2
56
|
|
|
3
57
|
// src/play.ts
|
|
4
58
|
function play(ctx, buffer, options) {
|
|
@@ -18,14 +72,22 @@ function play(ctx, buffer, options) {
|
|
|
18
72
|
} = options ?? {};
|
|
19
73
|
const emitter = createEmitter();
|
|
20
74
|
const duration = buffer.duration;
|
|
21
|
-
let state = "stopped";
|
|
22
75
|
let sourceNode = null;
|
|
23
76
|
let startedAt = 0;
|
|
24
77
|
let pausedAt = initialOffset;
|
|
25
|
-
let currentRate = initialRate;
|
|
78
|
+
let currentRate = initialRate > 0 ? initialRate : 1;
|
|
26
79
|
let isLooping = loop;
|
|
27
|
-
|
|
28
|
-
|
|
80
|
+
const sm = createPlaybackStateManager({
|
|
81
|
+
initialState: "stopped",
|
|
82
|
+
onStateChange: (next) => emitter.emit("statechange", { state: next }),
|
|
83
|
+
onTimerTick: () => {
|
|
84
|
+
emitter.emit("timeupdate", {
|
|
85
|
+
position: getCurrentTime(),
|
|
86
|
+
duration
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
timerInterval: timeupdateInterval
|
|
90
|
+
});
|
|
29
91
|
function createSource() {
|
|
30
92
|
const src = ctx.createBufferSource();
|
|
31
93
|
src.buffer = buffer;
|
|
@@ -62,90 +124,63 @@ function play(ctx, buffer, options) {
|
|
|
62
124
|
}
|
|
63
125
|
}
|
|
64
126
|
function handleEnded() {
|
|
65
|
-
if (
|
|
127
|
+
if (sm.getState() !== "playing") return;
|
|
66
128
|
if (isLooping) {
|
|
67
129
|
emitter.emit("loop", void 0);
|
|
68
130
|
return;
|
|
69
131
|
}
|
|
70
|
-
setState("stopped");
|
|
132
|
+
sm.setState("stopped");
|
|
71
133
|
pausedAt = 0;
|
|
72
|
-
stopTimer();
|
|
134
|
+
sm.stopTimer();
|
|
73
135
|
emitter.emit("ended", void 0);
|
|
74
136
|
}
|
|
75
|
-
function setState(next) {
|
|
76
|
-
if (state === next) return;
|
|
77
|
-
state = next;
|
|
78
|
-
emitter.emit("statechange", { state: next });
|
|
79
|
-
}
|
|
80
|
-
function startTimer() {
|
|
81
|
-
if (timerId !== null) return;
|
|
82
|
-
timerId = setInterval(() => {
|
|
83
|
-
if (state !== "playing") return;
|
|
84
|
-
emitter.emit("timeupdate", {
|
|
85
|
-
position: getCurrentTime(),
|
|
86
|
-
duration
|
|
87
|
-
});
|
|
88
|
-
}, timeupdateInterval);
|
|
89
|
-
}
|
|
90
|
-
function stopTimer() {
|
|
91
|
-
if (timerId !== null) {
|
|
92
|
-
clearInterval(timerId);
|
|
93
|
-
timerId = null;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
137
|
function getCurrentTime() {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const loopDur = (loopEnd ?? duration) - (loopStart ?? 0);
|
|
101
|
-
return (elapsed - (loopStart ?? 0)) % loopDur + (loopStart ?? 0);
|
|
102
|
-
}
|
|
103
|
-
return Math.min(elapsed, duration);
|
|
104
|
-
}
|
|
105
|
-
if (state === "paused") return pausedAt;
|
|
106
|
-
return 0;
|
|
138
|
+
const state = sm.getState();
|
|
139
|
+
const elapsed = state === "playing" ? (ctx.currentTime - startedAt) * currentRate : 0;
|
|
140
|
+
return calcPlaybackPosition(state, elapsed, duration, pausedAt, isLooping, loopStart, loopEnd);
|
|
107
141
|
}
|
|
108
142
|
function pause() {
|
|
109
|
-
if (
|
|
143
|
+
if (sm.getState() !== "playing" || sm.isDisposed()) return;
|
|
110
144
|
pausedAt = getCurrentTime();
|
|
111
145
|
stopSource();
|
|
112
|
-
stopTimer();
|
|
113
|
-
setState("paused");
|
|
146
|
+
sm.stopTimer();
|
|
147
|
+
sm.setState("paused");
|
|
114
148
|
emitter.emit("pause", void 0);
|
|
115
149
|
}
|
|
116
150
|
function resume() {
|
|
117
|
-
if (
|
|
151
|
+
if (sm.getState() !== "paused" || sm.isDisposed()) return;
|
|
118
152
|
startSource(pausedAt);
|
|
119
|
-
setState("playing");
|
|
120
|
-
startTimer();
|
|
153
|
+
sm.setState("playing");
|
|
154
|
+
sm.startTimer();
|
|
121
155
|
emitter.emit("resume", void 0);
|
|
122
156
|
}
|
|
123
157
|
function togglePlayPause() {
|
|
124
|
-
if (
|
|
125
|
-
else if (
|
|
158
|
+
if (sm.getState() === "playing") pause();
|
|
159
|
+
else if (sm.getState() === "paused") resume();
|
|
126
160
|
}
|
|
127
161
|
function seek(position) {
|
|
128
|
-
if (
|
|
162
|
+
if (sm.isDisposed()) return;
|
|
129
163
|
const clamped = Math.max(0, Math.min(position, duration));
|
|
130
|
-
const wasPlaying =
|
|
164
|
+
const wasPlaying = sm.getState() === "playing";
|
|
131
165
|
stopSource();
|
|
132
|
-
stopTimer();
|
|
166
|
+
sm.stopTimer();
|
|
133
167
|
pausedAt = clamped;
|
|
134
168
|
if (wasPlaying) {
|
|
135
169
|
startSource(clamped);
|
|
136
|
-
startTimer();
|
|
170
|
+
sm.startTimer();
|
|
137
171
|
}
|
|
138
172
|
emitter.emit("seek", { position: clamped });
|
|
139
173
|
}
|
|
140
174
|
function stop() {
|
|
141
|
-
if (
|
|
175
|
+
if (sm.getState() === "stopped" || sm.isDisposed()) return;
|
|
142
176
|
stopSource();
|
|
143
|
-
stopTimer();
|
|
177
|
+
sm.stopTimer();
|
|
144
178
|
pausedAt = 0;
|
|
145
|
-
setState("stopped");
|
|
179
|
+
sm.setState("stopped");
|
|
146
180
|
emitter.emit("stop", void 0);
|
|
147
181
|
}
|
|
148
182
|
function setPlaybackRate(rate) {
|
|
183
|
+
if (rate <= 0) return;
|
|
149
184
|
const position = getCurrentTime();
|
|
150
185
|
currentRate = rate;
|
|
151
186
|
if (sourceNode) {
|
|
@@ -160,18 +195,17 @@ function play(ctx, buffer, options) {
|
|
|
160
195
|
}
|
|
161
196
|
}
|
|
162
197
|
function dispose() {
|
|
163
|
-
if (
|
|
164
|
-
|
|
198
|
+
if (sm.isDisposed()) return;
|
|
199
|
+
sm.markDisposed();
|
|
165
200
|
stopSource();
|
|
166
|
-
stopTimer();
|
|
167
201
|
emitter.clear();
|
|
168
202
|
}
|
|
169
203
|
startSource(initialOffset);
|
|
170
|
-
setState("playing");
|
|
171
|
-
startTimer();
|
|
204
|
+
sm.setState("playing");
|
|
205
|
+
sm.startTimer();
|
|
172
206
|
emitter.emit("play", void 0);
|
|
173
207
|
return {
|
|
174
|
-
getState: () =>
|
|
208
|
+
getState: () => sm.getState(),
|
|
175
209
|
getCurrentTime,
|
|
176
210
|
getDuration: () => duration,
|
|
177
211
|
getProgress: () => duration > 0 ? getCurrentTime() / duration : 0,
|
|
@@ -198,17 +232,25 @@ function createStretchedPlayback(ctx, buffer, options) {
|
|
|
198
232
|
} = options;
|
|
199
233
|
const emitter = createEmitter();
|
|
200
234
|
const duration = buffer.duration;
|
|
201
|
-
let state = "playing";
|
|
202
235
|
let engineInstance = null;
|
|
203
|
-
let
|
|
204
|
-
let disposed = false;
|
|
205
|
-
let currentRate = initialRate;
|
|
236
|
+
let currentRate = initialRate > 0 ? initialRate : 1;
|
|
206
237
|
let isLooping = loop;
|
|
207
238
|
let pendingSeek = null;
|
|
239
|
+
const sm = createPlaybackStateManager({
|
|
240
|
+
initialState: "playing",
|
|
241
|
+
onStateChange: (next) => emitter.emit("statechange", { state: next }),
|
|
242
|
+
onTimerTick: () => {
|
|
243
|
+
emitter.emit("timeupdate", {
|
|
244
|
+
position: getCurrentTime(),
|
|
245
|
+
duration
|
|
246
|
+
});
|
|
247
|
+
},
|
|
248
|
+
timerInterval: timeupdateInterval
|
|
249
|
+
});
|
|
208
250
|
emitter.emit("statechange", { state: "playing" });
|
|
209
251
|
emitter.emit("play", void 0);
|
|
210
|
-
import('./engine-
|
|
211
|
-
if (
|
|
252
|
+
import('./engine-7DCOERRN.js').then(({ createStretcherEngine }) => {
|
|
253
|
+
if (sm.isDisposed()) return;
|
|
212
254
|
engineInstance = createStretcherEngine(ctx, buffer, {
|
|
213
255
|
tempo: currentRate,
|
|
214
256
|
offset: initialOffset,
|
|
@@ -218,60 +260,48 @@ function createStretchedPlayback(ctx, buffer, options) {
|
|
|
218
260
|
timeupdateInterval
|
|
219
261
|
});
|
|
220
262
|
engineInstance.on("buffering", (data) => {
|
|
221
|
-
if (
|
|
263
|
+
if (sm.isDisposed()) return;
|
|
222
264
|
emitter.emit("buffering", data);
|
|
223
265
|
});
|
|
224
266
|
engineInstance.on("buffered", (data) => {
|
|
225
|
-
if (
|
|
267
|
+
if (sm.isDisposed()) return;
|
|
226
268
|
emitter.emit("buffered", data);
|
|
227
269
|
});
|
|
228
270
|
engineInstance.on("loop", () => {
|
|
229
|
-
if (
|
|
271
|
+
if (sm.isDisposed()) return;
|
|
230
272
|
emitter.emit("loop", void 0);
|
|
231
273
|
});
|
|
232
274
|
engineInstance.on("ended", () => {
|
|
233
|
-
if (
|
|
234
|
-
|
|
235
|
-
stopTimer();
|
|
236
|
-
|
|
275
|
+
if (sm.isDisposed()) return;
|
|
276
|
+
if (sm.getState() === "stopped") return;
|
|
277
|
+
sm.stopTimer();
|
|
278
|
+
sm.setState("stopped");
|
|
237
279
|
emitter.emit("ended", void 0);
|
|
238
280
|
});
|
|
239
281
|
engineInstance.on("error", (data) => {
|
|
240
|
-
if (
|
|
282
|
+
if (sm.isDisposed()) return;
|
|
241
283
|
if (data.fatal) {
|
|
242
|
-
|
|
243
|
-
emitter.emit("statechange", { state: "stopped" });
|
|
284
|
+
sm.setState("stopped");
|
|
244
285
|
emitter.emit("ended", void 0);
|
|
245
286
|
}
|
|
246
287
|
});
|
|
247
288
|
engineInstance.start();
|
|
248
|
-
startTimer();
|
|
289
|
+
sm.startTimer();
|
|
249
290
|
if (pendingSeek !== null) {
|
|
250
291
|
engineInstance.seek(pendingSeek);
|
|
251
292
|
pendingSeek = null;
|
|
252
293
|
}
|
|
253
|
-
if (
|
|
294
|
+
if (sm.getState() === "paused") {
|
|
254
295
|
engineInstance.pause();
|
|
255
|
-
} else if (
|
|
296
|
+
} else if (sm.getState() === "stopped") {
|
|
256
297
|
engineInstance.stop();
|
|
257
298
|
}
|
|
299
|
+
}).catch(() => {
|
|
300
|
+
if (sm.isDisposed()) return;
|
|
301
|
+
sm.stopTimer();
|
|
302
|
+
sm.setState("stopped");
|
|
303
|
+
emitter.emit("ended", void 0);
|
|
258
304
|
});
|
|
259
|
-
function startTimer() {
|
|
260
|
-
if (timerId !== null) return;
|
|
261
|
-
timerId = setInterval(() => {
|
|
262
|
-
if (state !== "playing" || disposed) return;
|
|
263
|
-
emitter.emit("timeupdate", {
|
|
264
|
-
position: getCurrentTime(),
|
|
265
|
-
duration
|
|
266
|
-
});
|
|
267
|
-
}, timeupdateInterval);
|
|
268
|
-
}
|
|
269
|
-
function stopTimer() {
|
|
270
|
-
if (timerId !== null) {
|
|
271
|
-
clearInterval(timerId);
|
|
272
|
-
timerId = null;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
305
|
function getCurrentTime() {
|
|
276
306
|
if (pendingSeek !== null) {
|
|
277
307
|
return pendingSeek;
|
|
@@ -282,27 +312,25 @@ function createStretchedPlayback(ctx, buffer, options) {
|
|
|
282
312
|
return initialOffset;
|
|
283
313
|
}
|
|
284
314
|
function pause() {
|
|
285
|
-
if (
|
|
286
|
-
state = "paused";
|
|
315
|
+
if (sm.getState() !== "playing" || sm.isDisposed()) return;
|
|
287
316
|
engineInstance?.pause();
|
|
288
|
-
stopTimer();
|
|
289
|
-
|
|
317
|
+
sm.stopTimer();
|
|
318
|
+
sm.setState("paused");
|
|
290
319
|
emitter.emit("pause", void 0);
|
|
291
320
|
}
|
|
292
321
|
function resume() {
|
|
293
|
-
if (
|
|
294
|
-
state = "playing";
|
|
322
|
+
if (sm.getState() !== "paused" || sm.isDisposed()) return;
|
|
295
323
|
engineInstance?.resume();
|
|
296
|
-
startTimer();
|
|
297
|
-
|
|
324
|
+
sm.startTimer();
|
|
325
|
+
sm.setState("playing");
|
|
298
326
|
emitter.emit("resume", void 0);
|
|
299
327
|
}
|
|
300
328
|
function togglePlayPause() {
|
|
301
|
-
if (
|
|
302
|
-
else if (
|
|
329
|
+
if (sm.getState() === "playing") pause();
|
|
330
|
+
else if (sm.getState() === "paused") resume();
|
|
303
331
|
}
|
|
304
332
|
function seek(position) {
|
|
305
|
-
if (
|
|
333
|
+
if (sm.isDisposed()) return;
|
|
306
334
|
const clamped = Math.max(0, Math.min(position, duration));
|
|
307
335
|
if (engineInstance) {
|
|
308
336
|
engineInstance.seek(clamped);
|
|
@@ -312,14 +340,14 @@ function createStretchedPlayback(ctx, buffer, options) {
|
|
|
312
340
|
emitter.emit("seek", { position: clamped });
|
|
313
341
|
}
|
|
314
342
|
function stop() {
|
|
315
|
-
if (
|
|
316
|
-
state = "stopped";
|
|
343
|
+
if (sm.getState() === "stopped" || sm.isDisposed()) return;
|
|
317
344
|
engineInstance?.stop();
|
|
318
|
-
stopTimer();
|
|
319
|
-
|
|
345
|
+
sm.stopTimer();
|
|
346
|
+
sm.setState("stopped");
|
|
320
347
|
emitter.emit("stop", void 0);
|
|
321
348
|
}
|
|
322
349
|
function setPlaybackRate(rate) {
|
|
350
|
+
if (rate <= 0) return;
|
|
323
351
|
currentRate = rate;
|
|
324
352
|
if (engineInstance) {
|
|
325
353
|
engineInstance.setTempo(rate);
|
|
@@ -330,9 +358,8 @@ function createStretchedPlayback(ctx, buffer, options) {
|
|
|
330
358
|
engineInstance?.setLoop(value);
|
|
331
359
|
}
|
|
332
360
|
function dispose() {
|
|
333
|
-
if (
|
|
334
|
-
|
|
335
|
-
stopTimer();
|
|
361
|
+
if (sm.isDisposed()) return;
|
|
362
|
+
sm.markDisposed();
|
|
336
363
|
engineInstance?.dispose();
|
|
337
364
|
emitter.clear();
|
|
338
365
|
}
|
|
@@ -341,7 +368,7 @@ function createStretchedPlayback(ctx, buffer, options) {
|
|
|
341
368
|
return engineInstance.getSnapshot();
|
|
342
369
|
}
|
|
343
370
|
const playback = {
|
|
344
|
-
getState: () =>
|
|
371
|
+
getState: () => sm.getState(),
|
|
345
372
|
getCurrentTime,
|
|
346
373
|
getDuration: () => duration,
|
|
347
374
|
getProgress: () => duration > 0 ? getCurrentTime() / duration : 0,
|
|
@@ -361,5 +388,5 @@ function createStretchedPlayback(ctx, buffer, options) {
|
|
|
361
388
|
}
|
|
362
389
|
|
|
363
390
|
export { play };
|
|
364
|
-
//# sourceMappingURL=chunk-
|
|
365
|
-
//# sourceMappingURL=chunk-
|
|
391
|
+
//# sourceMappingURL=chunk-HYRDCTBO.js.map
|
|
392
|
+
//# sourceMappingURL=chunk-HYRDCTBO.js.map
|
|
@@ -6,7 +6,7 @@ function computeSnapshot(playback) {
|
|
|
6
6
|
const position = playback.getCurrentTime();
|
|
7
7
|
const duration = playback.getDuration();
|
|
8
8
|
const progress = playback.getProgress();
|
|
9
|
-
const getter = playback
|
|
9
|
+
const getter = playback._getStretcherSnapshot;
|
|
10
10
|
let stretcher;
|
|
11
11
|
if (typeof getter === "function") {
|
|
12
12
|
stretcher = getter();
|
|
@@ -72,6 +72,9 @@ function whenEnded(playback) {
|
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
74
|
function whenPosition(playback, position) {
|
|
75
|
+
if (playback.getCurrentTime() >= position) {
|
|
76
|
+
return Promise.resolve();
|
|
77
|
+
}
|
|
75
78
|
return new Promise((resolve) => {
|
|
76
79
|
const unsub = playback.on("timeupdate", ({ position: current }) => {
|
|
77
80
|
if (current >= position) {
|
|
@@ -83,5 +86,5 @@ function whenPosition(playback, position) {
|
|
|
83
86
|
}
|
|
84
87
|
|
|
85
88
|
export { getSnapshot, onFrame, subscribeSnapshot, whenEnded, whenPosition };
|
|
86
|
-
//# sourceMappingURL=chunk-
|
|
87
|
-
//# sourceMappingURL=chunk-
|
|
89
|
+
//# sourceMappingURL=chunk-JIHPQAEA.js.map
|
|
90
|
+
//# sourceMappingURL=chunk-JIHPQAEA.js.map
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkBRS7LZVH_cjs = require('./chunk-BRS7LZVH.cjs');
|
|
4
|
+
var chunkF6WXD3XW_cjs = require('./chunk-F6WXD3XW.cjs');
|
|
5
|
+
var chunkOZN5X4N6_cjs = require('./chunk-OZN5X4N6.cjs');
|
|
6
|
+
var chunk6UTN73HG_cjs = require('./chunk-6UTN73HG.cjs');
|
|
7
|
+
var chunk3VTU5OX5_cjs = require('./chunk-3VTU5OX5.cjs');
|
|
8
|
+
var chunkVY4UMZMJ_cjs = require('./chunk-VY4UMZMJ.cjs');
|
|
9
|
+
var chunkQGZGERGK_cjs = require('./chunk-QGZGERGK.cjs');
|
|
10
|
+
var chunkVOSIA3GF_cjs = require('./chunk-VOSIA3GF.cjs');
|
|
11
|
+
var chunkOIY6I4TU_cjs = require('./chunk-OIY6I4TU.cjs');
|
|
12
|
+
|
|
13
|
+
// src/player.ts
|
|
14
|
+
var WaaPlayer = class {
|
|
15
|
+
constructor(ctxOrOptions) {
|
|
16
|
+
if (ctxOrOptions && typeof ctxOrOptions.createGain === "function") {
|
|
17
|
+
this.ctx = ctxOrOptions;
|
|
18
|
+
this._ownsContext = false;
|
|
19
|
+
} else {
|
|
20
|
+
this.ctx = chunk6UTN73HG_cjs.createContext(ctxOrOptions);
|
|
21
|
+
this._ownsContext = true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// --- Context ---
|
|
25
|
+
resume() {
|
|
26
|
+
return chunk6UTN73HG_cjs.resumeContext(this.ctx);
|
|
27
|
+
}
|
|
28
|
+
ensureRunning() {
|
|
29
|
+
return chunk6UTN73HG_cjs.ensureRunning(this.ctx);
|
|
30
|
+
}
|
|
31
|
+
now() {
|
|
32
|
+
return chunk6UTN73HG_cjs.now(this.ctx);
|
|
33
|
+
}
|
|
34
|
+
// --- Buffer ---
|
|
35
|
+
load(url, options) {
|
|
36
|
+
return chunk3VTU5OX5_cjs.loadBuffer(this.ctx, url, options);
|
|
37
|
+
}
|
|
38
|
+
loadFromBlob(blob) {
|
|
39
|
+
return chunk3VTU5OX5_cjs.loadBufferFromBlob(this.ctx, blob);
|
|
40
|
+
}
|
|
41
|
+
loadAll(map) {
|
|
42
|
+
return chunk3VTU5OX5_cjs.loadBuffers(this.ctx, map);
|
|
43
|
+
}
|
|
44
|
+
getBufferInfo(buffer) {
|
|
45
|
+
return chunk3VTU5OX5_cjs.getBufferInfo(buffer);
|
|
46
|
+
}
|
|
47
|
+
// --- Play ---
|
|
48
|
+
play(buffer, options) {
|
|
49
|
+
return chunkVY4UMZMJ_cjs.play(this.ctx, buffer, options);
|
|
50
|
+
}
|
|
51
|
+
// --- Nodes ---
|
|
52
|
+
createGain(initialValue) {
|
|
53
|
+
return chunkQGZGERGK_cjs.createGain(this.ctx, initialValue);
|
|
54
|
+
}
|
|
55
|
+
createAnalyser(options) {
|
|
56
|
+
return chunkQGZGERGK_cjs.createAnalyser(this.ctx, options);
|
|
57
|
+
}
|
|
58
|
+
createFilter(options) {
|
|
59
|
+
return chunkQGZGERGK_cjs.createFilter(this.ctx, options);
|
|
60
|
+
}
|
|
61
|
+
createPanner(pan) {
|
|
62
|
+
return chunkQGZGERGK_cjs.createPanner(this.ctx, pan);
|
|
63
|
+
}
|
|
64
|
+
createCompressor(options) {
|
|
65
|
+
return chunkQGZGERGK_cjs.createCompressor(this.ctx, options);
|
|
66
|
+
}
|
|
67
|
+
rampGain(gain, target, duration) {
|
|
68
|
+
chunkQGZGERGK_cjs.rampGain(gain, target, duration);
|
|
69
|
+
}
|
|
70
|
+
getFrequencyData(analyser) {
|
|
71
|
+
return chunkQGZGERGK_cjs.getFrequencyData(analyser);
|
|
72
|
+
}
|
|
73
|
+
getFrequencyDataByte(analyser) {
|
|
74
|
+
return chunkQGZGERGK_cjs.getFrequencyDataByte(analyser);
|
|
75
|
+
}
|
|
76
|
+
chain(...nodes) {
|
|
77
|
+
chunkQGZGERGK_cjs.chain(...nodes);
|
|
78
|
+
}
|
|
79
|
+
disconnectChain(...nodes) {
|
|
80
|
+
chunkQGZGERGK_cjs.disconnectChain(...nodes);
|
|
81
|
+
}
|
|
82
|
+
// --- Waveform ---
|
|
83
|
+
extractPeaks(buffer, options) {
|
|
84
|
+
return chunkVOSIA3GF_cjs.extractPeaks(buffer, options);
|
|
85
|
+
}
|
|
86
|
+
extractPeakPairs(buffer, options) {
|
|
87
|
+
return chunkVOSIA3GF_cjs.extractPeakPairs(buffer, options);
|
|
88
|
+
}
|
|
89
|
+
extractRMS(buffer, options) {
|
|
90
|
+
return chunkVOSIA3GF_cjs.extractRMS(buffer, options);
|
|
91
|
+
}
|
|
92
|
+
// --- Fade ---
|
|
93
|
+
fadeIn(gain, target, options) {
|
|
94
|
+
chunkOIY6I4TU_cjs.fadeIn(gain, target, options);
|
|
95
|
+
}
|
|
96
|
+
fadeOut(gain, options) {
|
|
97
|
+
chunkOIY6I4TU_cjs.fadeOut(gain, options);
|
|
98
|
+
}
|
|
99
|
+
crossfade(gainA, gainB, options) {
|
|
100
|
+
chunkOIY6I4TU_cjs.crossfade(gainA, gainB, options);
|
|
101
|
+
}
|
|
102
|
+
autoFade(playback, gain, options) {
|
|
103
|
+
return chunkOIY6I4TU_cjs.autoFade(playback, gain, options);
|
|
104
|
+
}
|
|
105
|
+
// --- Scheduler ---
|
|
106
|
+
createScheduler(options) {
|
|
107
|
+
return chunkBRS7LZVH_cjs.createScheduler(this.ctx, options);
|
|
108
|
+
}
|
|
109
|
+
createClock(options) {
|
|
110
|
+
return chunkBRS7LZVH_cjs.createClock(this.ctx, options);
|
|
111
|
+
}
|
|
112
|
+
// --- Synth ---
|
|
113
|
+
createSineBuffer(frequency, duration) {
|
|
114
|
+
return chunkF6WXD3XW_cjs.createSineBuffer(this.ctx, frequency, duration);
|
|
115
|
+
}
|
|
116
|
+
createNoiseBuffer(duration) {
|
|
117
|
+
return chunkF6WXD3XW_cjs.createNoiseBuffer(this.ctx, duration);
|
|
118
|
+
}
|
|
119
|
+
createClickBuffer(frequency, duration) {
|
|
120
|
+
return chunkF6WXD3XW_cjs.createClickBuffer(this.ctx, frequency, duration);
|
|
121
|
+
}
|
|
122
|
+
// --- Adapters ---
|
|
123
|
+
getSnapshot(playback) {
|
|
124
|
+
return chunkOZN5X4N6_cjs.getSnapshot(playback);
|
|
125
|
+
}
|
|
126
|
+
subscribeSnapshot(playback, callback) {
|
|
127
|
+
return chunkOZN5X4N6_cjs.subscribeSnapshot(playback, callback);
|
|
128
|
+
}
|
|
129
|
+
onFrame(playback, callback) {
|
|
130
|
+
return chunkOZN5X4N6_cjs.onFrame(playback, callback);
|
|
131
|
+
}
|
|
132
|
+
whenEnded(playback) {
|
|
133
|
+
return chunkOZN5X4N6_cjs.whenEnded(playback);
|
|
134
|
+
}
|
|
135
|
+
whenPosition(playback, position) {
|
|
136
|
+
return chunkOZN5X4N6_cjs.whenPosition(playback, position);
|
|
137
|
+
}
|
|
138
|
+
// --- Lifecycle ---
|
|
139
|
+
dispose() {
|
|
140
|
+
if (this._ownsContext) {
|
|
141
|
+
this.ctx.close();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
exports.WaaPlayer = WaaPlayer;
|
|
147
|
+
//# sourceMappingURL=chunk-KVKW7W66.cjs.map
|
|
148
|
+
//# sourceMappingURL=chunk-KVKW7W66.cjs.map
|
|
@@ -9,10 +9,7 @@ function applyRamp(node, from, to, duration, curve) {
|
|
|
9
9
|
param.setValueAtTime(from, now);
|
|
10
10
|
switch (curve) {
|
|
11
11
|
case "exponential":
|
|
12
|
-
param.exponentialRampToValueAtTime(
|
|
13
|
-
Math.max(to, EXP_MIN),
|
|
14
|
-
now + duration
|
|
15
|
-
);
|
|
12
|
+
param.exponentialRampToValueAtTime(Math.max(to, EXP_MIN), now + duration);
|
|
16
13
|
break;
|
|
17
14
|
case "equal-power": {
|
|
18
15
|
const steps = Math.max(Math.ceil(duration * 100), 2);
|
|
@@ -25,7 +22,6 @@ function applyRamp(node, from, to, duration, curve) {
|
|
|
25
22
|
param.setValueCurveAtTime(values, now, duration);
|
|
26
23
|
break;
|
|
27
24
|
}
|
|
28
|
-
case "linear":
|
|
29
25
|
default:
|
|
30
26
|
param.linearRampToValueAtTime(to, now + duration);
|
|
31
27
|
break;
|
|
@@ -68,5 +64,5 @@ exports.autoFade = autoFade;
|
|
|
68
64
|
exports.crossfade = crossfade;
|
|
69
65
|
exports.fadeIn = fadeIn;
|
|
70
66
|
exports.fadeOut = fadeOut;
|
|
71
|
-
//# sourceMappingURL=chunk-
|
|
72
|
-
//# sourceMappingURL=chunk-
|
|
67
|
+
//# sourceMappingURL=chunk-OIY6I4TU.cjs.map
|
|
68
|
+
//# sourceMappingURL=chunk-OIY6I4TU.cjs.map
|