libadlmidi-js 1.1.1 → 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 -63
- 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 +468 -22
- 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 -54
- 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 */
|
|
@@ -30,9 +38,21 @@ var Emulator = Object.freeze({
|
|
|
30
38
|
/** Nuked OPL2 LLE - Transistor-level emulation */
|
|
31
39
|
NUKED_OPL2_LLE: 9,
|
|
32
40
|
/** Nuked OPL3 LLE - Transistor-level emulation */
|
|
33
|
-
NUKED_OPL3_LLE: 10
|
|
41
|
+
NUKED_OPL3_LLE: 10,
|
|
42
|
+
/** Nuked OPL2 Lite - Lightweight OPL2 emulation for AdLib-era music */
|
|
43
|
+
NUKED_OPL2_LITE: 11
|
|
34
44
|
});
|
|
35
|
-
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;
|
|
36
56
|
var AdlMidi = class {
|
|
37
57
|
/**
|
|
38
58
|
* Create a new AdlMidi instance
|
|
@@ -44,6 +64,8 @@ var AdlMidi = class {
|
|
|
44
64
|
__privateAdd(this, _ready, false);
|
|
45
65
|
/** @type {Map<string, Set<Function>>} */
|
|
46
66
|
__privateAdd(this, _messageHandlers, /* @__PURE__ */ new Map());
|
|
67
|
+
/** @type {number} */
|
|
68
|
+
__privateAdd(this, _nextRequestId, 0);
|
|
47
69
|
this.ctx = context || null;
|
|
48
70
|
this.node = null;
|
|
49
71
|
}
|
|
@@ -226,7 +248,7 @@ var AdlMidi = class {
|
|
|
226
248
|
* @param {ArrayBuffer} arrayBuffer - Bank file data
|
|
227
249
|
* @returns {Promise<void>}
|
|
228
250
|
*/
|
|
229
|
-
async
|
|
251
|
+
async loadBankData(arrayBuffer) {
|
|
230
252
|
return new Promise((resolve, reject) => {
|
|
231
253
|
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
232
254
|
this,
|
|
@@ -240,7 +262,7 @@ var AdlMidi = class {
|
|
|
240
262
|
}
|
|
241
263
|
}
|
|
242
264
|
);
|
|
243
|
-
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "
|
|
265
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "loadBankData", data: arrayBuffer });
|
|
244
266
|
});
|
|
245
267
|
}
|
|
246
268
|
/**
|
|
@@ -343,6 +365,23 @@ var AdlMidi = class {
|
|
|
343
365
|
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getNumFourOpChannels" });
|
|
344
366
|
});
|
|
345
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
|
+
}
|
|
346
385
|
/**
|
|
347
386
|
* Enable/disable scaling of modulators by volume
|
|
348
387
|
* @param {boolean} enabled
|
|
@@ -406,32 +445,66 @@ var AdlMidi = class {
|
|
|
406
445
|
});
|
|
407
446
|
}
|
|
408
447
|
/**
|
|
409
|
-
* Set the volume model
|
|
448
|
+
* Set the volume range model
|
|
410
449
|
* @param {number} model - Volume model number
|
|
411
450
|
*/
|
|
412
|
-
|
|
413
|
-
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "
|
|
451
|
+
setVolumeRangeModel(model) {
|
|
452
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "setVolumeRangeModel", model });
|
|
414
453
|
}
|
|
415
454
|
/**
|
|
416
|
-
* Enable/disable
|
|
455
|
+
* Enable/disable soft stereo panning
|
|
417
456
|
* @param {boolean} enabled
|
|
418
457
|
*/
|
|
419
|
-
|
|
420
|
-
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "
|
|
458
|
+
setSoftPanEnabled(enabled) {
|
|
459
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "setSoftPanEnabled", enabled });
|
|
421
460
|
}
|
|
422
461
|
/**
|
|
423
462
|
* Enable/disable deep vibrato
|
|
424
463
|
* @param {boolean} enabled
|
|
425
464
|
*/
|
|
426
|
-
|
|
427
|
-
__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
|
+
});
|
|
428
484
|
}
|
|
429
485
|
/**
|
|
430
486
|
* Enable/disable deep tremolo
|
|
431
487
|
* @param {boolean} enabled
|
|
432
488
|
*/
|
|
433
|
-
|
|
434
|
-
__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
|
+
});
|
|
435
508
|
}
|
|
436
509
|
/**
|
|
437
510
|
* Run emulator with PCM rate to reduce CPU usage
|
|
@@ -447,7 +520,7 @@ var AdlMidi = class {
|
|
|
447
520
|
* - nuked profile: NUKED only
|
|
448
521
|
* - dosbox profile: DOSBOX only
|
|
449
522
|
* - light profile: NUKED, DOSBOX
|
|
450
|
-
* - full profile: NUKED, DOSBOX, OPAL, JAVA,
|
|
523
|
+
* - full profile: NUKED, DOSBOX, OPAL, JAVA, ESFMu, YMFM_OPL2, YMFM_OPL3
|
|
451
524
|
*
|
|
452
525
|
* @param {number} emulator - Emulator ID from the Emulator enum
|
|
453
526
|
* @returns {Promise<void>} Resolves when emulator is switched, rejects if unavailable
|
|
@@ -492,6 +565,23 @@ var AdlMidi = class {
|
|
|
492
565
|
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getEmulatorName" });
|
|
493
566
|
});
|
|
494
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
|
+
}
|
|
495
585
|
/**
|
|
496
586
|
* Get the version string of the linked libADLMIDI library
|
|
497
587
|
* @returns {Promise<string>}
|
|
@@ -564,17 +654,17 @@ var AdlMidi = class {
|
|
|
564
654
|
* Get the volume range model
|
|
565
655
|
* @returns {Promise<number>}
|
|
566
656
|
*/
|
|
567
|
-
async
|
|
657
|
+
async getVolumeRangeModel() {
|
|
568
658
|
return new Promise((resolve) => {
|
|
569
659
|
__privateMethod(this, _AdlMidi_instances, onceMessage_fn).call(
|
|
570
660
|
this,
|
|
571
|
-
"
|
|
661
|
+
"volumeRangeModel",
|
|
572
662
|
/** @param {{model: number}} msg */
|
|
573
663
|
(msg) => {
|
|
574
664
|
resolve(msg.model);
|
|
575
665
|
}
|
|
576
666
|
);
|
|
577
|
-
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "
|
|
667
|
+
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getVolumeRangeModel" });
|
|
578
668
|
});
|
|
579
669
|
}
|
|
580
670
|
/**
|
|
@@ -598,6 +688,146 @@ var AdlMidi = class {
|
|
|
598
688
|
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getEmbeddedBanks" });
|
|
599
689
|
});
|
|
600
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
|
+
}
|
|
601
831
|
/**
|
|
602
832
|
* Reset the synthesizer
|
|
603
833
|
* @returns {void}
|
|
@@ -662,6 +892,60 @@ var AdlMidi = class {
|
|
|
662
892
|
__privateMethod(this, _AdlMidi_instances, send_fn).call(this, { type: "getMusicCopyright" });
|
|
663
893
|
});
|
|
664
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
|
+
}
|
|
665
949
|
/**
|
|
666
950
|
* Start or resume MIDI file playback
|
|
667
951
|
* @returns {void}
|
|
@@ -689,8 +973,149 @@ var AdlMidi = class {
|
|
|
689
973
|
* @param {boolean} enabled - Whether to loop
|
|
690
974
|
* @returns {void}
|
|
691
975
|
*/
|
|
692
|
-
|
|
693
|
-
__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
|
+
});
|
|
694
1119
|
}
|
|
695
1120
|
/**
|
|
696
1121
|
* Set the playback tempo multiplier
|
|
@@ -783,6 +1208,7 @@ var AdlMidi = class {
|
|
|
783
1208
|
};
|
|
784
1209
|
_ready = new WeakMap();
|
|
785
1210
|
_messageHandlers = new WeakMap();
|
|
1211
|
+
_nextRequestId = new WeakMap();
|
|
786
1212
|
_AdlMidi_instances = new WeakSet();
|
|
787
1213
|
/**
|
|
788
1214
|
* Internal message handler
|
|
@@ -812,6 +1238,25 @@ onceMessage_fn = function(type, handler) {
|
|
|
812
1238
|
};
|
|
813
1239
|
__privateGet(this, _messageHandlers).get(type)?.add(wrappedHandler);
|
|
814
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
|
+
};
|
|
815
1260
|
/**
|
|
816
1261
|
* Send a message to the processor
|
|
817
1262
|
* @param {Object} msg - Message to send
|
|
@@ -825,6 +1270,7 @@ var libadlmidi_default = AdlMidi;
|
|
|
825
1270
|
export {
|
|
826
1271
|
AdlMidi,
|
|
827
1272
|
Emulator,
|
|
1273
|
+
TrackOption,
|
|
828
1274
|
libadlmidi_default as default
|
|
829
1275
|
};
|
|
830
1276
|
//# sourceMappingURL=libadlmidi.js.map
|