@marmooo/midy 0.0.6 → 0.0.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/esm/midy-GM1.d.ts +12 -2
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +101 -42
- package/esm/midy-GM2.d.ts +22 -10
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +138 -65
- package/esm/midy-GMLite.d.ts +6 -2
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +47 -40
- package/esm/midy.d.ts +20 -8
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +137 -90
- package/package.json +1 -1
- package/script/midy-GM1.d.ts +12 -2
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +101 -42
- package/script/midy-GM2.d.ts +22 -10
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +138 -65
- package/script/midy-GMLite.d.ts +6 -2
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +47 -40
- package/script/midy.d.ts +20 -8
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +137 -90
package/script/midy.d.ts
CHANGED
|
@@ -256,14 +256,15 @@ export class Midy {
|
|
|
256
256
|
releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
|
|
257
257
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
258
258
|
releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
|
|
259
|
-
handleMIDIMessage(statusByte: any, data1: any, data2: any): any
|
|
259
|
+
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | any[] | Promise<any>;
|
|
260
260
|
handlePolyphonicKeyPressure(channelNumber: any, noteNumber: any, pressure: any): void;
|
|
261
261
|
handleProgramChange(channelNumber: any, program: any): void;
|
|
262
262
|
handleChannelPressure(channelNumber: any, pressure: any): void;
|
|
263
263
|
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
|
|
264
264
|
setPitchBend(channelNumber: any, pitchBend: any): void;
|
|
265
|
-
handleControlChange(channelNumber: any, controller: any, value: any): any;
|
|
265
|
+
handleControlChange(channelNumber: any, controller: any, value: any): void | any[];
|
|
266
266
|
setBankMSB(channelNumber: any, msb: any): void;
|
|
267
|
+
updateModulation(channel: any): void;
|
|
267
268
|
setModulation(channelNumber: any, modulation: any): void;
|
|
268
269
|
setPortamentoTime(channelNumber: any, portamentoTime: any): void;
|
|
269
270
|
setVolume(channelNumber: any, volume: any): void;
|
|
@@ -274,23 +275,34 @@ export class Midy {
|
|
|
274
275
|
setPan(channelNumber: any, pan: any): void;
|
|
275
276
|
setExpression(channelNumber: any, expression: any): void;
|
|
276
277
|
setBankLSB(channelNumber: any, lsb: any): void;
|
|
278
|
+
dataEntryLSB(channelNumber: any, value: any): void;
|
|
277
279
|
updateChannelGain(channel: any): void;
|
|
278
280
|
setSustainPedal(channelNumber: any, value: any): void;
|
|
279
281
|
setPortamento(channelNumber: any, value: any): void;
|
|
280
|
-
|
|
281
|
-
|
|
282
|
+
setReverbSendLevel(channelNumber: any, reverb: any): void;
|
|
283
|
+
setChorusSendLevel(channelNumber: any, chorus: any): void;
|
|
282
284
|
setSostenutoPedal(channelNumber: any, value: any): void;
|
|
283
285
|
setSoftPedal(channelNumber: any, softPedal: any): void;
|
|
284
286
|
setVibratoRate(channelNumber: any, vibratoRate: any): void;
|
|
285
287
|
setVibratoDepth(channelNumber: any, vibratoDepth: any): void;
|
|
286
288
|
setVibratoDelay(channelNumber: any, vibratoDelay: any): void;
|
|
287
|
-
|
|
288
|
-
|
|
289
|
+
limitData(channel: any, minMSB: any, maxMSB: any, minLSB: any, maxLSB: any): void;
|
|
290
|
+
limitDataMSB(channel: any, minMSB: any, maxMSB: any): void;
|
|
291
|
+
handleRPN(channelNumber: any, value: any): void;
|
|
292
|
+
dataIncrement(channelNumber: any): void;
|
|
293
|
+
dataDecrement(channelNumber: any): void;
|
|
289
294
|
setRPNMSB(channelNumber: any, value: any): void;
|
|
290
295
|
setRPNLSB(channelNumber: any, value: any): void;
|
|
291
|
-
|
|
292
|
-
|
|
296
|
+
dataEntryMSB(channelNumber: any, value: any): void;
|
|
297
|
+
updateDetune(channel: any, detuneChange: any): void;
|
|
298
|
+
handlePitchBendRangeRPN(channelNumber: any): void;
|
|
293
299
|
setPitchBendRange(channelNumber: any, pitchBendRange: any): void;
|
|
300
|
+
handleFineTuningRPN(channelNumber: any): void;
|
|
301
|
+
setFineTuning(channelNumber: any, fineTuning: any): void;
|
|
302
|
+
handleCoarseTuningRPN(channelNumber: any): void;
|
|
303
|
+
setCoarseTuning(channelNumber: any, coarseTuning: any): void;
|
|
304
|
+
handleModulationDepthRangeRPN(channelNumber: any): void;
|
|
305
|
+
setModulationDepthRange(channelNumber: any, modulationDepthRange: any): void;
|
|
294
306
|
allSoundOff(channelNumber: any): any[];
|
|
295
307
|
resetAllControllers(channelNumber: any): void;
|
|
296
308
|
allNotesOff(channelNumber: any): any[];
|
package/script/midy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAuBA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAzED,qBAAmB;IACnB,kBAAc;IACd,qBAAmB;IACnB,yBAAqB;IACrB,2BAAuB;IACvB,cAAa;IACb,cAAa;IACb,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IA+ChB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;MAqBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAiBC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EAyDC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgGC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED;;;;MAoCC;IAED;;;;;MAqCC;IAED,
|
|
1
|
+
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAuBA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAzED,qBAAmB;IACnB,kBAAc;IACd,qBAAmB;IACnB,yBAAqB;IACrB,2BAAuB;IACvB,cAAa;IACb,cAAa;IACb,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IA+ChB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;MAqBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAiBC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EAyDC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgGC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED;;;;MAoCC;IAED;;;;;MAqCC;IAED,sDA6BC;IAED,2BAEC;IAED,4BAEC;IAED,sCAKC;IAED,mFAGC;IAED,iDAiBC;IAED,iDAiCC;IAED,0DAmBC;IAED,uDAcC;IAED,wHAqCC;IAED,gDAQC;IAED,kGAgCC;IAED,0EAGC;IAED,sIAwDC;IAED,0FAGC;IAED,kEAeC;IAED,oEAYC;IAED,wFAqBC;IAED,sFAcC;IAED,4DAIC;IAED,+DAcC;IAED,qEAGC;IAED,uDAOC;IAED,mFAkEC;IAED,+CAEC;IAED,qCAcC;IAED,yDAIC;IAED,iEAEC;IAED,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,+CAEC;IAED,mDAGC;IAED,sCAUC;IAED,sDAMC;IAED,oDAEC;IAED,0DASC;IAED,0DAIC;IAED,wDAWC;IAED,uDAGC;IAED,2DAGC;IAED,6DAGC;IAED,6DASC;IAED,kFAeC;IAED,2DAMC;IAED,gDAyBC;IAED,wCAEC;IAED,wCAEC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAUC;IAED,kDAKC;IAED,iEAOC;IAED,8CAKC;IAED,yDAMC;IAED,gDAKC;IAED,6DAMC;IAED,wDAKC;IAED,6EAKC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,gBAEC;IAED,eAEC;IAED,eAEC;IAED,eAEC;IAED,4DAmBC;IAED,oBAQC;IAED,oBAQC;IAED,yDAgDC;IAED,yCAGC;IAED,mCAQC;IAED,6CAGC;IAED,2CAMC;IAED,+CAGC;IAED,+CAMC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAxjDD;IASE,gFAKC;IAbD,kBAAa;IACb,cAAS;IACT,gBAAW;IACX,YAAO;IACP,gBAAW;IACX,YAAO;IACP,gBAAW;IAGT,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
|
package/script/midy.js
CHANGED
|
@@ -78,13 +78,13 @@ class Midy {
|
|
|
78
78
|
configurable: true,
|
|
79
79
|
writable: true,
|
|
80
80
|
value: 0
|
|
81
|
-
});
|
|
81
|
+
}); // cb
|
|
82
82
|
Object.defineProperty(this, "masterCoarseTuning", {
|
|
83
83
|
enumerable: true,
|
|
84
84
|
configurable: true,
|
|
85
85
|
writable: true,
|
|
86
86
|
value: 0
|
|
87
|
-
});
|
|
87
|
+
}); // cb
|
|
88
88
|
Object.defineProperty(this, "mono", {
|
|
89
89
|
enumerable: true,
|
|
90
90
|
configurable: true,
|
|
@@ -654,14 +654,16 @@ class Midy {
|
|
|
654
654
|
connectNoteEffects(channel, gainNode) {
|
|
655
655
|
if (channel.reverb === 0) {
|
|
656
656
|
if (channel.chorus === 0) { // no effect
|
|
657
|
-
gainNode.connect(channel.
|
|
657
|
+
gainNode.connect(channel.gainL);
|
|
658
|
+
gainNode.connect(channel.gainR);
|
|
658
659
|
}
|
|
659
660
|
else { // chorus
|
|
660
661
|
channel.chorusEffect.delayNodes.forEach((delayNode) => {
|
|
661
662
|
gainNode.connect(delayNode);
|
|
662
663
|
});
|
|
663
664
|
channel.chorusEffect.chorusGains.forEach((chorusGain) => {
|
|
664
|
-
chorusGain.connect(channel.
|
|
665
|
+
chorusGain.connect(channel.gainL);
|
|
666
|
+
chorusGain.connect(channel.gainR);
|
|
665
667
|
});
|
|
666
668
|
}
|
|
667
669
|
}
|
|
@@ -749,7 +751,7 @@ class Midy {
|
|
|
749
751
|
startModulation(channel, note, time) {
|
|
750
752
|
const { instrumentKey } = note;
|
|
751
753
|
note.modLFOGain = new GainNode(this.audioContext, {
|
|
752
|
-
gain: this.cbToRatio(instrumentKey.modLfoToVolume
|
|
754
|
+
gain: this.cbToRatio(instrumentKey.modLfoToVolume + channel.modulation),
|
|
753
755
|
});
|
|
754
756
|
note.modLFO = new OscillatorNode(this.audioContext, {
|
|
755
757
|
frequency: this.centToHz(instrumentKey.freqModLFO),
|
|
@@ -980,20 +982,12 @@ class Midy {
|
|
|
980
982
|
this.setPitchBend(channelNumber, pitchBend);
|
|
981
983
|
}
|
|
982
984
|
setPitchBend(channelNumber, pitchBend) {
|
|
983
|
-
const now = this.audioContext.currentTime;
|
|
984
985
|
const channel = this.channels[channelNumber];
|
|
985
986
|
const prevPitchBend = channel.pitchBend;
|
|
986
987
|
channel.pitchBend = (pitchBend - 8192) / 8192;
|
|
987
988
|
const detuneChange = (channel.pitchBend - prevPitchBend) *
|
|
988
989
|
channel.pitchBendRange * 100;
|
|
989
|
-
|
|
990
|
-
activeNotes.forEach((activeNote) => {
|
|
991
|
-
const { bufferSource } = activeNote;
|
|
992
|
-
const detune = bufferSource.detune.value + detuneChange;
|
|
993
|
-
bufferSource.detune
|
|
994
|
-
.cancelScheduledValues(now)
|
|
995
|
-
.setValueAtTime(detune, now);
|
|
996
|
-
});
|
|
990
|
+
this.updateDetune(channel, detuneChange);
|
|
997
991
|
}
|
|
998
992
|
handleControlChange(channelNumber, controller, value) {
|
|
999
993
|
switch (controller) {
|
|
@@ -1004,7 +998,7 @@ class Midy {
|
|
|
1004
998
|
case 5:
|
|
1005
999
|
return this.setPortamentoTime(channelNumber, value);
|
|
1006
1000
|
case 6:
|
|
1007
|
-
return this.
|
|
1001
|
+
return this.dataEntryMSB(channelNumber, value);
|
|
1008
1002
|
case 7:
|
|
1009
1003
|
return this.setVolume(channelNumber, value);
|
|
1010
1004
|
case 10:
|
|
@@ -1014,7 +1008,7 @@ class Midy {
|
|
|
1014
1008
|
case 32:
|
|
1015
1009
|
return this.setBankLSB(channelNumber, value);
|
|
1016
1010
|
case 38:
|
|
1017
|
-
return this.
|
|
1011
|
+
return this.dataEntryLSB(channelNumber, value);
|
|
1018
1012
|
case 64:
|
|
1019
1013
|
return this.setSustainPedal(channelNumber, value);
|
|
1020
1014
|
case 65:
|
|
@@ -1031,17 +1025,17 @@ class Midy {
|
|
|
1031
1025
|
case 78:
|
|
1032
1026
|
return this.setVibratoDelay(channelNumber, value);
|
|
1033
1027
|
case 91:
|
|
1034
|
-
return this.
|
|
1028
|
+
return this.setReverbSendLevel(channelNumber, value);
|
|
1035
1029
|
case 93:
|
|
1036
|
-
return this.
|
|
1037
|
-
case 96:
|
|
1038
|
-
return
|
|
1039
|
-
case 97:
|
|
1040
|
-
return
|
|
1030
|
+
return this.setChorusSendLevel(channelNumber, value);
|
|
1031
|
+
case 96: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/rp18.pdf
|
|
1032
|
+
return this.dataIncrement(channelNumber);
|
|
1033
|
+
case 97: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/rp18.pdf
|
|
1034
|
+
return this.dataDecrement(channelNumber);
|
|
1041
1035
|
case 100:
|
|
1042
|
-
return this.setRPNMSB(channelNumber, value);
|
|
1043
|
-
case 101:
|
|
1044
1036
|
return this.setRPNLSB(channelNumber, value);
|
|
1037
|
+
case 101:
|
|
1038
|
+
return this.setRPNMSB(channelNumber, value);
|
|
1045
1039
|
case 120:
|
|
1046
1040
|
return this.allSoundOff(channelNumber);
|
|
1047
1041
|
case 121:
|
|
@@ -1063,22 +1057,24 @@ class Midy {
|
|
|
1063
1057
|
setBankMSB(channelNumber, msb) {
|
|
1064
1058
|
this.channels[channelNumber].bankMSB = msb;
|
|
1065
1059
|
}
|
|
1066
|
-
|
|
1060
|
+
updateModulation(channel) {
|
|
1067
1061
|
const now = this.audioContext.currentTime;
|
|
1068
|
-
const channel = this.channels[channelNumber];
|
|
1069
|
-
channel.modulation = (modulation / 127) *
|
|
1070
|
-
(channel.modulationDepthRange * 100);
|
|
1071
1062
|
const activeNotes = this.getActiveNotes(channel, now);
|
|
1072
1063
|
activeNotes.forEach((activeNote) => {
|
|
1073
1064
|
if (activeNote.modLFO) {
|
|
1074
|
-
|
|
1075
|
-
|
|
1065
|
+
const { gainNode, instrumentKey } = activeNote;
|
|
1066
|
+
gainNode.gain.setValueAtTime(this.cbToRatio(instrumentKey.modLfoToVolume + channel.modulation), now);
|
|
1076
1067
|
}
|
|
1077
1068
|
else {
|
|
1078
1069
|
this.startModulation(channel, activeNote, now);
|
|
1079
1070
|
}
|
|
1080
1071
|
});
|
|
1081
1072
|
}
|
|
1073
|
+
setModulation(channelNumber, modulation) {
|
|
1074
|
+
const channel = this.channels[channelNumber];
|
|
1075
|
+
channel.modulation = (modulation / 127) * channel.modulationDepthRange;
|
|
1076
|
+
this.updateModulation(channel);
|
|
1077
|
+
}
|
|
1082
1078
|
setPortamentoTime(channelNumber, portamentoTime) {
|
|
1083
1079
|
this.channels[channelNumber].portamentoTime = portamentoTime / 127;
|
|
1084
1080
|
}
|
|
@@ -1107,6 +1103,10 @@ class Midy {
|
|
|
1107
1103
|
setBankLSB(channelNumber, lsb) {
|
|
1108
1104
|
this.channels[channelNumber].bankLSB = lsb;
|
|
1109
1105
|
}
|
|
1106
|
+
dataEntryLSB(channelNumber, value) {
|
|
1107
|
+
this.channels[channelNumber].dataLSB = value;
|
|
1108
|
+
this.handleRPN(channelNumber, 0);
|
|
1109
|
+
}
|
|
1110
1110
|
updateChannelGain(channel) {
|
|
1111
1111
|
const now = this.audioContext.currentTime;
|
|
1112
1112
|
const volume = channel.volume * channel.expression;
|
|
@@ -1128,7 +1128,7 @@ class Midy {
|
|
|
1128
1128
|
setPortamento(channelNumber, value) {
|
|
1129
1129
|
this.channels[channelNumber].portamento = value >= 64;
|
|
1130
1130
|
}
|
|
1131
|
-
|
|
1131
|
+
setReverbSendLevel(channelNumber, reverb) {
|
|
1132
1132
|
const now = this.audioContext.currentTime;
|
|
1133
1133
|
const channel = this.channels[channelNumber];
|
|
1134
1134
|
const reverbEffect = channel.reverbEffect;
|
|
@@ -1138,7 +1138,7 @@ class Midy {
|
|
|
1138
1138
|
reverbEffect.wetGain.gain.cancelScheduledValues(now);
|
|
1139
1139
|
reverbEffect.wetGain.gain.setValueAtTime(channel.reverb, now);
|
|
1140
1140
|
}
|
|
1141
|
-
|
|
1141
|
+
setChorusSendLevel(channelNumber, chorus) {
|
|
1142
1142
|
const channel = this.channels[channelNumber];
|
|
1143
1143
|
channel.chorus = chorus / 127;
|
|
1144
1144
|
channel.chorusEffect.lfoGain = channel.chorus;
|
|
@@ -1178,79 +1178,74 @@ class Midy {
|
|
|
1178
1178
|
const channel = this.channels[channelNumber];
|
|
1179
1179
|
channel.vibratoDelay = vibratoDelay / 127 * 5; // 0-5sec
|
|
1180
1180
|
}
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1181
|
+
limitData(channel, minMSB, maxMSB, minLSB, maxLSB) {
|
|
1182
|
+
if (maxLSB < channel.dataLSB) {
|
|
1183
|
+
channel.dataMSB++;
|
|
1184
|
+
channel.dataLSB = minLSB;
|
|
1185
|
+
}
|
|
1186
|
+
else if (channel.dataLSB < 0) {
|
|
1187
|
+
channel.dataMSB--;
|
|
1188
|
+
channel.dataLSB = maxLSB;
|
|
1189
|
+
}
|
|
1190
|
+
if (maxMSB < channel.dataMSB) {
|
|
1191
|
+
channel.dataMSB = maxMSB;
|
|
1192
|
+
channel.dataLSB = maxLSB;
|
|
1193
|
+
}
|
|
1194
|
+
else if (channel.dataMSB < 0) {
|
|
1195
|
+
channel.dataMSB = minMSB;
|
|
1196
|
+
channel.dataLSB = minLSB;
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
limitDataMSB(channel, minMSB, maxMSB) {
|
|
1200
|
+
if (maxMSB < channel.dataMSB) {
|
|
1201
|
+
channel.dataMSB = maxMSB;
|
|
1202
|
+
}
|
|
1203
|
+
else if (channel.dataMSB < 0) {
|
|
1204
|
+
channel.dataMSB = minMSB;
|
|
1196
1205
|
}
|
|
1197
1206
|
}
|
|
1198
|
-
|
|
1207
|
+
handleRPN(channelNumber, value) {
|
|
1199
1208
|
const channel = this.channels[channelNumber];
|
|
1200
1209
|
const rpn = channel.rpnMSB * 128 + channel.rpnLSB;
|
|
1201
1210
|
switch (rpn) {
|
|
1202
1211
|
case 0:
|
|
1203
|
-
channel.
|
|
1212
|
+
channel.dataLSB += value;
|
|
1213
|
+
this.handlePitchBendRangeRPN(channelNumber);
|
|
1204
1214
|
break;
|
|
1205
1215
|
case 1:
|
|
1206
|
-
channel.
|
|
1216
|
+
channel.dataLSB += value;
|
|
1217
|
+
this.handleFineTuningRPN(channelNumber);
|
|
1207
1218
|
break;
|
|
1208
1219
|
case 2:
|
|
1209
|
-
channel.
|
|
1220
|
+
channel.dataMSB += value;
|
|
1221
|
+
this.handleCoarseTuningRPN(channelNumber);
|
|
1222
|
+
break;
|
|
1223
|
+
case 5:
|
|
1224
|
+
channel.dataLSB += value;
|
|
1225
|
+
this.handleModulationDepthRangeRPN(channelNumber);
|
|
1210
1226
|
break;
|
|
1211
1227
|
default:
|
|
1212
|
-
console.warn(`Channel ${channelNumber}: Unsupported RPN MSB=${channel.rpnMSB}
|
|
1228
|
+
console.warn(`Channel ${channelNumber}: Unsupported RPN MSB=${channel.rpnMSB} LSB=${channel.rpnLSB}`);
|
|
1213
1229
|
}
|
|
1214
1230
|
}
|
|
1231
|
+
dataIncrement(channelNumber) {
|
|
1232
|
+
this.handleRPN(channelNumber, 1);
|
|
1233
|
+
}
|
|
1234
|
+
dataDecrement(channelNumber) {
|
|
1235
|
+
this.handleRPN(channelNumber, -1);
|
|
1236
|
+
}
|
|
1215
1237
|
setRPNMSB(channelNumber, value) {
|
|
1216
1238
|
this.channels[channelNumber].rpnMSB = value;
|
|
1217
1239
|
}
|
|
1218
1240
|
setRPNLSB(channelNumber, value) {
|
|
1219
1241
|
this.channels[channelNumber].rpnLSB = value;
|
|
1220
1242
|
}
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
const rpn = channel.rpnMSB * 128 + channel.rpnLSB;
|
|
1225
|
-
isMSB ? channel.dataMSB = value : channel.dataLSB = value;
|
|
1226
|
-
const { dataMSB, dataLSB } = channel;
|
|
1227
|
-
switch (rpn) {
|
|
1228
|
-
case 0:
|
|
1229
|
-
return this.handlePitchBendRangeMessage(channelNumber, dataMSB, dataLSB);
|
|
1230
|
-
case 1:
|
|
1231
|
-
channel.fineTuning = (dataMSB * 128 + dataLSB - 8192) / 8192;
|
|
1232
|
-
break;
|
|
1233
|
-
case 2:
|
|
1234
|
-
channel.coarseTuning = dataMSB - 64;
|
|
1235
|
-
break;
|
|
1236
|
-
case 5:
|
|
1237
|
-
channel.modulationDepthRange = dataMSB + dataLSB / 128;
|
|
1238
|
-
break;
|
|
1239
|
-
default:
|
|
1240
|
-
console.warn(`Channel ${channelNumber}: Unsupported RPN MSB=${channel.rpnMSB} LSB=${channel.rpnLSB}`);
|
|
1241
|
-
}
|
|
1243
|
+
dataEntryMSB(channelNumber, value) {
|
|
1244
|
+
this.channels[channelNumber].dataMSB = value;
|
|
1245
|
+
this.handleRPN(channelNumber, 0);
|
|
1242
1246
|
}
|
|
1243
|
-
|
|
1244
|
-
const pitchBendRange = dataMSB + dataLSB / 100;
|
|
1245
|
-
this.setPitchBendRange(channelNumber, pitchBendRange);
|
|
1246
|
-
}
|
|
1247
|
-
setPitchBendRange(channelNumber, pitchBendRange) {
|
|
1247
|
+
updateDetune(channel, detuneChange) {
|
|
1248
1248
|
const now = this.audioContext.currentTime;
|
|
1249
|
-
const channel = this.channels[channelNumber];
|
|
1250
|
-
const prevPitchBendRange = channel.pitchBendRange;
|
|
1251
|
-
channel.pitchBendRange = pitchBendRange;
|
|
1252
|
-
const detuneChange = (channel.pitchBendRange - prevPitchBendRange) *
|
|
1253
|
-
channel.pitchBend * 100;
|
|
1254
1249
|
const activeNotes = this.getActiveNotes(channel, now);
|
|
1255
1250
|
activeNotes.forEach((activeNote) => {
|
|
1256
1251
|
const { bufferSource } = activeNote;
|
|
@@ -1260,6 +1255,58 @@ class Midy {
|
|
|
1260
1255
|
.setValueAtTime(detune, now);
|
|
1261
1256
|
});
|
|
1262
1257
|
}
|
|
1258
|
+
handlePitchBendRangeRPN(channelNumber) {
|
|
1259
|
+
const channel = this.channels[channelNumber];
|
|
1260
|
+
this.limitData(channel, 0, 127, 0, 99);
|
|
1261
|
+
const pitchBendRange = channel.dataMSB + channel.dataLSB / 100;
|
|
1262
|
+
this.setPitchBendRange(channelNumber, pitchBendRange);
|
|
1263
|
+
}
|
|
1264
|
+
setPitchBendRange(channelNumber, pitchBendRange) {
|
|
1265
|
+
const channel = this.channels[channelNumber];
|
|
1266
|
+
const prevPitchBendRange = channel.pitchBendRange;
|
|
1267
|
+
channel.pitchBendRange = pitchBendRange;
|
|
1268
|
+
const detuneChange = (channel.pitchBendRange - prevPitchBendRange) *
|
|
1269
|
+
channel.pitchBend * 100;
|
|
1270
|
+
this.updateDetune(channel, detuneChange);
|
|
1271
|
+
}
|
|
1272
|
+
handleFineTuningRPN(channelNumber) {
|
|
1273
|
+
const channel = this.channels[channelNumber];
|
|
1274
|
+
this.limitData(channel, 0, 127, 0, 127);
|
|
1275
|
+
const fineTuning = (channel.dataMSB * 128 + channel.dataLSB - 8192) / 8192;
|
|
1276
|
+
this.setFineTuning(channelNumber, fineTuning);
|
|
1277
|
+
}
|
|
1278
|
+
setFineTuning(channelNumber, fineTuning) {
|
|
1279
|
+
const channel = this.channels[channelNumber];
|
|
1280
|
+
const prevFineTuning = channel.fineTuning;
|
|
1281
|
+
channel.fineTuning = fineTuning;
|
|
1282
|
+
const detuneChange = channel.fineTuning - prevFineTuning;
|
|
1283
|
+
this.updateDetune(channel, detuneChange);
|
|
1284
|
+
}
|
|
1285
|
+
handleCoarseTuningRPN(channelNumber) {
|
|
1286
|
+
const channel = this.channels[channelNumber];
|
|
1287
|
+
this.limitDataMSB(channel, 0, 127);
|
|
1288
|
+
const coarseTuning = channel.dataMSB - 64;
|
|
1289
|
+
this.setFineTuning(channelNumber, coarseTuning);
|
|
1290
|
+
}
|
|
1291
|
+
setCoarseTuning(channelNumber, coarseTuning) {
|
|
1292
|
+
const channel = this.channels[channelNumber];
|
|
1293
|
+
const prevCoarseTuning = channel.coarseTuning;
|
|
1294
|
+
channel.coarseTuning = coarseTuning;
|
|
1295
|
+
const detuneChange = channel.coarseTuning - prevCoarseTuning;
|
|
1296
|
+
this.updateDetune(channel, detuneChange);
|
|
1297
|
+
}
|
|
1298
|
+
handleModulationDepthRangeRPN(channelNumber) {
|
|
1299
|
+
const channel = this.channels[channelNumber];
|
|
1300
|
+
this.limitData(channel, 0, 127, 0, 127);
|
|
1301
|
+
const modulationDepthRange = dataMSB + dataLSB / 128;
|
|
1302
|
+
this.setModulationDepthRange(channelNumber, modulationDepthRange);
|
|
1303
|
+
}
|
|
1304
|
+
setModulationDepthRange(channelNumber, modulationDepthRange) {
|
|
1305
|
+
const channel = this.channels[channelNumber];
|
|
1306
|
+
channel.modulationDepthRange = modulationDepthRange;
|
|
1307
|
+
channel.modulation = (modulation / 127) * channel.modulationDepthRange;
|
|
1308
|
+
this.updateModulation(channel);
|
|
1309
|
+
}
|
|
1263
1310
|
allSoundOff(channelNumber) {
|
|
1264
1311
|
const now = this.audioContext.currentTime;
|
|
1265
1312
|
const channel = this.channels[channelNumber];
|
|
@@ -1331,8 +1378,8 @@ class Midy {
|
|
|
1331
1378
|
channel.bankLSB = 0;
|
|
1332
1379
|
channel.bank = 0;
|
|
1333
1380
|
});
|
|
1334
|
-
this.channels[9].bankMSB =
|
|
1335
|
-
this.channels[9].bank =
|
|
1381
|
+
this.channels[9].bankMSB = 1;
|
|
1382
|
+
this.channels[9].bank = 128;
|
|
1336
1383
|
}
|
|
1337
1384
|
GM2SystemOn() {
|
|
1338
1385
|
this.channels.forEach((channel) => {
|
|
@@ -1349,9 +1396,9 @@ class Midy {
|
|
|
1349
1396
|
switch (data[3]) {
|
|
1350
1397
|
case 1:
|
|
1351
1398
|
return this.handleMasterVolumeSysEx(data);
|
|
1352
|
-
case 3:
|
|
1399
|
+
case 3: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca25.pdf
|
|
1353
1400
|
return this.handleMasterFineTuningSysEx(data);
|
|
1354
|
-
case 4:
|
|
1401
|
+
case 4: // https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/ca25.pdf
|
|
1355
1402
|
return this.handleMasterCoarseTuningSysEx(data);
|
|
1356
1403
|
// case 5: // TODO: Global Parameter Control
|
|
1357
1404
|
default:
|
|
@@ -1477,9 +1524,9 @@ Object.defineProperty(Midy, "channelSettings", {
|
|
|
1477
1524
|
dataLSB: 0,
|
|
1478
1525
|
program: 0,
|
|
1479
1526
|
pitchBend: 0,
|
|
1480
|
-
fineTuning: 0,
|
|
1481
|
-
coarseTuning: 0,
|
|
1482
|
-
modulationDepthRange: 0.5,
|
|
1527
|
+
fineTuning: 0, // cb
|
|
1528
|
+
coarseTuning: 0, // cb
|
|
1529
|
+
modulationDepthRange: 0.5, // cb
|
|
1483
1530
|
}
|
|
1484
1531
|
});
|
|
1485
1532
|
Object.defineProperty(Midy, "effectSettings", {
|