@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/esm/midy-GM2.js
CHANGED
|
@@ -284,18 +284,6 @@ export class MidyGM2 {
|
|
|
284
284
|
delayTimes: this.generateDistributedArray(0.02, 2, 0.5),
|
|
285
285
|
}
|
|
286
286
|
});
|
|
287
|
-
Object.defineProperty(this, "mono", {
|
|
288
|
-
enumerable: true,
|
|
289
|
-
configurable: true,
|
|
290
|
-
writable: true,
|
|
291
|
-
value: false
|
|
292
|
-
}); // CC#124, CC#125
|
|
293
|
-
Object.defineProperty(this, "omni", {
|
|
294
|
-
enumerable: true,
|
|
295
|
-
configurable: true,
|
|
296
|
-
writable: true,
|
|
297
|
-
value: false
|
|
298
|
-
}); // CC#126, CC#127
|
|
299
287
|
Object.defineProperty(this, "noteCheckInterval", {
|
|
300
288
|
enumerable: true,
|
|
301
289
|
configurable: true,
|
|
@@ -497,6 +485,7 @@ export class MidyGM2 {
|
|
|
497
485
|
controlTable: this.initControlTable(),
|
|
498
486
|
...this.setChannelAudioNodes(audioContext),
|
|
499
487
|
scheduledNotes: new SparseMap(128),
|
|
488
|
+
sustainNotes: [],
|
|
500
489
|
sostenutoNotes: new SparseMap(128),
|
|
501
490
|
scaleOctaveTuningTable: new Int8Array(12), // [-64, 63] cent
|
|
502
491
|
channelPressureTable: new Uint8Array([64, 64, 64, 0, 0, 0]),
|
|
@@ -579,7 +568,7 @@ export class MidyGM2 {
|
|
|
579
568
|
const portamentoTarget = this.findPortamentoTarget(queueIndex);
|
|
580
569
|
if (portamentoTarget)
|
|
581
570
|
portamentoTarget.portamento = true;
|
|
582
|
-
const notePromise = this.scheduleNoteOff(
|
|
571
|
+
const notePromise = this.scheduleNoteOff(event.channel, event.noteNumber, event.velocity, startTime, false, // force
|
|
583
572
|
portamentoTarget?.noteNumber);
|
|
584
573
|
if (notePromise) {
|
|
585
574
|
this.notePromises.push(notePromise);
|
|
@@ -587,7 +576,7 @@ export class MidyGM2 {
|
|
|
587
576
|
break;
|
|
588
577
|
}
|
|
589
578
|
case "controller":
|
|
590
|
-
this.handleControlChange(
|
|
579
|
+
this.handleControlChange(event.channel, event.controllerType, event.value, startTime);
|
|
591
580
|
break;
|
|
592
581
|
case "programChange":
|
|
593
582
|
this.handleProgramChange(event.channel, event.programNumber, startTime);
|
|
@@ -783,15 +772,10 @@ export class MidyGM2 {
|
|
|
783
772
|
stopChannelNotes(channelNumber, velocity, force, scheduleTime) {
|
|
784
773
|
const channel = this.channels[channelNumber];
|
|
785
774
|
const promises = [];
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
continue;
|
|
791
|
-
const promise = this.scheduleNoteOff(channelNumber, note.noteNumber, velocity, scheduleTime, force, undefined);
|
|
792
|
-
this.notePromises.push(promise);
|
|
793
|
-
promises.push(promise);
|
|
794
|
-
}
|
|
775
|
+
this.processScheduledNotes(channel, (note) => {
|
|
776
|
+
const promise = this.scheduleNoteOff(channelNumber, note.noteNumber, velocity, scheduleTime, force, undefined);
|
|
777
|
+
this.notePromises.push(promise);
|
|
778
|
+
promises.push(promise);
|
|
795
779
|
});
|
|
796
780
|
channel.scheduledNotes.clear();
|
|
797
781
|
return Promise.all(promises);
|
|
@@ -847,14 +831,12 @@ export class MidyGM2 {
|
|
|
847
831
|
const now = this.audioContext.currentTime;
|
|
848
832
|
return this.resumeTime + now - this.startTime - this.startDelay;
|
|
849
833
|
}
|
|
850
|
-
processScheduledNotes(channel,
|
|
834
|
+
processScheduledNotes(channel, callback) {
|
|
851
835
|
channel.scheduledNotes.forEach((noteList) => {
|
|
852
836
|
for (let i = 0; i < noteList.length; i++) {
|
|
853
837
|
const note = noteList[i];
|
|
854
838
|
if (!note)
|
|
855
839
|
continue;
|
|
856
|
-
if (scheduleTime < note.startTime)
|
|
857
|
-
continue;
|
|
858
840
|
callback(note);
|
|
859
841
|
}
|
|
860
842
|
});
|
|
@@ -1035,7 +1017,7 @@ export class MidyGM2 {
|
|
|
1035
1017
|
return channel.scaleOctaveTuningTable[note.noteNumber % 12];
|
|
1036
1018
|
}
|
|
1037
1019
|
updateChannelDetune(channel, scheduleTime) {
|
|
1038
|
-
this.processScheduledNotes(channel,
|
|
1020
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1039
1021
|
this.updateDetune(channel, note, scheduleTime);
|
|
1040
1022
|
});
|
|
1041
1023
|
}
|
|
@@ -1236,7 +1218,7 @@ export class MidyGM2 {
|
|
|
1236
1218
|
if (0 < state.modulationDepth) {
|
|
1237
1219
|
this.startModulation(channel, note, now);
|
|
1238
1220
|
}
|
|
1239
|
-
if (
|
|
1221
|
+
if (channel.mono && channel.currentBufferSource) {
|
|
1240
1222
|
channel.currentBufferSource.stop(startTime);
|
|
1241
1223
|
channel.currentBufferSource = note.bufferSource;
|
|
1242
1224
|
}
|
|
@@ -1277,8 +1259,8 @@ export class MidyGM2 {
|
|
|
1277
1259
|
const note = await this.createNote(channel, voice, noteNumber, velocity, startTime, portamento, isSF3);
|
|
1278
1260
|
note.gainL.connect(channel.gainL);
|
|
1279
1261
|
note.gainR.connect(channel.gainR);
|
|
1280
|
-
if (channel.state.
|
|
1281
|
-
channel.
|
|
1262
|
+
if (0.5 <= channel.state.sustainPedal) {
|
|
1263
|
+
channel.sustainNotes.push(note);
|
|
1282
1264
|
}
|
|
1283
1265
|
const exclusiveClass = note.voiceParams.exclusiveClass;
|
|
1284
1266
|
if (exclusiveClass !== 0) {
|
|
@@ -1347,7 +1329,7 @@ export class MidyGM2 {
|
|
|
1347
1329
|
const channel = this.channels[channelNumber];
|
|
1348
1330
|
const state = channel.state;
|
|
1349
1331
|
if (!force) {
|
|
1350
|
-
if (0.5
|
|
1332
|
+
if (0.5 <= state.sustainPedal)
|
|
1351
1333
|
return;
|
|
1352
1334
|
if (channel.sostenutoNotes.has(noteNumber))
|
|
1353
1335
|
return;
|
|
@@ -1391,28 +1373,27 @@ export class MidyGM2 {
|
|
|
1391
1373
|
const velocity = halfVelocity * 2;
|
|
1392
1374
|
const channel = this.channels[channelNumber];
|
|
1393
1375
|
const promises = [];
|
|
1394
|
-
|
|
1395
|
-
const
|
|
1396
|
-
const promise = this.noteOff(channelNumber, noteNumber, velocity);
|
|
1376
|
+
for (let i = 0; i < channel.sustainNotes.length; i++) {
|
|
1377
|
+
const promise = this.noteOff(channelNumber, channel.sustainNotes[i].noteNumber, velocity, scheduleTime);
|
|
1397
1378
|
promises.push(promise);
|
|
1398
|
-
}
|
|
1379
|
+
}
|
|
1380
|
+
channel.sustainNotes = [];
|
|
1399
1381
|
return promises;
|
|
1400
1382
|
}
|
|
1401
|
-
releaseSostenutoPedal(channelNumber, halfVelocity) {
|
|
1383
|
+
releaseSostenutoPedal(channelNumber, halfVelocity, scheduleTime) {
|
|
1402
1384
|
const velocity = halfVelocity * 2;
|
|
1403
1385
|
const channel = this.channels[channelNumber];
|
|
1404
1386
|
const promises = [];
|
|
1405
1387
|
channel.state.sostenutoPedal = 0;
|
|
1406
|
-
channel.sostenutoNotes.forEach((
|
|
1407
|
-
const
|
|
1408
|
-
const promise = this.noteOff(channelNumber, noteNumber, velocity);
|
|
1388
|
+
channel.sostenutoNotes.forEach((note) => {
|
|
1389
|
+
const promise = this.noteOff(channelNumber, note.noteNumber, velocity, scheduleTime);
|
|
1409
1390
|
promises.push(promise);
|
|
1410
1391
|
});
|
|
1411
1392
|
channel.sostenutoNotes.clear();
|
|
1412
1393
|
return promises;
|
|
1413
1394
|
}
|
|
1414
1395
|
handleMIDIMessage(statusByte, data1, data2, scheduleTime) {
|
|
1415
|
-
const channelNumber =
|
|
1396
|
+
const channelNumber = statusByte & 0x0F;
|
|
1416
1397
|
const messageType = statusByte & 0xF0;
|
|
1417
1398
|
switch (messageType) {
|
|
1418
1399
|
case 0x80:
|
|
@@ -1627,53 +1608,48 @@ export class MidyGM2 {
|
|
|
1627
1608
|
return state;
|
|
1628
1609
|
}
|
|
1629
1610
|
applyVoiceParams(channel, controllerType, scheduleTime) {
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1611
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1612
|
+
const controllerState = this.getControllerState(channel, note.noteNumber, note.velocity);
|
|
1613
|
+
const voiceParams = note.voice.getParams(controllerType, controllerState);
|
|
1614
|
+
let appliedFilterEnvelope = false;
|
|
1615
|
+
let appliedVolumeEnvelope = false;
|
|
1616
|
+
for (const [key, value] of Object.entries(voiceParams)) {
|
|
1617
|
+
const prevValue = note.voiceParams[key];
|
|
1618
|
+
if (value === prevValue)
|
|
1634
1619
|
continue;
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
if (value === prevValue)
|
|
1620
|
+
note.voiceParams[key] = value;
|
|
1621
|
+
if (key in this.voiceParamsHandlers) {
|
|
1622
|
+
this.voiceParamsHandlers[key](channel, note, prevValue, scheduleTime);
|
|
1623
|
+
}
|
|
1624
|
+
else if (filterEnvelopeKeySet.has(key)) {
|
|
1625
|
+
if (appliedFilterEnvelope)
|
|
1642
1626
|
continue;
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1627
|
+
appliedFilterEnvelope = true;
|
|
1628
|
+
const noteVoiceParams = note.voiceParams;
|
|
1629
|
+
for (let i = 0; i < filterEnvelopeKeys.length; i++) {
|
|
1630
|
+
const key = filterEnvelopeKeys[i];
|
|
1631
|
+
if (key in voiceParams)
|
|
1632
|
+
noteVoiceParams[key] = voiceParams[key];
|
|
1646
1633
|
}
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
continue;
|
|
1650
|
-
appliedFilterEnvelope = true;
|
|
1651
|
-
const noteVoiceParams = note.voiceParams;
|
|
1652
|
-
for (let i = 0; i < filterEnvelopeKeys.length; i++) {
|
|
1653
|
-
const key = filterEnvelopeKeys[i];
|
|
1654
|
-
if (key in voiceParams)
|
|
1655
|
-
noteVoiceParams[key] = voiceParams[key];
|
|
1656
|
-
}
|
|
1657
|
-
if (note.portamento) {
|
|
1658
|
-
this.setPortamentoStartFilterEnvelope(channel, note, scheduleTime);
|
|
1659
|
-
}
|
|
1660
|
-
else {
|
|
1661
|
-
this.setFilterEnvelope(channel, note, scheduleTime);
|
|
1662
|
-
}
|
|
1663
|
-
this.setPitchEnvelope(note, scheduleTime);
|
|
1634
|
+
if (note.portamento) {
|
|
1635
|
+
this.setPortamentoStartFilterEnvelope(channel, note, scheduleTime);
|
|
1664
1636
|
}
|
|
1665
|
-
else
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1637
|
+
else {
|
|
1638
|
+
this.setFilterEnvelope(channel, note, scheduleTime);
|
|
1639
|
+
}
|
|
1640
|
+
this.setPitchEnvelope(note, scheduleTime);
|
|
1641
|
+
}
|
|
1642
|
+
else if (volumeEnvelopeKeySet.has(key)) {
|
|
1643
|
+
if (appliedVolumeEnvelope)
|
|
1644
|
+
continue;
|
|
1645
|
+
appliedVolumeEnvelope = true;
|
|
1646
|
+
const noteVoiceParams = note.voiceParams;
|
|
1647
|
+
for (let i = 0; i < volumeEnvelopeKeys.length; i++) {
|
|
1648
|
+
const key = volumeEnvelopeKeys[i];
|
|
1649
|
+
if (key in voiceParams)
|
|
1650
|
+
noteVoiceParams[key] = voiceParams[key];
|
|
1676
1651
|
}
|
|
1652
|
+
this.setVolumeEnvelope(channel, note, scheduleTime);
|
|
1677
1653
|
}
|
|
1678
1654
|
}
|
|
1679
1655
|
});
|
|
@@ -1722,9 +1698,8 @@ export class MidyGM2 {
|
|
|
1722
1698
|
this.channels[channelNumber].bankMSB = msb;
|
|
1723
1699
|
}
|
|
1724
1700
|
updateModulation(channel, scheduleTime) {
|
|
1725
|
-
scheduleTime ??= this.audioContext.currentTime;
|
|
1726
1701
|
const depth = channel.state.modulationDepth * channel.modulationDepthRange;
|
|
1727
|
-
this.processScheduledNotes(channel,
|
|
1702
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1728
1703
|
if (note.modulationDepth) {
|
|
1729
1704
|
note.modulationDepth.gain.setValueAtTime(depth, scheduleTime);
|
|
1730
1705
|
}
|
|
@@ -1735,6 +1710,7 @@ export class MidyGM2 {
|
|
|
1735
1710
|
});
|
|
1736
1711
|
}
|
|
1737
1712
|
setModulationDepth(channelNumber, modulation, scheduleTime) {
|
|
1713
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1738
1714
|
const channel = this.channels[channelNumber];
|
|
1739
1715
|
channel.state.modulationDepth = modulation / 127;
|
|
1740
1716
|
this.updateModulation(channel, scheduleTime);
|
|
@@ -1745,8 +1721,7 @@ export class MidyGM2 {
|
|
|
1745
1721
|
channel.state.portamentoTime = Math.exp(factor * portamentoTime);
|
|
1746
1722
|
}
|
|
1747
1723
|
setKeyBasedVolume(channel, scheduleTime) {
|
|
1748
|
-
|
|
1749
|
-
this.processScheduledNotes(channel, scheduleTime, (note) => {
|
|
1724
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1750
1725
|
const keyBasedValue = this.getKeyBasedInstrumentControlValue(channel, note.noteNumber, 7);
|
|
1751
1726
|
if (keyBasedValue !== 0) {
|
|
1752
1727
|
note.volumeNode.gain
|
|
@@ -1756,6 +1731,7 @@ export class MidyGM2 {
|
|
|
1756
1731
|
});
|
|
1757
1732
|
}
|
|
1758
1733
|
setVolume(channelNumber, volume, scheduleTime) {
|
|
1734
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1759
1735
|
const channel = this.channels[channelNumber];
|
|
1760
1736
|
channel.state.volume = volume / 127;
|
|
1761
1737
|
this.updateChannelVolume(channel, scheduleTime);
|
|
@@ -1769,8 +1745,7 @@ export class MidyGM2 {
|
|
|
1769
1745
|
};
|
|
1770
1746
|
}
|
|
1771
1747
|
setKeyBasedPan(channel, scheduleTime) {
|
|
1772
|
-
|
|
1773
|
-
this.processScheduledNotes(channel, scheduleTime, (note) => {
|
|
1748
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1774
1749
|
const keyBasedValue = this.getKeyBasedInstrumentControlValue(channel, note.noteNumber, 10);
|
|
1775
1750
|
if (keyBasedValue !== 0) {
|
|
1776
1751
|
const { gainLeft, gainRight } = this.panToGain((keyBasedValue + 1) / 2);
|
|
@@ -1784,12 +1759,14 @@ export class MidyGM2 {
|
|
|
1784
1759
|
});
|
|
1785
1760
|
}
|
|
1786
1761
|
setPan(channelNumber, pan, scheduleTime) {
|
|
1762
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1787
1763
|
const channel = this.channels[channelNumber];
|
|
1788
1764
|
channel.state.pan = pan / 127;
|
|
1789
1765
|
this.updateChannelVolume(channel, scheduleTime);
|
|
1790
1766
|
this.setKeyBasedPan(channel, scheduleTime);
|
|
1791
1767
|
}
|
|
1792
1768
|
setExpression(channelNumber, expression, scheduleTime) {
|
|
1769
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1793
1770
|
const channel = this.channels[channelNumber];
|
|
1794
1771
|
channel.state.expression = expression / 127;
|
|
1795
1772
|
this.updateChannelVolume(channel, scheduleTime);
|
|
@@ -1814,8 +1791,14 @@ export class MidyGM2 {
|
|
|
1814
1791
|
}
|
|
1815
1792
|
setSustainPedal(channelNumber, value, scheduleTime) {
|
|
1816
1793
|
scheduleTime ??= this.audioContext.currentTime;
|
|
1817
|
-
this.channels[channelNumber]
|
|
1818
|
-
|
|
1794
|
+
const channel = this.channels[channelNumber];
|
|
1795
|
+
channel.state.sustainPedal = value / 127;
|
|
1796
|
+
if (64 <= value) {
|
|
1797
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1798
|
+
channel.sustainNotes.push(note);
|
|
1799
|
+
});
|
|
1800
|
+
}
|
|
1801
|
+
else {
|
|
1819
1802
|
this.releaseSustainPedal(channelNumber, value, scheduleTime);
|
|
1820
1803
|
}
|
|
1821
1804
|
}
|
|
@@ -1823,13 +1806,14 @@ export class MidyGM2 {
|
|
|
1823
1806
|
this.channels[channelNumber].state.portamento = value / 127;
|
|
1824
1807
|
}
|
|
1825
1808
|
setSostenutoPedal(channelNumber, value, scheduleTime) {
|
|
1809
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1826
1810
|
const channel = this.channels[channelNumber];
|
|
1827
1811
|
channel.state.sostenutoPedal = value / 127;
|
|
1828
1812
|
if (64 <= value) {
|
|
1829
1813
|
channel.sostenutoNotes = this.getActiveNotes(channel, scheduleTime);
|
|
1830
1814
|
}
|
|
1831
1815
|
else {
|
|
1832
|
-
this.releaseSostenutoPedal(channelNumber, value);
|
|
1816
|
+
this.releaseSostenutoPedal(channelNumber, value, scheduleTime);
|
|
1833
1817
|
}
|
|
1834
1818
|
}
|
|
1835
1819
|
setSoftPedal(channelNumber, softPedal, _scheduleTime) {
|
|
@@ -1837,6 +1821,7 @@ export class MidyGM2 {
|
|
|
1837
1821
|
channel.state.softPedal = softPedal / 127;
|
|
1838
1822
|
}
|
|
1839
1823
|
setReverbSendLevel(channelNumber, reverbSendLevel, scheduleTime) {
|
|
1824
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1840
1825
|
const channel = this.channels[channelNumber];
|
|
1841
1826
|
const state = channel.state;
|
|
1842
1827
|
const reverbEffect = this.reverbEffect;
|
|
@@ -1848,27 +1833,17 @@ export class MidyGM2 {
|
|
|
1848
1833
|
.setValueAtTime(state.reverbSendLevel, scheduleTime);
|
|
1849
1834
|
}
|
|
1850
1835
|
else {
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
continue;
|
|
1856
|
-
if (note.voiceParams.reverbEffectsSend <= 0)
|
|
1857
|
-
continue;
|
|
1858
|
-
note.reverbEffectsSend.disconnect();
|
|
1859
|
-
}
|
|
1836
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1837
|
+
if (note.voiceParams.reverbEffectsSend <= 0)
|
|
1838
|
+
return false;
|
|
1839
|
+
note.reverbEffectsSend.disconnect();
|
|
1860
1840
|
});
|
|
1861
1841
|
}
|
|
1862
1842
|
}
|
|
1863
1843
|
else {
|
|
1864
1844
|
if (0 < reverbSendLevel) {
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
const note = noteList[i];
|
|
1868
|
-
if (!note)
|
|
1869
|
-
continue;
|
|
1870
|
-
this.setReverbEffectsSend(channel, note, 0, scheduleTime);
|
|
1871
|
-
}
|
|
1845
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1846
|
+
this.setReverbEffectsSend(channel, note, 0, scheduleTime);
|
|
1872
1847
|
});
|
|
1873
1848
|
state.reverbSendLevel = reverbSendLevel / 127;
|
|
1874
1849
|
reverbEffect.input.gain
|
|
@@ -1878,6 +1853,7 @@ export class MidyGM2 {
|
|
|
1878
1853
|
}
|
|
1879
1854
|
}
|
|
1880
1855
|
setChorusSendLevel(channelNumber, chorusSendLevel, scheduleTime) {
|
|
1856
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
1881
1857
|
const channel = this.channels[channelNumber];
|
|
1882
1858
|
const state = channel.state;
|
|
1883
1859
|
const chorusEffect = this.chorusEffect;
|
|
@@ -1889,27 +1865,17 @@ export class MidyGM2 {
|
|
|
1889
1865
|
.setValueAtTime(state.chorusSendLevel, scheduleTime);
|
|
1890
1866
|
}
|
|
1891
1867
|
else {
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
continue;
|
|
1897
|
-
if (note.voiceParams.chorusEffectsSend <= 0)
|
|
1898
|
-
continue;
|
|
1899
|
-
note.chorusEffectsSend.disconnect();
|
|
1900
|
-
}
|
|
1868
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1869
|
+
if (note.voiceParams.chorusEffectsSend <= 0)
|
|
1870
|
+
return false;
|
|
1871
|
+
note.chorusEffectsSend.disconnect();
|
|
1901
1872
|
});
|
|
1902
1873
|
}
|
|
1903
1874
|
}
|
|
1904
1875
|
else {
|
|
1905
1876
|
if (0 < chorusSendLevel) {
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
const note = noteList[i];
|
|
1909
|
-
if (!note)
|
|
1910
|
-
continue;
|
|
1911
|
-
this.setChorusEffectsSend(channel, note, 0, scheduleTime);
|
|
1912
|
-
}
|
|
1877
|
+
this.processScheduledNotes(channel, (note) => {
|
|
1878
|
+
this.setChorusEffectsSend(channel, note, 0, scheduleTime);
|
|
1913
1879
|
});
|
|
1914
1880
|
state.chorusSendLevel = chorusSendLevel / 127;
|
|
1915
1881
|
chorusEffect.input.gain
|
|
@@ -1952,13 +1918,13 @@ export class MidyGM2 {
|
|
|
1952
1918
|
this.handlePitchBendRangeRPN(channelNumber, scheduleTime);
|
|
1953
1919
|
break;
|
|
1954
1920
|
case 1:
|
|
1955
|
-
this.handleFineTuningRPN(channelNumber);
|
|
1921
|
+
this.handleFineTuningRPN(channelNumber, scheduleTime);
|
|
1956
1922
|
break;
|
|
1957
1923
|
case 2:
|
|
1958
|
-
this.handleCoarseTuningRPN(channelNumber);
|
|
1924
|
+
this.handleCoarseTuningRPN(channelNumber, scheduleTime);
|
|
1959
1925
|
break;
|
|
1960
1926
|
case 5:
|
|
1961
|
-
this.handleModulationDepthRangeRPN(channelNumber);
|
|
1927
|
+
this.handleModulationDepthRangeRPN(channelNumber, scheduleTime);
|
|
1962
1928
|
break;
|
|
1963
1929
|
default:
|
|
1964
1930
|
console.warn(`Channel ${channelNumber}: Unsupported RPN MSB=${channel.rpnMSB} LSB=${channel.rpnLSB}`);
|
|
@@ -1991,44 +1957,47 @@ export class MidyGM2 {
|
|
|
1991
1957
|
this.updateChannelDetune(channel, scheduleTime);
|
|
1992
1958
|
this.applyVoiceParams(channel, 16, scheduleTime);
|
|
1993
1959
|
}
|
|
1994
|
-
handleFineTuningRPN(channelNumber) {
|
|
1960
|
+
handleFineTuningRPN(channelNumber, scheduleTime) {
|
|
1995
1961
|
const channel = this.channels[channelNumber];
|
|
1996
1962
|
this.limitData(channel, 0, 127, 0, 127);
|
|
1997
1963
|
const fineTuning = channel.dataMSB * 128 + channel.dataLSB;
|
|
1998
|
-
this.setFineTuning(channelNumber, fineTuning);
|
|
1964
|
+
this.setFineTuning(channelNumber, fineTuning, scheduleTime);
|
|
1999
1965
|
}
|
|
2000
|
-
setFineTuning(channelNumber, value) {
|
|
1966
|
+
setFineTuning(channelNumber, value, scheduleTime) {
|
|
1967
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
2001
1968
|
const channel = this.channels[channelNumber];
|
|
2002
1969
|
const prev = channel.fineTuning;
|
|
2003
1970
|
const next = (value - 8192) / 8.192; // cent
|
|
2004
1971
|
channel.fineTuning = next;
|
|
2005
1972
|
channel.detune += next - prev;
|
|
2006
|
-
this.updateChannelDetune(channel);
|
|
1973
|
+
this.updateChannelDetune(channel, scheduleTime);
|
|
2007
1974
|
}
|
|
2008
|
-
handleCoarseTuningRPN(channelNumber) {
|
|
1975
|
+
handleCoarseTuningRPN(channelNumber, scheduleTime) {
|
|
2009
1976
|
const channel = this.channels[channelNumber];
|
|
2010
1977
|
this.limitDataMSB(channel, 0, 127);
|
|
2011
1978
|
const coarseTuning = channel.dataMSB;
|
|
2012
|
-
this.setCoarseTuning(channelNumber, coarseTuning);
|
|
1979
|
+
this.setCoarseTuning(channelNumber, coarseTuning, scheduleTime);
|
|
2013
1980
|
}
|
|
2014
|
-
setCoarseTuning(channelNumber, value) {
|
|
1981
|
+
setCoarseTuning(channelNumber, value, scheduleTime) {
|
|
1982
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
2015
1983
|
const channel = this.channels[channelNumber];
|
|
2016
1984
|
const prev = channel.coarseTuning;
|
|
2017
1985
|
const next = (value - 64) * 100; // cent
|
|
2018
1986
|
channel.coarseTuning = next;
|
|
2019
1987
|
channel.detune += next - prev;
|
|
2020
|
-
this.updateChannelDetune(channel);
|
|
1988
|
+
this.updateChannelDetune(channel, scheduleTime);
|
|
2021
1989
|
}
|
|
2022
|
-
handleModulationDepthRangeRPN(channelNumber) {
|
|
1990
|
+
handleModulationDepthRangeRPN(channelNumber, scheduleTime) {
|
|
2023
1991
|
const channel = this.channels[channelNumber];
|
|
2024
1992
|
this.limitData(channel, 0, 127, 0, 127);
|
|
2025
1993
|
const modulationDepthRange = (dataMSB + dataLSB / 128) * 100;
|
|
2026
|
-
this.setModulationDepthRange(channelNumber, modulationDepthRange);
|
|
1994
|
+
this.setModulationDepthRange(channelNumber, modulationDepthRange, scheduleTime);
|
|
2027
1995
|
}
|
|
2028
|
-
setModulationDepthRange(channelNumber, modulationDepthRange) {
|
|
1996
|
+
setModulationDepthRange(channelNumber, modulationDepthRange, scheduleTime) {
|
|
1997
|
+
scheduleTime ??= this.audioContext.currentTime;
|
|
2029
1998
|
const channel = this.channels[channelNumber];
|
|
2030
1999
|
channel.modulationDepthRange = modulationDepthRange;
|
|
2031
|
-
this.updateModulation(channel);
|
|
2000
|
+
this.updateModulation(channel, scheduleTime);
|
|
2032
2001
|
}
|
|
2033
2002
|
allSoundOff(channelNumber, _value, scheduleTime) {
|
|
2034
2003
|
scheduleTime ??= this.audioContext.currentTime;
|
|
@@ -2064,17 +2033,21 @@ export class MidyGM2 {
|
|
|
2064
2033
|
scheduleTime ??= this.audioContext.currentTime;
|
|
2065
2034
|
return this.stopChannelNotes(channelNumber, 0, false, scheduleTime);
|
|
2066
2035
|
}
|
|
2067
|
-
omniOff() {
|
|
2068
|
-
this.
|
|
2036
|
+
omniOff(channelNumber, value, scheduleTime) {
|
|
2037
|
+
this.allNotesOff(channelNumber, value, scheduleTime);
|
|
2069
2038
|
}
|
|
2070
|
-
omniOn() {
|
|
2071
|
-
this.
|
|
2039
|
+
omniOn(channelNumber, value, scheduleTime) {
|
|
2040
|
+
this.allNotesOff(channelNumber, value, scheduleTime);
|
|
2072
2041
|
}
|
|
2073
|
-
monoOn() {
|
|
2074
|
-
|
|
2042
|
+
monoOn(channelNumber, value, scheduleTime) {
|
|
2043
|
+
const channel = this.channels[channelNumber];
|
|
2044
|
+
this.allNotesOff(channelNumber, value, scheduleTime);
|
|
2045
|
+
channel.mono = true;
|
|
2075
2046
|
}
|
|
2076
|
-
polyOn() {
|
|
2077
|
-
|
|
2047
|
+
polyOn(channelNumber, value, scheduleTime) {
|
|
2048
|
+
const channel = this.channels[channelNumber];
|
|
2049
|
+
this.allNotesOff(channelNumber, value, scheduleTime);
|
|
2050
|
+
channel.mono = false;
|
|
2078
2051
|
}
|
|
2079
2052
|
handleUniversalNonRealTimeExclusiveMessage(data, scheduleTime) {
|
|
2080
2053
|
switch (data[2]) {
|
|
@@ -2483,13 +2456,8 @@ export class MidyGM2 {
|
|
|
2483
2456
|
const slotSize = 6;
|
|
2484
2457
|
const offset = controllerType * slotSize;
|
|
2485
2458
|
const table = channel.controlTable.subarray(offset, offset + slotSize);
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
const note = noteList[i];
|
|
2489
|
-
if (!note)
|
|
2490
|
-
continue;
|
|
2491
|
-
this.setControllerParameters(channel, note, table);
|
|
2492
|
-
}
|
|
2459
|
+
this.processScheduledNotes(channel, (note) => {
|
|
2460
|
+
this.setControllerParameters(channel, note, table);
|
|
2493
2461
|
});
|
|
2494
2462
|
}
|
|
2495
2463
|
handleControlChangeSysEx(data) {
|
|
@@ -2556,6 +2524,7 @@ Object.defineProperty(MidyGM2, "channelSettings", {
|
|
|
2556
2524
|
dataLSB: 0,
|
|
2557
2525
|
rpnMSB: 127,
|
|
2558
2526
|
rpnLSB: 127,
|
|
2527
|
+
mono: false, // CC#124, CC#125
|
|
2559
2528
|
fineTuning: 0, // cb
|
|
2560
2529
|
coarseTuning: 0, // cb
|
|
2561
2530
|
modulationDepthRange: 50, // cent
|
package/esm/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;
|
package/esm/midy-GMLite.d.ts.map
CHANGED
|
@@ -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"}
|