@marmooo/midy 0.3.5 → 0.3.6
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/esm/midy-GM1.d.ts +2 -2
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +15 -12
- package/esm/midy-GM2.d.ts +11 -11
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +139 -166
- package/esm/midy-GMLite.d.ts +2 -2
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +15 -12
- package/esm/midy.d.ts +15 -15
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +145 -172
- package/package.json +2 -2
- package/script/midy-GM1.d.ts +2 -2
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +15 -12
- package/script/midy-GM2.d.ts +11 -11
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +139 -166
- package/script/midy-GMLite.d.ts +2 -2
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +15 -12
- package/script/midy.d.ts +15 -15
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +145 -172
package/script/midy.d.ts
CHANGED
|
@@ -49,8 +49,8 @@ export class Midy {
|
|
|
49
49
|
isStopping: boolean;
|
|
50
50
|
isSeeking: boolean;
|
|
51
51
|
timeline: any[];
|
|
52
|
-
instruments: any[];
|
|
53
52
|
notePromises: any[];
|
|
53
|
+
instruments: Set<any>;
|
|
54
54
|
exclusiveClassNotes: any[];
|
|
55
55
|
drumExclusiveClassNotes: any[];
|
|
56
56
|
audioContext: any;
|
|
@@ -62,8 +62,8 @@ export class Midy {
|
|
|
62
62
|
vibLfoToPitch: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
63
63
|
modLfoToFilterFc: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
64
64
|
modLfoToVolume: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
65
|
-
chorusEffectsSend: (channel: any, note: any,
|
|
66
|
-
reverbEffectsSend: (channel: any, note: any,
|
|
65
|
+
chorusEffectsSend: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
66
|
+
reverbEffectsSend: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
67
67
|
delayModLFO: (_channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
68
68
|
freqModLFO: (_channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
69
69
|
delayVibLFO: (channel: any, note: any, prevValue: any, scheduleTime: any) => void;
|
|
@@ -90,7 +90,7 @@ export class Midy {
|
|
|
90
90
|
loadSoundFont(input: any): Promise<void>;
|
|
91
91
|
loadMIDI(input: any): Promise<void>;
|
|
92
92
|
cacheVoiceIds(): void;
|
|
93
|
-
getVoiceId(channel: any, noteNumber: any, velocity: any):
|
|
93
|
+
getVoiceId(channel: any, noteNumber: any, velocity: any): any;
|
|
94
94
|
createChannelAudioNodes(audioContext: any): {
|
|
95
95
|
gainL: any;
|
|
96
96
|
gainR: any;
|
|
@@ -192,8 +192,8 @@ export class Midy {
|
|
|
192
192
|
setVibLfoToPitch(channel: any, note: any, scheduleTime: any): void;
|
|
193
193
|
setModLfoToFilterFc(channel: any, note: any, scheduleTime: any): void;
|
|
194
194
|
setModLfoToVolume(channel: any, note: any, scheduleTime: any): void;
|
|
195
|
-
|
|
196
|
-
|
|
195
|
+
setReverbSend(channel: any, note: any, scheduleTime: any): void;
|
|
196
|
+
setChorusSend(channel: any, note: any, scheduleTime: any): void;
|
|
197
197
|
setDelayModLFO(note: any, scheduleTime: any): void;
|
|
198
198
|
setFreqModLFO(note: any, scheduleTime: any): void;
|
|
199
199
|
setFreqVibLFO(channel: any, note: any, scheduleTime: any): void;
|
|
@@ -202,8 +202,8 @@ export class Midy {
|
|
|
202
202
|
vibLfoToPitch: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
203
203
|
modLfoToFilterFc: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
204
204
|
modLfoToVolume: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
205
|
-
chorusEffectsSend: (channel: any, note: any,
|
|
206
|
-
reverbEffectsSend: (channel: any, note: any,
|
|
205
|
+
chorusEffectsSend: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
206
|
+
reverbEffectsSend: (channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
207
207
|
delayModLFO: (_channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
208
208
|
freqModLFO: (_channel: any, note: any, _prevValue: any, scheduleTime: any) => void;
|
|
209
209
|
delayVibLFO: (channel: any, note: any, prevValue: any, scheduleTime: any) => void;
|
|
@@ -228,7 +228,7 @@ export class Midy {
|
|
|
228
228
|
setBankLSB(channelNumber: any, lsb: any): void;
|
|
229
229
|
dataEntryLSB(channelNumber: any, value: any, scheduleTime: any): void;
|
|
230
230
|
updateChannelVolume(channel: any, scheduleTime: any): void;
|
|
231
|
-
updateKeyBasedVolume(channel: any, scheduleTime: any): void;
|
|
231
|
+
updateKeyBasedVolume(channel: any, keyNumber: any, scheduleTime: any): void;
|
|
232
232
|
setSustainPedal(channelNumber: any, value: any, scheduleTime: any): void;
|
|
233
233
|
setPortamento(channelNumber: any, value: any, scheduleTime: any): void;
|
|
234
234
|
setSostenutoPedal(channelNumber: any, value: any, scheduleTime: any): void;
|
|
@@ -305,11 +305,11 @@ export class Midy {
|
|
|
305
305
|
getLFOPitchDepth(channel: any, note: any): number;
|
|
306
306
|
getLFOFilterDepth(channel: any, note: any): number;
|
|
307
307
|
getLFOAmplitudeDepth(channel: any, note: any): number;
|
|
308
|
-
|
|
309
|
-
handlePressureSysEx(data: any, tableName: any): void;
|
|
308
|
+
setEffects(channel: any, note: any, table: any, scheduleTime: any): void;
|
|
309
|
+
handlePressureSysEx(data: any, tableName: any, scheduleTime: any): void;
|
|
310
310
|
initControlTable(): Int8Array<ArrayBuffer>;
|
|
311
|
-
|
|
312
|
-
handleControlChangeSysEx(data: any): void;
|
|
311
|
+
setControlChangeEffects(channel: any, controllerType: any, scheduleTime: any): void;
|
|
312
|
+
handleControlChangeSysEx(data: any, scheduleTime: any): void;
|
|
313
313
|
getKeyBasedValue(channel: any, keyNumber: any, controllerType: any): any;
|
|
314
314
|
handleKeyBasedInstrumentControlSysEx(data: any, scheduleTime: any): void;
|
|
315
315
|
handleSysEx(data: any, scheduleTime: any): void;
|
|
@@ -328,8 +328,8 @@ declare class Note {
|
|
|
328
328
|
modulationDepth: any;
|
|
329
329
|
vibratoLFO: any;
|
|
330
330
|
vibratoDepth: any;
|
|
331
|
-
|
|
332
|
-
|
|
331
|
+
reverbSend: any;
|
|
332
|
+
chorusSend: any;
|
|
333
333
|
portamentoNoteNumber: number;
|
|
334
334
|
pressure: number;
|
|
335
335
|
noteNumber: any;
|
package/script/midy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AA4JA;IAyCE;;;;;;;;;;;;;;;MAeE;IAEF,+BAkBC;IA3ED,aAAa;IACb,yBAAqB;IACrB,2BAAuB;IACvB;;;;MAIE;IACF;;;;;;MAME;IACF,oBAAiB;IACjB,qBAAmB;IACnB,kBAAc;IACd,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,4BAAyB;IACzB,0BAAuB;IACvB,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,
|
|
1
|
+
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}
|
package/script/midy.js
CHANGED
|
@@ -71,13 +71,13 @@ class Note {
|
|
|
71
71
|
writable: true,
|
|
72
72
|
value: void 0
|
|
73
73
|
});
|
|
74
|
-
Object.defineProperty(this, "
|
|
74
|
+
Object.defineProperty(this, "reverbSend", {
|
|
75
75
|
enumerable: true,
|
|
76
76
|
configurable: true,
|
|
77
77
|
writable: true,
|
|
78
78
|
value: void 0
|
|
79
79
|
});
|
|
80
|
-
Object.defineProperty(this, "
|
|
80
|
+
Object.defineProperty(this, "chorusSend", {
|
|
81
81
|
enumerable: true,
|
|
82
82
|
configurable: true,
|
|
83
83
|
writable: true,
|
|
@@ -380,17 +380,17 @@ class Midy {
|
|
|
380
380
|
writable: true,
|
|
381
381
|
value: []
|
|
382
382
|
});
|
|
383
|
-
Object.defineProperty(this, "
|
|
383
|
+
Object.defineProperty(this, "notePromises", {
|
|
384
384
|
enumerable: true,
|
|
385
385
|
configurable: true,
|
|
386
386
|
writable: true,
|
|
387
387
|
value: []
|
|
388
388
|
});
|
|
389
|
-
Object.defineProperty(this, "
|
|
389
|
+
Object.defineProperty(this, "instruments", {
|
|
390
390
|
enumerable: true,
|
|
391
391
|
configurable: true,
|
|
392
392
|
writable: true,
|
|
393
|
-
value:
|
|
393
|
+
value: new Set()
|
|
394
394
|
});
|
|
395
395
|
Object.defineProperty(this, "exclusiveClassNotes", {
|
|
396
396
|
enumerable: true,
|
|
@@ -522,7 +522,7 @@ class Midy {
|
|
|
522
522
|
const soundFont = this.soundFonts[soundFontIndex];
|
|
523
523
|
const voice = soundFont.getVoice(bankNumber, channel.programNumber, noteNumber, velocity);
|
|
524
524
|
const { instrument, sampleID } = voice.generators;
|
|
525
|
-
return
|
|
525
|
+
return soundFontIndex * (2 ** 32) + (instrument << 16) + sampleID;
|
|
526
526
|
}
|
|
527
527
|
createChannelAudioNodes(audioContext) {
|
|
528
528
|
const { gainLeft, gainRight } = this.panToGain(defaultControllerState.pan.defaultValue);
|
|
@@ -927,13 +927,11 @@ class Midy {
|
|
|
927
927
|
return impulse;
|
|
928
928
|
}
|
|
929
929
|
createConvolutionReverb(audioContext, impulse) {
|
|
930
|
-
const input = new GainNode(audioContext);
|
|
931
930
|
const convolverNode = new ConvolverNode(audioContext, {
|
|
932
931
|
buffer: impulse,
|
|
933
932
|
});
|
|
934
|
-
input.connect(convolverNode);
|
|
935
933
|
return {
|
|
936
|
-
input,
|
|
934
|
+
input: convolverNode,
|
|
937
935
|
output: convolverNode,
|
|
938
936
|
convolverNode,
|
|
939
937
|
};
|
|
@@ -1370,12 +1368,8 @@ class Midy {
|
|
|
1370
1368
|
}
|
|
1371
1369
|
note.bufferSource.connect(note.filterNode);
|
|
1372
1370
|
note.filterNode.connect(note.volumeEnvelopeNode);
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
}
|
|
1376
|
-
if (0 < state.reverbSendLevel) {
|
|
1377
|
-
this.setReverbEffectsSend(channel, note, 0, now);
|
|
1378
|
-
}
|
|
1371
|
+
this.setChorusSend(channel, note, now);
|
|
1372
|
+
this.setReverbSend(channel, note, now);
|
|
1379
1373
|
note.bufferSource.start(startTime);
|
|
1380
1374
|
return note;
|
|
1381
1375
|
}
|
|
@@ -1441,10 +1435,14 @@ class Midy {
|
|
|
1441
1435
|
return;
|
|
1442
1436
|
const note = await this.createNote(channel, voice, noteNumber, velocity, startTime);
|
|
1443
1437
|
if (channel.isDrum) {
|
|
1444
|
-
const
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1438
|
+
const { keyBasedGainLs, keyBasedGainRs } = channel;
|
|
1439
|
+
let gainL = keyBasedGainLs[noteNumber];
|
|
1440
|
+
let gainR = keyBasedGainRs[noteNumber];
|
|
1441
|
+
if (!gainL) {
|
|
1442
|
+
const audioNodes = this.createChannelAudioNodes(this.audioContext);
|
|
1443
|
+
gainL = keyBasedGainLs[noteNumber] = audioNodes.gainL;
|
|
1444
|
+
gainR = keyBasedGainRs[noteNumber] = audioNodes.gainR;
|
|
1445
|
+
}
|
|
1448
1446
|
note.volumeEnvelopeNode.connect(gainL);
|
|
1449
1447
|
note.volumeEnvelopeNode.connect(gainR);
|
|
1450
1448
|
}
|
|
@@ -1478,11 +1476,11 @@ class Midy {
|
|
|
1478
1476
|
note.vibratoDepth.disconnect();
|
|
1479
1477
|
note.vibratoLFO.stop();
|
|
1480
1478
|
}
|
|
1481
|
-
if (note.
|
|
1482
|
-
note.
|
|
1479
|
+
if (note.reverbSend) {
|
|
1480
|
+
note.reverbSend.disconnect();
|
|
1483
1481
|
}
|
|
1484
|
-
if (note.
|
|
1485
|
-
note.
|
|
1482
|
+
if (note.chorusSend) {
|
|
1483
|
+
note.chorusSend.disconnect();
|
|
1486
1484
|
}
|
|
1487
1485
|
}
|
|
1488
1486
|
releaseNote(channel, note, endTime) {
|
|
@@ -1613,7 +1611,7 @@ class Midy {
|
|
|
1613
1611
|
this.processActiveNotes(channel, scheduleTime, (note) => {
|
|
1614
1612
|
if (note.noteNumber === noteNumber) {
|
|
1615
1613
|
note.pressure = pressure;
|
|
1616
|
-
this.
|
|
1614
|
+
this.setEffects(channel, note, table, scheduleTime);
|
|
1617
1615
|
}
|
|
1618
1616
|
});
|
|
1619
1617
|
this.applyVoiceParams(channel, 10);
|
|
@@ -1647,7 +1645,7 @@ class Midy {
|
|
|
1647
1645
|
}
|
|
1648
1646
|
const table = channel.channelPressureTable;
|
|
1649
1647
|
this.processActiveNotes(channel, scheduleTime, (note) => {
|
|
1650
|
-
this.
|
|
1648
|
+
this.setEffects(channel, note, table, scheduleTime);
|
|
1651
1649
|
});
|
|
1652
1650
|
this.applyVoiceParams(channel, 13);
|
|
1653
1651
|
}
|
|
@@ -1669,13 +1667,18 @@ class Midy {
|
|
|
1669
1667
|
this.applyVoiceParams(channel, 14, scheduleTime);
|
|
1670
1668
|
}
|
|
1671
1669
|
setModLfoToPitch(channel, note, scheduleTime) {
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
.
|
|
1678
|
-
|
|
1670
|
+
if (note.modulationDepth) {
|
|
1671
|
+
const modLfoToPitch = note.voiceParams.modLfoToPitch +
|
|
1672
|
+
this.getLFOPitchDepth(channel, note);
|
|
1673
|
+
const baseDepth = Math.abs(modLfoToPitch) + channel.state.modulationDepth;
|
|
1674
|
+
const modulationDepth = baseDepth * Math.sign(modLfoToPitch);
|
|
1675
|
+
note.modulationDepth.gain
|
|
1676
|
+
.cancelScheduledValues(scheduleTime)
|
|
1677
|
+
.setValueAtTime(modulationDepth, scheduleTime);
|
|
1678
|
+
}
|
|
1679
|
+
else {
|
|
1680
|
+
this.startModulation(channel, note, scheduleTime);
|
|
1681
|
+
}
|
|
1679
1682
|
}
|
|
1680
1683
|
setVibLfoToPitch(channel, note, scheduleTime) {
|
|
1681
1684
|
const vibLfoToPitch = note.voiceParams.vibLfoToPitch;
|
|
@@ -1702,63 +1705,63 @@ class Midy {
|
|
|
1702
1705
|
.cancelScheduledValues(scheduleTime)
|
|
1703
1706
|
.setValueAtTime(volumeDepth, scheduleTime);
|
|
1704
1707
|
}
|
|
1705
|
-
|
|
1706
|
-
let value = note.voiceParams.reverbEffectsSend
|
|
1708
|
+
setReverbSend(channel, note, scheduleTime) {
|
|
1709
|
+
let value = note.voiceParams.reverbEffectsSend *
|
|
1710
|
+
channel.state.reverbSendLevel;
|
|
1707
1711
|
if (channel.isDrum) {
|
|
1708
1712
|
const keyBasedValue = this.getKeyBasedValue(channel, note.noteNumber, 91);
|
|
1709
|
-
if (0 <= keyBasedValue)
|
|
1710
|
-
value
|
|
1711
|
-
}
|
|
1713
|
+
if (0 <= keyBasedValue)
|
|
1714
|
+
value = keyBasedValue / 127;
|
|
1712
1715
|
}
|
|
1713
|
-
if (
|
|
1716
|
+
if (!note.reverbSend) {
|
|
1714
1717
|
if (0 < value) {
|
|
1715
|
-
note.
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
}
|
|
1719
|
-
else {
|
|
1720
|
-
note.reverbEffectsSend.disconnect();
|
|
1718
|
+
note.reverbSend = new GainNode(this.audioContext, { gain: value });
|
|
1719
|
+
note.volumeEnvelopeNode.connect(note.reverbSend);
|
|
1720
|
+
note.reverbSend.connect(this.reverbEffect.input);
|
|
1721
1721
|
}
|
|
1722
1722
|
}
|
|
1723
1723
|
else {
|
|
1724
|
+
note.reverbSend.gain
|
|
1725
|
+
.cancelScheduledValues(scheduleTime)
|
|
1726
|
+
.setValueAtTime(value, scheduleTime);
|
|
1724
1727
|
if (0 < value) {
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
note.volumeEnvelopeNode.
|
|
1728
|
+
note.volumeEnvelopeNode.connect(note.reverbSend);
|
|
1729
|
+
}
|
|
1730
|
+
else {
|
|
1731
|
+
try {
|
|
1732
|
+
note.volumeEnvelopeNode.disconnect(note.reverbSend);
|
|
1730
1733
|
}
|
|
1731
|
-
|
|
1734
|
+
catch { /* empty */ }
|
|
1732
1735
|
}
|
|
1733
1736
|
}
|
|
1734
1737
|
}
|
|
1735
|
-
|
|
1736
|
-
let value = note.voiceParams.chorusEffectsSend
|
|
1738
|
+
setChorusSend(channel, note, scheduleTime) {
|
|
1739
|
+
let value = note.voiceParams.chorusEffectsSend *
|
|
1740
|
+
channel.state.chorusSendLevel;
|
|
1737
1741
|
if (channel.isDrum) {
|
|
1738
1742
|
const keyBasedValue = this.getKeyBasedValue(channel, note.noteNumber, 93);
|
|
1739
|
-
if (0 <= keyBasedValue)
|
|
1740
|
-
value
|
|
1741
|
-
}
|
|
1743
|
+
if (0 <= keyBasedValue)
|
|
1744
|
+
value = keyBasedValue / 127;
|
|
1742
1745
|
}
|
|
1743
|
-
if (
|
|
1746
|
+
if (!note.chorusSend) {
|
|
1744
1747
|
if (0 < value) {
|
|
1745
|
-
note.
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
}
|
|
1749
|
-
else {
|
|
1750
|
-
note.chorusEffectsSend.disconnect();
|
|
1748
|
+
note.chorusSend = new GainNode(this.audioContext, { gain: value });
|
|
1749
|
+
note.volumeEnvelopeNode.connect(note.chorusSend);
|
|
1750
|
+
note.chorusSend.connect(this.chorusEffect.input);
|
|
1751
1751
|
}
|
|
1752
1752
|
}
|
|
1753
1753
|
else {
|
|
1754
|
+
note.chorusSend.gain
|
|
1755
|
+
.cancelScheduledValues(scheduleTime)
|
|
1756
|
+
.setValueAtTime(value, scheduleTime);
|
|
1754
1757
|
if (0 < value) {
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
note.volumeEnvelopeNode.
|
|
1758
|
+
note.volumeEnvelopeNode.connect(note.chorusSend);
|
|
1759
|
+
}
|
|
1760
|
+
else {
|
|
1761
|
+
try {
|
|
1762
|
+
note.volumeEnvelopeNode.disconnect(note.chorusSend);
|
|
1760
1763
|
}
|
|
1761
|
-
|
|
1764
|
+
catch { /* empty */ }
|
|
1762
1765
|
}
|
|
1763
1766
|
}
|
|
1764
1767
|
}
|
|
@@ -1804,11 +1807,11 @@ class Midy {
|
|
|
1804
1807
|
this.setModLfoToVolume(channel, note, scheduleTime);
|
|
1805
1808
|
}
|
|
1806
1809
|
},
|
|
1807
|
-
chorusEffectsSend: (channel, note,
|
|
1808
|
-
this.
|
|
1810
|
+
chorusEffectsSend: (channel, note, _prevValue, scheduleTime) => {
|
|
1811
|
+
this.setChorusSend(channel, note, scheduleTime);
|
|
1809
1812
|
},
|
|
1810
|
-
reverbEffectsSend: (channel, note,
|
|
1811
|
-
this.
|
|
1813
|
+
reverbEffectsSend: (channel, note, _prevValue, scheduleTime) => {
|
|
1814
|
+
this.setReverbSend(channel, note, scheduleTime);
|
|
1812
1815
|
},
|
|
1813
1816
|
delayModLFO: (_channel, note, _prevValue, scheduleTime) => this.setDelayModLFO(note, scheduleTime),
|
|
1814
1817
|
freqModLFO: (_channel, note, _prevValue, scheduleTime) => this.setFreqModLFO(note, scheduleTime),
|
|
@@ -1918,7 +1921,7 @@ class Midy {
|
|
|
1918
1921
|
handler.call(this, channelNumber, value, scheduleTime);
|
|
1919
1922
|
const channel = this.channels[channelNumber];
|
|
1920
1923
|
this.applyVoiceParams(channel, controllerType + 128, scheduleTime);
|
|
1921
|
-
this.
|
|
1924
|
+
this.setControlChangeEffects(channel, controllerType, scheduleTime);
|
|
1922
1925
|
}
|
|
1923
1926
|
else {
|
|
1924
1927
|
console.warn(`Unsupported Control change: controllerType=${controllerType} value=${value}`);
|
|
@@ -1934,7 +1937,6 @@ class Midy {
|
|
|
1934
1937
|
note.modulationDepth.gain.setValueAtTime(depth, scheduleTime);
|
|
1935
1938
|
}
|
|
1936
1939
|
else {
|
|
1937
|
-
this.setPitchEnvelope(note, scheduleTime);
|
|
1938
1940
|
this.startModulation(channel, note, scheduleTime);
|
|
1939
1941
|
}
|
|
1940
1942
|
});
|
|
@@ -1979,8 +1981,14 @@ class Midy {
|
|
|
1979
1981
|
scheduleTime ??= this.audioContext.currentTime;
|
|
1980
1982
|
const channel = this.channels[channelNumber];
|
|
1981
1983
|
channel.state.volume = volume / 127;
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
+
if (channel.isDrum) {
|
|
1985
|
+
for (let i = 0; i < 128; i++) {
|
|
1986
|
+
this.updateKeyBasedVolume(channel, i, scheduleTime);
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
else {
|
|
1990
|
+
this.updateChannelVolume(channel, scheduleTime);
|
|
1991
|
+
}
|
|
1984
1992
|
}
|
|
1985
1993
|
panToGain(pan) {
|
|
1986
1994
|
const theta = Math.PI / 2 * Math.max(0, pan * 127 - 1) / 126;
|
|
@@ -1993,8 +2001,14 @@ class Midy {
|
|
|
1993
2001
|
scheduleTime ??= this.audioContext.currentTime;
|
|
1994
2002
|
const channel = this.channels[channelNumber];
|
|
1995
2003
|
channel.state.pan = pan / 127;
|
|
1996
|
-
|
|
1997
|
-
|
|
2004
|
+
if (channel.isDrum) {
|
|
2005
|
+
for (let i = 0; i < 128; i++) {
|
|
2006
|
+
this.updateKeyBasedVolume(channel, i, scheduleTime);
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
else {
|
|
2010
|
+
this.updateChannelVolume(channel, scheduleTime);
|
|
2011
|
+
}
|
|
1998
2012
|
}
|
|
1999
2013
|
setExpression(channelNumber, expression, scheduleTime) {
|
|
2000
2014
|
scheduleTime ??= this.audioContext.currentTime;
|
|
@@ -2020,33 +2034,27 @@ class Midy {
|
|
|
2020
2034
|
.cancelScheduledValues(scheduleTime)
|
|
2021
2035
|
.setValueAtTime(volume * gainRight, scheduleTime);
|
|
2022
2036
|
}
|
|
2023
|
-
updateKeyBasedVolume(channel, scheduleTime) {
|
|
2024
|
-
if (!channel.isDrum)
|
|
2025
|
-
return;
|
|
2037
|
+
updateKeyBasedVolume(channel, keyNumber, scheduleTime) {
|
|
2026
2038
|
const state = channel.state;
|
|
2027
2039
|
const defaultVolume = state.volume * state.expression;
|
|
2028
2040
|
const defaultPan = state.pan;
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
gainR.gain
|
|
2047
|
-
.cancelScheduledValues(scheduleTime)
|
|
2048
|
-
.setValueAtTime(volume * gainRight, scheduleTime);
|
|
2049
|
-
}
|
|
2041
|
+
const gainL = channel.keyBasedGainLs[keyNumber];
|
|
2042
|
+
const gainR = channel.keyBasedGainRs[keyNumber];
|
|
2043
|
+
if (!gainL)
|
|
2044
|
+
return;
|
|
2045
|
+
const keyBasedVolume = this.getKeyBasedValue(channel, keyNumber, 7);
|
|
2046
|
+
const volume = (0 <= keyBasedVolume)
|
|
2047
|
+
? defaultVolume * keyBasedVolume / 64
|
|
2048
|
+
: defaultVolume;
|
|
2049
|
+
const keyBasedPan = this.getKeyBasedValue(channel, keyNumber, 10);
|
|
2050
|
+
const pan = (0 <= keyBasedPan) ? keyBasedPan / 127 : defaultPan;
|
|
2051
|
+
const { gainLeft, gainRight } = this.panToGain(pan);
|
|
2052
|
+
gainL.gain
|
|
2053
|
+
.cancelScheduledValues(scheduleTime)
|
|
2054
|
+
.setValueAtTime(volume * gainLeft, scheduleTime);
|
|
2055
|
+
gainR.gain
|
|
2056
|
+
.cancelScheduledValues(scheduleTime)
|
|
2057
|
+
.setValueAtTime(volume * gainRight, scheduleTime);
|
|
2050
2058
|
}
|
|
2051
2059
|
setSustainPedal(channelNumber, value, scheduleTime) {
|
|
2052
2060
|
const channel = this.channels[channelNumber];
|
|
@@ -2212,67 +2220,19 @@ class Midy {
|
|
|
2212
2220
|
scheduleTime ??= this.audioContext.currentTime;
|
|
2213
2221
|
const channel = this.channels[channelNumber];
|
|
2214
2222
|
const state = channel.state;
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
reverbEffect.input.gain
|
|
2220
|
-
.cancelScheduledValues(scheduleTime)
|
|
2221
|
-
.setValueAtTime(state.reverbSendLevel, scheduleTime);
|
|
2222
|
-
}
|
|
2223
|
-
else {
|
|
2224
|
-
this.processScheduledNotes(channel, (note) => {
|
|
2225
|
-
if (note.voiceParams.reverbEffectsSend <= 0)
|
|
2226
|
-
return false;
|
|
2227
|
-
if (note.reverbEffectsSend)
|
|
2228
|
-
note.reverbEffectsSend.disconnect();
|
|
2229
|
-
});
|
|
2230
|
-
}
|
|
2231
|
-
}
|
|
2232
|
-
else {
|
|
2233
|
-
if (0 < reverbSendLevel) {
|
|
2234
|
-
this.processScheduledNotes(channel, (note) => {
|
|
2235
|
-
this.setReverbEffectsSend(channel, note, 0, scheduleTime);
|
|
2236
|
-
});
|
|
2237
|
-
state.reverbSendLevel = reverbSendLevel / 127;
|
|
2238
|
-
reverbEffect.input.gain
|
|
2239
|
-
.cancelScheduledValues(scheduleTime)
|
|
2240
|
-
.setValueAtTime(state.reverbSendLevel, scheduleTime);
|
|
2241
|
-
}
|
|
2242
|
-
}
|
|
2223
|
+
state.reverbSendLevel = reverbSendLevel / 127;
|
|
2224
|
+
this.processScheduledNotes(channel, (note) => {
|
|
2225
|
+
this.setReverbSend(channel, note, scheduleTime);
|
|
2226
|
+
});
|
|
2243
2227
|
}
|
|
2244
2228
|
setChorusSendLevel(channelNumber, chorusSendLevel, scheduleTime) {
|
|
2245
2229
|
scheduleTime ??= this.audioContext.currentTime;
|
|
2246
2230
|
const channel = this.channels[channelNumber];
|
|
2247
2231
|
const state = channel.state;
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
chorusEffect.input.gain
|
|
2253
|
-
.cancelScheduledValues(scheduleTime)
|
|
2254
|
-
.setValueAtTime(state.chorusSendLevel, scheduleTime);
|
|
2255
|
-
}
|
|
2256
|
-
else {
|
|
2257
|
-
this.processScheduledNotes(channel, (note) => {
|
|
2258
|
-
if (note.voiceParams.chorusEffectsSend <= 0)
|
|
2259
|
-
return false;
|
|
2260
|
-
if (note.chorusEffectsSend)
|
|
2261
|
-
note.chorusEffectsSend.disconnect();
|
|
2262
|
-
});
|
|
2263
|
-
}
|
|
2264
|
-
}
|
|
2265
|
-
else {
|
|
2266
|
-
if (0 < chorusSendLevel) {
|
|
2267
|
-
this.processScheduledNotes(channel, (note) => {
|
|
2268
|
-
this.setChorusEffectsSend(channel, note, 0, scheduleTime);
|
|
2269
|
-
});
|
|
2270
|
-
state.chorusSendLevel = chorusSendLevel / 127;
|
|
2271
|
-
chorusEffect.input.gain
|
|
2272
|
-
.cancelScheduledValues(scheduleTime)
|
|
2273
|
-
.setValueAtTime(state.chorusSendLevel, scheduleTime);
|
|
2274
|
-
}
|
|
2275
|
-
}
|
|
2232
|
+
state.chorusSendLevel = chorusSendLevel / 127;
|
|
2233
|
+
this.processScheduledNotes(channel, (note) => {
|
|
2234
|
+
this.setChorusSend(channel, note, scheduleTime);
|
|
2235
|
+
});
|
|
2276
2236
|
}
|
|
2277
2237
|
limitData(channel, minMSB, maxMSB, minLSB, maxLSB) {
|
|
2278
2238
|
if (maxLSB < channel.dataLSB) {
|
|
@@ -2583,11 +2543,11 @@ class Midy {
|
|
|
2583
2543
|
case 9:
|
|
2584
2544
|
switch (data[3]) {
|
|
2585
2545
|
case 1: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca22.pdf
|
|
2586
|
-
return this.handlePressureSysEx(data, "channelPressureTable");
|
|
2546
|
+
return this.handlePressureSysEx(data, "channelPressureTable", scheduleTime);
|
|
2587
2547
|
case 2: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca22.pdf
|
|
2588
|
-
return this.handlePressureSysEx(data, "polyphonicKeyPressureTable");
|
|
2548
|
+
return this.handlePressureSysEx(data, "polyphonicKeyPressureTable", scheduleTime);
|
|
2589
2549
|
case 3: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca22.pdf
|
|
2590
|
-
return this.handleControlChangeSysEx(data);
|
|
2550
|
+
return this.handleControlChangeSysEx(data, scheduleTime);
|
|
2591
2551
|
default:
|
|
2592
2552
|
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
2593
2553
|
}
|
|
@@ -2958,9 +2918,9 @@ class Midy {
|
|
|
2958
2918
|
: 0;
|
|
2959
2919
|
return (channelPressure + polyphonicKeyPressure) / 254;
|
|
2960
2920
|
}
|
|
2961
|
-
|
|
2921
|
+
setEffects(channel, note, table, scheduleTime) {
|
|
2962
2922
|
if (0 <= table[0])
|
|
2963
|
-
this.updateDetune(channel, note,
|
|
2923
|
+
this.updateDetune(channel, note, scheduleTime);
|
|
2964
2924
|
if (0.5 <= channel.state.portamemento && 0 <= note.portamentoNoteNumber) {
|
|
2965
2925
|
if (0 <= table[1]) {
|
|
2966
2926
|
this.setPortamentoFilterEnvelope(channel, note, scheduleTime);
|
|
@@ -2982,7 +2942,7 @@ class Midy {
|
|
|
2982
2942
|
if (0 <= table[5])
|
|
2983
2943
|
this.setModLfoToVolume(channel, note, scheduleTime);
|
|
2984
2944
|
}
|
|
2985
|
-
handlePressureSysEx(data, tableName) {
|
|
2945
|
+
handlePressureSysEx(data, tableName, scheduleTime) {
|
|
2986
2946
|
const channelNumber = data[4];
|
|
2987
2947
|
const channel = this.channels[channelNumber];
|
|
2988
2948
|
if (channel.isDrum)
|
|
@@ -2993,32 +2953,38 @@ class Midy {
|
|
|
2993
2953
|
const rr = data[i + 1];
|
|
2994
2954
|
table[pp] = rr;
|
|
2995
2955
|
}
|
|
2956
|
+
this.processActiveNotes(channel, scheduleTime, (note) => {
|
|
2957
|
+
this.setEffects(channel, note, table, scheduleTime);
|
|
2958
|
+
});
|
|
2996
2959
|
}
|
|
2997
2960
|
initControlTable() {
|
|
2998
2961
|
const ccCount = 128;
|
|
2999
2962
|
const slotSize = 6;
|
|
3000
2963
|
return new Int8Array(ccCount * slotSize).fill(-1);
|
|
3001
2964
|
}
|
|
3002
|
-
|
|
2965
|
+
setControlChangeEffects(channel, controllerType, scheduleTime) {
|
|
3003
2966
|
const slotSize = 6;
|
|
3004
2967
|
const offset = controllerType * slotSize;
|
|
3005
2968
|
const table = channel.controlTable.subarray(offset, offset + slotSize);
|
|
3006
2969
|
this.processScheduledNotes(channel, (note) => {
|
|
3007
|
-
this.
|
|
2970
|
+
this.setEffects(channel, note, table, scheduleTime);
|
|
3008
2971
|
});
|
|
3009
2972
|
}
|
|
3010
|
-
handleControlChangeSysEx(data) {
|
|
2973
|
+
handleControlChangeSysEx(data, scheduleTime) {
|
|
3011
2974
|
const channelNumber = data[4];
|
|
3012
2975
|
const channel = this.channels[channelNumber];
|
|
3013
2976
|
if (channel.isDrum)
|
|
3014
2977
|
return;
|
|
2978
|
+
const slotSize = 6;
|
|
3015
2979
|
const controllerType = data[5];
|
|
3016
|
-
const
|
|
3017
|
-
|
|
2980
|
+
const offset = controllerType * slotSize;
|
|
2981
|
+
const table = channel.controlTable;
|
|
2982
|
+
for (let i = 6; i < data.length; i += 2) {
|
|
3018
2983
|
const pp = data[i];
|
|
3019
2984
|
const rr = data[i + 1];
|
|
3020
|
-
table[pp] = rr;
|
|
2985
|
+
table[offset + pp] = rr;
|
|
3021
2986
|
}
|
|
2987
|
+
this.setControlChangeEffects(channel, controllerType, scheduleTime);
|
|
3022
2988
|
}
|
|
3023
2989
|
getKeyBasedValue(channel, keyNumber, controllerType) {
|
|
3024
2990
|
const index = keyNumber * 128 + controllerType;
|
|
@@ -3032,13 +2998,20 @@ class Midy {
|
|
|
3032
2998
|
return;
|
|
3033
2999
|
const keyNumber = data[5];
|
|
3034
3000
|
const table = channel.keyBasedInstrumentControlTable;
|
|
3035
|
-
for (let i = 6; i < data.length
|
|
3001
|
+
for (let i = 6; i < data.length; i += 2) {
|
|
3036
3002
|
const controllerType = data[i];
|
|
3037
3003
|
const value = data[i + 1];
|
|
3038
3004
|
const index = keyNumber * 128 + controllerType;
|
|
3039
3005
|
table[index] = value;
|
|
3006
|
+
switch (controllerType) {
|
|
3007
|
+
case 7:
|
|
3008
|
+
case 10:
|
|
3009
|
+
this.updateKeyBasedVolume(channel, keyNumber, scheduleTime);
|
|
3010
|
+
break;
|
|
3011
|
+
default: // TODO
|
|
3012
|
+
this.setControlChange(channelNumber, controllerType, value, scheduleTime);
|
|
3013
|
+
}
|
|
3040
3014
|
}
|
|
3041
|
-
this.setChannelPressure(channelNumber, channel.state.channelPressure * 127, scheduleTime);
|
|
3042
3015
|
}
|
|
3043
3016
|
handleSysEx(data, scheduleTime) {
|
|
3044
3017
|
switch (data[0]) {
|