libadlmidi-js 1.1.0 → 1.2.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 (58) hide show
  1. package/README.md +36 -1
  2. package/dist/core.d.ts +148 -0
  3. package/dist/fm_banks/manifest.json +1 -1
  4. package/dist/libadlmidi.d.ts +119 -2
  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 +152 -53
  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 +152 -53
  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 +152 -53
  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 +152 -53
  29. package/dist/libadlmidi.js +258 -4
  30. package/dist/libadlmidi.js.map +2 -2
  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 +152 -53
  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 +152 -53
  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 +152 -53
  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 +152 -53
  55. package/package.json +6 -5
  56. package/src/core.js +289 -24
  57. package/src/libadlmidi.js +229 -4
  58. package/src/processor.js +101 -1
package/README.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  WebAssembly build of [libADLMIDI](https://github.com/Wohlstand/libADLMIDI) - a free Software MIDI synthesizer library with OPL3 (FM synthesis) emulation.
4
4
 
5
+ Check out some [examples](https://libadlmidi-js.github.io):
6
+ - [oplsfxr](https://libadlmidi-js.github.io/examples/oplsfxr.html)
7
+ - [midi player](https://libadlmidi-js.github.io/examples/player.html)
8
+ - [keyboard](https://libadlmidi-js.github.io/examples/keyboard.html)
9
+ - [patch editor](https://libadlmidi-js.github.io/examples/patch-editor.html)
10
+ - [midi to wav](https://libadlmidi-js.github.io/examples/midi-to-audio.html)
11
+ - [connect any midi controller](https://libadlmidi-js.github.io/examples/webmidi.html)
12
+
5
13
  ## Features
6
14
 
7
15
  - **AudioWorklet Integration**: Runs synthesis in a separate thread to prevent UI stuttering. Interoperates with all the usual browser audio APIs.
@@ -32,6 +40,34 @@ setTimeout(() => {
32
40
  }, 1000);
33
41
  ```
34
42
 
43
+ ## CDN Usage
44
+
45
+ You can load the library from a CDN to use it right away.
46
+
47
+ **unpkg** or **jsdelivr**:
48
+ ```html
49
+ <script type="module">
50
+ import { AdlMidi } from 'https://unpkg.com/libadlmidi-js/src/profiles/light.js';
51
+ // or: https://cdn.jsdelivr.net/npm/libadlmidi-js/src/profiles/light.js
52
+
53
+ const synth = new AdlMidi();
54
+ await synth.init();
55
+ </script>
56
+ ```
57
+
58
+ **esm.sh** requires explicit URLs:
59
+ ```html
60
+ <script type="module">
61
+ import { AdlMidi } from 'https://esm.sh/libadlmidi-js/src/libadlmidi.js';
62
+
63
+ const synth = new AdlMidi();
64
+ await synth.init(
65
+ 'https://esm.sh/libadlmidi-js/dist/libadlmidi.light.processor.js?raw',
66
+ 'https://esm.sh/libadlmidi-js/dist/libadlmidi.light.core.wasm?raw'
67
+ );
68
+ </script>
69
+ ```
70
+
35
71
  ## Low-Level API (Node.js / Custom Backends)
36
72
 
37
73
  For batch rendering, custom audio backends, or non-browser environments:
@@ -98,7 +134,6 @@ synth.noteOn(0, 60, 100);
98
134
  // You can also decode instrument data from a bank
99
135
  const decoded = decodeInstrument(bytes);
100
136
  ```
101
-
102
137
  ## Profiles
103
138
 
104
139
  | Profile | Emulator(s) | Usage |
package/dist/core.d.ts CHANGED
@@ -61,6 +61,10 @@ export class AdlMidiCore {
61
61
  * Reset the synthesizer state (stop all notes).
62
62
  */
63
63
  reset(): void;
64
+ /**
65
+ * Full reset to apply instrument/bank changes.
66
+ */
67
+ resetFull(): void;
64
68
  /**
65
69
  * Panic - immediately stop all notes.
66
70
  */
@@ -101,6 +105,55 @@ export class AdlMidiCore {
101
105
  * @returns {boolean} True if successful
102
106
  */
103
107
  setNumChips(count: number): boolean;
108
+ /**
109
+ * Set the number of 4-operator channels.
110
+ *
111
+ * @param {number} count - Number of channels (-1 for auto)
112
+ * @returns {boolean} True if successful
113
+ */
114
+ setNumFourOpChannels(count: number): boolean;
115
+ /**
116
+ * Get the number of 4-operator channels.
117
+ *
118
+ * @returns {number} Count of channels
119
+ */
120
+ getNumFourOpChannels(): number;
121
+ /**
122
+ * Enable/disable scaling of modulators by volume.
123
+ *
124
+ * @param {boolean} enabled
125
+ */
126
+ setScaleModulators(enabled: boolean): void;
127
+ /**
128
+ * Enable/disable full-range brightness (0-127).
129
+ *
130
+ * @param {boolean} enabled
131
+ */
132
+ setFullRangeBrightness(enabled: boolean): void;
133
+ /**
134
+ * Enable/disable automatic arpeggio.
135
+ *
136
+ * @param {boolean} enabled
137
+ */
138
+ setAutoArpeggio(enabled: boolean): void;
139
+ /**
140
+ * Get automatic arpeggio state.
141
+ *
142
+ * @returns {boolean}
143
+ */
144
+ getAutoArpeggio(): boolean;
145
+ /**
146
+ * Set channel allocation mode.
147
+ *
148
+ * @param {number} mode - Mode ID
149
+ */
150
+ setChannelAllocMode(mode: number): void;
151
+ /**
152
+ * Get channel allocation mode.
153
+ *
154
+ * @returns {number} Mode ID
155
+ */
156
+ getChannelAllocMode(): number;
104
157
  /**
105
158
  * Enable/disable soft stereo panning.
106
159
  *
@@ -132,6 +185,53 @@ export class AdlMidiCore {
132
185
  * @returns {string} Emulator name
133
186
  */
134
187
  getEmulatorName(): string;
188
+ /**
189
+ * Get the version string of the linked libADLMIDI library.
190
+ *
191
+ * @returns {string} Version string (e.g., "1.5.1")
192
+ */
193
+ getLibraryVersion(): string;
194
+ /**
195
+ * Get the version of the linked libADLMIDI library as an object.
196
+ *
197
+ * @returns {{major: number, minor: number, patch: number}}
198
+ */
199
+ getVersion(): {
200
+ major: number;
201
+ minor: number;
202
+ patch: number;
203
+ };
204
+ /**
205
+ * Get the number of emulated chips.
206
+ *
207
+ * @returns {number}
208
+ */
209
+ getNumChips(): number;
210
+ /**
211
+ * Get the number of emulated chips obtained.
212
+ *
213
+ * @returns {number}
214
+ */
215
+ getNumChipsObtained(): number;
216
+ /**
217
+ * Get the volume range model.
218
+ *
219
+ * @returns {number}
220
+ */
221
+ getVolumeModel(): number;
222
+ /**
223
+ * Set the volume range model.
224
+ *
225
+ * @param {number} model - Volume model type
226
+ */
227
+ setVolumeModel(model: number): void;
228
+ /**
229
+ * Run emulator with PCM rate to reduce CPU usage.
230
+ *
231
+ * @param {boolean} enabled
232
+ * @returns {boolean} True if successful
233
+ */
234
+ setRunAtPcmRate(enabled: boolean): boolean;
135
235
  /**
136
236
  * Trigger a note on.
137
237
  *
@@ -147,6 +247,21 @@ export class AdlMidiCore {
147
247
  * @param {number} note - MIDI note (0-127)
148
248
  */
149
249
  noteOff(channel: number, note: number): void;
250
+ /**
251
+ * Send a note aftertouch message.
252
+ *
253
+ * @param {number} channel - MIDI channel (0-15)
254
+ * @param {number} note - MIDI note (0-127)
255
+ * @param {number} pressure - Aftertouch pressure (0-127)
256
+ */
257
+ noteAfterTouch(channel: number, note: number, pressure: number): void;
258
+ /**
259
+ * Send a channel aftertouch message.
260
+ *
261
+ * @param {number} channel - MIDI channel (0-15)
262
+ * @param {number} pressure - Aftertouch pressure (0-127)
263
+ */
264
+ channelAfterTouch(channel: number, pressure: number): void;
150
265
  /**
151
266
  * Send a pitch bend message.
152
267
  *
@@ -169,6 +284,27 @@ export class AdlMidiCore {
169
284
  * @param {number} program - Program number (0-127)
170
285
  */
171
286
  programChange(channel: number, program: number): void;
287
+ /**
288
+ * Send a bank change message (16-bit).
289
+ *
290
+ * @param {number} channel - MIDI channel (0-15)
291
+ * @param {number} bank - Bank number
292
+ */
293
+ bankChange(channel: number, bank: number): void;
294
+ /**
295
+ * Send a bank change MSB message.
296
+ *
297
+ * @param {number} channel - MIDI channel (0-15)
298
+ * @param {number} msb - Bank MSB (0-127)
299
+ */
300
+ bankChangeMSB(channel: number, msb: number): void;
301
+ /**
302
+ * Send a bank change LSB message.
303
+ *
304
+ * @param {number} channel - MIDI channel (0-15)
305
+ * @param {number} lsb - Bank LSB (0-127)
306
+ */
307
+ bankChangeLSB(channel: number, lsb: number): void;
172
308
  /**
173
309
  * Generate audio samples (real-time synthesis).
174
310
  *
@@ -183,6 +319,18 @@ export class AdlMidiCore {
183
319
  * @returns {boolean} True if successful
184
320
  */
185
321
  loadMidi(data: ArrayBuffer | Uint8Array): boolean;
322
+ /**
323
+ * Get the music title of the loaded MIDI file.
324
+ *
325
+ * @returns {string} Title or empty string
326
+ */
327
+ getMusicTitle(): string;
328
+ /**
329
+ * Get the copyright notice of the loaded MIDI file.
330
+ *
331
+ * @returns {string} Copyright or empty string
332
+ */
333
+ getMusicCopyright(): string;
186
334
  /**
187
335
  * Play MIDI file and generate audio.
188
336
  *
@@ -1,5 +1,5 @@
1
1
  {
2
- "generated": "2026-01-20T13:26:00.406Z",
2
+ "generated": "2026-03-17T14:43:16.332Z",
3
3
  "categories": {
4
4
  "wopl": {
5
5
  "description": "General WOPL banks",
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Available OPL3 emulator cores.
2
+ * Available OPL2/OPL3 emulator cores.
3
3
  * Use with switchEmulator() to change the synthesis engine at runtime.
4
4
  * Note: Only emulators compiled into the current profile are available.
5
5
  */
@@ -75,7 +75,7 @@ export type Emulator = number;
75
75
  * @property {boolean} [deepTremolo] - Enable deep tremolo
76
76
  */
77
77
  /**
78
- * Available OPL3 emulator cores.
78
+ * Available OPL2/OPL3 emulator cores.
79
79
  * Use with switchEmulator() to change the synthesis engine at runtime.
80
80
  * Note: Only emulators compiled into the current profile are available.
81
81
  * @readonly
@@ -104,6 +104,8 @@ export const Emulator: Readonly<{
104
104
  NUKED_OPL2_LLE: 9;
105
105
  /** Nuked OPL3 LLE - Transistor-level emulation */
106
106
  NUKED_OPL3_LLE: 10;
107
+ /** Nuked OPL2 Lite - Lightweight OPL2 emulation for AdLib-era music */
108
+ NUKED_OPL2_LITE: 11;
107
109
  }>;
108
110
  export class AdlMidi {
109
111
  /**
@@ -163,6 +165,37 @@ export class AdlMidi {
163
165
  * @param {number} program - Program number (0-127)
164
166
  */
165
167
  programChange(channel: number, program: number): void;
168
+ /**
169
+ * Send note aftertouch
170
+ * @param {number} channel - MIDI channel (0-15)
171
+ * @param {number} note - Note number (0-127)
172
+ * @param {number} pressure - Pressure (0-127)
173
+ */
174
+ noteAfterTouch(channel: number, note: number, pressure: number): void;
175
+ /**
176
+ * Send channel aftertouch
177
+ * @param {number} channel - MIDI channel (0-15)
178
+ * @param {number} pressure - Pressure (0-127)
179
+ */
180
+ channelAfterTouch(channel: number, pressure: number): void;
181
+ /**
182
+ * Change bank (16-bit)
183
+ * @param {number} channel - MIDI channel (0-15)
184
+ * @param {number} bank - Bank number
185
+ */
186
+ bankChange(channel: number, bank: number): void;
187
+ /**
188
+ * Change bank MSB
189
+ * @param {number} channel - MIDI channel (0-15)
190
+ * @param {number} msb - Bank MSB (0-127)
191
+ */
192
+ bankChangeMSB(channel: number, msb: number): void;
193
+ /**
194
+ * Change bank LSB
195
+ * @param {number} channel - MIDI channel (0-15)
196
+ * @param {number} lsb - Bank LSB (0-127)
197
+ */
198
+ bankChangeLSB(channel: number, lsb: number): void;
166
199
  /**
167
200
  * Reset the real-time state (stops all notes, resets controllers)
168
201
  * @returns {void}
@@ -211,6 +244,46 @@ export class AdlMidi {
211
244
  * @param {number} chips - Number of chips (1-100)
212
245
  */
213
246
  setNumChips(chips: number): void;
247
+ /**
248
+ * Set the number of 4-operator channels
249
+ * @param {number} channels - Number of channels (-1 for auto)
250
+ */
251
+ setNumFourOpChannels(channels: number): void;
252
+ /**
253
+ * Get the number of 4-operator channels
254
+ * @returns {Promise<number>}
255
+ */
256
+ getNumFourOpChannels(): Promise<number>;
257
+ /**
258
+ * Enable/disable scaling of modulators by volume
259
+ * @param {boolean} enabled
260
+ */
261
+ setScaleModulators(enabled: boolean): void;
262
+ /**
263
+ * Enable/disable full-range brightness
264
+ * @param {boolean} enabled
265
+ */
266
+ setFullRangeBrightness(enabled: boolean): void;
267
+ /**
268
+ * Enable/disable automatic arpeggio
269
+ * @param {boolean} enabled
270
+ */
271
+ setAutoArpeggio(enabled: boolean): void;
272
+ /**
273
+ * Get automatic arpeggio state
274
+ * @returns {Promise<boolean>}
275
+ */
276
+ getAutoArpeggio(): Promise<boolean>;
277
+ /**
278
+ * Set channel allocation mode
279
+ * @param {number} mode - Mode ID
280
+ */
281
+ setChannelAllocMode(mode: number): void;
282
+ /**
283
+ * Get channel allocation mode
284
+ * @returns {Promise<number>}
285
+ */
286
+ getChannelAllocMode(): Promise<number>;
214
287
  /**
215
288
  * Set the volume model
216
289
  * @param {number} model - Volume model number
@@ -231,6 +304,11 @@ export class AdlMidi {
231
304
  * @param {boolean} enabled
232
305
  */
233
306
  setTremolo(enabled: boolean): void;
307
+ /**
308
+ * Run emulator with PCM rate to reduce CPU usage
309
+ * @param {boolean} enabled
310
+ */
311
+ setRunAtPcmRate(enabled: boolean): void;
234
312
  /**
235
313
  * Switch the OPL3 emulator core at runtime
236
314
  *
@@ -255,6 +333,35 @@ export class AdlMidi {
255
333
  * console.log(`Using: ${name}`);
256
334
  */
257
335
  getEmulatorName(): Promise<string>;
336
+ /**
337
+ * Get the version string of the linked libADLMIDI library
338
+ * @returns {Promise<string>}
339
+ */
340
+ getLibraryVersion(): Promise<string>;
341
+ /**
342
+ * Get the version of the linked libADLMIDI library as an object
343
+ * @returns {Promise<{major: number, minor: number, patch: number}>}
344
+ */
345
+ getVersion(): Promise<{
346
+ major: number;
347
+ minor: number;
348
+ patch: number;
349
+ }>;
350
+ /**
351
+ * Get the number of emulated chips
352
+ * @returns {Promise<number>}
353
+ */
354
+ getNumChips(): Promise<number>;
355
+ /**
356
+ * Get the number of emulated chips obtained
357
+ * @returns {Promise<number>}
358
+ */
359
+ getNumChipsObtained(): Promise<number>;
360
+ /**
361
+ * Get the volume range model
362
+ * @returns {Promise<number>}
363
+ */
364
+ getVolumeModel(): Promise<number>;
258
365
  /**
259
366
  * Get list of embedded banks available in this build
260
367
  * Note: Slim builds have no embedded banks and will return an empty array
@@ -280,6 +387,16 @@ export class AdlMidi {
280
387
  loadMidi(arrayBuffer: ArrayBuffer): Promise<{
281
388
  duration: number;
282
389
  }>;
390
+ /**
391
+ * Get the music title of the loaded MIDI file
392
+ * @returns {Promise<string>}
393
+ */
394
+ getMusicTitle(): Promise<string>;
395
+ /**
396
+ * Get the copyright notice of the loaded MIDI file
397
+ * @returns {Promise<string>}
398
+ */
399
+ getMusicCopyright(): Promise<string>;
283
400
  /**
284
401
  * Start or resume MIDI file playback
285
402
  * @returns {void}