@viji-dev/core 0.5.3 → 0.5.5
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/artist-dts-p5.js +1 -1
- package/dist/artist-dts.js +1 -1
- package/dist/artist-global-p5.d.ts +1 -1
- package/dist/artist-global.d.ts +1 -1
- package/dist/docs-api.js +2 -2
- package/dist/{essentia-wasm.web-CPrFAj59.js → essentia-wasm.web-C58CPq4U.js} +2 -2
- package/dist/{essentia-wasm.web-CPrFAj59.js.map → essentia-wasm.web-C58CPq4U.js.map} +1 -1
- package/dist/{index-Bhq4eJe_.js → index-DsJxKERc.js} +99 -25
- package/dist/{index-Bhq4eJe_.js.map → index-DsJxKERc.js.map} +1 -1
- package/dist/index.d.ts +48 -7
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1897,7 +1897,7 @@ class EssentiaOnsetDetection {
|
|
|
1897
1897
|
this.initPromise = (async () => {
|
|
1898
1898
|
try {
|
|
1899
1899
|
const essentiaModule = await import("./essentia.js-core.es-DnrJE0uR.js");
|
|
1900
|
-
const wasmModule = await import("./essentia-wasm.web-
|
|
1900
|
+
const wasmModule = await import("./essentia-wasm.web-C58CPq4U.js").then((n) => n.e);
|
|
1901
1901
|
const EssentiaClass = essentiaModule.Essentia || essentiaModule.default?.Essentia || essentiaModule.default;
|
|
1902
1902
|
let WASMModule = wasmModule.default || wasmModule.EssentiaWASM || wasmModule.default?.EssentiaWASM;
|
|
1903
1903
|
if (!WASMModule) {
|
|
@@ -6179,9 +6179,31 @@ class OnsetTapManager {
|
|
|
6179
6179
|
modeChangeListeners = /* @__PURE__ */ new Set();
|
|
6180
6180
|
sessionEndListeners = /* @__PURE__ */ new Set();
|
|
6181
6181
|
muteChangeListeners = /* @__PURE__ */ new Set();
|
|
6182
|
-
|
|
6182
|
+
/**
|
|
6183
|
+
* Record a tap on `instrument`. Drives the visual envelope, advances
|
|
6184
|
+
* `lastTapTime`, flips mode to reflect activity, and (by default) feeds
|
|
6185
|
+
* the pattern-recognition pipeline.
|
|
6186
|
+
*
|
|
6187
|
+
* `options.skipRecognition: true` opts the tap out of the **recognition
|
|
6188
|
+
* pipeline only** — `tapIOIs` accumulation, `tryRecognizePattern`,
|
|
6189
|
+
* `applyPattern`, and `handlePatternTap` are skipped. Mode still flips
|
|
6190
|
+
* `'auto' → 'tapping'` on the first tap of a session (already-`'tapping'`
|
|
6191
|
+
* stays; already-`'pattern'` stays). This is load-bearing: `processFrame`'s
|
|
6192
|
+
* drain of `pendingTapEvents` and its audio-event filter both gate on
|
|
6193
|
+
* mode being non-`'auto'`, and downstream consumers (`onModeChange`
|
|
6194
|
+
* listeners, `broadcastOnsetState`) read mode as the signal that a tap
|
|
6195
|
+
* session is in progress. Suppressing the mode flip would silently break
|
|
6196
|
+
* all of them.
|
|
6197
|
+
*
|
|
6198
|
+
* Used for host-side relay of forwarded tap messages where another
|
|
6199
|
+
* instance owns the authoritative recognition (e.g. host receiving
|
|
6200
|
+
* controller taps over WebRTC). The `MIN_TAP_INTERVAL_MS` debounce still
|
|
6201
|
+
* applies regardless of `skipRecognition`.
|
|
6202
|
+
*/
|
|
6203
|
+
tap(instrument, options) {
|
|
6183
6204
|
const s = this.state[instrument];
|
|
6184
6205
|
const now = performance.now();
|
|
6206
|
+
const skipRecognition = options?.skipRecognition === true;
|
|
6185
6207
|
if (s.muted) {
|
|
6186
6208
|
s.muted = false;
|
|
6187
6209
|
s.mutedAt = 0;
|
|
@@ -6191,18 +6213,26 @@ class OnsetTapManager {
|
|
|
6191
6213
|
if (s.lastTapTime > 0) {
|
|
6192
6214
|
ioi = now - s.lastTapTime;
|
|
6193
6215
|
if (ioi < MIN_TAP_INTERVAL_MS) return;
|
|
6194
|
-
if (
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6216
|
+
if (!skipRecognition) {
|
|
6217
|
+
if (ioi > MAX_TAP_INTERVAL_MS) {
|
|
6218
|
+
s.tapIOIs = [];
|
|
6219
|
+
ioi = -1;
|
|
6220
|
+
} else {
|
|
6221
|
+
s.tapIOIs.push(ioi);
|
|
6222
|
+
if (s.tapIOIs.length > MAX_TAP_HISTORY) s.tapIOIs.shift();
|
|
6223
|
+
}
|
|
6200
6224
|
}
|
|
6201
6225
|
}
|
|
6202
6226
|
s.lastTapTime = now;
|
|
6203
6227
|
s.pendingTapEvents.push(now);
|
|
6204
6228
|
s.sessionActive = true;
|
|
6205
6229
|
this.scheduleSessionTimers(instrument);
|
|
6230
|
+
if (skipRecognition) {
|
|
6231
|
+
if (s.mode === "auto") {
|
|
6232
|
+
this.setMode(instrument, "tapping");
|
|
6233
|
+
}
|
|
6234
|
+
return;
|
|
6235
|
+
}
|
|
6206
6236
|
if (s.mode === "auto") {
|
|
6207
6237
|
this.setMode(instrument, "tapping");
|
|
6208
6238
|
if (ioi > 0) {
|
|
@@ -6302,16 +6332,27 @@ class OnsetTapManager {
|
|
|
6302
6332
|
/**
|
|
6303
6333
|
* Serialize per-instrument onset state for cross-instance transfer.
|
|
6304
6334
|
* Wall-clock fields are in this instance's `performance.now()` clock space.
|
|
6335
|
+
*
|
|
6336
|
+
* `options.instruments` scopes the output to the listed instruments only;
|
|
6337
|
+
* omitted instruments are absent from the payload (the receiver's
|
|
6338
|
+
* `applyInstrumentPayload` skips missing keys, leaving the receiver's
|
|
6339
|
+
* existing state for those instruments untouched). Default = all three —
|
|
6340
|
+
* the full-state-transfer used for same-process scene-switch.
|
|
6341
|
+
*
|
|
6342
|
+
* Cross-device commits should typically scope to the just-completed
|
|
6343
|
+
* instrument so an unrelated instrument's state on the receiver isn't
|
|
6344
|
+
* inadvertently overwritten.
|
|
6305
6345
|
*/
|
|
6306
|
-
exportSessionState() {
|
|
6346
|
+
exportSessionState(options) {
|
|
6347
|
+
const list = options?.instruments ?? INSTRUMENTS;
|
|
6348
|
+
const instruments = {};
|
|
6349
|
+
for (const inst of list) {
|
|
6350
|
+
instruments[inst] = this.serializeInstrument(inst);
|
|
6351
|
+
}
|
|
6307
6352
|
return {
|
|
6308
6353
|
version: STATE_SCHEMA_VERSION,
|
|
6309
6354
|
senderTime: performance.now(),
|
|
6310
|
-
instruments
|
|
6311
|
-
kick: this.serializeInstrument("kick"),
|
|
6312
|
-
snare: this.serializeInstrument("snare"),
|
|
6313
|
-
hat: this.serializeInstrument("hat")
|
|
6314
|
-
}
|
|
6355
|
+
instruments
|
|
6315
6356
|
};
|
|
6316
6357
|
}
|
|
6317
6358
|
/**
|
|
@@ -8497,10 +8538,16 @@ class AudioSystem {
|
|
|
8497
8538
|
// Public API Methods for Audio Analysis Configuration
|
|
8498
8539
|
// ═══════════════════════════════════════════════════════════
|
|
8499
8540
|
/**
|
|
8500
|
-
* Record a tap for the specified instrument onset
|
|
8541
|
+
* Record a tap for the specified instrument onset.
|
|
8542
|
+
* `options.skipRecognition` opts the tap out of the recognition pipeline
|
|
8543
|
+
* only (no IOI accumulation, no `tryRecognizePattern`, no `applyPattern`).
|
|
8544
|
+
* Mode still flips `'auto' → 'tapping'` so the visual envelope and
|
|
8545
|
+
* audio-event filter run; only the pattern-detection pipeline is bypassed.
|
|
8546
|
+
* Used by host-side relay of forwarded tap messages where another core
|
|
8547
|
+
* owns the authoritative recognition.
|
|
8501
8548
|
*/
|
|
8502
|
-
tapOnset(instrument) {
|
|
8503
|
-
this.onsetTapManager.tap(instrument);
|
|
8549
|
+
tapOnset(instrument, options) {
|
|
8550
|
+
this.onsetTapManager.tap(instrument, options);
|
|
8504
8551
|
}
|
|
8505
8552
|
/**
|
|
8506
8553
|
* Clear tap pattern for an instrument, restoring auto-detection
|
|
@@ -8550,8 +8597,8 @@ class AudioSystem {
|
|
|
8550
8597
|
// audio block is for same-process scene-switch transfer (sender's audio
|
|
8551
8598
|
// analysis state would corrupt receiver's tracking on a different source).
|
|
8552
8599
|
// ─────────────────────────────────────────────────────────────────────────
|
|
8553
|
-
exportOnsetSessionState() {
|
|
8554
|
-
return this.onsetTapManager.exportSessionState();
|
|
8600
|
+
exportOnsetSessionState(options) {
|
|
8601
|
+
return this.onsetTapManager.exportSessionState(options);
|
|
8555
8602
|
}
|
|
8556
8603
|
importOnsetSessionState(state, clockOffset) {
|
|
8557
8604
|
this.onsetTapManager.importSessionState(state, clockOffset);
|
|
@@ -11108,10 +11155,25 @@ class VijiCore {
|
|
|
11108
11155
|
* Tap an onset for a specific instrument.
|
|
11109
11156
|
* First tap switches the instrument from auto to tapping mode.
|
|
11110
11157
|
* If a repeating pattern is recognized, it continues after tapping stops.
|
|
11158
|
+
*
|
|
11159
|
+
* `options.skipRecognition: true` opts the tap out of the **recognition
|
|
11160
|
+
* pipeline only** — no `tapIOIs` accumulation, no `tryRecognizePattern`,
|
|
11161
|
+
* no `applyPattern`, no `handlePatternTap`. Mode still flips
|
|
11162
|
+
* `'auto' → 'tapping'` on the first tap of a session (and back to
|
|
11163
|
+
* `'auto'` on the 5s timeout). The mode flip is load-bearing for
|
|
11164
|
+
* `processFrame`'s drain of `pendingTapEvents`, the audio-event filter
|
|
11165
|
+
* that prevents music+tap doubling, and `onModeChange` consumers. Use
|
|
11166
|
+
* `skipRecognition` when relaying tap messages from another instance
|
|
11167
|
+
* that owns the authoritative recognition (e.g. host receiving
|
|
11168
|
+
* controller taps over WebRTC); the receiving core's pattern is then
|
|
11169
|
+
* driven only by `importSessionState` from the authoritative sender.
|
|
11170
|
+
*
|
|
11171
|
+
* The `MIN_TAP_INTERVAL_MS` debounce still applies regardless of the
|
|
11172
|
+
* `skipRecognition` flag.
|
|
11111
11173
|
*/
|
|
11112
|
-
tap: (instrument) => {
|
|
11174
|
+
tap: (instrument, options) => {
|
|
11113
11175
|
this.validateReady();
|
|
11114
|
-
this.audioSystem?.tapOnset(instrument);
|
|
11176
|
+
this.audioSystem?.tapOnset(instrument, options);
|
|
11115
11177
|
},
|
|
11116
11178
|
/**
|
|
11117
11179
|
* Clear the tap pattern for an instrument, restoring auto-detection
|
|
@@ -11214,10 +11276,22 @@ class VijiCore {
|
|
|
11214
11276
|
* Cross-device-safe (no audio analysis state included). Pair with
|
|
11215
11277
|
* `importSessionState` on a receiver. Wall-clock fields are in this
|
|
11216
11278
|
* instance's `performance.now()` clock space.
|
|
11279
|
+
*
|
|
11280
|
+
* `options.instruments` scopes the snapshot to the listed instruments
|
|
11281
|
+
* only; omitted instruments are absent from the payload. The receiver
|
|
11282
|
+
* leaves its existing state for those instruments untouched (the
|
|
11283
|
+
* receiver's `applyInstrumentPayload` skips missing keys). Default =
|
|
11284
|
+
* all three.
|
|
11285
|
+
*
|
|
11286
|
+
* Cross-device commits should typically scope to the just-completed
|
|
11287
|
+
* instrument (e.g. `exportSessionState({ instruments: [ev.instrument] })`
|
|
11288
|
+
* inside an `onSessionEnd` handler) so the receiver's unrelated
|
|
11289
|
+
* instrument state isn't inadvertently overwritten by the sender's
|
|
11290
|
+
* default values.
|
|
11217
11291
|
*/
|
|
11218
|
-
exportSessionState: () => {
|
|
11292
|
+
exportSessionState: (options) => {
|
|
11219
11293
|
this.validateReady();
|
|
11220
|
-
return this.audioSystem?.exportOnsetSessionState() ?? {
|
|
11294
|
+
return this.audioSystem?.exportOnsetSessionState(options) ?? {
|
|
11221
11295
|
version: 1,
|
|
11222
11296
|
senderTime: performance.now(),
|
|
11223
11297
|
instruments: {}
|
|
@@ -11649,7 +11723,7 @@ function validateCoreStatePayload(state) {
|
|
|
11649
11723
|
}
|
|
11650
11724
|
return null;
|
|
11651
11725
|
}
|
|
11652
|
-
const VERSION = "0.5.
|
|
11726
|
+
const VERSION = "0.5.5";
|
|
11653
11727
|
export {
|
|
11654
11728
|
AudioSystem as A,
|
|
11655
11729
|
VERSION as V,
|
|
@@ -11657,4 +11731,4 @@ export {
|
|
|
11657
11731
|
VijiCoreError as b,
|
|
11658
11732
|
getDefaultExportFromCjs as g
|
|
11659
11733
|
};
|
|
11660
|
-
//# sourceMappingURL=index-
|
|
11734
|
+
//# sourceMappingURL=index-DsJxKERc.js.map
|