spessasynth_core 4.0.5 → 4.0.7
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.d.ts +5 -0
- package/dist/index.js +82 -99
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -3293,6 +3293,11 @@ declare class BasicMIDI {
|
|
|
3293
3293
|
* @returns String, Date, ArrayBuffer or undefined.
|
|
3294
3294
|
*/
|
|
3295
3295
|
getRMIDInfo<K extends keyof RMIDInfoData>(infoType: K): RMIDInfoData[K] | undefined;
|
|
3296
|
+
/**
|
|
3297
|
+
* Iterates over the MIDI file, ordered by the time the events happen.
|
|
3298
|
+
* @param callback The callback function to process each event.
|
|
3299
|
+
*/
|
|
3300
|
+
iterate(callback: (event: MIDIMessage, trackNumber: number, eventIndexes: number[]) => unknown): void;
|
|
3296
3301
|
/**
|
|
3297
3302
|
* INTERNAL USE ONLY!
|
|
3298
3303
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1220,22 +1220,6 @@ var DEFAULT_COPYRIGHT = "Created using SpessaSynth";
|
|
|
1220
1220
|
function correctBankOffsetInternal(mid, bankOffset, soundBank) {
|
|
1221
1221
|
let system = "gm";
|
|
1222
1222
|
const unwantedSystems = [];
|
|
1223
|
-
const eventIndexes = Array(mid.tracks.length).fill(0);
|
|
1224
|
-
let remainingTracks = mid.tracks.length;
|
|
1225
|
-
const findFirstEventIndex = () => {
|
|
1226
|
-
let index = 0;
|
|
1227
|
-
let ticks = Infinity;
|
|
1228
|
-
mid.tracks.forEach((track, i) => {
|
|
1229
|
-
if (eventIndexes[i] >= track.events.length) {
|
|
1230
|
-
return;
|
|
1231
|
-
}
|
|
1232
|
-
if (track.events[eventIndexes[i]].ticks < ticks) {
|
|
1233
|
-
index = i;
|
|
1234
|
-
ticks = track.events[eventIndexes[i]].ticks;
|
|
1235
|
-
}
|
|
1236
|
-
});
|
|
1237
|
-
return index;
|
|
1238
|
-
};
|
|
1239
1223
|
const ports = Array(mid.tracks.length).fill(0);
|
|
1240
1224
|
const channelsAmount = 16 + Math.max(...mid.portChannelOffsetMap);
|
|
1241
1225
|
const channelsInfo = [];
|
|
@@ -1249,23 +1233,15 @@ function correctBankOffsetInternal(mid, bankOffset, soundBank) {
|
|
|
1249
1233
|
hasBankSelect: false
|
|
1250
1234
|
});
|
|
1251
1235
|
}
|
|
1252
|
-
|
|
1253
|
-
const trackNum = findFirstEventIndex();
|
|
1254
|
-
const track = mid.tracks[trackNum];
|
|
1255
|
-
if (eventIndexes[trackNum] >= track.events.length) {
|
|
1256
|
-
remainingTracks--;
|
|
1257
|
-
continue;
|
|
1258
|
-
}
|
|
1259
|
-
const e = track.events[eventIndexes[trackNum]];
|
|
1260
|
-
eventIndexes[trackNum]++;
|
|
1236
|
+
mid.iterate((e, trackNum) => {
|
|
1261
1237
|
const portOffset = mid.portChannelOffsetMap[ports[trackNum]];
|
|
1262
1238
|
if (e.statusByte === midiMessageTypes.midiPort) {
|
|
1263
1239
|
ports[trackNum] = e.data[0];
|
|
1264
|
-
|
|
1240
|
+
return;
|
|
1265
1241
|
}
|
|
1266
1242
|
const status = e.statusByte & 240;
|
|
1267
1243
|
if (status !== midiMessageTypes.controllerChange && status !== midiMessageTypes.programChange && status !== midiMessageTypes.systemExclusive) {
|
|
1268
|
-
|
|
1244
|
+
return;
|
|
1269
1245
|
}
|
|
1270
1246
|
if (status === midiMessageTypes.systemExclusive) {
|
|
1271
1247
|
if (!isGSDrumsOn(e)) {
|
|
@@ -1282,11 +1258,11 @@ function correctBankOffsetInternal(mid, bankOffset, soundBank) {
|
|
|
1282
1258
|
} else if (isGM2On(e)) {
|
|
1283
1259
|
system = "gm2";
|
|
1284
1260
|
}
|
|
1285
|
-
|
|
1261
|
+
return;
|
|
1286
1262
|
}
|
|
1287
1263
|
const sysexChannel = [9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15][e.data[5] & 15] + portOffset;
|
|
1288
1264
|
channelsInfo[sysexChannel].drums = !!(e.data[7] > 0 && e.data[5] >> 4);
|
|
1289
|
-
|
|
1265
|
+
return;
|
|
1290
1266
|
}
|
|
1291
1267
|
const chNum = (e.statusByte & 15) + portOffset;
|
|
1292
1268
|
const channel = channelsInfo[chNum];
|
|
@@ -1313,10 +1289,10 @@ function correctBankOffsetInternal(mid, bankOffset, soundBank) {
|
|
|
1313
1289
|
);
|
|
1314
1290
|
e.data[0] = targetPreset.program;
|
|
1315
1291
|
if (targetPreset.isGMGSDrum && BankSelectHacks.isSystemXG(system)) {
|
|
1316
|
-
|
|
1292
|
+
return;
|
|
1317
1293
|
}
|
|
1318
1294
|
if (channel.lastBank === void 0) {
|
|
1319
|
-
|
|
1295
|
+
return;
|
|
1320
1296
|
}
|
|
1321
1297
|
channel.lastBank.data[1] = BankSelectHacks.addBankOffset(
|
|
1322
1298
|
targetPreset.bankMSB,
|
|
@@ -1324,14 +1300,14 @@ function correctBankOffsetInternal(mid, bankOffset, soundBank) {
|
|
|
1324
1300
|
targetPreset.isXGDrums
|
|
1325
1301
|
);
|
|
1326
1302
|
if (channel.lastBankLSB === void 0) {
|
|
1327
|
-
|
|
1303
|
+
return;
|
|
1328
1304
|
}
|
|
1329
1305
|
channel.lastBankLSB.data[1] = targetPreset.bankLSB;
|
|
1330
|
-
|
|
1306
|
+
return;
|
|
1331
1307
|
}
|
|
1332
1308
|
const isLSB = e.data[0] === midiControllers.bankSelectLSB;
|
|
1333
1309
|
if (e.data[0] !== midiControllers.bankSelect && !isLSB) {
|
|
1334
|
-
|
|
1310
|
+
return;
|
|
1335
1311
|
}
|
|
1336
1312
|
channel.hasBankSelect = true;
|
|
1337
1313
|
if (isLSB) {
|
|
@@ -1339,7 +1315,7 @@ function correctBankOffsetInternal(mid, bankOffset, soundBank) {
|
|
|
1339
1315
|
} else {
|
|
1340
1316
|
channel.lastBank = e;
|
|
1341
1317
|
}
|
|
1342
|
-
}
|
|
1318
|
+
});
|
|
1343
1319
|
channelsInfo.forEach((has, ch) => {
|
|
1344
1320
|
if (has.hasBankSelect) {
|
|
1345
1321
|
return;
|
|
@@ -1411,7 +1387,7 @@ function correctBankOffsetInternal(mid, bankOffset, soundBank) {
|
|
|
1411
1387
|
indexToAdd
|
|
1412
1388
|
);
|
|
1413
1389
|
});
|
|
1414
|
-
if (system
|
|
1390
|
+
if (system === "gm" && !BankSelectHacks.isSystemXG(system)) {
|
|
1415
1391
|
for (const m of unwantedSystems) {
|
|
1416
1392
|
const track = mid.tracks[m.tNum];
|
|
1417
1393
|
track.deleteEvent(track.events.indexOf(m.e));
|
|
@@ -1545,39 +1521,15 @@ function getUsedProgramsAndKeys(mid, soundBank) {
|
|
|
1545
1521
|
});
|
|
1546
1522
|
}
|
|
1547
1523
|
const usedProgramsAndKeys = /* @__PURE__ */ new Map();
|
|
1548
|
-
const eventIndexes = Array(mid.tracks.length).fill(0);
|
|
1549
|
-
let remainingTracks = mid.tracks.length;
|
|
1550
|
-
function findFirstEventIndex() {
|
|
1551
|
-
let index = 0;
|
|
1552
|
-
let ticks = Infinity;
|
|
1553
|
-
mid.tracks.forEach(({ events: track }, i) => {
|
|
1554
|
-
if (eventIndexes[i] >= track.length) {
|
|
1555
|
-
return;
|
|
1556
|
-
}
|
|
1557
|
-
if (track[eventIndexes[i]].ticks < ticks) {
|
|
1558
|
-
index = i;
|
|
1559
|
-
ticks = track[eventIndexes[i]].ticks;
|
|
1560
|
-
}
|
|
1561
|
-
});
|
|
1562
|
-
return index;
|
|
1563
|
-
}
|
|
1564
1524
|
const ports = mid.tracks.map((t) => t.port);
|
|
1565
|
-
|
|
1566
|
-
const trackNum = findFirstEventIndex();
|
|
1567
|
-
const track = mid.tracks[trackNum].events;
|
|
1568
|
-
if (eventIndexes[trackNum] >= track.length) {
|
|
1569
|
-
remainingTracks--;
|
|
1570
|
-
continue;
|
|
1571
|
-
}
|
|
1572
|
-
const event = track[eventIndexes[trackNum]];
|
|
1573
|
-
eventIndexes[trackNum]++;
|
|
1525
|
+
mid.iterate((event, trackNum) => {
|
|
1574
1526
|
if (event.statusByte === midiMessageTypes.midiPort) {
|
|
1575
1527
|
ports[trackNum] = event.data[0];
|
|
1576
|
-
|
|
1528
|
+
return;
|
|
1577
1529
|
}
|
|
1578
1530
|
const status = event.statusByte & 240;
|
|
1579
1531
|
if (status !== midiMessageTypes.noteOn && status !== midiMessageTypes.controllerChange && status !== midiMessageTypes.programChange && status !== midiMessageTypes.systemExclusive) {
|
|
1580
|
-
|
|
1532
|
+
return;
|
|
1581
1533
|
}
|
|
1582
1534
|
const channel = (event.statusByte & 15) + mid.portChannelOffsetMap[ports[trackNum]] || 0;
|
|
1583
1535
|
let ch = channelPresets[channel];
|
|
@@ -1597,7 +1549,7 @@ function getUsedProgramsAndKeys(mid, soundBank) {
|
|
|
1597
1549
|
{
|
|
1598
1550
|
switch (event.data[0]) {
|
|
1599
1551
|
default:
|
|
1600
|
-
|
|
1552
|
+
return;
|
|
1601
1553
|
case midiControllers.bankSelectLSB:
|
|
1602
1554
|
ch.bankLSB = event.data[1];
|
|
1603
1555
|
break;
|
|
@@ -1608,7 +1560,7 @@ function getUsedProgramsAndKeys(mid, soundBank) {
|
|
|
1608
1560
|
break;
|
|
1609
1561
|
case midiMessageTypes.noteOn:
|
|
1610
1562
|
if (event.data[1] === 0) {
|
|
1611
|
-
|
|
1563
|
+
return;
|
|
1612
1564
|
}
|
|
1613
1565
|
let combos = usedProgramsAndKeys.get(ch.preset);
|
|
1614
1566
|
if (!combos) {
|
|
@@ -1626,8 +1578,26 @@ function getUsedProgramsAndKeys(mid, soundBank) {
|
|
|
1626
1578
|
"%cXG on detected!",
|
|
1627
1579
|
consoleColors.recognized
|
|
1628
1580
|
);
|
|
1581
|
+
} else if (isGM2On(event)) {
|
|
1582
|
+
system = "gm2";
|
|
1583
|
+
SpessaSynthInfo(
|
|
1584
|
+
"%cGM2 on detected!",
|
|
1585
|
+
consoleColors.recognized
|
|
1586
|
+
);
|
|
1587
|
+
} else if (isGMOn(event)) {
|
|
1588
|
+
system = "gm";
|
|
1589
|
+
SpessaSynthInfo(
|
|
1590
|
+
"%cGM on detected!",
|
|
1591
|
+
consoleColors.recognized
|
|
1592
|
+
);
|
|
1593
|
+
} else if (isGSOn(event)) {
|
|
1594
|
+
system = "gs";
|
|
1595
|
+
SpessaSynthInfo(
|
|
1596
|
+
"%cGS on detected!",
|
|
1597
|
+
consoleColors.recognized
|
|
1598
|
+
);
|
|
1629
1599
|
}
|
|
1630
|
-
|
|
1600
|
+
return;
|
|
1631
1601
|
}
|
|
1632
1602
|
const sysexChannel = [9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15][event.data[5] & 15] + mid.portChannelOffsetMap[ports[trackNum]];
|
|
1633
1603
|
const isDrum = !!(event.data[7] > 0 && event.data[5] >> 4);
|
|
@@ -1636,7 +1606,7 @@ function getUsedProgramsAndKeys(mid, soundBank) {
|
|
|
1636
1606
|
}
|
|
1637
1607
|
break;
|
|
1638
1608
|
}
|
|
1639
|
-
}
|
|
1609
|
+
});
|
|
1640
1610
|
usedProgramsAndKeys.forEach((combos, preset) => {
|
|
1641
1611
|
if (combos.size === 0) {
|
|
1642
1612
|
SpessaSynthInfo(
|
|
@@ -1825,22 +1795,6 @@ function modifyMIDIInternal(midi, desiredProgramChanges = [], desiredControllerC
|
|
|
1825
1795
|
});
|
|
1826
1796
|
let system = "gs";
|
|
1827
1797
|
let addedGs = false;
|
|
1828
|
-
const eventIndexes = Array(midi.tracks.length).fill(0);
|
|
1829
|
-
let remainingTracks = midi.tracks.length;
|
|
1830
|
-
function findFirstEventIndex() {
|
|
1831
|
-
let index = 0;
|
|
1832
|
-
let ticks = Infinity;
|
|
1833
|
-
midi.tracks.forEach((track, i) => {
|
|
1834
|
-
if (eventIndexes[i] >= track.events.length) {
|
|
1835
|
-
return;
|
|
1836
|
-
}
|
|
1837
|
-
if (track.events[eventIndexes[i]].ticks < ticks) {
|
|
1838
|
-
index = i;
|
|
1839
|
-
ticks = track.events[eventIndexes[i]].ticks;
|
|
1840
|
-
}
|
|
1841
|
-
});
|
|
1842
|
-
return index;
|
|
1843
|
-
}
|
|
1844
1798
|
const midiPorts = midi.tracks.map((t) => t.port);
|
|
1845
1799
|
const midiPortChannelOffsets = {};
|
|
1846
1800
|
let midiPortChannelOffset = 0;
|
|
@@ -1871,15 +1825,9 @@ function modifyMIDIInternal(midi, desiredProgramChanges = [], desiredControllerC
|
|
|
1871
1825
|
coarseTranspose[transpose.channel] = coarse;
|
|
1872
1826
|
fineTranspose[transpose.channel] = fine;
|
|
1873
1827
|
});
|
|
1874
|
-
|
|
1875
|
-
const trackNum = findFirstEventIndex();
|
|
1828
|
+
midi.iterate((e, trackNum, eventIndexes) => {
|
|
1876
1829
|
const track = midi.tracks[trackNum];
|
|
1877
|
-
|
|
1878
|
-
remainingTracks--;
|
|
1879
|
-
continue;
|
|
1880
|
-
}
|
|
1881
|
-
const index = eventIndexes[trackNum]++;
|
|
1882
|
-
const e = track.events[index];
|
|
1830
|
+
const index = eventIndexes[trackNum];
|
|
1883
1831
|
const deleteThisEvent = () => {
|
|
1884
1832
|
track.deleteEvent(index);
|
|
1885
1833
|
eventIndexes[trackNum]--;
|
|
@@ -1891,17 +1839,17 @@ function modifyMIDIInternal(midi, desiredProgramChanges = [], desiredControllerC
|
|
|
1891
1839
|
const portOffset = midiPortChannelOffsets[midiPorts[trackNum]] || 0;
|
|
1892
1840
|
if (e.statusByte === midiMessageTypes.midiPort) {
|
|
1893
1841
|
assignMIDIPort(trackNum, e.data[0]);
|
|
1894
|
-
|
|
1842
|
+
return;
|
|
1895
1843
|
}
|
|
1896
1844
|
if (e.statusByte <= midiMessageTypes.sequenceSpecific && e.statusByte >= midiMessageTypes.sequenceNumber) {
|
|
1897
|
-
|
|
1845
|
+
return;
|
|
1898
1846
|
}
|
|
1899
1847
|
const status = e.statusByte & 240;
|
|
1900
1848
|
const midiChannel = e.statusByte & 15;
|
|
1901
1849
|
const channel = midiChannel + portOffset;
|
|
1902
1850
|
if (desiredChannelsToClear.includes(channel)) {
|
|
1903
1851
|
deleteThisEvent();
|
|
1904
|
-
|
|
1852
|
+
return;
|
|
1905
1853
|
}
|
|
1906
1854
|
switch (status) {
|
|
1907
1855
|
case midiMessageTypes.noteOn:
|
|
@@ -1953,7 +1901,7 @@ function modifyMIDIInternal(midi, desiredProgramChanges = [], desiredControllerC
|
|
|
1953
1901
|
(c) => c.channel === channel
|
|
1954
1902
|
);
|
|
1955
1903
|
if (!change) {
|
|
1956
|
-
|
|
1904
|
+
return;
|
|
1957
1905
|
}
|
|
1958
1906
|
SpessaSynthInfo(
|
|
1959
1907
|
`%cSetting %c${change.channel}%c to %c${MIDIPatchTools.toMIDIString(change)}%c. Track num: %c${trackNum}`,
|
|
@@ -2011,7 +1959,7 @@ function modifyMIDIInternal(midi, desiredProgramChanges = [], desiredControllerC
|
|
|
2011
1959
|
case midiMessageTypes.programChange:
|
|
2012
1960
|
if (channelsToChangeProgram.has(channel)) {
|
|
2013
1961
|
deleteThisEvent();
|
|
2014
|
-
|
|
1962
|
+
return;
|
|
2015
1963
|
}
|
|
2016
1964
|
break;
|
|
2017
1965
|
case midiMessageTypes.controllerChange:
|
|
@@ -2022,7 +1970,7 @@ function modifyMIDIInternal(midi, desiredProgramChanges = [], desiredControllerC
|
|
|
2022
1970
|
);
|
|
2023
1971
|
if (changes !== void 0) {
|
|
2024
1972
|
deleteThisEvent();
|
|
2025
|
-
|
|
1973
|
+
return;
|
|
2026
1974
|
}
|
|
2027
1975
|
if (ccNum === midiControllers.bankSelect || ccNum === midiControllers.bankSelectLSB) {
|
|
2028
1976
|
if (channelsToChangeProgram.has(channel)) {
|
|
@@ -2069,7 +2017,7 @@ function modifyMIDIInternal(midi, desiredProgramChanges = [], desiredControllerC
|
|
|
2069
2017
|
addedGs = false;
|
|
2070
2018
|
}
|
|
2071
2019
|
}
|
|
2072
|
-
}
|
|
2020
|
+
});
|
|
2073
2021
|
if (!addedGs && desiredProgramChanges.length > 0) {
|
|
2074
2022
|
let index = 0;
|
|
2075
2023
|
if (midi.tracks[0].events[0].statusByte === midiMessageTypes.trackName) {
|
|
@@ -3226,6 +3174,41 @@ var BasicMIDI2 = class _BasicMIDI {
|
|
|
3226
3174
|
return void 0;
|
|
3227
3175
|
}
|
|
3228
3176
|
}
|
|
3177
|
+
/**
|
|
3178
|
+
* Iterates over the MIDI file, ordered by the time the events happen.
|
|
3179
|
+
* @param callback The callback function to process each event.
|
|
3180
|
+
*/
|
|
3181
|
+
iterate(callback) {
|
|
3182
|
+
const eventIndexes = Array(this.tracks.length).fill(
|
|
3183
|
+
0
|
|
3184
|
+
);
|
|
3185
|
+
let remainingTracks = this.tracks.length;
|
|
3186
|
+
const findFirstEventIndex = () => {
|
|
3187
|
+
let index = 0;
|
|
3188
|
+
let ticks = Infinity;
|
|
3189
|
+
this.tracks.forEach(({ events: track }, i) => {
|
|
3190
|
+
if (eventIndexes[i] >= track.length) {
|
|
3191
|
+
return;
|
|
3192
|
+
}
|
|
3193
|
+
if (track[eventIndexes[i]].ticks < ticks) {
|
|
3194
|
+
index = i;
|
|
3195
|
+
ticks = track[eventIndexes[i]].ticks;
|
|
3196
|
+
}
|
|
3197
|
+
});
|
|
3198
|
+
return index;
|
|
3199
|
+
};
|
|
3200
|
+
while (remainingTracks > 0) {
|
|
3201
|
+
const trackNum = findFirstEventIndex();
|
|
3202
|
+
const track = this.tracks[trackNum].events;
|
|
3203
|
+
if (eventIndexes[trackNum] >= track.length) {
|
|
3204
|
+
remainingTracks--;
|
|
3205
|
+
continue;
|
|
3206
|
+
}
|
|
3207
|
+
const event = track[eventIndexes[trackNum]];
|
|
3208
|
+
callback(event, trackNum, eventIndexes);
|
|
3209
|
+
eventIndexes[trackNum]++;
|
|
3210
|
+
}
|
|
3211
|
+
}
|
|
3229
3212
|
/**
|
|
3230
3213
|
* INTERNAL USE ONLY!
|
|
3231
3214
|
*/
|
|
@@ -15256,7 +15239,7 @@ var DownloadableSounds = class _DownloadableSounds extends DLSVerifier {
|
|
|
15256
15239
|
consoleColors.recognized
|
|
15257
15240
|
);
|
|
15258
15241
|
const pgalData = aliasingChunk.data;
|
|
15259
|
-
if (pgalData[0]
|
|
15242
|
+
if (pgalData[0] !== 0 || pgalData[1] !== 1 || pgalData[2] !== 2 || pgalData[3] !== 3) {
|
|
15260
15243
|
pgalData.currentIndex += 4;
|
|
15261
15244
|
}
|
|
15262
15245
|
const drumInstrument = dls.instruments.find(
|