libadlmidi-js 1.2.0 → 2.0.0
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/core.d.ts +186 -4
- package/dist/fm_banks/manifest.json +1 -1
- package/dist/libadlmidi.d.ts +143 -65
- package/dist/libadlmidi.dosbox.browser.js +1 -1
- package/dist/libadlmidi.dosbox.browser.wasm +0 -0
- package/dist/libadlmidi.dosbox.core.js +1 -1
- package/dist/libadlmidi.dosbox.core.wasm +0 -0
- package/dist/libadlmidi.dosbox.js +0 -0
- package/dist/libadlmidi.dosbox.processor.js +242 -74
- package/dist/libadlmidi.dosbox.slim.browser.js +1 -1
- package/dist/libadlmidi.dosbox.slim.browser.wasm +0 -0
- package/dist/libadlmidi.dosbox.slim.core.js +1 -1
- package/dist/libadlmidi.dosbox.slim.core.wasm +0 -0
- package/dist/libadlmidi.dosbox.slim.js +0 -0
- package/dist/libadlmidi.dosbox.slim.processor.js +242 -74
- package/dist/libadlmidi.full.browser.js +1 -1
- package/dist/libadlmidi.full.browser.wasm +0 -0
- package/dist/libadlmidi.full.core.js +1 -1
- package/dist/libadlmidi.full.core.wasm +0 -0
- package/dist/libadlmidi.full.js +0 -0
- package/dist/libadlmidi.full.processor.js +242 -74
- package/dist/libadlmidi.full.slim.browser.js +1 -1
- package/dist/libadlmidi.full.slim.browser.wasm +0 -0
- package/dist/libadlmidi.full.slim.core.js +1 -1
- package/dist/libadlmidi.full.slim.core.wasm +0 -0
- package/dist/libadlmidi.full.slim.js +0 -0
- package/dist/libadlmidi.full.slim.processor.js +242 -74
- package/dist/libadlmidi.js +465 -21
- package/dist/libadlmidi.js.map +3 -3
- package/dist/libadlmidi.light.browser.js +1 -1
- package/dist/libadlmidi.light.browser.wasm +0 -0
- package/dist/libadlmidi.light.core.js +1 -1
- package/dist/libadlmidi.light.core.wasm +0 -0
- package/dist/libadlmidi.light.js +0 -0
- package/dist/libadlmidi.light.processor.js +242 -74
- package/dist/libadlmidi.light.slim.browser.js +1 -1
- package/dist/libadlmidi.light.slim.browser.wasm +0 -0
- package/dist/libadlmidi.light.slim.core.js +1 -1
- package/dist/libadlmidi.light.slim.core.wasm +0 -0
- package/dist/libadlmidi.light.slim.js +0 -0
- package/dist/libadlmidi.light.slim.processor.js +242 -74
- package/dist/libadlmidi.nuked.browser.js +1 -1
- package/dist/libadlmidi.nuked.browser.wasm +0 -0
- package/dist/libadlmidi.nuked.core.js +1 -1
- package/dist/libadlmidi.nuked.core.wasm +0 -0
- package/dist/libadlmidi.nuked.js +0 -0
- package/dist/libadlmidi.nuked.processor.js +242 -74
- package/dist/libadlmidi.nuked.slim.browser.js +1 -1
- package/dist/libadlmidi.nuked.slim.browser.wasm +0 -0
- package/dist/libadlmidi.nuked.slim.core.js +1 -1
- package/dist/libadlmidi.nuked.slim.core.wasm +0 -0
- package/dist/libadlmidi.nuked.slim.js +0 -0
- package/dist/libadlmidi.nuked.slim.processor.js +242 -74
- package/dist/profiles/dosbox.d.ts +1 -0
- package/dist/profiles/dosbox.slim.d.ts +1 -0
- package/dist/profiles/full.d.ts +1 -0
- package/dist/profiles/full.slim.d.ts +1 -0
- package/dist/profiles/light.d.ts +1 -0
- package/dist/profiles/light.slim.d.ts +1 -0
- package/dist/profiles/nuked.d.ts +1 -0
- package/dist/profiles/nuked.slim.d.ts +1 -0
- package/dist/utils/constants.d.ts +59 -0
- package/package.json +1 -1
- package/src/core.js +352 -4
- package/src/libadlmidi.js +374 -56
- package/src/processor.js +204 -12
- package/src/profiles/dosbox.js +7 -4
- package/src/profiles/dosbox.slim.js +7 -4
- package/src/profiles/full.js +7 -4
- package/src/profiles/full.slim.js +7 -4
- package/src/profiles/light.js +7 -4
- package/src/profiles/light.slim.js +7 -4
- package/src/profiles/nuked.js +7 -4
- package/src/profiles/nuked.slim.js +7 -4
- package/src/utils/constants.js +51 -0
package/dist/libadlmidi.js
CHANGED
|
@@ -6,8 +6,16 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
|
|
|
6
6
|
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
7
7
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
8
8
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
9
|
+
var __privateWrapper = (obj, member, setter, getter) => ({
|
|
10
|
+
set _(value) {
|
|
11
|
+
__privateSet(obj, member, value, setter);
|
|
12
|
+
},
|
|
13
|
+
get _() {
|
|
14
|
+
return __privateGet(obj, member, getter);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
9
17
|
|
|
10
|
-
// src/
|
|
18
|
+
// src/utils/constants.js
|
|
11
19
|
var Emulator = Object.freeze({
|
|
12
20
|
/** Nuked OPL3 v1.8 - Most accurate, higher CPU usage */
|
|
13
21
|
NUKED: 0,
|
|
@@ -20,7 +28,7 @@ var Emulator = Object.freeze({
|
|
|
20
28
|
/** Java OPL3 - Port of emu8950 */
|
|
21
29
|
JAVA: 4,
|
|
22
30
|
/** ESFMu - ESFM chip emulator */
|
|
23
|
-
|
|
31
|
+
ESFMu: 5,
|
|
24
32
|
/** MAME OPL2 */
|
|
25
33
|
MAME_OPL2: 6,
|
|
26
34
|
/** YMFM OPL2 */
|
|
@@ -34,7 +42,17 @@ var Emulator = Object.freeze({
|
|
|
34
42
|
/** Nuked OPL2 Lite - Lightweight OPL2 emulation for AdLib-era music */
|
|
35
43
|
NUKED_OPL2_LITE: 11
|
|
36
44
|
});
|
|
37
|
-
var
|
|
45
|
+
var TrackOption = Object.freeze({
|
|
46
|
+
/** Enable the track (default state) */
|
|
47
|
+
ON: 1,
|
|
48
|
+
/** Mute/disable the track */
|
|
49
|
+
OFF: 2,
|
|
50
|
+
/** Solo the track (mute all others) */
|
|
51
|
+
SOLO: 3
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// src/libadlmidi.js
|
|
55
|
+
var _ready, _messageHandlers, _nextRequestId, _AdlMidi_instances, handleMessage_fn, onceMessage_fn, onceCorrelatedMessage_fn, send_fn;
|
|
38
56
|
var AdlMidi = class {
|
|
39
57
|
/**
|
|
40
58
|
* Create a new AdlMidi instance
|
|
@@ -46,6 +64,8 @@ var AdlMidi = class {
|
|
|
46
64
|
__privateAdd(this, _ready, false);
|
|
47
65
|
/** @type {Map<string, Set<Function>>} */
|
|
48
66
|
__privateAdd(this, _messageHandlers, /* @__PURE__ */ new Map());
|
|
67
|
+
/** @type {number} */
|
|
68
|
+
__privateAdd(this, _nextRequestId, 0);
|
|
49
69
|
this.ctx = context || null;
|
|
50
70
|
this.node = null;
|
|
51
71
|
}
|
|
@@ -228,7 +248,7 @@ var AdlMidi = class {
|
|
|
228
248
|
* @param {ArrayBuffer} arrayBuffer - Bank file data
|
|
229
249
|
* @returns {Promise<void>}
|
|
230
250
|
*/
|
|
231
|
-
async
|
|
251
|
+
async loadBankData(arrayBuffer) {
|
|
232
252
|
return new Promise((resolve, reject) => {
|
|
233
253
|
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
234
254
|
this,
|
|
@@ -242,7 +262,7 @@ var AdlMidi = class {
|
|
|
242
262
|
}
|
|
243
263
|
}
|
|
244
264
|
);
|
|
245
|
-
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "
|
|
265
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "loadBankData", data: arrayBuffer });
|
|
246
266
|
});
|
|
247
267
|
}
|
|
248
268
|
/**
|
|
@@ -345,6 +365,23 @@ var AdlMidi = class {
|
|
|
345
365
|
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getNumFourOpChannels" });
|
|
346
366
|
});
|
|
347
367
|
}
|
|
368
|
+
/**
|
|
369
|
+
* Get the number of 4-operator channels obtained
|
|
370
|
+
* @returns {Promise<number>}
|
|
371
|
+
*/
|
|
372
|
+
async getNumFourOpChannelsObtained() {
|
|
373
|
+
return new Promise((resolve) => {
|
|
374
|
+
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
375
|
+
this,
|
|
376
|
+
"numFourOpChannelsObtained",
|
|
377
|
+
/** @param {{channels: number}} msg */
|
|
378
|
+
(msg) => {
|
|
379
|
+
resolve(msg.channels);
|
|
380
|
+
}
|
|
381
|
+
);
|
|
382
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getNumFourOpChannelsObtained" });
|
|
383
|
+
});
|
|
384
|
+
}
|
|
348
385
|
/**
|
|
349
386
|
* Enable/disable scaling of modulators by volume
|
|
350
387
|
* @param {boolean} enabled
|
|
@@ -408,32 +445,66 @@ var AdlMidi = class {
|
|
|
408
445
|
});
|
|
409
446
|
}
|
|
410
447
|
/**
|
|
411
|
-
* Set the volume model
|
|
448
|
+
* Set the volume range model
|
|
412
449
|
* @param {number} model - Volume model number
|
|
413
450
|
*/
|
|
414
|
-
|
|
415
|
-
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "
|
|
451
|
+
setVolumeRangeModel(model) {
|
|
452
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "setVolumeRangeModel", model });
|
|
416
453
|
}
|
|
417
454
|
/**
|
|
418
|
-
* Enable/disable
|
|
455
|
+
* Enable/disable soft stereo panning
|
|
419
456
|
* @param {boolean} enabled
|
|
420
457
|
*/
|
|
421
|
-
|
|
422
|
-
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "
|
|
458
|
+
setSoftPanEnabled(enabled) {
|
|
459
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "setSoftPanEnabled", enabled });
|
|
423
460
|
}
|
|
424
461
|
/**
|
|
425
462
|
* Enable/disable deep vibrato
|
|
426
463
|
* @param {boolean} enabled
|
|
427
464
|
*/
|
|
428
|
-
|
|
429
|
-
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "
|
|
465
|
+
setDeepVibrato(enabled) {
|
|
466
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "setDeepVibrato", enabled });
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Get deep vibrato state
|
|
470
|
+
* @returns {Promise<boolean>}
|
|
471
|
+
*/
|
|
472
|
+
async getDeepVibrato() {
|
|
473
|
+
return new Promise((resolve) => {
|
|
474
|
+
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
475
|
+
this,
|
|
476
|
+
"deepVibrato",
|
|
477
|
+
/** @param {{enabled: boolean}} msg */
|
|
478
|
+
(msg) => {
|
|
479
|
+
resolve(msg.enabled);
|
|
480
|
+
}
|
|
481
|
+
);
|
|
482
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getDeepVibrato" });
|
|
483
|
+
});
|
|
430
484
|
}
|
|
431
485
|
/**
|
|
432
486
|
* Enable/disable deep tremolo
|
|
433
487
|
* @param {boolean} enabled
|
|
434
488
|
*/
|
|
435
|
-
|
|
436
|
-
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "
|
|
489
|
+
setDeepTremolo(enabled) {
|
|
490
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "setDeepTremolo", enabled });
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Get deep tremolo state
|
|
494
|
+
* @returns {Promise<boolean>}
|
|
495
|
+
*/
|
|
496
|
+
async getDeepTremolo() {
|
|
497
|
+
return new Promise((resolve) => {
|
|
498
|
+
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
499
|
+
this,
|
|
500
|
+
"deepTremolo",
|
|
501
|
+
/** @param {{enabled: boolean}} msg */
|
|
502
|
+
(msg) => {
|
|
503
|
+
resolve(msg.enabled);
|
|
504
|
+
}
|
|
505
|
+
);
|
|
506
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getDeepTremolo" });
|
|
507
|
+
});
|
|
437
508
|
}
|
|
438
509
|
/**
|
|
439
510
|
* Run emulator with PCM rate to reduce CPU usage
|
|
@@ -449,7 +520,7 @@ var AdlMidi = class {
|
|
|
449
520
|
* - nuked profile: NUKED only
|
|
450
521
|
* - dosbox profile: DOSBOX only
|
|
451
522
|
* - light profile: NUKED, DOSBOX
|
|
452
|
-
* - full profile: NUKED, DOSBOX, OPAL, JAVA,
|
|
523
|
+
* - full profile: NUKED, DOSBOX, OPAL, JAVA, ESFMu, YMFM_OPL2, YMFM_OPL3
|
|
453
524
|
*
|
|
454
525
|
* @param {number} emulator - Emulator ID from the Emulator enum
|
|
455
526
|
* @returns {Promise<void>} Resolves when emulator is switched, rejects if unavailable
|
|
@@ -494,6 +565,23 @@ var AdlMidi = class {
|
|
|
494
565
|
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getEmulatorName" });
|
|
495
566
|
});
|
|
496
567
|
}
|
|
568
|
+
/**
|
|
569
|
+
* Get the last error info for the player instance
|
|
570
|
+
* @returns {Promise<string>}
|
|
571
|
+
*/
|
|
572
|
+
async getErrorInfo() {
|
|
573
|
+
return new Promise((resolve) => {
|
|
574
|
+
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
575
|
+
this,
|
|
576
|
+
"errorInfo",
|
|
577
|
+
/** @param {{info: string}} msg */
|
|
578
|
+
(msg) => {
|
|
579
|
+
resolve(msg.info);
|
|
580
|
+
}
|
|
581
|
+
);
|
|
582
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getErrorInfo" });
|
|
583
|
+
});
|
|
584
|
+
}
|
|
497
585
|
/**
|
|
498
586
|
* Get the version string of the linked libADLMIDI library
|
|
499
587
|
* @returns {Promise<string>}
|
|
@@ -566,17 +654,17 @@ var AdlMidi = class {
|
|
|
566
654
|
* Get the volume range model
|
|
567
655
|
* @returns {Promise<number>}
|
|
568
656
|
*/
|
|
569
|
-
async
|
|
657
|
+
async getVolumeRangeModel() {
|
|
570
658
|
return new Promise((resolve) => {
|
|
571
659
|
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
572
660
|
this,
|
|
573
|
-
"
|
|
661
|
+
"volumeRangeModel",
|
|
574
662
|
/** @param {{model: number}} msg */
|
|
575
663
|
(msg) => {
|
|
576
664
|
resolve(msg.model);
|
|
577
665
|
}
|
|
578
666
|
);
|
|
579
|
-
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "
|
|
667
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getVolumeRangeModel" });
|
|
580
668
|
});
|
|
581
669
|
}
|
|
582
670
|
/**
|
|
@@ -600,6 +688,146 @@ var AdlMidi = class {
|
|
|
600
688
|
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getEmbeddedBanks" });
|
|
601
689
|
});
|
|
602
690
|
}
|
|
691
|
+
// ================== Bank Management API ==================
|
|
692
|
+
/**
|
|
693
|
+
* Reserve a number of banks
|
|
694
|
+
* @param {number} count - Number of banks to reserve
|
|
695
|
+
* @returns {Promise<void>} Resolves on success, rejects on failure
|
|
696
|
+
*/
|
|
697
|
+
async reserveBanks(count) {
|
|
698
|
+
const reqId = __privateWrapper(this, _nextRequestId)._++;
|
|
699
|
+
return new Promise((resolve, reject) => {
|
|
700
|
+
__privateMethod(this, _AdlMidi_instances, onceCorrelatedMessage_fn).call(
|
|
701
|
+
this,
|
|
702
|
+
"banksReserved",
|
|
703
|
+
reqId,
|
|
704
|
+
/** @param {{success: boolean}} msg */
|
|
705
|
+
(msg) => {
|
|
706
|
+
if (msg.success) {
|
|
707
|
+
resolve();
|
|
708
|
+
} else {
|
|
709
|
+
reject(new Error("Failed to reserve banks"));
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
);
|
|
713
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "reserveBanks", count, reqId });
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Get the bank ID for a given bank identifier
|
|
718
|
+
* @param {BankId} bankId - Bank identifier
|
|
719
|
+
* @returns {Promise<{percussive: number, msb: number, lsb: number}|null>} Bank ID or null if not found
|
|
720
|
+
*/
|
|
721
|
+
async getBankId(bankId) {
|
|
722
|
+
const reqId = __privateWrapper(this, _nextRequestId)._++;
|
|
723
|
+
return new Promise((resolve) => {
|
|
724
|
+
__privateMethod(this, _AdlMidi_instances, onceCorrelatedMessage_fn).call(
|
|
725
|
+
this,
|
|
726
|
+
"bankId",
|
|
727
|
+
reqId,
|
|
728
|
+
/** @param {{id: {percussive: number, msb: number, lsb: number}|null}} msg */
|
|
729
|
+
(msg) => {
|
|
730
|
+
resolve(msg.id);
|
|
731
|
+
}
|
|
732
|
+
);
|
|
733
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getBankId", bankId, reqId });
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
/**
|
|
737
|
+
* Remove a bank by its identifier
|
|
738
|
+
* @param {BankId} bankId - Bank identifier
|
|
739
|
+
* @returns {Promise<void>} Resolves on success, rejects on failure
|
|
740
|
+
*/
|
|
741
|
+
async removeBank(bankId) {
|
|
742
|
+
const reqId = __privateWrapper(this, _nextRequestId)._++;
|
|
743
|
+
return new Promise((resolve, reject) => {
|
|
744
|
+
__privateMethod(this, _AdlMidi_instances, onceCorrelatedMessage_fn).call(
|
|
745
|
+
this,
|
|
746
|
+
"bankRemoved",
|
|
747
|
+
reqId,
|
|
748
|
+
/** @param {{success: boolean}} msg */
|
|
749
|
+
(msg) => {
|
|
750
|
+
if (msg.success) {
|
|
751
|
+
resolve();
|
|
752
|
+
} else {
|
|
753
|
+
reject(new Error("Failed to remove bank"));
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
);
|
|
757
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "removeBank", bankId, reqId });
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* Load an embedded bank into a custom bank slot
|
|
762
|
+
* @param {BankId} bankId - Target bank identifier
|
|
763
|
+
* @param {number} num - Embedded bank number to load
|
|
764
|
+
* @returns {Promise<void>} Resolves on success, rejects on failure
|
|
765
|
+
*/
|
|
766
|
+
async loadEmbeddedBank(bankId, num) {
|
|
767
|
+
const reqId = __privateWrapper(this, _nextRequestId)._++;
|
|
768
|
+
return new Promise((resolve, reject) => {
|
|
769
|
+
__privateMethod(this, _AdlMidi_instances, onceCorrelatedMessage_fn).call(
|
|
770
|
+
this,
|
|
771
|
+
"embeddedBankLoaded",
|
|
772
|
+
reqId,
|
|
773
|
+
/** @param {{success: boolean}} msg */
|
|
774
|
+
(msg) => {
|
|
775
|
+
if (msg.success) {
|
|
776
|
+
resolve();
|
|
777
|
+
} else {
|
|
778
|
+
reject(new Error("Failed to load embedded bank"));
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
);
|
|
782
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "loadEmbeddedBank", bankId, num, reqId });
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
// ================== SysEx API ==================
|
|
786
|
+
/**
|
|
787
|
+
* Send a System Exclusive (SysEx) message
|
|
788
|
+
* @param {Uint8Array|ArrayBuffer} data - SysEx message data
|
|
789
|
+
* @returns {Promise<void>} Resolves on success, rejects on failure
|
|
790
|
+
*/
|
|
791
|
+
async systemExclusive(data) {
|
|
792
|
+
const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
|
|
793
|
+
const reqId = __privateWrapper(this, _nextRequestId)._++;
|
|
794
|
+
return new Promise((resolve, reject) => {
|
|
795
|
+
__privateMethod(this, _AdlMidi_instances, onceCorrelatedMessage_fn).call(
|
|
796
|
+
this,
|
|
797
|
+
"systemExclusiveSent",
|
|
798
|
+
reqId,
|
|
799
|
+
/** @param {{success: boolean}} msg */
|
|
800
|
+
(msg) => {
|
|
801
|
+
if (msg.success) {
|
|
802
|
+
resolve();
|
|
803
|
+
} else {
|
|
804
|
+
reject(new Error("Failed to send system exclusive message"));
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
);
|
|
808
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "systemExclusive", data: Array.from(bytes), reqId });
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
// ================== Debug / Diagnostics API ==================
|
|
812
|
+
/**
|
|
813
|
+
* Describe the current state of all channels (debug utility)
|
|
814
|
+
* @returns {Promise<{text: string, attr: Uint8Array}>} Channel state text and raw per-channel attribute bytes
|
|
815
|
+
*/
|
|
816
|
+
async describeChannels() {
|
|
817
|
+
const reqId = __privateWrapper(this, _nextRequestId)._++;
|
|
818
|
+
return new Promise((resolve) => {
|
|
819
|
+
__privateMethod(this, _AdlMidi_instances, onceCorrelatedMessage_fn).call(
|
|
820
|
+
this,
|
|
821
|
+
"channelsDescribed",
|
|
822
|
+
reqId,
|
|
823
|
+
/** @param {{text: string, attr: number[]}} msg */
|
|
824
|
+
(msg) => {
|
|
825
|
+
resolve({ text: msg.text, attr: new Uint8Array(msg.attr) });
|
|
826
|
+
}
|
|
827
|
+
);
|
|
828
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "describeChannels", reqId });
|
|
829
|
+
});
|
|
830
|
+
}
|
|
603
831
|
/**
|
|
604
832
|
* Reset the synthesizer
|
|
605
833
|
* @returns {void}
|
|
@@ -664,6 +892,60 @@ var AdlMidi = class {
|
|
|
664
892
|
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getMusicCopyright" });
|
|
665
893
|
});
|
|
666
894
|
}
|
|
895
|
+
/**
|
|
896
|
+
* Get the number of track titles in the loaded MIDI file
|
|
897
|
+
* @returns {Promise<number>}
|
|
898
|
+
*/
|
|
899
|
+
async getTrackTitleCount() {
|
|
900
|
+
return new Promise((resolve) => {
|
|
901
|
+
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
902
|
+
this,
|
|
903
|
+
"trackTitleCount",
|
|
904
|
+
/** @param {{count: number}} msg */
|
|
905
|
+
(msg) => {
|
|
906
|
+
resolve(msg.count);
|
|
907
|
+
}
|
|
908
|
+
);
|
|
909
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getTrackTitleCount" });
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Get a track title by index
|
|
914
|
+
* @param {number} index - Track title index
|
|
915
|
+
* @returns {Promise<string>}
|
|
916
|
+
*/
|
|
917
|
+
async getTrackTitle(index) {
|
|
918
|
+
const reqId = __privateWrapper(this, _nextRequestId)._++;
|
|
919
|
+
return new Promise((resolve) => {
|
|
920
|
+
__privateMethod(this, _AdlMidi_instances, onceCorrelatedMessage_fn).call(
|
|
921
|
+
this,
|
|
922
|
+
"trackTitle",
|
|
923
|
+
reqId,
|
|
924
|
+
/** @param {{title: string}} msg */
|
|
925
|
+
(msg) => {
|
|
926
|
+
resolve(msg.title);
|
|
927
|
+
}
|
|
928
|
+
);
|
|
929
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getTrackTitle", index, reqId });
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
* Get the number of MIDI markers in the loaded file
|
|
934
|
+
* @returns {Promise<number>}
|
|
935
|
+
*/
|
|
936
|
+
async getMarkerCount() {
|
|
937
|
+
return new Promise((resolve) => {
|
|
938
|
+
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
939
|
+
this,
|
|
940
|
+
"markerCount",
|
|
941
|
+
/** @param {{count: number}} msg */
|
|
942
|
+
(msg) => {
|
|
943
|
+
resolve(msg.count);
|
|
944
|
+
}
|
|
945
|
+
);
|
|
946
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getMarkerCount" });
|
|
947
|
+
});
|
|
948
|
+
}
|
|
667
949
|
/**
|
|
668
950
|
* Start or resume MIDI file playback
|
|
669
951
|
* @returns {void}
|
|
@@ -691,8 +973,149 @@ var AdlMidi = class {
|
|
|
691
973
|
* @param {boolean} enabled - Whether to loop
|
|
692
974
|
* @returns {void}
|
|
693
975
|
*/
|
|
694
|
-
|
|
695
|
-
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "
|
|
976
|
+
setLoopEnabled(enabled) {
|
|
977
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "setLoopEnabled", enabled });
|
|
978
|
+
}
|
|
979
|
+
/**
|
|
980
|
+
* Set the number of loop repetitions
|
|
981
|
+
* @param {number} count - Loop count (-1 = infinite, 0 = no loops, 1+ = number of loops)
|
|
982
|
+
*/
|
|
983
|
+
setLoopCount(count) {
|
|
984
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "setLoopCount", count });
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Enable/disable loop hooks only mode
|
|
988
|
+
* @param {boolean} enabled
|
|
989
|
+
*/
|
|
990
|
+
setLoopHooksOnly(enabled) {
|
|
991
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "setLoopHooksOnly", enabled });
|
|
992
|
+
}
|
|
993
|
+
/**
|
|
994
|
+
* Get the loop start time in seconds
|
|
995
|
+
* @returns {Promise<number>}
|
|
996
|
+
*/
|
|
997
|
+
async getLoopStartTime() {
|
|
998
|
+
return new Promise((resolve) => {
|
|
999
|
+
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
1000
|
+
this,
|
|
1001
|
+
"loopStartTime",
|
|
1002
|
+
/** @param {{time: number}} msg */
|
|
1003
|
+
(msg) => {
|
|
1004
|
+
resolve(msg.time);
|
|
1005
|
+
}
|
|
1006
|
+
);
|
|
1007
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getLoopStartTime" });
|
|
1008
|
+
});
|
|
1009
|
+
}
|
|
1010
|
+
/**
|
|
1011
|
+
* Get the loop end time in seconds
|
|
1012
|
+
* @returns {Promise<number>}
|
|
1013
|
+
*/
|
|
1014
|
+
async getLoopEndTime() {
|
|
1015
|
+
return new Promise((resolve) => {
|
|
1016
|
+
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
1017
|
+
this,
|
|
1018
|
+
"loopEndTime",
|
|
1019
|
+
/** @param {{time: number}} msg */
|
|
1020
|
+
(msg) => {
|
|
1021
|
+
resolve(msg.time);
|
|
1022
|
+
}
|
|
1023
|
+
);
|
|
1024
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getLoopEndTime" });
|
|
1025
|
+
});
|
|
1026
|
+
}
|
|
1027
|
+
/**
|
|
1028
|
+
* Select a song number for multi-song MIDI files
|
|
1029
|
+
* @param {number} num - Song number (0-based)
|
|
1030
|
+
*/
|
|
1031
|
+
selectSongNum(num) {
|
|
1032
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "selectSongNum", num });
|
|
1033
|
+
}
|
|
1034
|
+
/**
|
|
1035
|
+
* Get the number of songs in the loaded MIDI file
|
|
1036
|
+
* @returns {Promise<number>}
|
|
1037
|
+
*/
|
|
1038
|
+
async getSongsCount() {
|
|
1039
|
+
return new Promise((resolve) => {
|
|
1040
|
+
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
1041
|
+
this,
|
|
1042
|
+
"songsCount",
|
|
1043
|
+
/** @param {{count: number}} msg */
|
|
1044
|
+
(msg) => {
|
|
1045
|
+
resolve(msg.count);
|
|
1046
|
+
}
|
|
1047
|
+
);
|
|
1048
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getSongsCount" });
|
|
1049
|
+
});
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Get the number of tracks in the loaded MIDI file
|
|
1053
|
+
* @returns {Promise<number>}
|
|
1054
|
+
*/
|
|
1055
|
+
async getTrackCount() {
|
|
1056
|
+
return new Promise((resolve) => {
|
|
1057
|
+
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
1058
|
+
this,
|
|
1059
|
+
"trackCount",
|
|
1060
|
+
/** @param {{count: number}} msg */
|
|
1061
|
+
(msg) => {
|
|
1062
|
+
resolve(msg.count);
|
|
1063
|
+
}
|
|
1064
|
+
);
|
|
1065
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getTrackCount" });
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
/**
|
|
1069
|
+
* Set track options (enable, mute, or solo)
|
|
1070
|
+
* Use the TrackOption enum: TrackOption.ON (1), TrackOption.OFF (2), TrackOption.SOLO (3).
|
|
1071
|
+
* Note: Passing 0 is a silent no-op that resolves without changing state.
|
|
1072
|
+
* @param {number} track - Track index
|
|
1073
|
+
* @param {number} options - Track option from TrackOption enum
|
|
1074
|
+
* @returns {Promise<void>} Resolves on success, rejects on failure
|
|
1075
|
+
*/
|
|
1076
|
+
async setTrackOptions(track, options) {
|
|
1077
|
+
const reqId = __privateWrapper(this, _nextRequestId)._++;
|
|
1078
|
+
return new Promise((resolve, reject) => {
|
|
1079
|
+
__privateMethod(this, _AdlMidi_instances, onceCorrelatedMessage_fn).call(
|
|
1080
|
+
this,
|
|
1081
|
+
"trackOptionsSet",
|
|
1082
|
+
reqId,
|
|
1083
|
+
/** @param {{success: boolean}} msg */
|
|
1084
|
+
(msg) => {
|
|
1085
|
+
if (msg.success) {
|
|
1086
|
+
resolve();
|
|
1087
|
+
} else {
|
|
1088
|
+
reject(new Error(`Failed to set track options for track ${track}`));
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
);
|
|
1092
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "setTrackOptions", track, options, reqId });
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Enable or disable a MIDI channel
|
|
1097
|
+
* @param {number} channel - MIDI channel (0-15)
|
|
1098
|
+
* @param {boolean} enabled - Whether to enable the channel
|
|
1099
|
+
* @returns {Promise<void>} Resolves on success, rejects on failure
|
|
1100
|
+
*/
|
|
1101
|
+
async setChannelEnabled(channel, enabled) {
|
|
1102
|
+
const reqId = __privateWrapper(this, _nextRequestId)._++;
|
|
1103
|
+
return new Promise((resolve, reject) => {
|
|
1104
|
+
__privateMethod(this, _AdlMidi_instances, onceCorrelatedMessage_fn).call(
|
|
1105
|
+
this,
|
|
1106
|
+
"channelEnabledSet",
|
|
1107
|
+
reqId,
|
|
1108
|
+
/** @param {{success: boolean}} msg */
|
|
1109
|
+
(msg) => {
|
|
1110
|
+
if (msg.success) {
|
|
1111
|
+
resolve();
|
|
1112
|
+
} else {
|
|
1113
|
+
reject(new Error(`Failed to set channel ${channel} enabled state`));
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
);
|
|
1117
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "setChannelEnabled", channel, enabled, reqId });
|
|
1118
|
+
});
|
|
696
1119
|
}
|
|
697
1120
|
/**
|
|
698
1121
|
* Set the playback tempo multiplier
|
|
@@ -785,6 +1208,7 @@ var AdlMidi = class {
|
|
|
785
1208
|
};
|
|
786
1209
|
_ready = new WeakMap();
|
|
787
1210
|
_messageHandlers = new WeakMap();
|
|
1211
|
+
_nextRequestId = new WeakMap();
|
|
788
1212
|
_AdlMidi_instances = new WeakSet();
|
|
789
1213
|
/**
|
|
790
1214
|
* Internal message handler
|
|
@@ -814,6 +1238,25 @@ onceMessage_fn = function(type, handler) {
|
|
|
814
1238
|
};
|
|
815
1239
|
__privateGet(this, _messageHandlers).get(type)?.add(wrappedHandler);
|
|
816
1240
|
};
|
|
1241
|
+
/**
|
|
1242
|
+
* Register a one-time handler correlated by request ID.
|
|
1243
|
+
* Allows concurrent operations of the same type without reply misrouting.
|
|
1244
|
+
* @param {string} type - Message type
|
|
1245
|
+
* @param {number} reqId - Request ID to match against
|
|
1246
|
+
* @param {Function} handler - Handler function
|
|
1247
|
+
*/
|
|
1248
|
+
onceCorrelatedMessage_fn = function(type, reqId, handler) {
|
|
1249
|
+
if (!__privateGet(this, _messageHandlers).has(type)) {
|
|
1250
|
+
__privateGet(this, _messageHandlers).set(type, /* @__PURE__ */ new Set());
|
|
1251
|
+
}
|
|
1252
|
+
const filteredHandler = (msg) => {
|
|
1253
|
+
if (msg.reqId === reqId) {
|
|
1254
|
+
__privateGet(this, _messageHandlers).get(type)?.delete(filteredHandler);
|
|
1255
|
+
handler(msg);
|
|
1256
|
+
}
|
|
1257
|
+
};
|
|
1258
|
+
__privateGet(this, _messageHandlers).get(type)?.add(filteredHandler);
|
|
1259
|
+
};
|
|
817
1260
|
/**
|
|
818
1261
|
* Send a message to the processor
|
|
819
1262
|
* @param {Object} msg - Message to send
|
|
@@ -827,6 +1270,7 @@ var libadlmidi_default = AdlMidi;
|
|
|
827
1270
|
export {
|
|
828
1271
|
AdlMidi,
|
|
829
1272
|
Emulator,
|
|
1273
|
+
TrackOption,
|
|
830
1274
|
libadlmidi_default as default
|
|
831
1275
|
};
|
|
832
1276
|
//# sourceMappingURL=libadlmidi.js.map
|