midi-audio-player 2.0.0 → 2.0.2
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/index.js +54 -53
- package/dist/index.js.map +2 -2
- package/dist/index.mjs +4 -4
- package/dist/index.mjs.map +3 -3
- package/dist/midi-audio-player.js +54 -53
- package/dist/midi-audio-player.min.js +4 -4
- package/package.json +12 -5
- package/src/midiaudioplayer.js +25 -23
- package/CHANGELOG.md +0 -26
package/dist/index.js
CHANGED
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
██║ ╚═╝ ██║██║██████╔╝██║██║ ██║╚██████╔╝██████╔╝██║╚██████╔╝██║ ███████╗██║ ██║ ██║ ███████╗██║ ██║
|
|
8
8
|
╚═╝ ╚═╝╚═╝╚═════╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝
|
|
9
9
|
|
|
10
|
-
Version: 2.0.
|
|
11
|
-
Build: 2026-
|
|
10
|
+
Version: 2.0.2
|
|
11
|
+
Build: 2026-06-02 12:19:59
|
|
12
12
|
Author: Maxime Larrivée-Roy <mlarriveeroy@gmail.com>
|
|
13
13
|
Github: https://github.com/webaudiofonts/midi-audio-player/
|
|
14
|
-
Website: https://webaudiofonts.
|
|
14
|
+
Website: https://webaudiofonts.com/midiaudioplayer/
|
|
15
15
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
@@ -1213,7 +1213,7 @@ var index = {
|
|
|
1213
1213
|
};
|
|
1214
1214
|
|
|
1215
1215
|
// node_modules/webaudiofontplayer/dist/index.js
|
|
1216
|
-
var WebAudioFontPlayer = class {
|
|
1216
|
+
var WebAudioFontPlayer = class _WebAudioFontPlayer {
|
|
1217
1217
|
#audioCtx = null;
|
|
1218
1218
|
#compressor = null;
|
|
1219
1219
|
#preset = null;
|
|
@@ -1228,24 +1228,34 @@ var WebAudioFontPlayer = class {
|
|
|
1228
1228
|
#sustain = false;
|
|
1229
1229
|
#pitchBendValue = 8192;
|
|
1230
1230
|
#notesWaitingForSustain = /* @__PURE__ */ new Set();
|
|
1231
|
-
constructor(preset, audioCtx, compressor = null) {
|
|
1231
|
+
constructor(preset, audioCtx, compressor = null, callback = null) {
|
|
1232
1232
|
this.#audioCtx = audioCtx;
|
|
1233
1233
|
this.#compressor = compressor;
|
|
1234
|
-
this.#preset = preset;
|
|
1235
1234
|
this.#mainGain = this.#audioCtx.createGain();
|
|
1236
1235
|
this.#mainGain.gain.setValueAtTime(this.#volumeValue, this.#audioCtx.currentTime);
|
|
1237
1236
|
this.#expressionGain = this.#audioCtx.createGain();
|
|
1238
1237
|
this.#expressionGain.gain.setValueAtTime(this.#expressionValue, this.#audioCtx.currentTime);
|
|
1239
1238
|
this.#mainGain.connect(this.#expressionGain);
|
|
1240
1239
|
this.#expressionGain.connect(this.#compressor ? this.#compressor.input : this.#audioCtx.destination);
|
|
1241
|
-
this
|
|
1240
|
+
this.setPreset(preset).then(() => {
|
|
1241
|
+
if (typeof callback === "function") callback();
|
|
1242
|
+
});
|
|
1242
1243
|
}
|
|
1243
1244
|
get preset() {
|
|
1244
1245
|
return this.#preset;
|
|
1245
1246
|
}
|
|
1246
1247
|
set preset(preset) {
|
|
1248
|
+
this.setPreset(preset);
|
|
1249
|
+
}
|
|
1250
|
+
static load(preset, audioCtx, compressor = null) {
|
|
1251
|
+
return new Promise((resolve) => {
|
|
1252
|
+
const player = new _WebAudioFontPlayer(preset, audioCtx, compressor, () => resolve(player));
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1255
|
+
async setPreset(preset, nonblocking = false) {
|
|
1247
1256
|
this.#preset = preset;
|
|
1248
|
-
this.#preset.zones.map((zone) => this.#adjustZone(zone));
|
|
1257
|
+
if (nonblocking) this.#preset.zones.map((zone) => this.#adjustZone(zone));
|
|
1258
|
+
else await Promise.all(this.#preset.zones.map((zone) => this.#adjustZone(zone)));
|
|
1249
1259
|
}
|
|
1250
1260
|
close() {
|
|
1251
1261
|
const now = this.#audioCtx.currentTime;
|
|
@@ -1380,30 +1390,24 @@ var WebAudioFontPlayer = class {
|
|
|
1380
1390
|
break;
|
|
1381
1391
|
}
|
|
1382
1392
|
}
|
|
1383
|
-
#adjustZone(zone) {
|
|
1384
|
-
if (zone.buffer) return
|
|
1393
|
+
async #adjustZone(zone) {
|
|
1394
|
+
if (zone.buffer) return zone;
|
|
1385
1395
|
zone.delay = 0;
|
|
1386
1396
|
if (zone.file) {
|
|
1387
|
-
const
|
|
1388
|
-
const
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
(error) => {
|
|
1398
|
-
console.error("Audio decoding error:", error);
|
|
1399
|
-
console.warn(this.#preset);
|
|
1400
|
-
return false;
|
|
1401
|
-
}
|
|
1402
|
-
);
|
|
1397
|
+
const binary = atob(zone.file);
|
|
1398
|
+
const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0));
|
|
1399
|
+
try {
|
|
1400
|
+
zone.buffer = await this.#audioCtx.decodeAudioData(bytes.buffer);
|
|
1401
|
+
this.#applyZoneParameters(zone);
|
|
1402
|
+
} catch (error) {
|
|
1403
|
+
console.error("Audio decoding error:", error);
|
|
1404
|
+
console.warn(this.#preset);
|
|
1405
|
+
return false;
|
|
1406
|
+
}
|
|
1403
1407
|
} else {
|
|
1404
1408
|
this.#applyZoneParameters(zone);
|
|
1405
|
-
return zone;
|
|
1406
1409
|
}
|
|
1410
|
+
return zone;
|
|
1407
1411
|
}
|
|
1408
1412
|
#applyZoneParameters(zone) {
|
|
1409
1413
|
zone.loopStart = this.#numValue(zone.loopStart, 0);
|
|
@@ -1495,9 +1499,7 @@ var WebAudioFontPlayer = class {
|
|
|
1495
1499
|
return envelope;
|
|
1496
1500
|
}
|
|
1497
1501
|
#findZone(pitch) {
|
|
1498
|
-
|
|
1499
|
-
if (zone) this.#adjustZone(zone);
|
|
1500
|
-
return zone;
|
|
1502
|
+
return this.#preset.zones.findLast((z) => pitch >= z.keyRangeLow && pitch <= z.keyRangeHigh);
|
|
1501
1503
|
}
|
|
1502
1504
|
#limitVolume(v) {
|
|
1503
1505
|
const requestedVolume = v ? 1 * v : 0.5;
|
|
@@ -1958,13 +1960,16 @@ var MidiAudioPlayer = class _MidiAudioPlayer extends index.Player {
|
|
|
1958
1960
|
throw new Error("Invalid preset: ".concat(id));
|
|
1959
1961
|
}
|
|
1960
1962
|
}
|
|
1961
|
-
async loadPreset(presetId, channel) {
|
|
1963
|
+
async loadPreset(presetId, channel, nonblocking = false) {
|
|
1962
1964
|
const presetInfo = await this.findPreset(presetId);
|
|
1963
1965
|
if (!presetInfo) throw new Error("Invalid preset: ".concat(presetId));
|
|
1964
1966
|
this.#presetMap[presetInfo.program] = presetInfo;
|
|
1965
1967
|
const preset = await this.getPreset(presetId);
|
|
1966
|
-
this.#players[channel].preset
|
|
1967
|
-
|
|
1968
|
+
if (nonblocking) this.#players[channel].setPreset(preset, nonblocking).then(() => this.#setupChange());
|
|
1969
|
+
else {
|
|
1970
|
+
await this.#players[channel].setPreset(preset, nonblocking);
|
|
1971
|
+
this.#setupChange();
|
|
1972
|
+
}
|
|
1968
1973
|
}
|
|
1969
1974
|
async load(content, setup) {
|
|
1970
1975
|
if (typeof content === "string") {
|
|
@@ -1992,6 +1997,15 @@ var MidiAudioPlayer = class _MidiAudioPlayer extends index.Player {
|
|
|
1992
1997
|
} catch (e) {
|
|
1993
1998
|
await this.loadArrayBuffer(await this.#repairMidi(content));
|
|
1994
1999
|
}
|
|
2000
|
+
if (this.#opts.karaoke) {
|
|
2001
|
+
this.#log("Generating karaoke frames...");
|
|
2002
|
+
this.#lyrics = null;
|
|
2003
|
+
await this.#generateKaraokeFrames();
|
|
2004
|
+
if (this.#title) this.#sendKaraokeFrame("title", this.#title);
|
|
2005
|
+
}
|
|
2006
|
+
this.#log("Trim midi events...");
|
|
2007
|
+
this.#trimMidiEvents();
|
|
2008
|
+
queueMicrotask(() => this.triggerPlayerEvent("computed"));
|
|
1995
2009
|
this.#log("Loading instruments...");
|
|
1996
2010
|
this.#channels = await this.#getInstruments();
|
|
1997
2011
|
this.#channelStates = Object.keys(this.#channels).reduce((acc, key) => ({ ...acc, [key]: false }), {});
|
|
@@ -2002,8 +2016,8 @@ var MidiAudioPlayer = class _MidiAudioPlayer extends index.Player {
|
|
|
2002
2016
|
this.#channelVolumes[channel] = setup.volumes[channel];
|
|
2003
2017
|
}));
|
|
2004
2018
|
}
|
|
2005
|
-
const setupPrograms = /* @__PURE__ */ new Set();
|
|
2006
2019
|
const setupPresets = {};
|
|
2020
|
+
const setupPrograms = /* @__PURE__ */ new Set();
|
|
2007
2021
|
if (setup?.presets !== void 0) {
|
|
2008
2022
|
await Promise.all(Object.keys(setup.presets).map(async (channel) => {
|
|
2009
2023
|
const presetInfo = await this.findPreset(setup.presets[channel]);
|
|
@@ -2014,7 +2028,7 @@ var MidiAudioPlayer = class _MidiAudioPlayer extends index.Player {
|
|
|
2014
2028
|
}
|
|
2015
2029
|
const uniqueInstruments = await this.#getUniqueInstruments();
|
|
2016
2030
|
if (!Object.values(this.#channels).length) this.#log("Error: no instrument found");
|
|
2017
|
-
|
|
2031
|
+
await Promise.all([...uniqueInstruments].map(async (program) => {
|
|
2018
2032
|
if (setupPrograms.has(program)) return;
|
|
2019
2033
|
let preset = null;
|
|
2020
2034
|
if (this.#presetMap[program] !== void 0) preset = await this.getPreset(this.#presetMap[program].id);
|
|
@@ -2022,16 +2036,6 @@ var MidiAudioPlayer = class _MidiAudioPlayer extends index.Player {
|
|
|
2022
2036
|
else preset = await this.#getAutoPreset(program);
|
|
2023
2037
|
this.#instruments[program] = preset;
|
|
2024
2038
|
}));
|
|
2025
|
-
if (this.#opts.karaoke) {
|
|
2026
|
-
this.#log("Generating karaoke frames...");
|
|
2027
|
-
this.#lyrics = null;
|
|
2028
|
-
await this.#generateKaraokeFrames();
|
|
2029
|
-
if (this.#title) this.#sendKaraokeFrame("title", this.#title);
|
|
2030
|
-
}
|
|
2031
|
-
this.#log("Trim midi events...");
|
|
2032
|
-
this.#trimMidiEvents();
|
|
2033
|
-
queueMicrotask(() => this.triggerPlayerEvent("computed"));
|
|
2034
|
-
await presets;
|
|
2035
2039
|
await Promise.all(Object.keys(this.#channels).map(async (channel) => {
|
|
2036
2040
|
if (this.#players[channel]) this.#players[channel].close();
|
|
2037
2041
|
if (setupPresets[channel] !== void 0) this.#players[channel] = await this.#createPlayer(setupPresets[channel]);
|
|
@@ -2414,12 +2418,9 @@ var MidiAudioPlayer = class _MidiAudioPlayer extends index.Player {
|
|
|
2414
2418
|
this.#players[channel].setPitchBend?.(event.value);
|
|
2415
2419
|
break;
|
|
2416
2420
|
case "Program Change":
|
|
2417
|
-
if (
|
|
2418
|
-
// (this.#opts.presetAuto || this.#opts.presetRandom) &&
|
|
2419
|
-
event.value >= 0 && event.value <= 127 && this.#instruments[event.value + 1] !== void 0 && event.channel != 10
|
|
2420
|
-
) {
|
|
2421
|
+
if (event.value >= 0 && event.value <= 127 && this.#instruments[event.value + 1] !== void 0 && event.channel != 10) {
|
|
2421
2422
|
if (this.#players[channel].preset?.program !== event.value + 1) {
|
|
2422
|
-
this.#players[channel].
|
|
2423
|
+
this.#players[channel].setPreset(this.#instruments[event.value + 1]);
|
|
2423
2424
|
}
|
|
2424
2425
|
}
|
|
2425
2426
|
break;
|
|
@@ -2489,8 +2490,8 @@ var MidiAudioPlayer = class _MidiAudioPlayer extends index.Player {
|
|
|
2489
2490
|
this.#presetMap[program] = preset;
|
|
2490
2491
|
return await this.getPreset(preset.id);
|
|
2491
2492
|
}
|
|
2492
|
-
|
|
2493
|
-
return
|
|
2493
|
+
#createPlayer(preset) {
|
|
2494
|
+
return index_default.load(preset, this.#audioCtx, this.#compressor);
|
|
2494
2495
|
}
|
|
2495
2496
|
async #handleMidiPipeline(event) {
|
|
2496
2497
|
if (!this.isPlaying()) return;
|
|
@@ -2525,7 +2526,7 @@ var MidiAudioPlayer = class _MidiAudioPlayer extends index.Player {
|
|
|
2525
2526
|
if (!this.#players[event.channel]) return;
|
|
2526
2527
|
if (event.channel == 10 || event.value > 127 || event.value < 0) break;
|
|
2527
2528
|
if (this.#players[event.channel] !== void 0 && this.#players[event.channel].preset.program != event.value + 1)
|
|
2528
|
-
this.#players[event.channel].
|
|
2529
|
+
this.#players[event.channel].setPreset(this.#instruments[event.value + 1]);
|
|
2529
2530
|
break;
|
|
2530
2531
|
case "Karaoke Event":
|
|
2531
2532
|
if (event.tick < this.tick - this.secondsToTicks(10)) return;
|