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 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
- while (remainingTracks > 0) {
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
- continue;
1240
+ return;
1265
1241
  }
1266
1242
  const status = e.statusByte & 240;
1267
1243
  if (status !== midiMessageTypes.controllerChange && status !== midiMessageTypes.programChange && status !== midiMessageTypes.systemExclusive) {
1268
- continue;
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
- continue;
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
- continue;
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
- continue;
1292
+ return;
1317
1293
  }
1318
1294
  if (channel.lastBank === void 0) {
1319
- continue;
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
- continue;
1303
+ return;
1328
1304
  }
1329
1305
  channel.lastBankLSB.data[1] = targetPreset.bankLSB;
1330
- continue;
1306
+ return;
1331
1307
  }
1332
1308
  const isLSB = e.data[0] === midiControllers.bankSelectLSB;
1333
1309
  if (e.data[0] !== midiControllers.bankSelect && !isLSB) {
1334
- continue;
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 !== "gs" && !BankSelectHacks.isSystemXG(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
- while (remainingTracks > 0) {
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
- continue;
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
- continue;
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
- continue;
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
- continue;
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
- continue;
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
- while (remainingTracks > 0) {
1875
- const trackNum = findFirstEventIndex();
1828
+ midi.iterate((e, trackNum, eventIndexes) => {
1876
1829
  const track = midi.tracks[trackNum];
1877
- if (eventIndexes[trackNum] >= track.events.length) {
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
- continue;
1842
+ return;
1895
1843
  }
1896
1844
  if (e.statusByte <= midiMessageTypes.sequenceSpecific && e.statusByte >= midiMessageTypes.sequenceNumber) {
1897
- continue;
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
- continue;
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
- continue;
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
- continue;
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
- continue;
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] === 2 && pgalData[1] + pgalData[2] + pgalData[3] === 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(