libadlmidi-js 1.2.0 → 2.1.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.
Files changed (76) hide show
  1. package/README.md +8 -5
  2. package/dist/core.d.ts +191 -4
  3. package/dist/fm_banks/manifest.json +1 -1
  4. package/dist/libadlmidi.d.ts +146 -66
  5. package/dist/libadlmidi.dosbox.browser.js +1 -1
  6. package/dist/libadlmidi.dosbox.browser.wasm +0 -0
  7. package/dist/libadlmidi.dosbox.core.js +1 -1
  8. package/dist/libadlmidi.dosbox.core.wasm +0 -0
  9. package/dist/libadlmidi.dosbox.js +0 -0
  10. package/dist/libadlmidi.dosbox.processor.js +247 -74
  11. package/dist/libadlmidi.dosbox.slim.browser.js +1 -1
  12. package/dist/libadlmidi.dosbox.slim.browser.wasm +0 -0
  13. package/dist/libadlmidi.dosbox.slim.core.js +1 -1
  14. package/dist/libadlmidi.dosbox.slim.core.wasm +0 -0
  15. package/dist/libadlmidi.dosbox.slim.js +0 -0
  16. package/dist/libadlmidi.dosbox.slim.processor.js +247 -74
  17. package/dist/libadlmidi.full.browser.js +1 -1
  18. package/dist/libadlmidi.full.browser.wasm +0 -0
  19. package/dist/libadlmidi.full.core.js +1 -1
  20. package/dist/libadlmidi.full.core.wasm +0 -0
  21. package/dist/libadlmidi.full.js +0 -0
  22. package/dist/libadlmidi.full.processor.js +247 -74
  23. package/dist/libadlmidi.full.slim.browser.js +1 -1
  24. package/dist/libadlmidi.full.slim.browser.wasm +0 -0
  25. package/dist/libadlmidi.full.slim.core.js +1 -1
  26. package/dist/libadlmidi.full.slim.core.wasm +0 -0
  27. package/dist/libadlmidi.full.slim.js +0 -0
  28. package/dist/libadlmidi.full.slim.processor.js +247 -74
  29. package/dist/libadlmidi.js +473 -24
  30. package/dist/libadlmidi.js.map +3 -3
  31. package/dist/libadlmidi.light.browser.js +1 -1
  32. package/dist/libadlmidi.light.browser.wasm +0 -0
  33. package/dist/libadlmidi.light.core.js +1 -1
  34. package/dist/libadlmidi.light.core.wasm +0 -0
  35. package/dist/libadlmidi.light.js +0 -0
  36. package/dist/libadlmidi.light.processor.js +247 -74
  37. package/dist/libadlmidi.light.slim.browser.js +1 -1
  38. package/dist/libadlmidi.light.slim.browser.wasm +0 -0
  39. package/dist/libadlmidi.light.slim.core.js +1 -1
  40. package/dist/libadlmidi.light.slim.core.wasm +0 -0
  41. package/dist/libadlmidi.light.slim.js +0 -0
  42. package/dist/libadlmidi.light.slim.processor.js +247 -74
  43. package/dist/libadlmidi.nuked.browser.js +1 -1
  44. package/dist/libadlmidi.nuked.browser.wasm +0 -0
  45. package/dist/libadlmidi.nuked.core.js +1 -1
  46. package/dist/libadlmidi.nuked.core.wasm +0 -0
  47. package/dist/libadlmidi.nuked.js +0 -0
  48. package/dist/libadlmidi.nuked.processor.js +247 -74
  49. package/dist/libadlmidi.nuked.slim.browser.js +1 -1
  50. package/dist/libadlmidi.nuked.slim.browser.wasm +0 -0
  51. package/dist/libadlmidi.nuked.slim.core.js +1 -1
  52. package/dist/libadlmidi.nuked.slim.core.wasm +0 -0
  53. package/dist/libadlmidi.nuked.slim.js +0 -0
  54. package/dist/libadlmidi.nuked.slim.processor.js +247 -74
  55. package/dist/profiles/dosbox.d.ts +7 -2
  56. package/dist/profiles/dosbox.slim.d.ts +7 -2
  57. package/dist/profiles/full.d.ts +7 -2
  58. package/dist/profiles/full.slim.d.ts +7 -2
  59. package/dist/profiles/light.d.ts +7 -2
  60. package/dist/profiles/light.slim.d.ts +7 -2
  61. package/dist/profiles/nuked.d.ts +7 -2
  62. package/dist/profiles/nuked.slim.d.ts +7 -2
  63. package/dist/utils/constants.d.ts +61 -0
  64. package/package.json +30 -9
  65. package/src/core.js +361 -4
  66. package/src/libadlmidi.js +379 -58
  67. package/src/processor.js +210 -12
  68. package/src/profiles/dosbox.js +20 -10
  69. package/src/profiles/dosbox.slim.js +20 -10
  70. package/src/profiles/full.js +21 -11
  71. package/src/profiles/full.slim.js +21 -11
  72. package/src/profiles/light.js +21 -11
  73. package/src/profiles/light.slim.js +21 -11
  74. package/src/profiles/nuked.js +21 -11
  75. package/src/profiles/nuked.slim.js +21 -11
  76. package/src/utils/constants.js +53 -0
package/src/processor.js CHANGED
@@ -45,6 +45,7 @@ class AdlMidiProcessor extends AudioWorkletProcessor {
45
45
  softPan: true, // Soft stereo panning
46
46
  deepVibrato: false, // Deep vibrato
47
47
  deepTremolo: false, // Deep tremolo
48
+ emulator: undefined, // Emulator core (undefined = libADLMIDI default)
48
49
  ...options.processorOptions?.settings
49
50
  };
50
51
 
@@ -104,6 +105,11 @@ class AdlMidiProcessor extends AudioWorkletProcessor {
104
105
  applySettings(settings) {
105
106
  if (!this.midi) return;
106
107
 
108
+ // Switch emulator first; adl_switchEmulator does a partialReset and a
109
+ // wrong-order subsequent setBank etc. would otherwise need re-applying.
110
+ if (settings.emulator !== undefined) {
111
+ this.adl._adl_switchEmulator(this.midi, settings.emulator);
112
+ }
107
113
  if (settings.numChips !== undefined) {
108
114
  this.adl._adl_setNumChips(this.midi, settings.numChips);
109
115
  }
@@ -333,8 +339,8 @@ class AdlMidiProcessor extends AudioWorkletProcessor {
333
339
  this.port.postMessage({ type: 'configured' });
334
340
  break;
335
341
 
336
- case 'loadBank':
337
- this.loadBank(msg.data);
342
+ case 'loadBankData':
343
+ this.loadBankData(msg.data);
338
344
  break;
339
345
 
340
346
  case 'setBank': {
@@ -367,6 +373,10 @@ class AdlMidiProcessor extends AudioWorkletProcessor {
367
373
  this.port.postMessage({ type: 'numFourOpChannels', channels: this.adl._adl_getNumFourOpsChn(this.midi) });
368
374
  break;
369
375
 
376
+ case 'getNumFourOpChannelsObtained':
377
+ this.port.postMessage({ type: 'numFourOpChannelsObtained', channels: this.adl._adl_getNumFourOpsChnObtained(this.midi) });
378
+ break;
379
+
370
380
  case 'setScaleModulators':
371
381
  this.adl._adl_setScaleModulators(this.midi, msg.enabled ? 1 : 0);
372
382
  break;
@@ -391,22 +401,30 @@ class AdlMidiProcessor extends AudioWorkletProcessor {
391
401
  this.port.postMessage({ type: 'channelAllocMode', mode: this.adl._adl_getChannelAllocMode(this.midi) });
392
402
  break;
393
403
 
394
- case 'setVolumeModel':
404
+ case 'setVolumeRangeModel':
395
405
  this.adl._adl_setVolumeRangeModel(this.midi, msg.model);
396
406
  break;
397
407
 
398
- case 'setPercMode':
399
- this.adl._adl_setPercMode(this.midi, msg.enabled ? 1 : 0);
408
+ case 'setDeepVibrato':
409
+ this.adl._adl_setHVibrato(this.midi, msg.enabled ? 1 : 0);
400
410
  break;
401
411
 
402
- case 'setVibrato':
403
- this.adl._adl_setHVibrato(this.midi, msg.enabled ? 1 : 0);
412
+ case 'getDeepVibrato':
413
+ this.port.postMessage({ type: 'deepVibrato', enabled: this.adl._adl_getHVibrato(this.midi) !== 0 });
404
414
  break;
405
415
 
406
- case 'setTremolo':
416
+ case 'setDeepTremolo':
407
417
  this.adl._adl_setHTremolo(this.midi, msg.enabled ? 1 : 0);
408
418
  break;
409
419
 
420
+ case 'getDeepTremolo':
421
+ this.port.postMessage({ type: 'deepTremolo', enabled: this.adl._adl_getHTremolo(this.midi) !== 0 });
422
+ break;
423
+
424
+ case 'setSoftPanEnabled':
425
+ this.adl._adl_setSoftPanEnabled(this.midi, msg.enabled ? 1 : 0);
426
+ break;
427
+
410
428
  case 'setRunAtPcmRate':
411
429
  this.adl._adl_setRunAtPcmRate(this.midi, msg.enabled ? 1 : 0);
412
430
  break;
@@ -425,6 +443,13 @@ class AdlMidiProcessor extends AudioWorkletProcessor {
425
443
  break;
426
444
  }
427
445
 
446
+ case 'getErrorInfo': {
447
+ const ptr = this.adl._adl_errorInfo(this.midi);
448
+ const info = ptr ? this.adl.UTF8ToString(ptr) : '';
449
+ this.port.postMessage({ type: 'errorInfo', info });
450
+ break;
451
+ }
452
+
428
453
  case 'getLibraryVersion': {
429
454
  const ptr = this.adl._adl_linkedLibraryVersion();
430
455
  const version = ptr ? this.adl.UTF8ToString(ptr) : 'Unknown';
@@ -451,8 +476,8 @@ class AdlMidiProcessor extends AudioWorkletProcessor {
451
476
  this.port.postMessage({ type: 'numChipsObtained', chips: this.adl._adl_getNumChipsObtained(this.midi) });
452
477
  break;
453
478
 
454
- case 'getVolumeModel':
455
- this.port.postMessage({ type: 'volumeModel', model: this.adl._adl_getVolumeRangeModel(this.midi) });
479
+ case 'getVolumeRangeModel':
480
+ this.port.postMessage({ type: 'volumeRangeModel', model: this.adl._adl_getVolumeRangeModel(this.midi) });
456
481
  break;
457
482
 
458
483
  case 'getEmbeddedBanks': {
@@ -480,6 +505,21 @@ class AdlMidiProcessor extends AudioWorkletProcessor {
480
505
  break;
481
506
  }
482
507
 
508
+ case 'getTrackTitleCount':
509
+ this.port.postMessage({ type: 'trackTitleCount', count: this.adl._adl_metaTrackTitleCount(this.midi) });
510
+ break;
511
+
512
+ case 'getTrackTitle': {
513
+ const ptr = this.adl._adl_metaTrackTitle(this.midi, msg.index);
514
+ const title = ptr ? this.adl.UTF8ToString(ptr) : '';
515
+ this.port.postMessage({ type: 'trackTitle', title, index: msg.index, reqId: msg.reqId });
516
+ break;
517
+ }
518
+
519
+ case 'getMarkerCount':
520
+ this.port.postMessage({ type: 'markerCount', count: this.adl._adl_metaMarkerCount(this.midi) });
521
+ break;
522
+
483
523
  case 'play':
484
524
  // If at end, rewind first so play works as expected
485
525
  if (this.adl._adl_atEnd(this.midi) !== 0) {
@@ -498,10 +538,50 @@ class AdlMidiProcessor extends AudioWorkletProcessor {
498
538
  this.adl._adl_positionSeek(this.midi, msg.position);
499
539
  break;
500
540
 
501
- case 'setLoop':
541
+ case 'setLoopEnabled':
502
542
  this.adl._adl_setLoopEnabled(this.midi, msg.enabled ? 1 : 0);
503
543
  break;
504
544
 
545
+ case 'setLoopCount':
546
+ this.adl._adl_setLoopCount(this.midi, msg.count);
547
+ break;
548
+
549
+ case 'setLoopHooksOnly':
550
+ this.adl._adl_setLoopHooksOnly(this.midi, msg.enabled ? 1 : 0);
551
+ break;
552
+
553
+ case 'getLoopStartTime':
554
+ this.port.postMessage({ type: 'loopStartTime', time: this.adl._adl_loopStartTime(this.midi) });
555
+ break;
556
+
557
+ case 'getLoopEndTime':
558
+ this.port.postMessage({ type: 'loopEndTime', time: this.adl._adl_loopEndTime(this.midi) });
559
+ break;
560
+
561
+ case 'selectSongNum':
562
+ this.adl._adl_selectSongNum(this.midi, msg.num);
563
+ break;
564
+
565
+ case 'getSongsCount':
566
+ this.port.postMessage({ type: 'songsCount', count: this.adl._adl_getSongsCount(this.midi) });
567
+ break;
568
+
569
+ case 'getTrackCount':
570
+ this.port.postMessage({ type: 'trackCount', count: this.adl._adl_trackCount(this.midi) });
571
+ break;
572
+
573
+ case 'setTrackOptions': {
574
+ const result = this.adl._adl_setTrackOptions(this.midi, msg.track, msg.options);
575
+ this.port.postMessage({ type: 'trackOptionsSet', success: result === 0, track: msg.track, reqId: msg.reqId });
576
+ break;
577
+ }
578
+
579
+ case 'setChannelEnabled': {
580
+ const result = this.adl._adl_setChannelEnabled(this.midi, msg.channel, msg.enabled ? 1 : 0);
581
+ this.port.postMessage({ type: 'channelEnabledSet', success: result === 0, channel: msg.channel, reqId: msg.reqId });
582
+ break;
583
+ }
584
+
505
585
  case 'setTempo':
506
586
  this.adl._adl_setTempo(this.midi, msg.tempo);
507
587
  break;
@@ -520,6 +600,124 @@ class AdlMidiProcessor extends AudioWorkletProcessor {
520
600
  this.adl._adl_reset(this.midi);
521
601
  this.playMode = 'realtime';
522
602
  break;
603
+
604
+ // ================== Bank Management ==================
605
+
606
+ case 'reserveBanks': {
607
+ // adl_reserveBanks returns the resulting capacity (>= 0), not 0 on success
608
+ const result = this.adl._adl_reserveBanks(this.midi, msg.count);
609
+ this.port.postMessage({ type: 'banksReserved', success: result >= 0, reqId: msg.reqId });
610
+ break;
611
+ }
612
+
613
+ case 'getBankId': {
614
+ const bankIdPtr = this.adl._malloc(AdlMidiProcessor.SIZEOF_ADL_BANK_ID);
615
+ this.adl.HEAPU8[bankIdPtr] = msg.bankId.percussive ? 1 : 0;
616
+ this.adl.HEAPU8[bankIdPtr + 1] = msg.bankId.msb || 0;
617
+ this.adl.HEAPU8[bankIdPtr + 2] = msg.bankId.lsb || 0;
618
+
619
+ const bankPtr = this.adl._malloc(AdlMidiProcessor.SIZEOF_ADL_BANK);
620
+ const bankResult = this.adl._adl_getBank(this.midi, bankIdPtr, 0, bankPtr);
621
+
622
+ let id = null;
623
+ if (bankResult === 0) {
624
+ const outIdPtr = this.adl._malloc(AdlMidiProcessor.SIZEOF_ADL_BANK_ID);
625
+ const idResult = this.adl._adl_getBankId(this.midi, bankPtr, outIdPtr);
626
+ if (idResult === 0) {
627
+ id = {
628
+ percussive: this.adl.HEAPU8[outIdPtr],
629
+ msb: this.adl.HEAPU8[outIdPtr + 1],
630
+ lsb: this.adl.HEAPU8[outIdPtr + 2],
631
+ };
632
+ }
633
+ this.adl._free(outIdPtr);
634
+ }
635
+ this.adl._free(bankIdPtr);
636
+ this.adl._free(bankPtr);
637
+ // Echo bankId for concurrent request correlation
638
+ this.port.postMessage({ type: 'bankId', id, bankId: msg.bankId, reqId: msg.reqId });
639
+ break;
640
+ }
641
+
642
+ case 'removeBank': {
643
+ const bankIdPtr = this.adl._malloc(AdlMidiProcessor.SIZEOF_ADL_BANK_ID);
644
+ this.adl.HEAPU8[bankIdPtr] = msg.bankId.percussive ? 1 : 0;
645
+ this.adl.HEAPU8[bankIdPtr + 1] = msg.bankId.msb || 0;
646
+ this.adl.HEAPU8[bankIdPtr + 2] = msg.bankId.lsb || 0;
647
+
648
+ const bankPtr = this.adl._malloc(AdlMidiProcessor.SIZEOF_ADL_BANK);
649
+ const bankResult = this.adl._adl_getBank(this.midi, bankIdPtr, 0, bankPtr);
650
+
651
+ let success = false;
652
+ if (bankResult === 0) {
653
+ success = this.adl._adl_removeBank(this.midi, bankPtr) === 0;
654
+ }
655
+
656
+ this.adl._free(bankIdPtr);
657
+ this.adl._free(bankPtr);
658
+ // Echo bankId for concurrent request correlation
659
+ this.port.postMessage({ type: 'bankRemoved', success, bankId: msg.bankId, reqId: msg.reqId });
660
+ break;
661
+ }
662
+
663
+ case 'loadEmbeddedBank': {
664
+ const bankIdPtr = this.adl._malloc(AdlMidiProcessor.SIZEOF_ADL_BANK_ID);
665
+ this.adl.HEAPU8[bankIdPtr] = msg.bankId.percussive ? 1 : 0;
666
+ this.adl.HEAPU8[bankIdPtr + 1] = msg.bankId.msb || 0;
667
+ this.adl.HEAPU8[bankIdPtr + 2] = msg.bankId.lsb || 0;
668
+
669
+ const bankPtr = this.adl._malloc(AdlMidiProcessor.SIZEOF_ADL_BANK);
670
+
671
+ // Check if bank already exists before creating
672
+ const existed = this.adl._adl_getBank(this.midi, bankIdPtr, 0, bankPtr) === 0;
673
+ const bankResult = existed ? 0 : this.adl._adl_getBank(this.midi, bankIdPtr, 1, bankPtr);
674
+
675
+ let success = false;
676
+ if (bankResult === 0) {
677
+ success = this.adl._adl_loadEmbeddedBank(this.midi, bankPtr, msg.num) === 0;
678
+ // Clean up: if we created a new slot but load failed, remove it
679
+ if (!success && !existed) {
680
+ this.adl._adl_removeBank(this.midi, bankPtr);
681
+ }
682
+ }
683
+
684
+ this.adl._free(bankIdPtr);
685
+ this.adl._free(bankPtr);
686
+ // Echo bankId for concurrent request correlation
687
+ this.port.postMessage({ type: 'embeddedBankLoaded', success, bankId: msg.bankId, reqId: msg.reqId });
688
+ break;
689
+ }
690
+
691
+ // ================== SysEx ==================
692
+
693
+ case 'systemExclusive': {
694
+ const bytes = new Uint8Array(msg.data);
695
+ const ptr = this.adl._malloc(bytes.length);
696
+ this.adl.HEAPU8.set(bytes, ptr);
697
+ const result = this.adl._adl_rt_systemExclusive(this.midi, ptr, bytes.length);
698
+ this.adl._free(ptr);
699
+ // adl_rt_systemExclusive returns 1 when processed, 0 when rejected
700
+ this.port.postMessage({ type: 'systemExclusiveSent', success: result !== 0, reqId: msg.reqId });
701
+ break;
702
+ }
703
+
704
+ // ================== Debug / Diagnostics ==================
705
+
706
+ case 'describeChannels': {
707
+ // Size buffers based on actual chip count (~23 channels per OPL3 chip)
708
+ const numChips = this.adl._adl_getNumChipsObtained(this.midi);
709
+ const size = Math.max(256, (numChips + 1) * 23);
710
+ const textPtr = this.adl._malloc(size);
711
+ const attrPtr = this.adl._malloc(size);
712
+ this.adl._adl_describeChannels(this.midi, textPtr, attrPtr, size);
713
+ const text = this.adl.UTF8ToString(textPtr);
714
+ // attr contains raw per-channel bytes; one byte per channel char in text
715
+ const attr = Array.from(this.adl.HEAPU8.slice(attrPtr, attrPtr + text.length));
716
+ this.adl._free(textPtr);
717
+ this.adl._free(attrPtr);
718
+ this.port.postMessage({ type: 'channelsDescribed', text, attr, reqId: msg.reqId });
719
+ break;
720
+ }
523
721
  }
524
722
  }
525
723
 
@@ -575,7 +773,7 @@ class AdlMidiProcessor extends AudioWorkletProcessor {
575
773
  return banks;
576
774
  }
577
775
 
578
- loadBank(arrayBuffer) {
776
+ loadBankData(arrayBuffer) {
579
777
  try {
580
778
  const data = new Uint8Array(arrayBuffer);
581
779
  const dataPtr = this.adl._malloc(data.length);
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Zero-config dosbox profile for libADLMIDI-JS
3
- *
3
+ *
4
4
  * Exports pre-configured AdlMidi and AdlMidiCore with this profile's WASM.
5
5
  *
6
- *
6
+ *
7
7
  * @module profiles/dosbox
8
8
  */
9
9
 
@@ -15,6 +15,10 @@ const PROCESSOR_URL = new URL('../../dist/libadlmidi.dosbox.processor.js', impor
15
15
  const WASM_URL = new URL('../../dist/libadlmidi.dosbox.core.wasm', import.meta.url).href;
16
16
  const CORE_PATH = new URL('../../dist/libadlmidi.dosbox.core.js', import.meta.url).href;
17
17
 
18
+ // Default synth settings injected at init. NUKED_FAST is preferred when the
19
+ // profile bundles it (bit-exact vs Nuked 1.8, roughly 1.5x faster).
20
+ const DEFAULT_SETTINGS = {};
21
+
18
22
  /**
19
23
  * Pre-configured AdlMidi for dosbox profile.
20
24
  *
@@ -30,15 +34,17 @@ const CORE_PATH = new URL('../../dist/libadlmidi.dosbox.core.js', import.meta.ur
30
34
  export class AdlMidi extends BaseAdlMidi {
31
35
  /**
32
36
  * Initialize the synthesizer with this profile's WASM.
33
- *
37
+ *
34
38
  * @param {string} [processorUrl] - Override processor URL (optional)
35
39
  * @param {string} [wasmUrl] - Override WASM URL (optional)
40
+ * @param {object} [defaultSettings] - Override profile's default synth settings
36
41
  * @returns {Promise<void>}
37
42
  */
38
- async init(processorUrl, wasmUrl) {
43
+ async init(processorUrl, wasmUrl, defaultSettings) {
39
44
  return super.init(
40
45
  processorUrl || PROCESSOR_URL,
41
- wasmUrl || WASM_URL
46
+ wasmUrl || WASM_URL,
47
+ defaultSettings || DEFAULT_SETTINGS
42
48
  );
43
49
  }
44
50
  }
@@ -60,7 +66,8 @@ export class AdlMidiCore {
60
66
  /**
61
67
  * Create a new AdlMidiCore instance with this profile's WASM.
62
68
  *
63
- * @param {{corePath?: string}} [options] - Options (corePath is pre-configured)
69
+ * @param {{corePath?: string, defaultEmulator?: number, wasmBinary?: ArrayBuffer}} [options]
70
+ * Override profile defaults. corePath and defaultEmulator are pre-configured.
64
71
  * @returns {Promise<BaseAdlMidiCore>}
65
72
  */
66
73
  static async create(options = {}) {
@@ -72,11 +79,14 @@ export class AdlMidiCore {
72
79
  }
73
80
 
74
81
  // Re-export struct utilities for convenience
75
- export {
76
- encodeInstrument,
77
- decodeInstrument,
82
+ export {
83
+ encodeInstrument,
84
+ decodeInstrument,
78
85
  defaultInstrument,
79
86
  encodeOperator,
80
87
  decodeOperator,
81
- defaultOperator
88
+ defaultOperator
82
89
  } from '../utils/struct.js';
90
+
91
+ // Re-export enums
92
+ export { Emulator, TrackOption } from '../utils/constants.js';
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Zero-config dosbox (slim) profile for libADLMIDI-JS
3
- *
3
+ *
4
4
  * Exports pre-configured AdlMidi and AdlMidiCore with this profile's WASM.
5
5
  * Slim builds require loading a WOPL bank at runtime.
6
- *
6
+ *
7
7
  * @module profiles/dosbox.slim
8
8
  */
9
9
 
@@ -15,6 +15,10 @@ const PROCESSOR_URL = new URL('../../dist/libadlmidi.dosbox.slim.processor.js',
15
15
  const WASM_URL = new URL('../../dist/libadlmidi.dosbox.slim.core.wasm', import.meta.url).href;
16
16
  const CORE_PATH = new URL('../../dist/libadlmidi.dosbox.slim.core.js', import.meta.url).href;
17
17
 
18
+ // Default synth settings injected at init. NUKED_FAST is preferred when the
19
+ // profile bundles it (bit-exact vs Nuked 1.8, roughly 1.5x faster).
20
+ const DEFAULT_SETTINGS = {};
21
+
18
22
  /**
19
23
  * Pre-configured AdlMidi for dosbox slim profile.
20
24
  *
@@ -30,15 +34,17 @@ const CORE_PATH = new URL('../../dist/libadlmidi.dosbox.slim.core.js', import.me
30
34
  export class AdlMidi extends BaseAdlMidi {
31
35
  /**
32
36
  * Initialize the synthesizer with this profile's WASM.
33
- *
37
+ *
34
38
  * @param {string} [processorUrl] - Override processor URL (optional)
35
39
  * @param {string} [wasmUrl] - Override WASM URL (optional)
40
+ * @param {object} [defaultSettings] - Override profile's default synth settings
36
41
  * @returns {Promise<void>}
37
42
  */
38
- async init(processorUrl, wasmUrl) {
43
+ async init(processorUrl, wasmUrl, defaultSettings) {
39
44
  return super.init(
40
45
  processorUrl || PROCESSOR_URL,
41
- wasmUrl || WASM_URL
46
+ wasmUrl || WASM_URL,
47
+ defaultSettings || DEFAULT_SETTINGS
42
48
  );
43
49
  }
44
50
  }
@@ -60,7 +66,8 @@ export class AdlMidiCore {
60
66
  /**
61
67
  * Create a new AdlMidiCore instance with this profile's WASM.
62
68
  *
63
- * @param {{corePath?: string}} [options] - Options (corePath is pre-configured)
69
+ * @param {{corePath?: string, defaultEmulator?: number, wasmBinary?: ArrayBuffer}} [options]
70
+ * Override profile defaults. corePath and defaultEmulator are pre-configured.
64
71
  * @returns {Promise<BaseAdlMidiCore>}
65
72
  */
66
73
  static async create(options = {}) {
@@ -72,11 +79,14 @@ export class AdlMidiCore {
72
79
  }
73
80
 
74
81
  // Re-export struct utilities for convenience
75
- export {
76
- encodeInstrument,
77
- decodeInstrument,
82
+ export {
83
+ encodeInstrument,
84
+ decodeInstrument,
78
85
  defaultInstrument,
79
86
  encodeOperator,
80
87
  decodeOperator,
81
- defaultOperator
88
+ defaultOperator
82
89
  } from '../utils/struct.js';
90
+
91
+ // Re-export enums
92
+ export { Emulator, TrackOption } from '../utils/constants.js';
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Zero-config full profile for libADLMIDI-JS
3
- *
3
+ *
4
4
  * Exports pre-configured AdlMidi and AdlMidiCore with this profile's WASM.
5
5
  *
6
- *
6
+ *
7
7
  * @module profiles/full
8
8
  */
9
9
 
@@ -15,6 +15,10 @@ const PROCESSOR_URL = new URL('../../dist/libadlmidi.full.processor.js', import.
15
15
  const WASM_URL = new URL('../../dist/libadlmidi.full.core.wasm', import.meta.url).href;
16
16
  const CORE_PATH = new URL('../../dist/libadlmidi.full.core.js', import.meta.url).href;
17
17
 
18
+ // Default synth settings injected at init. NUKED_FAST is preferred when the
19
+ // profile bundles it (bit-exact vs Nuked 1.8, roughly 1.5x faster).
20
+ const DEFAULT_SETTINGS = { emulator: 1 };
21
+
18
22
  /**
19
23
  * Pre-configured AdlMidi for full profile.
20
24
  *
@@ -30,15 +34,17 @@ const CORE_PATH = new URL('../../dist/libadlmidi.full.core.js', import.meta.url)
30
34
  export class AdlMidi extends BaseAdlMidi {
31
35
  /**
32
36
  * Initialize the synthesizer with this profile's WASM.
33
- *
37
+ *
34
38
  * @param {string} [processorUrl] - Override processor URL (optional)
35
39
  * @param {string} [wasmUrl] - Override WASM URL (optional)
40
+ * @param {object} [defaultSettings] - Override profile's default synth settings
36
41
  * @returns {Promise<void>}
37
42
  */
38
- async init(processorUrl, wasmUrl) {
43
+ async init(processorUrl, wasmUrl, defaultSettings) {
39
44
  return super.init(
40
45
  processorUrl || PROCESSOR_URL,
41
- wasmUrl || WASM_URL
46
+ wasmUrl || WASM_URL,
47
+ defaultSettings || DEFAULT_SETTINGS
42
48
  );
43
49
  }
44
50
  }
@@ -60,23 +66,27 @@ export class AdlMidiCore {
60
66
  /**
61
67
  * Create a new AdlMidiCore instance with this profile's WASM.
62
68
  *
63
- * @param {{corePath?: string}} [options] - Options (corePath is pre-configured)
69
+ * @param {{corePath?: string, defaultEmulator?: number, wasmBinary?: ArrayBuffer}} [options]
70
+ * Override profile defaults. corePath and defaultEmulator are pre-configured.
64
71
  * @returns {Promise<BaseAdlMidiCore>}
65
72
  */
66
73
  static async create(options = {}) {
67
74
  return BaseAdlMidiCore.create({
68
75
  ...options,
69
- corePath: options.corePath || CORE_PATH
76
+ corePath: options.corePath || CORE_PATH, defaultEmulator: options.defaultEmulator !== undefined ? options.defaultEmulator : 1
70
77
  });
71
78
  }
72
79
  }
73
80
 
74
81
  // Re-export struct utilities for convenience
75
- export {
76
- encodeInstrument,
77
- decodeInstrument,
82
+ export {
83
+ encodeInstrument,
84
+ decodeInstrument,
78
85
  defaultInstrument,
79
86
  encodeOperator,
80
87
  decodeOperator,
81
- defaultOperator
88
+ defaultOperator
82
89
  } from '../utils/struct.js';
90
+
91
+ // Re-export enums
92
+ export { Emulator, TrackOption } from '../utils/constants.js';
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Zero-config full (slim) profile for libADLMIDI-JS
3
- *
3
+ *
4
4
  * Exports pre-configured AdlMidi and AdlMidiCore with this profile's WASM.
5
5
  * Slim builds require loading a WOPL bank at runtime.
6
- *
6
+ *
7
7
  * @module profiles/full.slim
8
8
  */
9
9
 
@@ -15,6 +15,10 @@ const PROCESSOR_URL = new URL('../../dist/libadlmidi.full.slim.processor.js', im
15
15
  const WASM_URL = new URL('../../dist/libadlmidi.full.slim.core.wasm', import.meta.url).href;
16
16
  const CORE_PATH = new URL('../../dist/libadlmidi.full.slim.core.js', import.meta.url).href;
17
17
 
18
+ // Default synth settings injected at init. NUKED_FAST is preferred when the
19
+ // profile bundles it (bit-exact vs Nuked 1.8, roughly 1.5x faster).
20
+ const DEFAULT_SETTINGS = { emulator: 1 };
21
+
18
22
  /**
19
23
  * Pre-configured AdlMidi for full slim profile.
20
24
  *
@@ -30,15 +34,17 @@ const CORE_PATH = new URL('../../dist/libadlmidi.full.slim.core.js', import.meta
30
34
  export class AdlMidi extends BaseAdlMidi {
31
35
  /**
32
36
  * Initialize the synthesizer with this profile's WASM.
33
- *
37
+ *
34
38
  * @param {string} [processorUrl] - Override processor URL (optional)
35
39
  * @param {string} [wasmUrl] - Override WASM URL (optional)
40
+ * @param {object} [defaultSettings] - Override profile's default synth settings
36
41
  * @returns {Promise<void>}
37
42
  */
38
- async init(processorUrl, wasmUrl) {
43
+ async init(processorUrl, wasmUrl, defaultSettings) {
39
44
  return super.init(
40
45
  processorUrl || PROCESSOR_URL,
41
- wasmUrl || WASM_URL
46
+ wasmUrl || WASM_URL,
47
+ defaultSettings || DEFAULT_SETTINGS
42
48
  );
43
49
  }
44
50
  }
@@ -60,23 +66,27 @@ export class AdlMidiCore {
60
66
  /**
61
67
  * Create a new AdlMidiCore instance with this profile's WASM.
62
68
  *
63
- * @param {{corePath?: string}} [options] - Options (corePath is pre-configured)
69
+ * @param {{corePath?: string, defaultEmulator?: number, wasmBinary?: ArrayBuffer}} [options]
70
+ * Override profile defaults. corePath and defaultEmulator are pre-configured.
64
71
  * @returns {Promise<BaseAdlMidiCore>}
65
72
  */
66
73
  static async create(options = {}) {
67
74
  return BaseAdlMidiCore.create({
68
75
  ...options,
69
- corePath: options.corePath || CORE_PATH
76
+ corePath: options.corePath || CORE_PATH, defaultEmulator: options.defaultEmulator !== undefined ? options.defaultEmulator : 1
70
77
  });
71
78
  }
72
79
  }
73
80
 
74
81
  // Re-export struct utilities for convenience
75
- export {
76
- encodeInstrument,
77
- decodeInstrument,
82
+ export {
83
+ encodeInstrument,
84
+ decodeInstrument,
78
85
  defaultInstrument,
79
86
  encodeOperator,
80
87
  decodeOperator,
81
- defaultOperator
88
+ defaultOperator
82
89
  } from '../utils/struct.js';
90
+
91
+ // Re-export enums
92
+ export { Emulator, TrackOption } from '../utils/constants.js';
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Zero-config light profile for libADLMIDI-JS
3
- *
3
+ *
4
4
  * Exports pre-configured AdlMidi and AdlMidiCore with this profile's WASM.
5
5
  *
6
- *
6
+ *
7
7
  * @module profiles/light
8
8
  */
9
9
 
@@ -15,6 +15,10 @@ const PROCESSOR_URL = new URL('../../dist/libadlmidi.light.processor.js', import
15
15
  const WASM_URL = new URL('../../dist/libadlmidi.light.core.wasm', import.meta.url).href;
16
16
  const CORE_PATH = new URL('../../dist/libadlmidi.light.core.js', import.meta.url).href;
17
17
 
18
+ // Default synth settings injected at init. NUKED_FAST is preferred when the
19
+ // profile bundles it (bit-exact vs Nuked 1.8, roughly 1.5x faster).
20
+ const DEFAULT_SETTINGS = { emulator: 1 };
21
+
18
22
  /**
19
23
  * Pre-configured AdlMidi for light profile.
20
24
  *
@@ -30,15 +34,17 @@ const CORE_PATH = new URL('../../dist/libadlmidi.light.core.js', import.meta.url
30
34
  export class AdlMidi extends BaseAdlMidi {
31
35
  /**
32
36
  * Initialize the synthesizer with this profile's WASM.
33
- *
37
+ *
34
38
  * @param {string} [processorUrl] - Override processor URL (optional)
35
39
  * @param {string} [wasmUrl] - Override WASM URL (optional)
40
+ * @param {object} [defaultSettings] - Override profile's default synth settings
36
41
  * @returns {Promise<void>}
37
42
  */
38
- async init(processorUrl, wasmUrl) {
43
+ async init(processorUrl, wasmUrl, defaultSettings) {
39
44
  return super.init(
40
45
  processorUrl || PROCESSOR_URL,
41
- wasmUrl || WASM_URL
46
+ wasmUrl || WASM_URL,
47
+ defaultSettings || DEFAULT_SETTINGS
42
48
  );
43
49
  }
44
50
  }
@@ -60,23 +66,27 @@ export class AdlMidiCore {
60
66
  /**
61
67
  * Create a new AdlMidiCore instance with this profile's WASM.
62
68
  *
63
- * @param {{corePath?: string}} [options] - Options (corePath is pre-configured)
69
+ * @param {{corePath?: string, defaultEmulator?: number, wasmBinary?: ArrayBuffer}} [options]
70
+ * Override profile defaults. corePath and defaultEmulator are pre-configured.
64
71
  * @returns {Promise<BaseAdlMidiCore>}
65
72
  */
66
73
  static async create(options = {}) {
67
74
  return BaseAdlMidiCore.create({
68
75
  ...options,
69
- corePath: options.corePath || CORE_PATH
76
+ corePath: options.corePath || CORE_PATH, defaultEmulator: options.defaultEmulator !== undefined ? options.defaultEmulator : 1
70
77
  });
71
78
  }
72
79
  }
73
80
 
74
81
  // Re-export struct utilities for convenience
75
- export {
76
- encodeInstrument,
77
- decodeInstrument,
82
+ export {
83
+ encodeInstrument,
84
+ decodeInstrument,
78
85
  defaultInstrument,
79
86
  encodeOperator,
80
87
  decodeOperator,
81
- defaultOperator
88
+ defaultOperator
82
89
  } from '../utils/struct.js';
90
+
91
+ // Re-export enums
92
+ export { Emulator, TrackOption } from '../utils/constants.js';