@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/esm/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/esm/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/esm/midy.js
CHANGED
|
@@ -68,13 +68,13 @@ class Note {
|
|
|
68
68
|
writable: true,
|
|
69
69
|
value: void 0
|
|
70
70
|
});
|
|
71
|
-
Object.defineProperty(this, "
|
|
71
|
+
Object.defineProperty(this, "reverbSend", {
|
|
72
72
|
enumerable: true,
|
|
73
73
|
configurable: true,
|
|
74
74
|
writable: true,
|
|
75
75
|
value: void 0
|
|
76
76
|
});
|
|
77
|
-
Object.defineProperty(this, "
|
|
77
|
+
Object.defineProperty(this, "chorusSend", {
|
|
78
78
|
enumerable: true,
|
|
79
79
|
configurable: true,
|
|
80
80
|
writable: true,
|
|
@@ -377,17 +377,17 @@ export class Midy {
|
|
|
377
377
|
writable: true,
|
|
378
378
|
value: []
|
|
379
379
|
});
|
|
380
|
-
Object.defineProperty(this, "
|
|
380
|
+
Object.defineProperty(this, "notePromises", {
|
|
381
381
|
enumerable: true,
|
|
382
382
|
configurable: true,
|
|
383
383
|
writable: true,
|
|
384
384
|
value: []
|
|
385
385
|
});
|
|
386
|
-
Object.defineProperty(this, "
|
|
386
|
+
Object.defineProperty(this, "instruments", {
|
|
387
387
|
enumerable: true,
|
|
388
388
|
configurable: true,
|
|
389
389
|
writable: true,
|
|
390
|
-
value:
|
|
390
|
+
value: new Set()
|
|
391
391
|
});
|
|
392
392
|
Object.defineProperty(this, "exclusiveClassNotes", {
|
|
393
393
|
enumerable: true,
|
|
@@ -519,7 +519,7 @@ export class Midy {
|
|
|
519
519
|
const soundFont = this.soundFonts[soundFontIndex];
|
|
520
520
|
const voice = soundFont.getVoice(bankNumber, channel.programNumber, noteNumber, velocity);
|
|
521
521
|
const { instrument, sampleID } = voice.generators;
|
|
522
|
-
return
|
|
522
|
+
return soundFontIndex * (2 ** 32) + (instrument << 16) + sampleID;
|
|
523
523
|
}
|
|
524
524
|
createChannelAudioNodes(audioContext) {
|
|
525
525
|
const { gainLeft, gainRight } = this.panToGain(defaultControllerState.pan.defaultValue);
|
|
@@ -924,13 +924,11 @@ export class Midy {
|
|
|
924
924
|
return impulse;
|
|
925
925
|
}
|
|
926
926
|
createConvolutionReverb(audioContext, impulse) {
|
|
927
|
-
const input = new GainNode(audioContext);
|
|
928
927
|
const convolverNode = new ConvolverNode(audioContext, {
|
|
929
928
|
buffer: impulse,
|
|
930
929
|
});
|
|
931
|
-
input.connect(convolverNode);
|
|
932
930
|
return {
|
|
933
|
-
input,
|
|
931
|
+
input: convolverNode,
|
|
934
932
|
output: convolverNode,
|
|
935
933
|
convolverNode,
|
|
936
934
|
};
|
|
@@ -1367,12 +1365,8 @@ export class Midy {
|
|
|
1367
1365
|
}
|
|
1368
1366
|
note.bufferSource.connect(note.filterNode);
|
|
1369
1367
|
note.filterNode.connect(note.volumeEnvelopeNode);
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
}
|
|
1373
|
-
if (0 < state.reverbSendLevel) {
|
|
1374
|
-
this.setReverbEffectsSend(channel, note, 0, now);
|
|
1375
|
-
}
|
|
1368
|
+
this.setChorusSend(channel, note, now);
|
|
1369
|
+
this.setReverbSend(channel, note, now);
|
|
1376
1370
|
note.bufferSource.start(startTime);
|
|
1377
1371
|
return note;
|
|
1378
1372
|
}
|
|
@@ -1438,10 +1432,14 @@ export class Midy {
|
|
|
1438
1432
|
return;
|
|
1439
1433
|
const note = await this.createNote(channel, voice, noteNumber, velocity, startTime);
|
|
1440
1434
|
if (channel.isDrum) {
|
|
1441
|
-
const
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1435
|
+
const { keyBasedGainLs, keyBasedGainRs } = channel;
|
|
1436
|
+
let gainL = keyBasedGainLs[noteNumber];
|
|
1437
|
+
let gainR = keyBasedGainRs[noteNumber];
|
|
1438
|
+
if (!gainL) {
|
|
1439
|
+
const audioNodes = this.createChannelAudioNodes(this.audioContext);
|
|
1440
|
+
gainL = keyBasedGainLs[noteNumber] = audioNodes.gainL;
|
|
1441
|
+
gainR = keyBasedGainRs[noteNumber] = audioNodes.gainR;
|
|
1442
|
+
}
|
|
1445
1443
|
note.volumeEnvelopeNode.connect(gainL);
|
|
1446
1444
|
note.volumeEnvelopeNode.connect(gainR);
|
|
1447
1445
|
}
|
|
@@ -1475,11 +1473,11 @@ export class Midy {
|
|
|
1475
1473
|
note.vibratoDepth.disconnect();
|
|
1476
1474
|
note.vibratoLFO.stop();
|
|
1477
1475
|
}
|
|
1478
|
-
if (note.
|
|
1479
|
-
note.
|
|
1476
|
+
if (note.reverbSend) {
|
|
1477
|
+
note.reverbSend.disconnect();
|
|
1480
1478
|
}
|
|
1481
|
-
if (note.
|
|
1482
|
-
note.
|
|
1479
|
+
if (note.chorusSend) {
|
|
1480
|
+
note.chorusSend.disconnect();
|
|
1483
1481
|
}
|
|
1484
1482
|
}
|
|
1485
1483
|
releaseNote(channel, note, endTime) {
|
|
@@ -1610,7 +1608,7 @@ export class Midy {
|
|
|
1610
1608
|
this.processActiveNotes(channel, scheduleTime, (note) => {
|
|
1611
1609
|
if (note.noteNumber === noteNumber) {
|
|
1612
1610
|
note.pressure = pressure;
|
|
1613
|
-
this.
|
|
1611
|
+
this.setEffects(channel, note, table, scheduleTime);
|
|
1614
1612
|
}
|
|
1615
1613
|
});
|
|
1616
1614
|
this.applyVoiceParams(channel, 10);
|
|
@@ -1644,7 +1642,7 @@ export class Midy {
|
|
|
1644
1642
|
}
|
|
1645
1643
|
const table = channel.channelPressureTable;
|
|
1646
1644
|
this.processActiveNotes(channel, scheduleTime, (note) => {
|
|
1647
|
-
this.
|
|
1645
|
+
this.setEffects(channel, note, table, scheduleTime);
|
|
1648
1646
|
});
|
|
1649
1647
|
this.applyVoiceParams(channel, 13);
|
|
1650
1648
|
}
|
|
@@ -1666,13 +1664,18 @@ export class Midy {
|
|
|
1666
1664
|
this.applyVoiceParams(channel, 14, scheduleTime);
|
|
1667
1665
|
}
|
|
1668
1666
|
setModLfoToPitch(channel, note, scheduleTime) {
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
.
|
|
1675
|
-
|
|
1667
|
+
if (note.modulationDepth) {
|
|
1668
|
+
const modLfoToPitch = note.voiceParams.modLfoToPitch +
|
|
1669
|
+
this.getLFOPitchDepth(channel, note);
|
|
1670
|
+
const baseDepth = Math.abs(modLfoToPitch) + channel.state.modulationDepth;
|
|
1671
|
+
const modulationDepth = baseDepth * Math.sign(modLfoToPitch);
|
|
1672
|
+
note.modulationDepth.gain
|
|
1673
|
+
.cancelScheduledValues(scheduleTime)
|
|
1674
|
+
.setValueAtTime(modulationDepth, scheduleTime);
|
|
1675
|
+
}
|
|
1676
|
+
else {
|
|
1677
|
+
this.startModulation(channel, note, scheduleTime);
|
|
1678
|
+
}
|
|
1676
1679
|
}
|
|
1677
1680
|
setVibLfoToPitch(channel, note, scheduleTime) {
|
|
1678
1681
|
const vibLfoToPitch = note.voiceParams.vibLfoToPitch;
|
|
@@ -1699,63 +1702,63 @@ export class Midy {
|
|
|
1699
1702
|
.cancelScheduledValues(scheduleTime)
|
|
1700
1703
|
.setValueAtTime(volumeDepth, scheduleTime);
|
|
1701
1704
|
}
|
|
1702
|
-
|
|
1703
|
-
let value = note.voiceParams.reverbEffectsSend
|
|
1705
|
+
setReverbSend(channel, note, scheduleTime) {
|
|
1706
|
+
let value = note.voiceParams.reverbEffectsSend *
|
|
1707
|
+
channel.state.reverbSendLevel;
|
|
1704
1708
|
if (channel.isDrum) {
|
|
1705
1709
|
const keyBasedValue = this.getKeyBasedValue(channel, note.noteNumber, 91);
|
|
1706
|
-
if (0 <= keyBasedValue)
|
|
1707
|
-
value
|
|
1708
|
-
}
|
|
1710
|
+
if (0 <= keyBasedValue)
|
|
1711
|
+
value = keyBasedValue / 127;
|
|
1709
1712
|
}
|
|
1710
|
-
if (
|
|
1713
|
+
if (!note.reverbSend) {
|
|
1711
1714
|
if (0 < value) {
|
|
1712
|
-
note.
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
}
|
|
1716
|
-
else {
|
|
1717
|
-
note.reverbEffectsSend.disconnect();
|
|
1715
|
+
note.reverbSend = new GainNode(this.audioContext, { gain: value });
|
|
1716
|
+
note.volumeEnvelopeNode.connect(note.reverbSend);
|
|
1717
|
+
note.reverbSend.connect(this.reverbEffect.input);
|
|
1718
1718
|
}
|
|
1719
1719
|
}
|
|
1720
1720
|
else {
|
|
1721
|
+
note.reverbSend.gain
|
|
1722
|
+
.cancelScheduledValues(scheduleTime)
|
|
1723
|
+
.setValueAtTime(value, scheduleTime);
|
|
1721
1724
|
if (0 < value) {
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
note.volumeEnvelopeNode.
|
|
1725
|
+
note.volumeEnvelopeNode.connect(note.reverbSend);
|
|
1726
|
+
}
|
|
1727
|
+
else {
|
|
1728
|
+
try {
|
|
1729
|
+
note.volumeEnvelopeNode.disconnect(note.reverbSend);
|
|
1727
1730
|
}
|
|
1728
|
-
|
|
1731
|
+
catch { /* empty */ }
|
|
1729
1732
|
}
|
|
1730
1733
|
}
|
|
1731
1734
|
}
|
|
1732
|
-
|
|
1733
|
-
let value = note.voiceParams.chorusEffectsSend
|
|
1735
|
+
setChorusSend(channel, note, scheduleTime) {
|
|
1736
|
+
let value = note.voiceParams.chorusEffectsSend *
|
|
1737
|
+
channel.state.chorusSendLevel;
|
|
1734
1738
|
if (channel.isDrum) {
|
|
1735
1739
|
const keyBasedValue = this.getKeyBasedValue(channel, note.noteNumber, 93);
|
|
1736
|
-
if (0 <= keyBasedValue)
|
|
1737
|
-
value
|
|
1738
|
-
}
|
|
1740
|
+
if (0 <= keyBasedValue)
|
|
1741
|
+
value = keyBasedValue / 127;
|
|
1739
1742
|
}
|
|
1740
|
-
if (
|
|
1743
|
+
if (!note.chorusSend) {
|
|
1741
1744
|
if (0 < value) {
|
|
1742
|
-
note.
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
}
|
|
1746
|
-
else {
|
|
1747
|
-
note.chorusEffectsSend.disconnect();
|
|
1745
|
+
note.chorusSend = new GainNode(this.audioContext, { gain: value });
|
|
1746
|
+
note.volumeEnvelopeNode.connect(note.chorusSend);
|
|
1747
|
+
note.chorusSend.connect(this.chorusEffect.input);
|
|
1748
1748
|
}
|
|
1749
1749
|
}
|
|
1750
1750
|
else {
|
|
1751
|
+
note.chorusSend.gain
|
|
1752
|
+
.cancelScheduledValues(scheduleTime)
|
|
1753
|
+
.setValueAtTime(value, scheduleTime);
|
|
1751
1754
|
if (0 < value) {
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
note.volumeEnvelopeNode.
|
|
1755
|
+
note.volumeEnvelopeNode.connect(note.chorusSend);
|
|
1756
|
+
}
|
|
1757
|
+
else {
|
|
1758
|
+
try {
|
|
1759
|
+
note.volumeEnvelopeNode.disconnect(note.chorusSend);
|
|
1757
1760
|
}
|
|
1758
|
-
|
|
1761
|
+
catch { /* empty */ }
|
|
1759
1762
|
}
|
|
1760
1763
|
}
|
|
1761
1764
|
}
|
|
@@ -1801,11 +1804,11 @@ export class Midy {
|
|
|
1801
1804
|
this.setModLfoToVolume(channel, note, scheduleTime);
|
|
1802
1805
|
}
|
|
1803
1806
|
},
|
|
1804
|
-
chorusEffectsSend: (channel, note,
|
|
1805
|
-
this.
|
|
1807
|
+
chorusEffectsSend: (channel, note, _prevValue, scheduleTime) => {
|
|
1808
|
+
this.setChorusSend(channel, note, scheduleTime);
|
|
1806
1809
|
},
|
|
1807
|
-
reverbEffectsSend: (channel, note,
|
|
1808
|
-
this.
|
|
1810
|
+
reverbEffectsSend: (channel, note, _prevValue, scheduleTime) => {
|
|
1811
|
+
this.setReverbSend(channel, note, scheduleTime);
|
|
1809
1812
|
},
|
|
1810
1813
|
delayModLFO: (_channel, note, _prevValue, scheduleTime) => this.setDelayModLFO(note, scheduleTime),
|
|
1811
1814
|
freqModLFO: (_channel, note, _prevValue, scheduleTime) => this.setFreqModLFO(note, scheduleTime),
|
|
@@ -1915,7 +1918,7 @@ export class Midy {
|
|
|
1915
1918
|
handler.call(this, channelNumber, value, scheduleTime);
|
|
1916
1919
|
const channel = this.channels[channelNumber];
|
|
1917
1920
|
this.applyVoiceParams(channel, controllerType + 128, scheduleTime);
|
|
1918
|
-
this.
|
|
1921
|
+
this.setControlChangeEffects(channel, controllerType, scheduleTime);
|
|
1919
1922
|
}
|
|
1920
1923
|
else {
|
|
1921
1924
|
console.warn(`Unsupported Control change: controllerType=${controllerType} value=${value}`);
|
|
@@ -1931,7 +1934,6 @@ export class Midy {
|
|
|
1931
1934
|
note.modulationDepth.gain.setValueAtTime(depth, scheduleTime);
|
|
1932
1935
|
}
|
|
1933
1936
|
else {
|
|
1934
|
-
this.setPitchEnvelope(note, scheduleTime);
|
|
1935
1937
|
this.startModulation(channel, note, scheduleTime);
|
|
1936
1938
|
}
|
|
1937
1939
|
});
|
|
@@ -1976,8 +1978,14 @@ export class Midy {
|
|
|
1976
1978
|
scheduleTime ??= this.audioContext.currentTime;
|
|
1977
1979
|
const channel = this.channels[channelNumber];
|
|
1978
1980
|
channel.state.volume = volume / 127;
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
+
if (channel.isDrum) {
|
|
1982
|
+
for (let i = 0; i < 128; i++) {
|
|
1983
|
+
this.updateKeyBasedVolume(channel, i, scheduleTime);
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
else {
|
|
1987
|
+
this.updateChannelVolume(channel, scheduleTime);
|
|
1988
|
+
}
|
|
1981
1989
|
}
|
|
1982
1990
|
panToGain(pan) {
|
|
1983
1991
|
const theta = Math.PI / 2 * Math.max(0, pan * 127 - 1) / 126;
|
|
@@ -1990,8 +1998,14 @@ export class Midy {
|
|
|
1990
1998
|
scheduleTime ??= this.audioContext.currentTime;
|
|
1991
1999
|
const channel = this.channels[channelNumber];
|
|
1992
2000
|
channel.state.pan = pan / 127;
|
|
1993
|
-
|
|
1994
|
-
|
|
2001
|
+
if (channel.isDrum) {
|
|
2002
|
+
for (let i = 0; i < 128; i++) {
|
|
2003
|
+
this.updateKeyBasedVolume(channel, i, scheduleTime);
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
else {
|
|
2007
|
+
this.updateChannelVolume(channel, scheduleTime);
|
|
2008
|
+
}
|
|
1995
2009
|
}
|
|
1996
2010
|
setExpression(channelNumber, expression, scheduleTime) {
|
|
1997
2011
|
scheduleTime ??= this.audioContext.currentTime;
|
|
@@ -2017,33 +2031,27 @@ export class Midy {
|
|
|
2017
2031
|
.cancelScheduledValues(scheduleTime)
|
|
2018
2032
|
.setValueAtTime(volume * gainRight, scheduleTime);
|
|
2019
2033
|
}
|
|
2020
|
-
updateKeyBasedVolume(channel, scheduleTime) {
|
|
2021
|
-
if (!channel.isDrum)
|
|
2022
|
-
return;
|
|
2034
|
+
updateKeyBasedVolume(channel, keyNumber, scheduleTime) {
|
|
2023
2035
|
const state = channel.state;
|
|
2024
2036
|
const defaultVolume = state.volume * state.expression;
|
|
2025
2037
|
const defaultPan = state.pan;
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
gainR.gain
|
|
2044
|
-
.cancelScheduledValues(scheduleTime)
|
|
2045
|
-
.setValueAtTime(volume * gainRight, scheduleTime);
|
|
2046
|
-
}
|
|
2038
|
+
const gainL = channel.keyBasedGainLs[keyNumber];
|
|
2039
|
+
const gainR = channel.keyBasedGainRs[keyNumber];
|
|
2040
|
+
if (!gainL)
|
|
2041
|
+
return;
|
|
2042
|
+
const keyBasedVolume = this.getKeyBasedValue(channel, keyNumber, 7);
|
|
2043
|
+
const volume = (0 <= keyBasedVolume)
|
|
2044
|
+
? defaultVolume * keyBasedVolume / 64
|
|
2045
|
+
: defaultVolume;
|
|
2046
|
+
const keyBasedPan = this.getKeyBasedValue(channel, keyNumber, 10);
|
|
2047
|
+
const pan = (0 <= keyBasedPan) ? keyBasedPan / 127 : defaultPan;
|
|
2048
|
+
const { gainLeft, gainRight } = this.panToGain(pan);
|
|
2049
|
+
gainL.gain
|
|
2050
|
+
.cancelScheduledValues(scheduleTime)
|
|
2051
|
+
.setValueAtTime(volume * gainLeft, scheduleTime);
|
|
2052
|
+
gainR.gain
|
|
2053
|
+
.cancelScheduledValues(scheduleTime)
|
|
2054
|
+
.setValueAtTime(volume * gainRight, scheduleTime);
|
|
2047
2055
|
}
|
|
2048
2056
|
setSustainPedal(channelNumber, value, scheduleTime) {
|
|
2049
2057
|
const channel = this.channels[channelNumber];
|
|
@@ -2209,67 +2217,19 @@ export class Midy {
|
|
|
2209
2217
|
scheduleTime ??= this.audioContext.currentTime;
|
|
2210
2218
|
const channel = this.channels[channelNumber];
|
|
2211
2219
|
const state = channel.state;
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
reverbEffect.input.gain
|
|
2217
|
-
.cancelScheduledValues(scheduleTime)
|
|
2218
|
-
.setValueAtTime(state.reverbSendLevel, scheduleTime);
|
|
2219
|
-
}
|
|
2220
|
-
else {
|
|
2221
|
-
this.processScheduledNotes(channel, (note) => {
|
|
2222
|
-
if (note.voiceParams.reverbEffectsSend <= 0)
|
|
2223
|
-
return false;
|
|
2224
|
-
if (note.reverbEffectsSend)
|
|
2225
|
-
note.reverbEffectsSend.disconnect();
|
|
2226
|
-
});
|
|
2227
|
-
}
|
|
2228
|
-
}
|
|
2229
|
-
else {
|
|
2230
|
-
if (0 < reverbSendLevel) {
|
|
2231
|
-
this.processScheduledNotes(channel, (note) => {
|
|
2232
|
-
this.setReverbEffectsSend(channel, note, 0, scheduleTime);
|
|
2233
|
-
});
|
|
2234
|
-
state.reverbSendLevel = reverbSendLevel / 127;
|
|
2235
|
-
reverbEffect.input.gain
|
|
2236
|
-
.cancelScheduledValues(scheduleTime)
|
|
2237
|
-
.setValueAtTime(state.reverbSendLevel, scheduleTime);
|
|
2238
|
-
}
|
|
2239
|
-
}
|
|
2220
|
+
state.reverbSendLevel = reverbSendLevel / 127;
|
|
2221
|
+
this.processScheduledNotes(channel, (note) => {
|
|
2222
|
+
this.setReverbSend(channel, note, scheduleTime);
|
|
2223
|
+
});
|
|
2240
2224
|
}
|
|
2241
2225
|
setChorusSendLevel(channelNumber, chorusSendLevel, scheduleTime) {
|
|
2242
2226
|
scheduleTime ??= this.audioContext.currentTime;
|
|
2243
2227
|
const channel = this.channels[channelNumber];
|
|
2244
2228
|
const state = channel.state;
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
chorusEffect.input.gain
|
|
2250
|
-
.cancelScheduledValues(scheduleTime)
|
|
2251
|
-
.setValueAtTime(state.chorusSendLevel, scheduleTime);
|
|
2252
|
-
}
|
|
2253
|
-
else {
|
|
2254
|
-
this.processScheduledNotes(channel, (note) => {
|
|
2255
|
-
if (note.voiceParams.chorusEffectsSend <= 0)
|
|
2256
|
-
return false;
|
|
2257
|
-
if (note.chorusEffectsSend)
|
|
2258
|
-
note.chorusEffectsSend.disconnect();
|
|
2259
|
-
});
|
|
2260
|
-
}
|
|
2261
|
-
}
|
|
2262
|
-
else {
|
|
2263
|
-
if (0 < chorusSendLevel) {
|
|
2264
|
-
this.processScheduledNotes(channel, (note) => {
|
|
2265
|
-
this.setChorusEffectsSend(channel, note, 0, scheduleTime);
|
|
2266
|
-
});
|
|
2267
|
-
state.chorusSendLevel = chorusSendLevel / 127;
|
|
2268
|
-
chorusEffect.input.gain
|
|
2269
|
-
.cancelScheduledValues(scheduleTime)
|
|
2270
|
-
.setValueAtTime(state.chorusSendLevel, scheduleTime);
|
|
2271
|
-
}
|
|
2272
|
-
}
|
|
2229
|
+
state.chorusSendLevel = chorusSendLevel / 127;
|
|
2230
|
+
this.processScheduledNotes(channel, (note) => {
|
|
2231
|
+
this.setChorusSend(channel, note, scheduleTime);
|
|
2232
|
+
});
|
|
2273
2233
|
}
|
|
2274
2234
|
limitData(channel, minMSB, maxMSB, minLSB, maxLSB) {
|
|
2275
2235
|
if (maxLSB < channel.dataLSB) {
|
|
@@ -2580,11 +2540,11 @@ export class Midy {
|
|
|
2580
2540
|
case 9:
|
|
2581
2541
|
switch (data[3]) {
|
|
2582
2542
|
case 1: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca22.pdf
|
|
2583
|
-
return this.handlePressureSysEx(data, "channelPressureTable");
|
|
2543
|
+
return this.handlePressureSysEx(data, "channelPressureTable", scheduleTime);
|
|
2584
2544
|
case 2: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca22.pdf
|
|
2585
|
-
return this.handlePressureSysEx(data, "polyphonicKeyPressureTable");
|
|
2545
|
+
return this.handlePressureSysEx(data, "polyphonicKeyPressureTable", scheduleTime);
|
|
2586
2546
|
case 3: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca22.pdf
|
|
2587
|
-
return this.handleControlChangeSysEx(data);
|
|
2547
|
+
return this.handleControlChangeSysEx(data, scheduleTime);
|
|
2588
2548
|
default:
|
|
2589
2549
|
console.warn(`Unsupported Exclusive Message: ${data}`);
|
|
2590
2550
|
}
|
|
@@ -2955,9 +2915,9 @@ export class Midy {
|
|
|
2955
2915
|
: 0;
|
|
2956
2916
|
return (channelPressure + polyphonicKeyPressure) / 254;
|
|
2957
2917
|
}
|
|
2958
|
-
|
|
2918
|
+
setEffects(channel, note, table, scheduleTime) {
|
|
2959
2919
|
if (0 <= table[0])
|
|
2960
|
-
this.updateDetune(channel, note,
|
|
2920
|
+
this.updateDetune(channel, note, scheduleTime);
|
|
2961
2921
|
if (0.5 <= channel.state.portamemento && 0 <= note.portamentoNoteNumber) {
|
|
2962
2922
|
if (0 <= table[1]) {
|
|
2963
2923
|
this.setPortamentoFilterEnvelope(channel, note, scheduleTime);
|
|
@@ -2979,7 +2939,7 @@ export class Midy {
|
|
|
2979
2939
|
if (0 <= table[5])
|
|
2980
2940
|
this.setModLfoToVolume(channel, note, scheduleTime);
|
|
2981
2941
|
}
|
|
2982
|
-
handlePressureSysEx(data, tableName) {
|
|
2942
|
+
handlePressureSysEx(data, tableName, scheduleTime) {
|
|
2983
2943
|
const channelNumber = data[4];
|
|
2984
2944
|
const channel = this.channels[channelNumber];
|
|
2985
2945
|
if (channel.isDrum)
|
|
@@ -2990,32 +2950,38 @@ export class Midy {
|
|
|
2990
2950
|
const rr = data[i + 1];
|
|
2991
2951
|
table[pp] = rr;
|
|
2992
2952
|
}
|
|
2953
|
+
this.processActiveNotes(channel, scheduleTime, (note) => {
|
|
2954
|
+
this.setEffects(channel, note, table, scheduleTime);
|
|
2955
|
+
});
|
|
2993
2956
|
}
|
|
2994
2957
|
initControlTable() {
|
|
2995
2958
|
const ccCount = 128;
|
|
2996
2959
|
const slotSize = 6;
|
|
2997
2960
|
return new Int8Array(ccCount * slotSize).fill(-1);
|
|
2998
2961
|
}
|
|
2999
|
-
|
|
2962
|
+
setControlChangeEffects(channel, controllerType, scheduleTime) {
|
|
3000
2963
|
const slotSize = 6;
|
|
3001
2964
|
const offset = controllerType * slotSize;
|
|
3002
2965
|
const table = channel.controlTable.subarray(offset, offset + slotSize);
|
|
3003
2966
|
this.processScheduledNotes(channel, (note) => {
|
|
3004
|
-
this.
|
|
2967
|
+
this.setEffects(channel, note, table, scheduleTime);
|
|
3005
2968
|
});
|
|
3006
2969
|
}
|
|
3007
|
-
handleControlChangeSysEx(data) {
|
|
2970
|
+
handleControlChangeSysEx(data, scheduleTime) {
|
|
3008
2971
|
const channelNumber = data[4];
|
|
3009
2972
|
const channel = this.channels[channelNumber];
|
|
3010
2973
|
if (channel.isDrum)
|
|
3011
2974
|
return;
|
|
2975
|
+
const slotSize = 6;
|
|
3012
2976
|
const controllerType = data[5];
|
|
3013
|
-
const
|
|
3014
|
-
|
|
2977
|
+
const offset = controllerType * slotSize;
|
|
2978
|
+
const table = channel.controlTable;
|
|
2979
|
+
for (let i = 6; i < data.length; i += 2) {
|
|
3015
2980
|
const pp = data[i];
|
|
3016
2981
|
const rr = data[i + 1];
|
|
3017
|
-
table[pp] = rr;
|
|
2982
|
+
table[offset + pp] = rr;
|
|
3018
2983
|
}
|
|
2984
|
+
this.setControlChangeEffects(channel, controllerType, scheduleTime);
|
|
3019
2985
|
}
|
|
3020
2986
|
getKeyBasedValue(channel, keyNumber, controllerType) {
|
|
3021
2987
|
const index = keyNumber * 128 + controllerType;
|
|
@@ -3029,13 +2995,20 @@ export class Midy {
|
|
|
3029
2995
|
return;
|
|
3030
2996
|
const keyNumber = data[5];
|
|
3031
2997
|
const table = channel.keyBasedInstrumentControlTable;
|
|
3032
|
-
for (let i = 6; i < data.length
|
|
2998
|
+
for (let i = 6; i < data.length; i += 2) {
|
|
3033
2999
|
const controllerType = data[i];
|
|
3034
3000
|
const value = data[i + 1];
|
|
3035
3001
|
const index = keyNumber * 128 + controllerType;
|
|
3036
3002
|
table[index] = value;
|
|
3003
|
+
switch (controllerType) {
|
|
3004
|
+
case 7:
|
|
3005
|
+
case 10:
|
|
3006
|
+
this.updateKeyBasedVolume(channel, keyNumber, scheduleTime);
|
|
3007
|
+
break;
|
|
3008
|
+
default: // TODO
|
|
3009
|
+
this.setControlChange(channelNumber, controllerType, value, scheduleTime);
|
|
3010
|
+
}
|
|
3037
3011
|
}
|
|
3038
|
-
this.setChannelPressure(channelNumber, channel.state.channelPressure * 127, scheduleTime);
|
|
3039
3012
|
}
|
|
3040
3013
|
handleSysEx(data, scheduleTime) {
|
|
3041
3014
|
switch (data[0]) {
|