@ainsej/rubberband-wasm 4.0.0 → 4.0.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/dist/index.esm.js +463 -0
- package/dist/index.esm.min.js +7 -0
- package/dist/index.umd.js +475 -0
- package/dist/index.umd.min.js +7 -0
- package/dist/rubberband-processor.js +689 -0
- package/dist/rubberband-processor.min.js +7 -0
- package/dist/rubberband.wasm +0 -0
- package/dist/types/RubberBandInterface.d.ts +101 -0
- package/dist/types/RubberBandNode.d.ts +84 -0
- package/dist/types/RubberBandProcessor.d.ts +1 -0
- package/dist/types/index.d.ts +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* rubberband-wasm v4.0.1 (https://www.npmjs.com/package/rubberband-wasm)
|
|
3
|
+
* (c) Dani Biro
|
|
4
|
+
* @license GPLv2
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
(function (global, factory) {
|
|
8
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
9
|
+
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
10
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.rubberband = {}));
|
|
11
|
+
})(this, (function (exports) { 'use strict';
|
|
12
|
+
|
|
13
|
+
exports.RubberBandOption = void 0;
|
|
14
|
+
(function (RubberBandOption) {
|
|
15
|
+
RubberBandOption[RubberBandOption["RubberBandOptionProcessOffline"] = 0] = "RubberBandOptionProcessOffline";
|
|
16
|
+
RubberBandOption[RubberBandOption["RubberBandOptionProcessRealTime"] = 1] = "RubberBandOptionProcessRealTime";
|
|
17
|
+
RubberBandOption[RubberBandOption["RubberBandOptionStretchElastic"] = 0] = "RubberBandOptionStretchElastic";
|
|
18
|
+
RubberBandOption[RubberBandOption["RubberBandOptionStretchPrecise"] = 16] = "RubberBandOptionStretchPrecise";
|
|
19
|
+
RubberBandOption[RubberBandOption["RubberBandOptionTransientsCrisp"] = 0] = "RubberBandOptionTransientsCrisp";
|
|
20
|
+
RubberBandOption[RubberBandOption["RubberBandOptionTransientsMixed"] = 256] = "RubberBandOptionTransientsMixed";
|
|
21
|
+
RubberBandOption[RubberBandOption["RubberBandOptionTransientsSmooth"] = 512] = "RubberBandOptionTransientsSmooth";
|
|
22
|
+
RubberBandOption[RubberBandOption["RubberBandOptionDetectorCompound"] = 0] = "RubberBandOptionDetectorCompound";
|
|
23
|
+
RubberBandOption[RubberBandOption["RubberBandOptionDetectorPercussive"] = 1024] = "RubberBandOptionDetectorPercussive";
|
|
24
|
+
RubberBandOption[RubberBandOption["RubberBandOptionDetectorSoft"] = 2048] = "RubberBandOptionDetectorSoft";
|
|
25
|
+
RubberBandOption[RubberBandOption["RubberBandOptionPhaseLaminar"] = 0] = "RubberBandOptionPhaseLaminar";
|
|
26
|
+
RubberBandOption[RubberBandOption["RubberBandOptionPhaseIndependent"] = 8192] = "RubberBandOptionPhaseIndependent";
|
|
27
|
+
RubberBandOption[RubberBandOption["RubberBandOptionThreadingAuto"] = 0] = "RubberBandOptionThreadingAuto";
|
|
28
|
+
RubberBandOption[RubberBandOption["RubberBandOptionThreadingNever"] = 65536] = "RubberBandOptionThreadingNever";
|
|
29
|
+
RubberBandOption[RubberBandOption["RubberBandOptionThreadingAlways"] = 131072] = "RubberBandOptionThreadingAlways";
|
|
30
|
+
RubberBandOption[RubberBandOption["RubberBandOptionWindowStandard"] = 0] = "RubberBandOptionWindowStandard";
|
|
31
|
+
RubberBandOption[RubberBandOption["RubberBandOptionWindowShort"] = 1048576] = "RubberBandOptionWindowShort";
|
|
32
|
+
RubberBandOption[RubberBandOption["RubberBandOptionWindowLong"] = 2097152] = "RubberBandOptionWindowLong";
|
|
33
|
+
RubberBandOption[RubberBandOption["RubberBandOptionSmoothingOff"] = 0] = "RubberBandOptionSmoothingOff";
|
|
34
|
+
RubberBandOption[RubberBandOption["RubberBandOptionSmoothingOn"] = 8388608] = "RubberBandOptionSmoothingOn";
|
|
35
|
+
RubberBandOption[RubberBandOption["RubberBandOptionFormantShifted"] = 0] = "RubberBandOptionFormantShifted";
|
|
36
|
+
RubberBandOption[RubberBandOption["RubberBandOptionFormantPreserved"] = 16777216] = "RubberBandOptionFormantPreserved";
|
|
37
|
+
RubberBandOption[RubberBandOption["RubberBandOptionPitchHighSpeed"] = 0] = "RubberBandOptionPitchHighSpeed";
|
|
38
|
+
RubberBandOption[RubberBandOption["RubberBandOptionPitchHighQuality"] = 33554432] = "RubberBandOptionPitchHighQuality";
|
|
39
|
+
RubberBandOption[RubberBandOption["RubberBandOptionPitchHighConsistency"] = 67108864] = "RubberBandOptionPitchHighConsistency";
|
|
40
|
+
RubberBandOption[RubberBandOption["RubberBandOptionChannelsApart"] = 0] = "RubberBandOptionChannelsApart";
|
|
41
|
+
RubberBandOption[RubberBandOption["RubberBandOptionChannelsTogether"] = 268435456] = "RubberBandOptionChannelsTogether";
|
|
42
|
+
RubberBandOption[RubberBandOption["RubberBandOptionEngineFaster"] = 0] = "RubberBandOptionEngineFaster";
|
|
43
|
+
RubberBandOption[RubberBandOption["RubberBandOptionEngineFiner"] = 536870912] = "RubberBandOptionEngineFiner";
|
|
44
|
+
})(exports.RubberBandOption || (exports.RubberBandOption = {}));
|
|
45
|
+
exports.RubberBandPresetOption = void 0;
|
|
46
|
+
(function (RubberBandPresetOption) {
|
|
47
|
+
RubberBandPresetOption[RubberBandPresetOption["DefaultOptions"] = 0] = "DefaultOptions";
|
|
48
|
+
RubberBandPresetOption[RubberBandPresetOption["PercussiveOptions"] = 1056768] = "PercussiveOptions";
|
|
49
|
+
})(exports.RubberBandPresetOption || (exports.RubberBandPresetOption = {}));
|
|
50
|
+
exports.RubberBandLiveOption = void 0;
|
|
51
|
+
(function (RubberBandLiveOption) {
|
|
52
|
+
RubberBandLiveOption[RubberBandLiveOption["RubberBandLiveOptionWindowShort"] = 0] = "RubberBandLiveOptionWindowShort";
|
|
53
|
+
RubberBandLiveOption[RubberBandLiveOption["RubberBandLiveOptionWindowMedium"] = 1048576] = "RubberBandLiveOptionWindowMedium";
|
|
54
|
+
RubberBandLiveOption[RubberBandLiveOption["RubberBandLiveOptionFormantShifted"] = 0] = "RubberBandLiveOptionFormantShifted";
|
|
55
|
+
RubberBandLiveOption[RubberBandLiveOption["RubberBandLiveOptionFormantPreserved"] = 16777216] = "RubberBandLiveOptionFormantPreserved";
|
|
56
|
+
RubberBandLiveOption[RubberBandLiveOption["RubberBandLiveOptionChannelsApart"] = 0] = "RubberBandLiveOptionChannelsApart";
|
|
57
|
+
RubberBandLiveOption[RubberBandLiveOption["RubberBandLiveOptionChannelsTogether"] = 268435456] = "RubberBandLiveOptionChannelsTogether";
|
|
58
|
+
})(exports.RubberBandLiveOption || (exports.RubberBandLiveOption = {}));
|
|
59
|
+
class RubberBandInterface {
|
|
60
|
+
constructor() { }
|
|
61
|
+
static async initialize(module) {
|
|
62
|
+
if (typeof WebAssembly === "undefined") {
|
|
63
|
+
throw new Error("WebAssembly is not supported in this environment!");
|
|
64
|
+
}
|
|
65
|
+
let heap = {};
|
|
66
|
+
const errorHandler = (...params) => {
|
|
67
|
+
console.error("WASI called with params", params);
|
|
68
|
+
return 52;
|
|
69
|
+
};
|
|
70
|
+
let printBuffer = [];
|
|
71
|
+
const wasmInstance = await WebAssembly.instantiate(module, {
|
|
72
|
+
env: {
|
|
73
|
+
emscripten_notify_memory_growth: () => {
|
|
74
|
+
heap.HEAP8 = new Uint8Array(wasmInstance.exports.memory.buffer);
|
|
75
|
+
heap.HEAP32 = new Uint32Array(wasmInstance.exports.memory.buffer);
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
wasi_snapshot_preview1: {
|
|
79
|
+
proc_exit: (...params) => errorHandler("proc_exit", params),
|
|
80
|
+
fd_read: (...params) => errorHandler("fd_read", params),
|
|
81
|
+
fd_write: (fd, iov, iovcnt, pnum) => {
|
|
82
|
+
if (fd > 2)
|
|
83
|
+
return 52;
|
|
84
|
+
let num = 0;
|
|
85
|
+
for (let i = 0; i < iovcnt; i++) {
|
|
86
|
+
const ptr = heap.HEAP32[iov >> 2];
|
|
87
|
+
const len = heap.HEAP32[(iov + 4) >> 2];
|
|
88
|
+
iov += 8;
|
|
89
|
+
for (let j = 0; j < len; j++) {
|
|
90
|
+
const curr = heap.HEAP8[ptr + j];
|
|
91
|
+
if (curr === 0 || curr === 10) {
|
|
92
|
+
console.log(printBuffer.join(""));
|
|
93
|
+
printBuffer.length = 0;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
printBuffer.push(String.fromCharCode(curr));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
num += len;
|
|
100
|
+
}
|
|
101
|
+
heap.HEAP32[pnum >> 2] = num;
|
|
102
|
+
return 0;
|
|
103
|
+
},
|
|
104
|
+
fd_seek: (...params) => errorHandler("fd_seek", params),
|
|
105
|
+
fd_close: (...params) => errorHandler("fd_close", params),
|
|
106
|
+
environ_sizes_get: (penviron_count, penviron_buf_size) => {
|
|
107
|
+
// heap.HEAP32[penviron_count >> 2] = 0;
|
|
108
|
+
// heap.HEAP32[penviron_buf_size >> 2] = 0;
|
|
109
|
+
return 52; // NO_SYS
|
|
110
|
+
},
|
|
111
|
+
environ_get: (...params) => errorHandler("environ_get", params),
|
|
112
|
+
clock_time_get: (...params) => errorHandler("clock_time_get", params),
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
const exports = wasmInstance.exports;
|
|
116
|
+
heap.HEAP8 = new Uint8Array(wasmInstance.exports.memory.buffer);
|
|
117
|
+
heap.HEAP32 = new Uint32Array(wasmInstance.exports.memory.buffer);
|
|
118
|
+
exports._initialize();
|
|
119
|
+
const instance = { heap, exports };
|
|
120
|
+
const ret = new RubberBandInterface();
|
|
121
|
+
ret.wasm = instance;
|
|
122
|
+
return ret;
|
|
123
|
+
}
|
|
124
|
+
malloc(size) {
|
|
125
|
+
return this.wasm.exports.wasm_malloc(size);
|
|
126
|
+
}
|
|
127
|
+
memWrite(destPtr, data) {
|
|
128
|
+
const uint8Array = data instanceof Uint8Array ? data : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
129
|
+
this.wasm.heap.HEAP8.set(uint8Array, destPtr);
|
|
130
|
+
}
|
|
131
|
+
memWritePtr(destPtr, srcPtr) {
|
|
132
|
+
const buf = new Uint8Array(4);
|
|
133
|
+
const view = new DataView(buf.buffer);
|
|
134
|
+
view.setUint32(0, srcPtr, true);
|
|
135
|
+
this.wasm.heap.HEAP8.set(buf, destPtr);
|
|
136
|
+
}
|
|
137
|
+
memReadU8(srcPtr, length) {
|
|
138
|
+
return this.wasm.heap.HEAP8.subarray(srcPtr, srcPtr + length);
|
|
139
|
+
}
|
|
140
|
+
memReadF32(srcPtr, length) {
|
|
141
|
+
const res = this.memReadU8(srcPtr, length * 4);
|
|
142
|
+
return new Float32Array(res.buffer, res.byteOffset, length);
|
|
143
|
+
}
|
|
144
|
+
free(ptr) {
|
|
145
|
+
this.wasm.exports.wasm_free(ptr);
|
|
146
|
+
}
|
|
147
|
+
rubberband_new(sampleRate, channels, options, initialTimeRatio, initialPitchScale) {
|
|
148
|
+
return this.wasm.exports.rb_new(sampleRate, channels, options, initialTimeRatio, initialPitchScale);
|
|
149
|
+
}
|
|
150
|
+
rubberband_delete(state) {
|
|
151
|
+
this.wasm.exports.rb_delete(state);
|
|
152
|
+
}
|
|
153
|
+
rubberband_reset(state) {
|
|
154
|
+
this.wasm.exports.rb_reset(state);
|
|
155
|
+
}
|
|
156
|
+
rubberband_get_engine_version(state) {
|
|
157
|
+
return this.wasm.exports.rb_get_engine_version(state);
|
|
158
|
+
}
|
|
159
|
+
rubberband_set_time_ratio(state, ratio) {
|
|
160
|
+
this.wasm.exports.rb_set_time_ratio(state, ratio);
|
|
161
|
+
}
|
|
162
|
+
rubberband_set_pitch_scale(state, scale) {
|
|
163
|
+
this.wasm.exports.rb_set_pitch_scale(state, scale);
|
|
164
|
+
}
|
|
165
|
+
rubberband_set_formant_scale(state, scale) {
|
|
166
|
+
this.wasm.exports.rb_set_formant_scale(state, scale);
|
|
167
|
+
}
|
|
168
|
+
rubberband_get_time_ratio(state) {
|
|
169
|
+
return this.wasm.exports.rb_get_time_ratio(state);
|
|
170
|
+
}
|
|
171
|
+
rubberband_get_pitch_scale(state) {
|
|
172
|
+
return this.wasm.exports.rb_get_pitch_scale(state);
|
|
173
|
+
}
|
|
174
|
+
rubberband_get_formant_scale(state) {
|
|
175
|
+
return this.wasm.exports.rb_get_formant_scale(state);
|
|
176
|
+
}
|
|
177
|
+
rubberband_get_preferred_start_pad(state) {
|
|
178
|
+
return this.wasm.exports.rb_get_preferred_start_pad(state);
|
|
179
|
+
}
|
|
180
|
+
rubberband_get_start_delay(state) {
|
|
181
|
+
return this.wasm.exports.rb_get_start_delay(state);
|
|
182
|
+
}
|
|
183
|
+
rubberband_get_latency(state) {
|
|
184
|
+
return this.wasm.exports.rb_get_latency(state);
|
|
185
|
+
}
|
|
186
|
+
rubberband_set_transients_option(state, options) {
|
|
187
|
+
this.wasm.exports.rb_set_transients_option(state, options);
|
|
188
|
+
}
|
|
189
|
+
rubberband_set_detector_option(state, options) {
|
|
190
|
+
this.wasm.exports.rb_set_detector_option(state, options);
|
|
191
|
+
}
|
|
192
|
+
rubberband_set_phase_option(state, options) {
|
|
193
|
+
this.wasm.exports.rb_set_phase_option(state, options);
|
|
194
|
+
}
|
|
195
|
+
rubberband_set_formant_option(state, options) {
|
|
196
|
+
this.wasm.exports.rb_set_formant_option(state, options);
|
|
197
|
+
}
|
|
198
|
+
rubberband_set_pitch_option(state, options) {
|
|
199
|
+
this.wasm.exports.rb_set_pitch_option(state, options);
|
|
200
|
+
}
|
|
201
|
+
rubberband_set_expected_input_duration(state, samples) {
|
|
202
|
+
this.wasm.exports.rb_set_expected_input_duration(state, samples);
|
|
203
|
+
}
|
|
204
|
+
rubberband_get_samples_required(state) {
|
|
205
|
+
return this.wasm.exports.rb_get_samples_required(state);
|
|
206
|
+
}
|
|
207
|
+
rubberband_set_max_process_size(state, samples) {
|
|
208
|
+
this.wasm.exports.rb_set_max_process_size(state, samples);
|
|
209
|
+
}
|
|
210
|
+
rubberband_get_process_size_limit(state) {
|
|
211
|
+
return this.wasm.exports.rb_get_process_size_limit(state);
|
|
212
|
+
}
|
|
213
|
+
rubberband_set_key_frame_map(state, keyframecount, from, to) {
|
|
214
|
+
this.wasm.exports.rb_set_key_frame_map(state, keyframecount, from, to);
|
|
215
|
+
}
|
|
216
|
+
rubberband_study(state, input, samples, final) {
|
|
217
|
+
this.wasm.exports.rb_study(state, input, samples, final);
|
|
218
|
+
}
|
|
219
|
+
rubberband_process(state, input, samples, final) {
|
|
220
|
+
this.wasm.exports.rb_process(state, input, samples, final);
|
|
221
|
+
}
|
|
222
|
+
rubberband_available(state) {
|
|
223
|
+
return this.wasm.exports.rb_available(state);
|
|
224
|
+
}
|
|
225
|
+
rubberband_retrieve(state, output, samples) {
|
|
226
|
+
return this.wasm.exports.rb_retrieve(state, output, samples);
|
|
227
|
+
}
|
|
228
|
+
rubberband_get_channel_count(state) {
|
|
229
|
+
return this.wasm.exports.rb_get_channel_count(state);
|
|
230
|
+
}
|
|
231
|
+
rubberband_calculate_stretch(state) {
|
|
232
|
+
this.wasm.exports.rb_calculate_stretch(state);
|
|
233
|
+
}
|
|
234
|
+
rubberband_set_debug_level(state, level) {
|
|
235
|
+
this.wasm.exports.rb_set_debug_level(state, level);
|
|
236
|
+
}
|
|
237
|
+
rubberband_set_default_debug_level(level) {
|
|
238
|
+
this.wasm.exports.rb_set_default_debug_level(level);
|
|
239
|
+
}
|
|
240
|
+
// RubberBandLiveShifter — real-time pitch shifter introduced in Rubber Band 4.0.
|
|
241
|
+
rubberband_live_new(sampleRate, channels, options) {
|
|
242
|
+
return this.wasm.exports.rb_live_new(sampleRate, channels, options);
|
|
243
|
+
}
|
|
244
|
+
rubberband_live_delete(state) {
|
|
245
|
+
this.wasm.exports.rb_live_delete(state);
|
|
246
|
+
}
|
|
247
|
+
rubberband_live_reset(state) {
|
|
248
|
+
this.wasm.exports.rb_live_reset(state);
|
|
249
|
+
}
|
|
250
|
+
rubberband_live_set_pitch_scale(state, scale) {
|
|
251
|
+
this.wasm.exports.rb_live_set_pitch_scale(state, scale);
|
|
252
|
+
}
|
|
253
|
+
rubberband_live_get_pitch_scale(state) {
|
|
254
|
+
return this.wasm.exports.rb_live_get_pitch_scale(state);
|
|
255
|
+
}
|
|
256
|
+
rubberband_live_set_formant_scale(state, scale) {
|
|
257
|
+
this.wasm.exports.rb_live_set_formant_scale(state, scale);
|
|
258
|
+
}
|
|
259
|
+
rubberband_live_get_formant_scale(state) {
|
|
260
|
+
return this.wasm.exports.rb_live_get_formant_scale(state);
|
|
261
|
+
}
|
|
262
|
+
rubberband_live_get_start_delay(state) {
|
|
263
|
+
return this.wasm.exports.rb_live_get_start_delay(state);
|
|
264
|
+
}
|
|
265
|
+
rubberband_live_set_formant_option(state, options) {
|
|
266
|
+
this.wasm.exports.rb_live_set_formant_option(state, options);
|
|
267
|
+
}
|
|
268
|
+
rubberband_live_get_block_size(state) {
|
|
269
|
+
return this.wasm.exports.rb_live_get_block_size(state);
|
|
270
|
+
}
|
|
271
|
+
rubberband_live_shift(state, input, output) {
|
|
272
|
+
this.wasm.exports.rb_live_shift(state, input, output);
|
|
273
|
+
}
|
|
274
|
+
rubberband_live_get_channel_count(state) {
|
|
275
|
+
return this.wasm.exports.rb_live_get_channel_count(state);
|
|
276
|
+
}
|
|
277
|
+
rubberband_live_set_debug_level(state, level) {
|
|
278
|
+
this.wasm.exports.rb_live_set_debug_level(state, level);
|
|
279
|
+
}
|
|
280
|
+
rubberband_live_set_default_debug_level(level) {
|
|
281
|
+
this.wasm.exports.rb_live_set_default_debug_level(level);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Tracks which contexts have already had the worklet module registered.
|
|
286
|
+
const moduleAdded = new WeakSet();
|
|
287
|
+
/**
|
|
288
|
+
* RubberBandNode — a Web Audio source node that plays a buffer through Rubber
|
|
289
|
+
* Band Library with live, real-time control over tempo (time-stretch) and pitch.
|
|
290
|
+
*
|
|
291
|
+
* It has no inputs and one output; connect it to the graph like an
|
|
292
|
+
* AudioBufferSourceNode:
|
|
293
|
+
*
|
|
294
|
+
* ```js
|
|
295
|
+
* const node = await RubberBandNode.create(ctx, {
|
|
296
|
+
* processorUrl: "rubberband-processor.js",
|
|
297
|
+
* wasmUrl: "rubberband.wasm",
|
|
298
|
+
* channelCount: audioBuffer.numberOfChannels,
|
|
299
|
+
* });
|
|
300
|
+
* node.connect(ctx.destination);
|
|
301
|
+
* node.setBuffer(audioBuffer);
|
|
302
|
+
* node.setTempo(1.5); // 1.5x speed, pitch unchanged
|
|
303
|
+
* node.setPitchSemitones(-3); // down a minor third, speed unchanged
|
|
304
|
+
* node.play();
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
307
|
+
class RubberBandNode extends AudioWorkletNode {
|
|
308
|
+
constructor(context, channels) {
|
|
309
|
+
super(context, "rubberband-processor", {
|
|
310
|
+
numberOfInputs: 0,
|
|
311
|
+
numberOfOutputs: 1,
|
|
312
|
+
outputChannelCount: [channels],
|
|
313
|
+
});
|
|
314
|
+
/** Fired once when playback reaches the end (re-armed on every play/seek/stop). */
|
|
315
|
+
this.onended = null;
|
|
316
|
+
/** Fired periodically with the current playback position, in seconds of source time. */
|
|
317
|
+
this.onposition = null;
|
|
318
|
+
this._channels = channels;
|
|
319
|
+
this._sourceSampleRate = context.sampleRate;
|
|
320
|
+
this._ready = new Promise((resolve, reject) => {
|
|
321
|
+
this._readyResolve = resolve;
|
|
322
|
+
this._readyReject = reject;
|
|
323
|
+
});
|
|
324
|
+
this.port.onmessage = (e) => {
|
|
325
|
+
const d = e.data;
|
|
326
|
+
if (!d)
|
|
327
|
+
return;
|
|
328
|
+
if (d.type === "ready")
|
|
329
|
+
this._readyResolve();
|
|
330
|
+
else if (d.type === "error")
|
|
331
|
+
this._readyReject(new Error("RubberBand worklet init failed: " + d.error));
|
|
332
|
+
else if (d.type === "ended")
|
|
333
|
+
this.onended && this.onended();
|
|
334
|
+
else if (d.type === "position")
|
|
335
|
+
this.onposition && this.onposition(d.seconds);
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
/** Number of output channels the node was created with. */
|
|
339
|
+
get sourceChannels() {
|
|
340
|
+
return this._channels;
|
|
341
|
+
}
|
|
342
|
+
/** Resolves once the worklet has compiled the wasm and is ready to play. */
|
|
343
|
+
get ready() {
|
|
344
|
+
return this._ready;
|
|
345
|
+
}
|
|
346
|
+
/** Register the worklet module on a context (idempotent per context). */
|
|
347
|
+
static async addModule(context, processorUrl) {
|
|
348
|
+
if (!moduleAdded.has(context)) {
|
|
349
|
+
await context.audioWorklet.addModule(processorUrl);
|
|
350
|
+
moduleAdded.add(context);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/** Create a ready-to-use RubberBandNode. */
|
|
354
|
+
static async create(context, opts = {}) {
|
|
355
|
+
if (typeof AudioWorkletNode === "undefined" || !context.audioWorklet) {
|
|
356
|
+
throw new Error("AudioWorklet is not supported in this AudioContext.");
|
|
357
|
+
}
|
|
358
|
+
const processorUrl = opts.processorUrl || "rubberband-processor.js";
|
|
359
|
+
await RubberBandNode.addModule(context, processorUrl);
|
|
360
|
+
// The worklet compiles the wasm itself: a compiled WebAssembly.Module cannot
|
|
361
|
+
// be reliably structured-cloned into an AudioWorkletGlobalScope, but bytes can.
|
|
362
|
+
let bytes;
|
|
363
|
+
if (opts.wasmBinary) {
|
|
364
|
+
const b = opts.wasmBinary;
|
|
365
|
+
bytes = b instanceof Uint8Array ? b.slice().buffer : b.slice(0);
|
|
366
|
+
}
|
|
367
|
+
else if (opts.wasmUrl) {
|
|
368
|
+
bytes = await (await fetch(opts.wasmUrl)).arrayBuffer();
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
throw new Error("RubberBandNode.create requires one of: wasmBinary, wasmUrl.");
|
|
372
|
+
}
|
|
373
|
+
const channels = opts.channelCount && opts.channelCount > 0 ? opts.channelCount : 2;
|
|
374
|
+
const node = new RubberBandNode(context, channels);
|
|
375
|
+
node.port.postMessage({ type: "initialise", wasm: bytes, channels, options: opts.options }, [bytes]);
|
|
376
|
+
try {
|
|
377
|
+
await node._ready;
|
|
378
|
+
}
|
|
379
|
+
catch (e) {
|
|
380
|
+
node.close(); // tear down the worklet + free any wasm it allocated
|
|
381
|
+
throw e;
|
|
382
|
+
}
|
|
383
|
+
return node;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Load source audio. Channel data is copied before transfer, so the supplied
|
|
387
|
+
* AudioBuffer/arrays are left intact. Resets the transport to the start.
|
|
388
|
+
*/
|
|
389
|
+
setBuffer(buffer) {
|
|
390
|
+
let chans;
|
|
391
|
+
let rate;
|
|
392
|
+
if (Array.isArray(buffer)) {
|
|
393
|
+
chans = buffer.map((c) => new Float32Array(c));
|
|
394
|
+
rate = this._sourceSampleRate;
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
rate = buffer.sampleRate;
|
|
398
|
+
chans = [];
|
|
399
|
+
for (let ch = 0; ch < buffer.numberOfChannels; ch++) {
|
|
400
|
+
chans.push(new Float32Array(buffer.getChannelData(ch)));
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
chans = this._normalizeChannels(chans);
|
|
404
|
+
const transfer = chans.map((c) => c.buffer);
|
|
405
|
+
this.port.postMessage({ type: "buffer", channels: chans, sampleRate: rate }, transfer);
|
|
406
|
+
}
|
|
407
|
+
// Coerce to exactly this._channels with distinct backing buffers (so every
|
|
408
|
+
// entry in the transfer list is unique): a source with fewer channels is
|
|
409
|
+
// duplicated, a source with more has its extra channels dropped.
|
|
410
|
+
_normalizeChannels(chans) {
|
|
411
|
+
const n = this._channels;
|
|
412
|
+
if (chans.length === n)
|
|
413
|
+
return chans;
|
|
414
|
+
const out = [];
|
|
415
|
+
for (let ch = 0; ch < n; ch++) {
|
|
416
|
+
const src = chans[ch < chans.length ? ch : chans.length - 1] || new Float32Array(0);
|
|
417
|
+
out.push(ch < chans.length ? src : new Float32Array(src));
|
|
418
|
+
}
|
|
419
|
+
return out;
|
|
420
|
+
}
|
|
421
|
+
/** Start (or restart, if previously ended) playback. */
|
|
422
|
+
play() {
|
|
423
|
+
this.port.postMessage({ type: "play" });
|
|
424
|
+
}
|
|
425
|
+
/** Pause, keeping the current position. */
|
|
426
|
+
pause() {
|
|
427
|
+
this.port.postMessage({ type: "pause" });
|
|
428
|
+
}
|
|
429
|
+
/** Stop and rewind to the start. */
|
|
430
|
+
stop() {
|
|
431
|
+
this.port.postMessage({ type: "stop" });
|
|
432
|
+
}
|
|
433
|
+
/** Seek to a position in seconds of source time. */
|
|
434
|
+
seek(seconds) {
|
|
435
|
+
this.port.postMessage({ type: "seek", seconds });
|
|
436
|
+
}
|
|
437
|
+
/** Enable/disable looping. */
|
|
438
|
+
set loop(value) {
|
|
439
|
+
this.port.postMessage({ type: "loop", value });
|
|
440
|
+
}
|
|
441
|
+
/** Set playback speed (1 = normal, 2 = double speed) without changing pitch. */
|
|
442
|
+
setTempo(speed) {
|
|
443
|
+
this.port.postMessage({ type: "speed", value: speed });
|
|
444
|
+
}
|
|
445
|
+
/** Set the time ratio directly (output duration / input duration). */
|
|
446
|
+
setTimeRatio(ratio) {
|
|
447
|
+
this.port.postMessage({ type: "speed", value: ratio > 0 ? 1 / ratio : 1 });
|
|
448
|
+
}
|
|
449
|
+
/** Set the pitch scale directly (1 = no shift, 2 = up one octave). */
|
|
450
|
+
setPitchScale(scale) {
|
|
451
|
+
this.port.postMessage({ type: "pitch", value: scale });
|
|
452
|
+
}
|
|
453
|
+
/** Set the pitch shift in semitones (without changing tempo). */
|
|
454
|
+
setPitchSemitones(semitones) {
|
|
455
|
+
this.port.postMessage({ type: "pitch", value: Math.pow(2, semitones / 12) });
|
|
456
|
+
}
|
|
457
|
+
/** Free wasm resources in the worklet and disconnect the node. */
|
|
458
|
+
close() {
|
|
459
|
+
this.port.postMessage({ type: "close" });
|
|
460
|
+
this.disconnect();
|
|
461
|
+
this.port.onmessage = null;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
/** Default RubberBand options used by the real-time node (exported for reference/override). */
|
|
465
|
+
const RUBBERBAND_REALTIME_DEFAULT_OPTIONS = exports.RubberBandOption.RubberBandOptionProcessRealTime |
|
|
466
|
+
exports.RubberBandOption.RubberBandOptionEngineFaster |
|
|
467
|
+
exports.RubberBandOption.RubberBandOptionPitchHighConsistency;
|
|
468
|
+
|
|
469
|
+
exports.RUBBERBAND_REALTIME_DEFAULT_OPTIONS = RUBBERBAND_REALTIME_DEFAULT_OPTIONS;
|
|
470
|
+
exports.RubberBandInterface = RubberBandInterface;
|
|
471
|
+
exports.RubberBandNode = RubberBandNode;
|
|
472
|
+
|
|
473
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
474
|
+
|
|
475
|
+
}));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* rubberband-wasm v4.0.1 (https://www.npmjs.com/package/rubberband-wasm)
|
|
3
|
+
* (c) Dani Biro
|
|
4
|
+
* @license GPLv2
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).rubberband={})}(this,(function(e){"use strict";var t,r,n;e.RubberBandOption=void 0,(t=e.RubberBandOption||(e.RubberBandOption={}))[t.RubberBandOptionProcessOffline=0]="RubberBandOptionProcessOffline",t[t.RubberBandOptionProcessRealTime=1]="RubberBandOptionProcessRealTime",t[t.RubberBandOptionStretchElastic=0]="RubberBandOptionStretchElastic",t[t.RubberBandOptionStretchPrecise=16]="RubberBandOptionStretchPrecise",t[t.RubberBandOptionTransientsCrisp=0]="RubberBandOptionTransientsCrisp",t[t.RubberBandOptionTransientsMixed=256]="RubberBandOptionTransientsMixed",t[t.RubberBandOptionTransientsSmooth=512]="RubberBandOptionTransientsSmooth",t[t.RubberBandOptionDetectorCompound=0]="RubberBandOptionDetectorCompound",t[t.RubberBandOptionDetectorPercussive=1024]="RubberBandOptionDetectorPercussive",t[t.RubberBandOptionDetectorSoft=2048]="RubberBandOptionDetectorSoft",t[t.RubberBandOptionPhaseLaminar=0]="RubberBandOptionPhaseLaminar",t[t.RubberBandOptionPhaseIndependent=8192]="RubberBandOptionPhaseIndependent",t[t.RubberBandOptionThreadingAuto=0]="RubberBandOptionThreadingAuto",t[t.RubberBandOptionThreadingNever=65536]="RubberBandOptionThreadingNever",t[t.RubberBandOptionThreadingAlways=131072]="RubberBandOptionThreadingAlways",t[t.RubberBandOptionWindowStandard=0]="RubberBandOptionWindowStandard",t[t.RubberBandOptionWindowShort=1048576]="RubberBandOptionWindowShort",t[t.RubberBandOptionWindowLong=2097152]="RubberBandOptionWindowLong",t[t.RubberBandOptionSmoothingOff=0]="RubberBandOptionSmoothingOff",t[t.RubberBandOptionSmoothingOn=8388608]="RubberBandOptionSmoothingOn",t[t.RubberBandOptionFormantShifted=0]="RubberBandOptionFormantShifted",t[t.RubberBandOptionFormantPreserved=16777216]="RubberBandOptionFormantPreserved",t[t.RubberBandOptionPitchHighSpeed=0]="RubberBandOptionPitchHighSpeed",t[t.RubberBandOptionPitchHighQuality=33554432]="RubberBandOptionPitchHighQuality",t[t.RubberBandOptionPitchHighConsistency=67108864]="RubberBandOptionPitchHighConsistency",t[t.RubberBandOptionChannelsApart=0]="RubberBandOptionChannelsApart",t[t.RubberBandOptionChannelsTogether=268435456]="RubberBandOptionChannelsTogether",t[t.RubberBandOptionEngineFaster=0]="RubberBandOptionEngineFaster",t[t.RubberBandOptionEngineFiner=536870912]="RubberBandOptionEngineFiner",e.RubberBandPresetOption=void 0,(r=e.RubberBandPresetOption||(e.RubberBandPresetOption={}))[r.DefaultOptions=0]="DefaultOptions",r[r.PercussiveOptions=1056768]="PercussiveOptions",e.RubberBandLiveOption=void 0,(n=e.RubberBandLiveOption||(e.RubberBandLiveOption={}))[n.RubberBandLiveOptionWindowShort=0]="RubberBandLiveOptionWindowShort",n[n.RubberBandLiveOptionWindowMedium=1048576]="RubberBandLiveOptionWindowMedium",n[n.RubberBandLiveOptionFormantShifted=0]="RubberBandLiveOptionFormantShifted",n[n.RubberBandLiveOptionFormantPreserved=16777216]="RubberBandLiveOptionFormantPreserved",n[n.RubberBandLiveOptionChannelsApart=0]="RubberBandLiveOptionChannelsApart",n[n.RubberBandLiveOptionChannelsTogether=268435456]="RubberBandLiveOptionChannelsTogether";class s{constructor(){}static async initialize(e){if("undefined"==typeof WebAssembly)throw new Error("WebAssembly is not supported in this environment!");let t={};const r=(...e)=>(console.error("WASI called with params",e),52);let n=[];const a=await WebAssembly.instantiate(e,{env:{emscripten_notify_memory_growth:()=>{t.HEAP8=new Uint8Array(a.exports.memory.buffer),t.HEAP32=new Uint32Array(a.exports.memory.buffer)}},wasi_snapshot_preview1:{proc_exit:(...e)=>r("proc_exit",e),fd_read:(...e)=>r("fd_read",e),fd_write:(e,r,s,a)=>{if(e>2)return 52;let i=0;for(let e=0;e<s;e++){const e=t.HEAP32[r>>2],s=t.HEAP32[r+4>>2];r+=8;for(let r=0;r<s;r++){const s=t.HEAP8[e+r];0===s||10===s?(console.log(n.join("")),n.length=0):n.push(String.fromCharCode(s))}i+=s}return t.HEAP32[a>>2]=i,0},fd_seek:(...e)=>r("fd_seek",e),fd_close:(...e)=>r("fd_close",e),environ_sizes_get:(e,t)=>52,environ_get:(...e)=>r("environ_get",e),clock_time_get:(...e)=>r("clock_time_get",e)}}),i=a.exports;t.HEAP8=new Uint8Array(a.exports.memory.buffer),t.HEAP32=new Uint32Array(a.exports.memory.buffer),i._initialize();const o={heap:t,exports:i},b=new s;return b.wasm=o,b}malloc(e){return this.wasm.exports.wasm_malloc(e)}memWrite(e,t){const r=t instanceof Uint8Array?t:new Uint8Array(t.buffer,t.byteOffset,t.byteLength);this.wasm.heap.HEAP8.set(r,e)}memWritePtr(e,t){const r=new Uint8Array(4);new DataView(r.buffer).setUint32(0,t,!0),this.wasm.heap.HEAP8.set(r,e)}memReadU8(e,t){return this.wasm.heap.HEAP8.subarray(e,e+t)}memReadF32(e,t){const r=this.memReadU8(e,4*t);return new Float32Array(r.buffer,r.byteOffset,t)}free(e){this.wasm.exports.wasm_free(e)}rubberband_new(e,t,r,n,s){return this.wasm.exports.rb_new(e,t,r,n,s)}rubberband_delete(e){this.wasm.exports.rb_delete(e)}rubberband_reset(e){this.wasm.exports.rb_reset(e)}rubberband_get_engine_version(e){return this.wasm.exports.rb_get_engine_version(e)}rubberband_set_time_ratio(e,t){this.wasm.exports.rb_set_time_ratio(e,t)}rubberband_set_pitch_scale(e,t){this.wasm.exports.rb_set_pitch_scale(e,t)}rubberband_set_formant_scale(e,t){this.wasm.exports.rb_set_formant_scale(e,t)}rubberband_get_time_ratio(e){return this.wasm.exports.rb_get_time_ratio(e)}rubberband_get_pitch_scale(e){return this.wasm.exports.rb_get_pitch_scale(e)}rubberband_get_formant_scale(e){return this.wasm.exports.rb_get_formant_scale(e)}rubberband_get_preferred_start_pad(e){return this.wasm.exports.rb_get_preferred_start_pad(e)}rubberband_get_start_delay(e){return this.wasm.exports.rb_get_start_delay(e)}rubberband_get_latency(e){return this.wasm.exports.rb_get_latency(e)}rubberband_set_transients_option(e,t){this.wasm.exports.rb_set_transients_option(e,t)}rubberband_set_detector_option(e,t){this.wasm.exports.rb_set_detector_option(e,t)}rubberband_set_phase_option(e,t){this.wasm.exports.rb_set_phase_option(e,t)}rubberband_set_formant_option(e,t){this.wasm.exports.rb_set_formant_option(e,t)}rubberband_set_pitch_option(e,t){this.wasm.exports.rb_set_pitch_option(e,t)}rubberband_set_expected_input_duration(e,t){this.wasm.exports.rb_set_expected_input_duration(e,t)}rubberband_get_samples_required(e){return this.wasm.exports.rb_get_samples_required(e)}rubberband_set_max_process_size(e,t){this.wasm.exports.rb_set_max_process_size(e,t)}rubberband_get_process_size_limit(e){return this.wasm.exports.rb_get_process_size_limit(e)}rubberband_set_key_frame_map(e,t,r,n){this.wasm.exports.rb_set_key_frame_map(e,t,r,n)}rubberband_study(e,t,r,n){this.wasm.exports.rb_study(e,t,r,n)}rubberband_process(e,t,r,n){this.wasm.exports.rb_process(e,t,r,n)}rubberband_available(e){return this.wasm.exports.rb_available(e)}rubberband_retrieve(e,t,r){return this.wasm.exports.rb_retrieve(e,t,r)}rubberband_get_channel_count(e){return this.wasm.exports.rb_get_channel_count(e)}rubberband_calculate_stretch(e){this.wasm.exports.rb_calculate_stretch(e)}rubberband_set_debug_level(e,t){this.wasm.exports.rb_set_debug_level(e,t)}rubberband_set_default_debug_level(e){this.wasm.exports.rb_set_default_debug_level(e)}rubberband_live_new(e,t,r){return this.wasm.exports.rb_live_new(e,t,r)}rubberband_live_delete(e){this.wasm.exports.rb_live_delete(e)}rubberband_live_reset(e){this.wasm.exports.rb_live_reset(e)}rubberband_live_set_pitch_scale(e,t){this.wasm.exports.rb_live_set_pitch_scale(e,t)}rubberband_live_get_pitch_scale(e){return this.wasm.exports.rb_live_get_pitch_scale(e)}rubberband_live_set_formant_scale(e,t){this.wasm.exports.rb_live_set_formant_scale(e,t)}rubberband_live_get_formant_scale(e){return this.wasm.exports.rb_live_get_formant_scale(e)}rubberband_live_get_start_delay(e){return this.wasm.exports.rb_live_get_start_delay(e)}rubberband_live_set_formant_option(e,t){this.wasm.exports.rb_live_set_formant_option(e,t)}rubberband_live_get_block_size(e){return this.wasm.exports.rb_live_get_block_size(e)}rubberband_live_shift(e,t,r){this.wasm.exports.rb_live_shift(e,t,r)}rubberband_live_get_channel_count(e){return this.wasm.exports.rb_live_get_channel_count(e)}rubberband_live_set_debug_level(e,t){this.wasm.exports.rb_live_set_debug_level(e,t)}rubberband_live_set_default_debug_level(e){this.wasm.exports.rb_live_set_default_debug_level(e)}}const a=new WeakSet;class i extends AudioWorkletNode{constructor(e,t){super(e,"rubberband-processor",{numberOfInputs:0,numberOfOutputs:1,outputChannelCount:[t]}),this.onended=null,this.onposition=null,this._channels=t,this._sourceSampleRate=e.sampleRate,this._ready=new Promise(((e,t)=>{this._readyResolve=e,this._readyReject=t})),this.port.onmessage=e=>{const t=e.data;t&&("ready"===t.type?this._readyResolve():"error"===t.type?this._readyReject(new Error("RubberBand worklet init failed: "+t.error)):"ended"===t.type?this.onended&&this.onended():"position"===t.type&&this.onposition&&this.onposition(t.seconds))}}get sourceChannels(){return this._channels}get ready(){return this._ready}static async addModule(e,t){a.has(e)||(await e.audioWorklet.addModule(t),a.add(e))}static async create(e,t={}){if("undefined"==typeof AudioWorkletNode||!e.audioWorklet)throw new Error("AudioWorklet is not supported in this AudioContext.");const r=t.processorUrl||"rubberband-processor.js";let n;if(await i.addModule(e,r),t.wasmBinary){const e=t.wasmBinary;n=e instanceof Uint8Array?e.slice().buffer:e.slice(0)}else{if(!t.wasmUrl)throw new Error("RubberBandNode.create requires one of: wasmBinary, wasmUrl.");n=await(await fetch(t.wasmUrl)).arrayBuffer()}const s=t.channelCount&&t.channelCount>0?t.channelCount:2,a=new i(e,s);a.port.postMessage({type:"initialise",wasm:n,channels:s,options:t.options},[n]);try{await a._ready}catch(e){throw a.close(),e}return a}setBuffer(e){let t,r;if(Array.isArray(e))t=e.map((e=>new Float32Array(e))),r=this._sourceSampleRate;else{r=e.sampleRate,t=[];for(let r=0;r<e.numberOfChannels;r++)t.push(new Float32Array(e.getChannelData(r)))}t=this._normalizeChannels(t);const n=t.map((e=>e.buffer));this.port.postMessage({type:"buffer",channels:t,sampleRate:r},n)}_normalizeChannels(e){const t=this._channels;if(e.length===t)return e;const r=[];for(let n=0;n<t;n++){const t=e[n<e.length?n:e.length-1]||new Float32Array(0);r.push(n<e.length?t:new Float32Array(t))}return r}play(){this.port.postMessage({type:"play"})}pause(){this.port.postMessage({type:"pause"})}stop(){this.port.postMessage({type:"stop"})}seek(e){this.port.postMessage({type:"seek",seconds:e})}set loop(e){this.port.postMessage({type:"loop",value:e})}setTempo(e){this.port.postMessage({type:"speed",value:e})}setTimeRatio(e){this.port.postMessage({type:"speed",value:e>0?1/e:1})}setPitchScale(e){this.port.postMessage({type:"pitch",value:e})}setPitchSemitones(e){this.port.postMessage({type:"pitch",value:Math.pow(2,e/12)})}close(){this.port.postMessage({type:"close"}),this.disconnect(),this.port.onmessage=null}}const o=e.RubberBandOption.RubberBandOptionProcessRealTime|e.RubberBandOption.RubberBandOptionEngineFaster|e.RubberBandOption.RubberBandOptionPitchHighConsistency;e.RUBBERBAND_REALTIME_DEFAULT_OPTIONS=o,e.RubberBandInterface=s,e.RubberBandNode=i,Object.defineProperty(e,"__esModule",{value:!0})}));
|