@marmooo/midy 0.2.7 → 0.2.8
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/README.md +2 -2
- package/esm/midy-GM1.d.ts +6 -6
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +75 -73
- package/esm/midy-GM2.d.ts +22 -23
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +122 -153
- package/esm/midy-GMLite.d.ts +2 -2
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +63 -62
- package/esm/midy.d.ts +22 -23
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +153 -216
- package/package.json +1 -1
- package/script/midy-GM1.d.ts +6 -6
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +75 -73
- package/script/midy-GM2.d.ts +22 -23
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +122 -153
- package/script/midy-GMLite.d.ts +2 -2
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +63 -62
- package/script/midy.d.ts +22 -23
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +153 -216
package/script/midy-GM2.js
CHANGED
|
@@ -287,18 +287,6 @@ class MidyGM2 {
|
|
|
287
287
|
delayTimes: this.generateDistributedArray(0.02, 2, 0.5),
|
|
288
288
|
}
|
|
289
289
|
});
|
|
290
|
-
Object.defineProperty(this, "mono", {
|
|
291
|
-
enumerable: true,
|
|
292
|
-
configurable: true,
|
|
293
|
-
writable: true,
|
|
294
|
-
value: false
|
|
295
|
-
}); // CC#124, CC#125
|
|
296
|
-
Object.defineProperty(this, "omni", {
|
|
297
|
-
enumerable: true,
|
|
298
|
-
configurable: true,
|
|
299
|
-
writable: true,
|
|
300
|
-
value: false
|
|
301
|
-
}); // CC#126, CC#127
|
|
302
290
|
Object.defineProperty(this, "noteCheckInterval", {
|
|
303
291
|
enumerable: true,
|
|
304
292
|
configurable: true,
|
|
@@ -500,6 +488,7 @@ class MidyGM2 {
|
|
|
500
488
|
controlTable: this.initControlTable(),
|
|
501
489
|
...this.setChannelAudioNodes(audioContext),
|
|
502
490
|
scheduledNotes: new SparseMap(128),
|
|
491
|
+
sustainNotes: [],
|
|
503
492
|
sostenutoNotes: new SparseMap(128),
|
|
504
493
|
scaleOctaveTuningTable: new Int8Array(12), // [-64, 63] cent
|
|
505
494
|
channelPressureTable: new Uint8Array([64, 64, 64, 0, 0, 0]),
|
|
@@ -582,7 +571,7 @@ class MidyGM2 {
|
|
|
582
571
|
const portamentoTarget = this.findPortamentoTarget(queueIndex);
|
|
583
572
|
if (portamentoTarget)
|
|
584
573
|
portamentoTarget.portamento = true;
|
|
585
|
-
const notePromise = this.scheduleNoteOff(
|
|
574
|
+
const notePromise = this.scheduleNoteOff(event.channel, event.noteNumber, event.velocity, startTime, false, // force
|
|
586
575
|
portamentoTarget?.noteNumber);
|
|
587
576
|
if (notePromise) {
|
|
588
577
|
this.notePromises.push(notePromise);
|
|
@@ -590,7 +579,7 @@ class MidyGM2 {
|
|
|
590
579
|
break;
|
|
591
580
|
}
|
|
592
581
|
case "controller":
|
|
593
|
-
this.handleControlChange(
|
|
582
|
+
this.handleControlChange(event.channel, event.controllerType, event.value, startTime);
|
|
594
583
|
break;
|
|
595
584
|
case "programChange":
|
|
596
585
|
this.handleProgramChange(event.channel, event.programNumber, startTime);
|
|
@@ -786,15 +775,10 @@ class MidyGM2 {
|
|
|
786
775
|
stopChannelNotes(channelNumber, velocity, force, scheduleTime) {
|
|
787
776
|
const channel = this.channels[channelNumber];
|
|
788
777
|
const promises = [];
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
continue;
|
|
794
|
-
const promise = this.scheduleNoteOff(channelNumber, note.noteNumber, velocity, scheduleTime, force, undefined);
|
|
795
|
-
this.notePromises.push(promise);
|
|
796
|
-
promises.push(promise);
|
|
797
|
-
}
|
|
778
|
+
this.processScheduledNotes(channel, (note) => {
|
|
779
|
+
const promise = this.scheduleNoteOff(channelNumber, note.noteNumber, velocity, scheduleTime, force, undefined);
|
|
780
|
+
this.notePromises.push(promise);
|
|
781
|
+
promises.push(promise);
|
|
798
782
|
});
|
|
799
783
|
channel.scheduledNotes.clear();
|
|
800
784
|
return Promise.all(promises);
|
|
@@ -850,14 +834,12 @@ class MidyGM2 {
|
|
|
850
834
|
const now = this.audioContext.currentTime;
|
|
851
835
|
return this.resumeTime + now - this.startTime - this.startDelay;
|
|
852
836
|
}
|
|
853
|
-
processScheduledNotes(channel,
|
|
837
|
+
processScheduledNotes(channel, callback) {
|
|
854
838
|
channel.scheduledNotes.forEach((noteList) => {
|
|
855
839
|
for (let i = 0; i < noteList.length; i++) {
|
|
856
840
|
const note = noteList[i];
|
|
857
841
|
if (!note)
|
|
858
842
|
continue;
|
|
859
|
-
if (scheduleTime < note.startTime)
|
|
860
|
-
continue;
|
|
861
843
|
callback(note);
|
|
862
844
|
}
|
|
863
845
|
});
|
|
@@ -1038,7 +1020,7 @@ class MidyGM2 {
|
|
|
1038
1020
|
return channel.scaleOctaveTuningTable[note.noteNumber % 12];
|
|
1039
1021
|
}
|
|
1040
1022
|
updateChannelDetune(channel, scheduleTime) {
|
|
1041
|
-
this.processScheduledNotes(channel,
|
|
1023
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1042
1024
|
this.updateDetune(channel, note, scheduleTime);
|
|
1043
1025
|
});
|
|
1044
1026
|
}
|
|
@@ -1239,7 +1221,7 @@ class MidyGM2 {
|
|
|
1239
1221
|
if (0 < state.modulationDepth) {
|
|
1240
1222
|
this.startModulation(channel, note, now);
|
|
1241
1223
|
}
|
|
1242
|
-
if (
|
|
1224
|
+
if (channel.mono && channel.currentBufferSource) {
|
|
1243
1225
|
channel.currentBufferSource.stop(startTime);
|
|
1244
1226
|
channel.currentBufferSource = note.bufferSource;
|
|
1245
1227
|
}
|
|
@@ -1280,8 +1262,8 @@ class MidyGM2 {
|
|
|
1280
1262
|
const note = await this.createNote(channel, voice, noteNumber, velocity, startTime, portamento, isSF3);
|
|
1281
1263
|
note.gainL.connect(channel.gainL);
|
|
1282
1264
|
note.gainR.connect(channel.gainR);
|
|
1283
|
-
if (channel.state.
|
|
1284
|
-
channel.
|
|
1265
|
+
if (0.5 <= channel.state.sustainPedal) {
|
|
1266
|
+
channel.sustainNotes.push(note);
|
|
1285
1267
|
}
|
|
1286
1268
|
const exclusiveClass = note.voiceParams.exclusiveClass;
|
|
1287
1269
|
if (exclusiveClass !== 0) {
|
|
@@ -1350,7 +1332,7 @@ class MidyGM2 {
|
|
|
1350
1332
|
const channel = this.channels[channelNumber];
|
|
1351
1333
|
const state = channel.state;
|
|
1352
1334
|
if (!force) {
|
|
1353
|
-
if (0.5
|
|
1335
|
+
if (0.5 <= state.sustainPedal)
|
|
1354
1336
|
return;
|
|
1355
1337
|
if (channel.sostenutoNotes.has(noteNumber))
|
|
1356
1338
|
return;
|
|
@@ -1394,28 +1376,27 @@ class MidyGM2 {
|
|
|
1394
1376
|
const velocity = halfVelocity * 2;
|
|
1395
1377
|
const channel = this.channels[channelNumber];
|
|
1396
1378
|
const promises = [];
|
|
1397
|
-
|
|
1398
|
-
const
|
|
1399
|
-
const promise = this.noteOff(channelNumber, noteNumber, velocity);
|
|
1379
|
+
for (let i = 0; i < channel.sustainNotes.length; i++) {
|
|
1380
|
+
const promise = this.noteOff(channelNumber, channel.sustainNotes[i].noteNumber, velocity, scheduleTime);
|
|
1400
1381
|
promises.push(promise);
|
|
1401
|
-
}
|
|
1382
|
+
}
|
|
1383
|
+
channel.sustainNotes = [];
|
|
1402
1384
|
return promises;
|
|
1403
1385
|
}
|
|
1404
|
-
releaseSostenutoPedal(channelNumber, halfVelocity) {
|
|
1386
|
+
releaseSostenutoPedal(channelNumber, halfVelocity, scheduleTime) {
|
|
1405
1387
|
const velocity = halfVelocity * 2;
|
|
1406
1388
|
const channel = this.channels[channelNumber];
|
|
1407
1389
|
const promises = [];
|
|
1408
1390
|
channel.state.sostenutoPedal = 0;
|
|
1409
|
-
channel.sostenutoNotes.forEach((
|
|
1410
|
-
const
|
|
1411
|
-
const promise = this.noteOff(channelNumber, noteNumber, velocity);
|
|
1391
|
+
channel.sostenutoNotes.forEach((note) => {
|
|
1392
|
+
const promise = this.noteOff(channelNumber, note.noteNumber, velocity, scheduleTime);
|
|
1412
1393
|
promises.push(promise);
|
|
1413
1394
|
});
|
|
1414
1395
|
channel.sostenutoNotes.clear();
|
|
1415
1396
|
return promises;
|
|
1416
1397
|
}
|
|
1417
1398
|
handleMIDIMessage(statusByte, data1, data2, scheduleTime) {
|
|
1418
|
-
const channelNumber =
|
|
1399
|
+
const channelNumber = statusByte & 0x0F;
|
|
1419
1400
|
const messageType = statusByte & 0xF0;
|
|
1420
1401
|
switch (messageType) {
|
|
1421
1402
|
case 0x80:
|
|
@@ -1630,53 +1611,48 @@ class MidyGM2 {
|
|
|
1630
1611
|
return state;
|
|
1631
1612
|
}
|
|
1632
1613
|
applyVoiceParams(channel, controllerType, scheduleTime) {
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1614
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1615
|
+
const controllerState = this.getControllerState(channel, note.noteNumber, note.velocity);
|
|
1616
|
+
const voiceParams = note.voice.getParams(controllerType, controllerState);
|
|
1617
|
+
let appliedFilterEnvelope = false;
|
|
1618
|
+
let appliedVolumeEnvelope = false;
|
|
1619
|
+
for (const [key, value] of Object.entries(voiceParams)) {
|
|
1620
|
+
const prevValue = note.voiceParams[key];
|
|
1621
|
+
if (value === prevValue)
|
|
1637
1622
|
continue;
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
if (value === prevValue)
|
|
1623
|
+
note.voiceParams[key] = value;
|
|
1624
|
+
if (key in this.voiceParamsHandlers) {
|
|
1625
|
+
this.voiceParamsHandlers[key](channel, note, prevValue, scheduleTime);
|
|
1626
|
+
}
|
|
1627
|
+
else if (filterEnvelopeKeySet.has(key)) {
|
|
1628
|
+
if (appliedFilterEnvelope)
|
|
1645
1629
|
continue;
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1630
|
+
appliedFilterEnvelope = true;
|
|
1631
|
+
const noteVoiceParams = note.voiceParams;
|
|
1632
|
+
for (let i = 0; i < filterEnvelopeKeys.length; i++) {
|
|
1633
|
+
const key = filterEnvelopeKeys[i];
|
|
1634
|
+
if (key in voiceParams)
|
|
1635
|
+
noteVoiceParams[key] = voiceParams[key];
|
|
1649
1636
|
}
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
continue;
|
|
1653
|
-
appliedFilterEnvelope = true;
|
|
1654
|
-
const noteVoiceParams = note.voiceParams;
|
|
1655
|
-
for (let i = 0; i < filterEnvelopeKeys.length; i++) {
|
|
1656
|
-
const key = filterEnvelopeKeys[i];
|
|
1657
|
-
if (key in voiceParams)
|
|
1658
|
-
noteVoiceParams[key] = voiceParams[key];
|
|
1659
|
-
}
|
|
1660
|
-
if (note.portamento) {
|
|
1661
|
-
this.setPortamentoStartFilterEnvelope(channel, note, scheduleTime);
|
|
1662
|
-
}
|
|
1663
|
-
else {
|
|
1664
|
-
this.setFilterEnvelope(channel, note, scheduleTime);
|
|
1665
|
-
}
|
|
1666
|
-
this.setPitchEnvelope(note, scheduleTime);
|
|
1637
|
+
if (note.portamento) {
|
|
1638
|
+
this.setPortamentoStartFilterEnvelope(channel, note, scheduleTime);
|
|
1667
1639
|
}
|
|
1668
|
-
else
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1640
|
+
else {
|
|
1641
|
+
this.setFilterEnvelope(channel, note, scheduleTime);
|
|
1642
|
+
}
|
|
1643
|
+
this.setPitchEnvelope(note, scheduleTime);
|
|
1644
|
+
}
|
|
1645
|
+
else if (volumeEnvelopeKeySet.has(key)) {
|
|
1646
|
+
if (appliedVolumeEnvelope)
|
|
1647
|
+
continue;
|
|
1648
|
+
appliedVolumeEnvelope = true;
|
|
1649
|
+
const noteVoiceParams = note.voiceParams;
|
|
1650
|
+
for (let i = 0; i < volumeEnvelopeKeys.length; i++) {
|
|
1651
|
+
const key = volumeEnvelopeKeys[i];
|
|
1652
|
+
if (key in voiceParams)
|
|
1653
|
+
noteVoiceParams[key] = voiceParams[key];
|
|
1679
1654
|
}
|
|
1655
|
+
this.setVolumeEnvelope(channel, note, scheduleTime);
|
|
1680
1656
|
}
|
|
1681
1657
|
}
|
|
1682
1658
|
});
|
|
@@ -1725,9 +1701,8 @@ class MidyGM2 {
|
|
|
1725
1701
|
this.channels[channelNumber].bankMSB = msb;
|
|
1726
1702
|
}
|
|
1727
1703
|
updateModulation(channel, scheduleTime) {
|
|
1728
|
-
scheduleTime ??= this.audioContext.currentTime;
|
|
1729
1704
|
const depth = channel.state.modulationDepth * channel.modulationDepthRange;
|
|
1730
|
-
this.processScheduledNotes(channel,
|
|
1705
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1731
1706
|
if (note.modulationDepth) {
|
|
1732
1707
|
note.modulationDepth.gain.setValueAtTime(depth, scheduleTime);
|
|
1733
1708
|
}
|
|
@@ -1738,6 +1713,7 @@ class MidyGM2 {
|
|
|
1738
1713
|
});
|
|
1739
1714
|
}
|
|
1740
1715
|
setModulationDepth(channelNumber, modulation, scheduleTime) {
|
|
1716
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1741
1717
|
const channel = this.channels[channelNumber];
|
|
1742
1718
|
channel.state.modulationDepth = modulation / 127;
|
|
1743
1719
|
this.updateModulation(channel, scheduleTime);
|
|
@@ -1748,8 +1724,7 @@ class MidyGM2 {
|
|
|
1748
1724
|
channel.state.portamentoTime = Math.exp(factor * portamentoTime);
|
|
1749
1725
|
}
|
|
1750
1726
|
setKeyBasedVolume(channel, scheduleTime) {
|
|
1751
|
-
|
|
1752
|
-
this.processScheduledNotes(channel, scheduleTime, (note) => {
|
|
1727
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1753
1728
|
const keyBasedValue = this.getKeyBasedInstrumentControlValue(channel, note.noteNumber, 7);
|
|
1754
1729
|
if (keyBasedValue !== 0) {
|
|
1755
1730
|
note.volumeNode.gain
|
|
@@ -1759,6 +1734,7 @@ class MidyGM2 {
|
|
|
1759
1734
|
});
|
|
1760
1735
|
}
|
|
1761
1736
|
setVolume(channelNumber, volume, scheduleTime) {
|
|
1737
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1762
1738
|
const channel = this.channels[channelNumber];
|
|
1763
1739
|
channel.state.volume = volume / 127;
|
|
1764
1740
|
this.updateChannelVolume(channel, scheduleTime);
|
|
@@ -1772,8 +1748,7 @@ class MidyGM2 {
|
|
|
1772
1748
|
};
|
|
1773
1749
|
}
|
|
1774
1750
|
setKeyBasedPan(channel, scheduleTime) {
|
|
1775
|
-
|
|
1776
|
-
this.processScheduledNotes(channel, scheduleTime, (note) => {
|
|
1751
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1777
1752
|
const keyBasedValue = this.getKeyBasedInstrumentControlValue(channel, note.noteNumber, 10);
|
|
1778
1753
|
if (keyBasedValue !== 0) {
|
|
1779
1754
|
const { gainLeft, gainRight } = this.panToGain((keyBasedValue + 1) / 2);
|
|
@@ -1787,12 +1762,14 @@ class MidyGM2 {
|
|
|
1787
1762
|
});
|
|
1788
1763
|
}
|
|
1789
1764
|
setPan(channelNumber, pan, scheduleTime) {
|
|
1765
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1790
1766
|
const channel = this.channels[channelNumber];
|
|
1791
1767
|
channel.state.pan = pan / 127;
|
|
1792
1768
|
this.updateChannelVolume(channel, scheduleTime);
|
|
1793
1769
|
this.setKeyBasedPan(channel, scheduleTime);
|
|
1794
1770
|
}
|
|
1795
1771
|
setExpression(channelNumber, expression, scheduleTime) {
|
|
1772
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1796
1773
|
const channel = this.channels[channelNumber];
|
|
1797
1774
|
channel.state.expression = expression / 127;
|
|
1798
1775
|
this.updateChannelVolume(channel, scheduleTime);
|
|
@@ -1817,8 +1794,14 @@ class MidyGM2 {
|
|
|
1817
1794
|
}
|
|
1818
1795
|
setSustainPedal(channelNumber, value, scheduleTime) {
|
|
1819
1796
|
scheduleTime ??= this.audioContext.currentTime;
|
|
1820
|
-
this.channels[channelNumber]
|
|
1821
|
-
|
|
1797
|
+
const channel = this.channels[channelNumber];
|
|
1798
|
+
channel.state.sustainPedal = value / 127;
|
|
1799
|
+
if (64 <= value) {
|
|
1800
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1801
|
+
channel.sustainNotes.push(note);
|
|
1802
|
+
});
|
|
1803
|
+
}
|
|
1804
|
+
else {
|
|
1822
1805
|
this.releaseSustainPedal(channelNumber, value, scheduleTime);
|
|
1823
1806
|
}
|
|
1824
1807
|
}
|
|
@@ -1826,13 +1809,14 @@ class MidyGM2 {
|
|
|
1826
1809
|
this.channels[channelNumber].state.portamento = value / 127;
|
|
1827
1810
|
}
|
|
1828
1811
|
setSostenutoPedal(channelNumber, value, scheduleTime) {
|
|
1812
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1829
1813
|
const channel = this.channels[channelNumber];
|
|
1830
1814
|
channel.state.sostenutoPedal = value / 127;
|
|
1831
1815
|
if (64 <= value) {
|
|
1832
1816
|
channel.sostenutoNotes = this.getActiveNotes(channel, scheduleTime);
|
|
1833
1817
|
}
|
|
1834
1818
|
else {
|
|
1835
|
-
this.releaseSostenutoPedal(channelNumber, value);
|
|
1819
|
+
this.releaseSostenutoPedal(channelNumber, value, scheduleTime);
|
|
1836
1820
|
}
|
|
1837
1821
|
}
|
|
1838
1822
|
setSoftPedal(channelNumber, softPedal, _scheduleTime) {
|
|
@@ -1840,6 +1824,7 @@ class MidyGM2 {
|
|
|
1840
1824
|
channel.state.softPedal = softPedal / 127;
|
|
1841
1825
|
}
|
|
1842
1826
|
setReverbSendLevel(channelNumber, reverbSendLevel, scheduleTime) {
|
|
1827
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1843
1828
|
const channel = this.channels[channelNumber];
|
|
1844
1829
|
const state = channel.state;
|
|
1845
1830
|
const reverbEffect = this.reverbEffect;
|
|
@@ -1851,27 +1836,17 @@ class MidyGM2 {
|
|
|
1851
1836
|
.setValueAtTime(state.reverbSendLevel, scheduleTime);
|
|
1852
1837
|
}
|
|
1853
1838
|
else {
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
continue;
|
|
1859
|
-
if (note.voiceParams.reverbEffectsSend <= 0)
|
|
1860
|
-
continue;
|
|
1861
|
-
note.reverbEffectsSend.disconnect();
|
|
1862
|
-
}
|
|
1839
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1840
|
+
if (note.voiceParams.reverbEffectsSend <= 0)
|
|
1841
|
+
return false;
|
|
1842
|
+
note.reverbEffectsSend.disconnect();
|
|
1863
1843
|
});
|
|
1864
1844
|
}
|
|
1865
1845
|
}
|
|
1866
1846
|
else {
|
|
1867
1847
|
if (0 < reverbSendLevel) {
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
const note = noteList[i];
|
|
1871
|
-
if (!note)
|
|
1872
|
-
continue;
|
|
1873
|
-
this.setReverbEffectsSend(channel, note, 0, scheduleTime);
|
|
1874
|
-
}
|
|
1848
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1849
|
+
this.setReverbEffectsSend(channel, note, 0, scheduleTime);
|
|
1875
1850
|
});
|
|
1876
1851
|
state.reverbSendLevel = reverbSendLevel / 127;
|
|
1877
1852
|
reverbEffect.input.gain
|
|
@@ -1881,6 +1856,7 @@ class MidyGM2 {
|
|
|
1881
1856
|
}
|
|
1882
1857
|
}
|
|
1883
1858
|
setChorusSendLevel(channelNumber, chorusSendLevel, scheduleTime) {
|
|
1859
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1884
1860
|
const channel = this.channels[channelNumber];
|
|
1885
1861
|
const state = channel.state;
|
|
1886
1862
|
const chorusEffect = this.chorusEffect;
|
|
@@ -1892,27 +1868,17 @@ class MidyGM2 {
|
|
|
1892
1868
|
.setValueAtTime(state.chorusSendLevel, scheduleTime);
|
|
1893
1869
|
}
|
|
1894
1870
|
else {
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
continue;
|
|
1900
|
-
if (note.voiceParams.chorusEffectsSend <= 0)
|
|
1901
|
-
continue;
|
|
1902
|
-
note.chorusEffectsSend.disconnect();
|
|
1903
|
-
}
|
|
1871
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1872
|
+
if (note.voiceParams.chorusEffectsSend <= 0)
|
|
1873
|
+
return false;
|
|
1874
|
+
note.chorusEffectsSend.disconnect();
|
|
1904
1875
|
});
|
|
1905
1876
|
}
|
|
1906
1877
|
}
|
|
1907
1878
|
else {
|
|
1908
1879
|
if (0 < chorusSendLevel) {
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
const note = noteList[i];
|
|
1912
|
-
if (!note)
|
|
1913
|
-
continue;
|
|
1914
|
-
this.setChorusEffectsSend(channel, note, 0, scheduleTime);
|
|
1915
|
-
}
|
|
1880
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1881
|
+
this.setChorusEffectsSend(channel, note, 0, scheduleTime);
|
|
1916
1882
|
});
|
|
1917
1883
|
state.chorusSendLevel = chorusSendLevel / 127;
|
|
1918
1884
|
chorusEffect.input.gain
|
|
@@ -1955,13 +1921,13 @@ class MidyGM2 {
|
|
|
1955
1921
|
this.handlePitchBendRangeRPN(channelNumber, scheduleTime);
|
|
1956
1922
|
break;
|
|
1957
1923
|
case 1:
|
|
1958
|
-
this.handleFineTuningRPN(channelNumber);
|
|
1924
|
+
this.handleFineTuningRPN(channelNumber, scheduleTime);
|
|
1959
1925
|
break;
|
|
1960
1926
|
case 2:
|
|
1961
|
-
this.handleCoarseTuningRPN(channelNumber);
|
|
1927
|
+
this.handleCoarseTuningRPN(channelNumber, scheduleTime);
|
|
1962
1928
|
break;
|
|
1963
1929
|
case 5:
|
|
1964
|
-
this.handleModulationDepthRangeRPN(channelNumber);
|
|
1930
|
+
this.handleModulationDepthRangeRPN(channelNumber, scheduleTime);
|
|
1965
1931
|
break;
|
|
1966
1932
|
default:
|
|
1967
1933
|
console.warn(`Channel ${channelNumber}: Unsupported RPN MSB=${channel.rpnMSB} LSB=${channel.rpnLSB}`);
|
|
@@ -1994,44 +1960,47 @@ class MidyGM2 {
|
|
|
1994
1960
|
this.updateChannelDetune(channel, scheduleTime);
|
|
1995
1961
|
this.applyVoiceParams(channel, 16, scheduleTime);
|
|
1996
1962
|
}
|
|
1997
|
-
handleFineTuningRPN(channelNumber) {
|
|
1963
|
+
handleFineTuningRPN(channelNumber, scheduleTime) {
|
|
1998
1964
|
const channel = this.channels[channelNumber];
|
|
1999
1965
|
this.limitData(channel, 0, 127, 0, 127);
|
|
2000
1966
|
const fineTuning = channel.dataMSB * 128 + channel.dataLSB;
|
|
2001
|
-
this.setFineTuning(channelNumber, fineTuning);
|
|
1967
|
+
this.setFineTuning(channelNumber, fineTuning, scheduleTime);
|
|
2002
1968
|
}
|
|
2003
|
-
setFineTuning(channelNumber, value) {
|
|
1969
|
+
setFineTuning(channelNumber, value, scheduleTime) {
|
|
1970
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
2004
1971
|
const channel = this.channels[channelNumber];
|
|
2005
1972
|
const prev = channel.fineTuning;
|
|
2006
1973
|
const next = (value - 8192) / 8.192; // cent
|
|
2007
1974
|
channel.fineTuning = next;
|
|
2008
1975
|
channel.detune += next - prev;
|
|
2009
|
-
this.updateChannelDetune(channel);
|
|
1976
|
+
this.updateChannelDetune(channel, scheduleTime);
|
|
2010
1977
|
}
|
|
2011
|
-
handleCoarseTuningRPN(channelNumber) {
|
|
1978
|
+
handleCoarseTuningRPN(channelNumber, scheduleTime) {
|
|
2012
1979
|
const channel = this.channels[channelNumber];
|
|
2013
1980
|
this.limitDataMSB(channel, 0, 127);
|
|
2014
1981
|
const coarseTuning = channel.dataMSB;
|
|
2015
|
-
this.setCoarseTuning(channelNumber, coarseTuning);
|
|
1982
|
+
this.setCoarseTuning(channelNumber, coarseTuning, scheduleTime);
|
|
2016
1983
|
}
|
|
2017
|
-
setCoarseTuning(channelNumber, value) {
|
|
1984
|
+
setCoarseTuning(channelNumber, value, scheduleTime) {
|
|
1985
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
2018
1986
|
const channel = this.channels[channelNumber];
|
|
2019
1987
|
const prev = channel.coarseTuning;
|
|
2020
1988
|
const next = (value - 64) * 100; // cent
|
|
2021
1989
|
channel.coarseTuning = next;
|
|
2022
1990
|
channel.detune += next - prev;
|
|
2023
|
-
this.updateChannelDetune(channel);
|
|
1991
|
+
this.updateChannelDetune(channel, scheduleTime);
|
|
2024
1992
|
}
|
|
2025
|
-
handleModulationDepthRangeRPN(channelNumber) {
|
|
1993
|
+
handleModulationDepthRangeRPN(channelNumber, scheduleTime) {
|
|
2026
1994
|
const channel = this.channels[channelNumber];
|
|
2027
1995
|
this.limitData(channel, 0, 127, 0, 127);
|
|
2028
1996
|
const modulationDepthRange = (dataMSB + dataLSB / 128) * 100;
|
|
2029
|
-
this.setModulationDepthRange(channelNumber, modulationDepthRange);
|
|
1997
|
+
this.setModulationDepthRange(channelNumber, modulationDepthRange, scheduleTime);
|
|
2030
1998
|
}
|
|
2031
|
-
setModulationDepthRange(channelNumber, modulationDepthRange) {
|
|
1999
|
+
setModulationDepthRange(channelNumber, modulationDepthRange, scheduleTime) {
|
|
2000
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
2032
2001
|
const channel = this.channels[channelNumber];
|
|
2033
2002
|
channel.modulationDepthRange = modulationDepthRange;
|
|
2034
|
-
this.updateModulation(channel);
|
|
2003
|
+
this.updateModulation(channel, scheduleTime);
|
|
2035
2004
|
}
|
|
2036
2005
|
allSoundOff(channelNumber, _value, scheduleTime) {
|
|
2037
2006
|
scheduleTime ??= this.audioContext.currentTime;
|
|
@@ -2067,17 +2036,21 @@ class MidyGM2 {
|
|
|
2067
2036
|
scheduleTime ??= this.audioContext.currentTime;
|
|
2068
2037
|
return this.stopChannelNotes(channelNumber, 0, false, scheduleTime);
|
|
2069
2038
|
}
|
|
2070
|
-
omniOff() {
|
|
2071
|
-
this.
|
|
2039
|
+
omniOff(channelNumber, value, scheduleTime) {
|
|
2040
|
+
this.allNotesOff(channelNumber, value, scheduleTime);
|
|
2072
2041
|
}
|
|
2073
|
-
omniOn() {
|
|
2074
|
-
this.
|
|
2042
|
+
omniOn(channelNumber, value, scheduleTime) {
|
|
2043
|
+
this.allNotesOff(channelNumber, value, scheduleTime);
|
|
2075
2044
|
}
|
|
2076
|
-
monoOn() {
|
|
2077
|
-
|
|
2045
|
+
monoOn(channelNumber, value, scheduleTime) {
|
|
2046
|
+
const channel = this.channels[channelNumber];
|
|
2047
|
+
this.allNotesOff(channelNumber, value, scheduleTime);
|
|
2048
|
+
channel.mono = true;
|
|
2078
2049
|
}
|
|
2079
|
-
polyOn() {
|
|
2080
|
-
|
|
2050
|
+
polyOn(channelNumber, value, scheduleTime) {
|
|
2051
|
+
const channel = this.channels[channelNumber];
|
|
2052
|
+
this.allNotesOff(channelNumber, value, scheduleTime);
|
|
2053
|
+
channel.mono = false;
|
|
2081
2054
|
}
|
|
2082
2055
|
handleUniversalNonRealTimeExclusiveMessage(data, scheduleTime) {
|
|
2083
2056
|
switch (data[2]) {
|
|
@@ -2486,13 +2459,8 @@ class MidyGM2 {
|
|
|
2486
2459
|
const slotSize = 6;
|
|
2487
2460
|
const offset = controllerType * slotSize;
|
|
2488
2461
|
const table = channel.controlTable.subarray(offset, offset + slotSize);
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
const note = noteList[i];
|
|
2492
|
-
if (!note)
|
|
2493
|
-
continue;
|
|
2494
|
-
this.setControllerParameters(channel, note, table);
|
|
2495
|
-
}
|
|
2462
|
+
this.processScheduledNotes(channel, (note) => {
|
|
2463
|
+
this.setControllerParameters(channel, note, table);
|
|
2496
2464
|
});
|
|
2497
2465
|
}
|
|
2498
2466
|
handleControlChangeSysEx(data) {
|
|
@@ -2560,6 +2528,7 @@ Object.defineProperty(MidyGM2, "channelSettings", {
|
|
|
2560
2528
|
dataLSB: 0,
|
|
2561
2529
|
rpnMSB: 127,
|
|
2562
2530
|
rpnLSB: 127,
|
|
2531
|
+
mono: false, // CC#124, CC#125
|
|
2563
2532
|
fineTuning: 0, // cb
|
|
2564
2533
|
coarseTuning: 0, // cb
|
|
2565
2534
|
modulationDepthRange: 50, // cent
|
package/script/midy-GMLite.d.ts
CHANGED
|
@@ -90,7 +90,7 @@ export class MidyGMLite {
|
|
|
90
90
|
seekTo(second: any): void;
|
|
91
91
|
calcTotalTime(): number;
|
|
92
92
|
currentTime(): number;
|
|
93
|
-
processScheduledNotes(channel: any,
|
|
93
|
+
processScheduledNotes(channel: any, callback: any): void;
|
|
94
94
|
getActiveNotes(channel: any, scheduleTime: any): SparseMap;
|
|
95
95
|
getActiveNote(noteList: any, scheduleTime: any): any;
|
|
96
96
|
cbToRatio(cb: any): number;
|
|
@@ -112,7 +112,7 @@ export class MidyGMLite {
|
|
|
112
112
|
stopNote(endTime: any, stopTime: any, scheduledNotes: any, index: any): Promise<any>;
|
|
113
113
|
scheduleNoteOff(channelNumber: any, noteNumber: any, _velocity: any, endTime: any, force: any): Promise<any> | undefined;
|
|
114
114
|
noteOff(channelNumber: any, noteNumber: any, velocity: any, scheduleTime: any): Promise<any> | undefined;
|
|
115
|
-
releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): any[];
|
|
115
|
+
releaseSustainPedal(channelNumber: any, halfVelocity: any, scheduleTime: any): (Promise<any> | undefined)[];
|
|
116
116
|
handleMIDIMessage(statusByte: any, data1: any, data2: any, scheduleTime: any): void | Promise<any>;
|
|
117
117
|
handleProgramChange(channelNumber: any, program: any, _scheduleTime: any): void;
|
|
118
118
|
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any, scheduleTime: any): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAiJA;IAsBE;;;;;;;;;MASE;IAEF,+BAQC;IAxCD,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,kCAA+B;IAC/B,gCAA6B;IAC7B,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IAClB,6BAAuC;IAcrC,kBAAgC;IAChC,kBAA8C;IAC9C;;;;;;;;;;;MAA2D;IAC3D;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IAKnD,4BAMC;IAED,mCAWC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,
|
|
1
|
+
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAiJA;IAsBE;;;;;;;;;MASE;IAEF,+BAQC;IAxCD,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,kCAA+B;IAC/B,gCAA6B;IAC7B,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IAClB,6BAAuC;IAcrC,kBAAgC;IAChC,kBAA8C;IAC9C;;;;;;;;;;;MAA2D;IAC3D;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IAKnD,4BAMC;IAED,mCAWC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAWC;IAED,6DA2BC;IAED,8DASC;IAED,2EAsDC;IAED,mCAOC;IAED,0BAoDC;IAED,uDAEC;IAED,wDAEC;IAED,6EAEC;IAED;;;MA4EC;IAED,mGAgBC;IAED,wEAMC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,yDAQC;IAED,2DASC;IAED,qDAQC;IAED,2BAEC;IAED,8BAEC;IAED,8BAEC;IAED,4BAEC;IAED,wCAIC;IAED,2DAIC;IAED,+DAIC;IAED,sDAeC;IAED,qDAoBC;IAED,6CAIC;IAED,sDAsBC;IAED,kEAoBC;IAED,yGAgBC;IAED,gHAwCC;IAED,kGAkDC;IAED,6FAQC;IAED,qFAwBC;IAED,yHAuBC;IAED,yGASC;IAED,4GAeC;IAED,mGA2BC;IAED,gFAGC;IAED,wFAGC;IAED,sEAUC;IAED,mEAQC;IAED,wDAKC;IAED,sDAOC;IAED,mDAMC;IAED,kDAKC;IAED;;;;;;;;;;;MA2BC;IAED,oFAMC;IAED,6EA2CC;IAED;;;;;;;;;;;;;MAeC;IAED,kGAWC;IAED,wDAWC;IAED,iFAKC;IAED,oEAKC;IAED;;;MAMC;IAED,8DAKC;IAED,4EAKC;IAED,sEAGC;IAED,2DAUC;IAED,yEAWC;IAED,kFAeC;IAED,uDAYC;IAED,gDAEC;IAED,gDAEC;IAED,sEAGC;IAED,qEAKC;IAED,2EAUC;IAED,gFAGC;IAED,8CAqBC;IAED,gFAGC;IAED,gFAgBC;IAED,oBAMC;IAED,4EAaC;IAED,4DAGC;IAED,sDASC;IAED,gDAYC;IAED,6DAUC;CACF;AAj3CD;IACE,uBAGC;IAFC,YAA2B;IAC3B,qBAAuB;IAGzB,gCAKC;IAED,mBAEC;IAED,0BAUC;IAED,uBAEC;IAED,mBAEC;IAED,cAMC;IASD,6BAKC;IAZD,qDAKC;CAQF;AAED;IASE,0FAMC;IAdD,kBAAa;IACb,gBAAW;IACX,iBAAY;IACZ,wBAAmB;IACnB,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,WAAkB;IAClB,iBAA8B;CAEjC"}
|