@ugfoundation/swaralipi-js 0.7.5 → 0.7.6
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/{batch-DLPDVNFK.js → batch-5NMEPJ6E.js} +4 -4
- package/dist/{batch-DLPDVNFK.js.map → batch-5NMEPJ6E.js.map} +1 -1
- package/dist/{chunk-YAXYP7BR.js → chunk-ITOP5O5M.js} +3 -3
- package/dist/{chunk-YAXYP7BR.js.map → chunk-ITOP5O5M.js.map} +1 -1
- package/dist/{chunk-ZAK3QRDN.js → chunk-NJGHFQJP.js} +3 -3
- package/dist/{chunk-ZAK3QRDN.js.map → chunk-NJGHFQJP.js.map} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/convert/index.cjs +1 -1
- package/dist/convert/index.cjs.map +1 -1
- package/dist/convert/index.js +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/player/index.cjs +31 -5
- package/dist/player/index.cjs.map +1 -1
- package/dist/player/index.d.cts +15 -1
- package/dist/player/index.d.ts +15 -1
- package/dist/player/index.js +32 -6
- package/dist/player/index.js.map +1 -1
- package/dist/spec/index.cjs +1 -1
- package/dist/spec/index.cjs.map +1 -1
- package/dist/spec/index.d.cts +1 -1
- package/dist/spec/index.d.ts +1 -1
- package/dist/spec/index.js +1 -1
- package/dist/viewer/index.cjs +1 -1
- package/dist/viewer/index.cjs.map +1 -1
- package/package.json +1 -1
package/dist/player/index.d.cts
CHANGED
|
@@ -54,7 +54,8 @@ interface PlayerOptions {
|
|
|
54
54
|
* `requestAnimationFrame`, which stops the moment a screen locks, so anything
|
|
55
55
|
* hanging off it freezes until the reader looks at the page again. Use this for
|
|
56
56
|
* consumers that are not drawing (media-session metadata, analytics); it fires
|
|
57
|
-
*
|
|
57
|
+
* early — one transport lookahead (~0.1s) plus MEDIA_LEAD_SEC — and only in
|
|
58
|
+
* doc mode. */
|
|
58
59
|
onEvent?: (path: string | null) => void;
|
|
59
60
|
/** Taal mode only (`loadTaal`): called on the draw thread once per matra with
|
|
60
61
|
* the beat index within the cycle (0-based, `< numBeats`), so a consumer can
|
|
@@ -92,6 +93,19 @@ declare class SwaralipiPlayer {
|
|
|
92
93
|
get taalId(): TaalId | undefined;
|
|
93
94
|
/** Whether the effective rhythm will actually be a sampled tabla. */
|
|
94
95
|
get usesTabla(): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Length of one play-through in seconds, for a progress bar (the OS media
|
|
98
|
+
* session's, typically). Derived from the loaded notation on every read and
|
|
99
|
+
* never stored, because every input can move: re-engrave the document, drag
|
|
100
|
+
* the tempo, switch the rhythm off, and this changes with it. `Infinity` in
|
|
101
|
+
* taal mode (one avartan looping, no end — the value the Media Session spec
|
|
102
|
+
* reserves for exactly that), 0 with nothing loaded, and clamped by a preview
|
|
103
|
+
* cap when one is set, since that is when playback will really stop.
|
|
104
|
+
*/
|
|
105
|
+
get durationSec(): number;
|
|
106
|
+
/** Seconds played so far, off the Transport's own clock — so it holds while
|
|
107
|
+
* paused, and reads 0 before the first play and after stop(). */
|
|
108
|
+
get positionSec(): number;
|
|
95
109
|
/** Set the document to play. Stops any current playback. */
|
|
96
110
|
load(doc: Swaralipi): void;
|
|
97
111
|
/**
|
package/dist/player/index.d.ts
CHANGED
|
@@ -54,7 +54,8 @@ interface PlayerOptions {
|
|
|
54
54
|
* `requestAnimationFrame`, which stops the moment a screen locks, so anything
|
|
55
55
|
* hanging off it freezes until the reader looks at the page again. Use this for
|
|
56
56
|
* consumers that are not drawing (media-session metadata, analytics); it fires
|
|
57
|
-
*
|
|
57
|
+
* early — one transport lookahead (~0.1s) plus MEDIA_LEAD_SEC — and only in
|
|
58
|
+
* doc mode. */
|
|
58
59
|
onEvent?: (path: string | null) => void;
|
|
59
60
|
/** Taal mode only (`loadTaal`): called on the draw thread once per matra with
|
|
60
61
|
* the beat index within the cycle (0-based, `< numBeats`), so a consumer can
|
|
@@ -92,6 +93,19 @@ declare class SwaralipiPlayer {
|
|
|
92
93
|
get taalId(): TaalId | undefined;
|
|
93
94
|
/** Whether the effective rhythm will actually be a sampled tabla. */
|
|
94
95
|
get usesTabla(): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Length of one play-through in seconds, for a progress bar (the OS media
|
|
98
|
+
* session's, typically). Derived from the loaded notation on every read and
|
|
99
|
+
* never stored, because every input can move: re-engrave the document, drag
|
|
100
|
+
* the tempo, switch the rhythm off, and this changes with it. `Infinity` in
|
|
101
|
+
* taal mode (one avartan looping, no end — the value the Media Session spec
|
|
102
|
+
* reserves for exactly that), 0 with nothing loaded, and clamped by a preview
|
|
103
|
+
* cap when one is set, since that is when playback will really stop.
|
|
104
|
+
*/
|
|
105
|
+
get durationSec(): number;
|
|
106
|
+
/** Seconds played so far, off the Transport's own clock — so it holds while
|
|
107
|
+
* paused, and reads 0 before the first play and after stop(). */
|
|
108
|
+
get positionSec(): number;
|
|
95
109
|
/** Set the document to play. Stops any current playback. */
|
|
96
110
|
load(doc: Swaralipi): void;
|
|
97
111
|
/**
|
package/dist/player/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { DEFAULT_SOUNDS_BASE, INSTRUMENTS, SAMPLED_TAALS, instrumentSampleUrl, probeUrl, normalizeBase, nearestTablaBpm, tablaBpms,
|
|
1
|
+
import { DEFAULT_SOUNDS_BASE, INSTRUMENTS, SAMPLED_TAALS, buildSchedule, instrumentSampleUrl, probeUrl, normalizeBase, nearestTablaBpm, tablaBpms, quantizeLoopEnd, midiToSampleName, glideTargets, triggerGlide, createSampler, createBuffers, tablaUrl, tablaShiftSemitones, TABLA_GRAIN_OVERLAP_SEC, TABLA_GRAIN_SEC, createDrumKit, drumPattern, createMetronome, TANPURA_PCS, createTanpura, parseTonic, MEEND_HOLD, sCurve } from '../chunk-2SAZWTTK.js';
|
|
2
2
|
export { ARC_RAW_RE, DEFAULT_SOUNDS_BASE, DRUM_KIT_BASE, INSTRUMENTS, MEEND_HOLD, OCTAVE_OFFSET, SALAMANDER_BASE, SAMPLED_TAALS, SHUDDHA, TABLA_BPMS, TABLA_VARIATIONS, TONEJS_INSTRUMENTS_BASE, buildSchedule, createBuffers, drumPattern, glideTargets, instrumentSampleUrl, isArcRaw, meendContinuations, midiToSampleName, nearestSampleKey, nearestTablaBpm, normalizeBase, parseTonic, probeUrl, quantizeLoopEnd, sCurve, sampleFileName, santoorUrls, subsetUrls, svaraSemitone, svaraToMidi, tablaBpms, tablaUrl, triggerGlide } from '../chunk-2SAZWTTK.js';
|
|
3
3
|
import { TAALS } from '../chunk-UF5OSJRP.js';
|
|
4
4
|
|
|
5
5
|
// src/player/player.ts
|
|
6
6
|
var STOP_FADE_SEC = 0.5;
|
|
7
|
+
var MEDIA_LEAD_SEC = 0.25;
|
|
7
8
|
function midiRange(schedule) {
|
|
8
9
|
let lo = Infinity;
|
|
9
10
|
let hi = -Infinity;
|
|
@@ -17,6 +18,9 @@ function midiRange(schedule) {
|
|
|
17
18
|
}
|
|
18
19
|
return lo <= hi ? { lo, hi } : void 0;
|
|
19
20
|
}
|
|
21
|
+
function playDurationSec(schedule, spb, rhythm) {
|
|
22
|
+
return schedule.totalBeats * spb + (rhythm !== "none" ? schedule.pickupBeats * spb : 0) + spb;
|
|
23
|
+
}
|
|
20
24
|
async function loadedOrWarn(Tone) {
|
|
21
25
|
try {
|
|
22
26
|
await Tone.loaded();
|
|
@@ -97,6 +101,27 @@ var SwaralipiPlayer = class {
|
|
|
97
101
|
const id = this.#taalId();
|
|
98
102
|
return this.#opts.rhythm === "tabla" && id !== void 0 && SAMPLED_TAALS.has(id) && !!this.#opts.soundsBaseUrl;
|
|
99
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Length of one play-through in seconds, for a progress bar (the OS media
|
|
106
|
+
* session's, typically). Derived from the loaded notation on every read and
|
|
107
|
+
* never stored, because every input can move: re-engrave the document, drag
|
|
108
|
+
* the tempo, switch the rhythm off, and this changes with it. `Infinity` in
|
|
109
|
+
* taal mode (one avartan looping, no end — the value the Media Session spec
|
|
110
|
+
* reserves for exactly that), 0 with nothing loaded, and clamped by a preview
|
|
111
|
+
* cap when one is set, since that is when playback will really stop.
|
|
112
|
+
*/
|
|
113
|
+
get durationSec() {
|
|
114
|
+
if (this.#taal !== void 0) return Infinity;
|
|
115
|
+
if (this.#doc === void 0) return 0;
|
|
116
|
+
const schedule = buildSchedule(this.#doc, { tonic: this.#opts.tonic, baseOctave: this.#opts.baseOctave });
|
|
117
|
+
const full = playDurationSec(schedule, 60 / this.#effectiveBpm(), this.#opts.rhythm);
|
|
118
|
+
return Math.min(full, this.#opts.previewLimitSec);
|
|
119
|
+
}
|
|
120
|
+
/** Seconds played so far, off the Transport's own clock — so it holds while
|
|
121
|
+
* paused, and reads 0 before the first play and after stop(). */
|
|
122
|
+
get positionSec() {
|
|
123
|
+
return this.#tone?.getTransport().seconds ?? 0;
|
|
124
|
+
}
|
|
100
125
|
/* ----------------------------------------------------------------- */
|
|
101
126
|
/* Loading + transport control */
|
|
102
127
|
/* ----------------------------------------------------------------- */
|
|
@@ -409,6 +434,7 @@ var SwaralipiPlayer = class {
|
|
|
409
434
|
}
|
|
410
435
|
const draw = Tone.getDraw();
|
|
411
436
|
const shift = this.#opts.rhythm !== "none" ? schedule.pickupBeats * spb : 0;
|
|
437
|
+
const mediaLead = Math.min(MEDIA_LEAD_SEC, spb);
|
|
412
438
|
schedule.events.forEach((ev, i) => {
|
|
413
439
|
const at = ev.beat * spb + shift;
|
|
414
440
|
if (ev.midi !== null && ev.glide !== true) {
|
|
@@ -442,12 +468,12 @@ var SwaralipiPlayer = class {
|
|
|
442
468
|
transport.scheduleOnce((time) => melody.triggerAttackRelease(name, dur, time), at);
|
|
443
469
|
}
|
|
444
470
|
}
|
|
445
|
-
|
|
446
|
-
this.#opts.onEvent?.(ev.path);
|
|
447
|
-
|
|
448
|
-
|
|
471
|
+
if (this.#opts.onEvent !== void 0) {
|
|
472
|
+
transport.scheduleOnce(() => this.#opts.onEvent?.(ev.path), Math.max(at - mediaLead, 0));
|
|
473
|
+
}
|
|
474
|
+
transport.scheduleOnce((time) => draw.schedule(() => this.#emitHighlight(ev.path), time), at);
|
|
449
475
|
});
|
|
450
|
-
const endAt = schedule
|
|
476
|
+
const endAt = playDurationSec(schedule, spb, this.#opts.rhythm);
|
|
451
477
|
transport.scheduleOnce((time) => {
|
|
452
478
|
this.#opts.onEvent?.(null);
|
|
453
479
|
draw.schedule(() => this.#emitHighlight(null), time);
|