@marmooo/midy 0.1.3 → 0.1.5
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/deps/cdn.jsdelivr.net/npm/@marmooo/{soundfont-parser@0.0.4 → soundfont-parser@0.0.6}/+esm.d.ts +16 -20
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts.map +1 -0
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js +180 -0
- package/esm/midy-GM1.d.ts +32 -3
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +93 -87
- package/esm/midy-GM2.d.ts +56 -3
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +142 -126
- package/esm/midy-GMLite.d.ts +32 -3
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +91 -85
- package/esm/midy.d.ts +87 -4
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +234 -140
- package/package.json +1 -1
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/{soundfont-parser@0.0.4 → soundfont-parser@0.0.6}/+esm.d.ts +16 -20
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts.map +1 -0
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js +190 -0
- package/script/midy-GM1.d.ts +32 -3
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +93 -87
- package/script/midy-GM2.d.ts +56 -3
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +142 -126
- package/script/midy-GMLite.d.ts +32 -3
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +91 -85
- package/script/midy.d.ts +87 -4
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +234 -140
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts.map +0 -1
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.js +0 -162
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts.map +0 -1
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.js +0 -169
package/esm/midy-GM2.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parseMidi } from "./deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.js";
|
|
2
|
-
import { parse, SoundFont, } from "./deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.
|
|
2
|
+
import { parse, SoundFont, } from "./deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js";
|
|
3
3
|
class Note {
|
|
4
4
|
constructor(noteNumber, velocity, startTime, instrumentKey) {
|
|
5
5
|
Object.defineProperty(this, "bufferSource", {
|
|
@@ -230,6 +230,7 @@ export class MidyGM2 {
|
|
|
230
230
|
this.audioContext = audioContext;
|
|
231
231
|
this.options = { ...this.defaultOptions, ...options };
|
|
232
232
|
this.masterGain = new GainNode(audioContext);
|
|
233
|
+
this.controlChangeHandlers = this.createControlChangeHandlers();
|
|
233
234
|
this.channels = this.createChannels(audioContext);
|
|
234
235
|
this.reverbEffect = this.options.reverbAlgorithm(audioContext);
|
|
235
236
|
this.chorusEffect = this.createChorusEffect(audioContext);
|
|
@@ -545,12 +546,13 @@ export class MidyGM2 {
|
|
|
545
546
|
const now = this.audioContext.currentTime;
|
|
546
547
|
const channel = this.channels[channelNumber];
|
|
547
548
|
channel.scheduledNotes.forEach((noteList) => {
|
|
548
|
-
noteList.
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
549
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
550
|
+
const note = noteList[i];
|
|
551
|
+
if (!note)
|
|
552
|
+
continue;
|
|
553
|
+
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
|
|
554
|
+
this.notePromises.push(promise);
|
|
555
|
+
}
|
|
554
556
|
});
|
|
555
557
|
channel.scheduledNotes.clear();
|
|
556
558
|
await Promise.all(this.notePromises);
|
|
@@ -773,7 +775,6 @@ export class MidyGM2 {
|
|
|
773
775
|
}
|
|
774
776
|
setVolumeEnvelope(note) {
|
|
775
777
|
const { instrumentKey, startTime } = note;
|
|
776
|
-
note.volumeNode = new GainNode(this.audioContext, { gain: 0 });
|
|
777
778
|
const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
|
|
778
779
|
const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
|
|
779
780
|
const volDelay = startTime + instrumentKey.volDelay;
|
|
@@ -781,6 +782,8 @@ export class MidyGM2 {
|
|
|
781
782
|
const volHold = volAttack + instrumentKey.volHold;
|
|
782
783
|
const volDecay = volHold + instrumentKey.volDecay;
|
|
783
784
|
note.volumeNode.gain
|
|
785
|
+
.cancelScheduledValues(startTime)
|
|
786
|
+
.setValueAtTime(0, startTime)
|
|
784
787
|
.setValueAtTime(1e-6, volDelay) // exponentialRampToValueAtTime() requires a non-zero value
|
|
785
788
|
.exponentialRampToValueAtTime(attackVolume, volAttack)
|
|
786
789
|
.setValueAtTime(attackVolume, volHold)
|
|
@@ -804,29 +807,30 @@ export class MidyGM2 {
|
|
|
804
807
|
.setValueAtTime(peekPitch, modHold)
|
|
805
808
|
.linearRampToValueAtTime(basePitch, modDecay);
|
|
806
809
|
}
|
|
807
|
-
|
|
810
|
+
clampCutoffFrequency(frequency) {
|
|
811
|
+
const minFrequency = 20; // min Hz of initialFilterFc
|
|
812
|
+
const maxFrequency = 20000; // max Hz of initialFilterFc
|
|
813
|
+
return Math.max(minFrequency, Math.min(frequency, maxFrequency));
|
|
814
|
+
}
|
|
815
|
+
setFilterEnvelope(channel, note) {
|
|
808
816
|
const { instrumentKey, noteNumber, startTime } = note;
|
|
809
817
|
const softPedalFactor = 1 -
|
|
810
818
|
(0.1 + (noteNumber / 127) * 0.2) * channel.softPedal;
|
|
811
|
-
const maxFreq = this.audioContext.sampleRate / 2;
|
|
812
819
|
const baseFreq = this.centToHz(instrumentKey.initialFilterFc) *
|
|
813
820
|
softPedalFactor;
|
|
814
821
|
const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc) * softPedalFactor;
|
|
815
822
|
const sustainFreq = baseFreq +
|
|
816
823
|
(peekFreq - baseFreq) * (1 - instrumentKey.modSustain);
|
|
817
|
-
const adjustedBaseFreq =
|
|
818
|
-
const adjustedPeekFreq =
|
|
819
|
-
const adjustedSustainFreq =
|
|
824
|
+
const adjustedBaseFreq = this.clampCutoffFrequency(baseFreq);
|
|
825
|
+
const adjustedPeekFreq = this.clampCutoffFrequency(peekFreq);
|
|
826
|
+
const adjustedSustainFreq = this.clampCutoffFrequency(sustainFreq);
|
|
820
827
|
const modDelay = startTime + instrumentKey.modDelay;
|
|
821
828
|
const modAttack = modDelay + instrumentKey.modAttack;
|
|
822
829
|
const modHold = modAttack + instrumentKey.modHold;
|
|
823
830
|
const modDecay = modHold + instrumentKey.modDecay;
|
|
824
|
-
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
825
|
-
type: "lowpass",
|
|
826
|
-
Q: instrumentKey.initialFilterQ / 10, // dB
|
|
827
|
-
frequency: adjustedBaseFreq,
|
|
828
|
-
});
|
|
829
831
|
note.filterNode.frequency
|
|
832
|
+
.cancelScheduledValues(startTime)
|
|
833
|
+
.setValueAtTime(adjustedBaseFreq, startTime)
|
|
830
834
|
.setValueAtTime(adjustedBaseFreq, modDelay)
|
|
831
835
|
.exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
|
|
832
836
|
.setValueAtTime(adjustedPeekFreq, modHold)
|
|
@@ -879,8 +883,13 @@ export class MidyGM2 {
|
|
|
879
883
|
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
880
884
|
const note = new Note(noteNumber, velocity, startTime, instrumentKey);
|
|
881
885
|
note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
|
|
882
|
-
this.
|
|
886
|
+
note.volumeNode = new GainNode(this.audioContext);
|
|
887
|
+
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
888
|
+
type: "lowpass",
|
|
889
|
+
Q: instrumentKey.initialFilterQ / 10 * channel.filterResonance, // dB
|
|
890
|
+
});
|
|
883
891
|
this.setVolumeEnvelope(note);
|
|
892
|
+
this.setFilterEnvelope(channel, note);
|
|
884
893
|
if (0 < channel.vibratoDepth) {
|
|
885
894
|
this.startVibrato(channel, note, startTime);
|
|
886
895
|
}
|
|
@@ -917,7 +926,7 @@ export class MidyGM2 {
|
|
|
917
926
|
return;
|
|
918
927
|
const soundFont = this.soundFonts[soundFontIndex];
|
|
919
928
|
const isSF3 = soundFont.parsed.info.version.major === 3;
|
|
920
|
-
const instrumentKey = soundFont.getInstrumentKey(bankNumber, channel.program, noteNumber);
|
|
929
|
+
const instrumentKey = soundFont.getInstrumentKey(bankNumber, channel.program, noteNumber, velocity);
|
|
921
930
|
if (!instrumentKey)
|
|
922
931
|
return;
|
|
923
932
|
const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
|
|
@@ -938,12 +947,14 @@ export class MidyGM2 {
|
|
|
938
947
|
const now = this.audioContext.currentTime;
|
|
939
948
|
return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now);
|
|
940
949
|
}
|
|
941
|
-
scheduleNoteRelease(channelNumber, noteNumber,
|
|
950
|
+
scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, stopPedal = false) {
|
|
942
951
|
const channel = this.channels[channelNumber];
|
|
943
|
-
if (stopPedal
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
952
|
+
if (stopPedal) {
|
|
953
|
+
if (channel.sustainPedal)
|
|
954
|
+
return;
|
|
955
|
+
if (channel.sostenutoNotes.has(noteNumber))
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
947
958
|
if (!channel.scheduledNotes.has(noteNumber))
|
|
948
959
|
return;
|
|
949
960
|
const scheduledNotes = channel.scheduledNotes.get(noteNumber);
|
|
@@ -953,14 +964,11 @@ export class MidyGM2 {
|
|
|
953
964
|
continue;
|
|
954
965
|
if (note.ending)
|
|
955
966
|
continue;
|
|
956
|
-
const
|
|
957
|
-
const volEndTime = stopTime +
|
|
958
|
-
note.instrumentKey.volRelease * velocityRate;
|
|
967
|
+
const volEndTime = stopTime + note.instrumentKey.volRelease;
|
|
959
968
|
note.volumeNode.gain
|
|
960
969
|
.cancelScheduledValues(stopTime)
|
|
961
970
|
.linearRampToValueAtTime(0, volEndTime);
|
|
962
|
-
const modRelease = stopTime +
|
|
963
|
-
note.instrumentKey.modRelease * velocityRate;
|
|
971
|
+
const modRelease = stopTime + note.instrumentKey.modRelease;
|
|
964
972
|
note.filterNode.frequency
|
|
965
973
|
.cancelScheduledValues(stopTime)
|
|
966
974
|
.linearRampToValueAtTime(0, modRelease);
|
|
@@ -974,16 +982,11 @@ export class MidyGM2 {
|
|
|
974
982
|
note.bufferSource.disconnect();
|
|
975
983
|
note.volumeNode.disconnect();
|
|
976
984
|
note.filterNode.disconnect();
|
|
977
|
-
if (note.
|
|
985
|
+
if (note.modulationDepth) {
|
|
978
986
|
note.volumeDepth.disconnect();
|
|
979
|
-
if (note.modulationDepth)
|
|
980
987
|
note.modulationDepth.disconnect();
|
|
981
|
-
if (note.modulationLFO)
|
|
982
988
|
note.modulationLFO.stop();
|
|
983
|
-
|
|
984
|
-
note.vibratoDepth.disconnect();
|
|
985
|
-
if (note.vibratoLFO)
|
|
986
|
-
note.vibratoLFO.stop();
|
|
989
|
+
}
|
|
987
990
|
resolve();
|
|
988
991
|
};
|
|
989
992
|
note.bufferSource.stop(volEndTime);
|
|
@@ -1000,13 +1003,14 @@ export class MidyGM2 {
|
|
|
1000
1003
|
const promises = [];
|
|
1001
1004
|
channel.sustainPedal = false;
|
|
1002
1005
|
channel.scheduledNotes.forEach((noteList) => {
|
|
1003
|
-
noteList.
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1006
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1007
|
+
const note = noteList[i];
|
|
1008
|
+
if (!note)
|
|
1009
|
+
continue;
|
|
1010
|
+
const { noteNumber } = note;
|
|
1011
|
+
const promise = this.releaseNote(channelNumber, noteNumber, velocity);
|
|
1012
|
+
promises.push(promise);
|
|
1013
|
+
}
|
|
1010
1014
|
});
|
|
1011
1015
|
return promises;
|
|
1012
1016
|
}
|
|
@@ -1075,58 +1079,41 @@ export class MidyGM2 {
|
|
|
1075
1079
|
channel.pitchBendRange * 100;
|
|
1076
1080
|
this.updateDetune(channel, detuneChange);
|
|
1077
1081
|
}
|
|
1082
|
+
createControlChangeHandlers() {
|
|
1083
|
+
return {
|
|
1084
|
+
0: this.setBankMSB,
|
|
1085
|
+
1: this.setModulationDepth,
|
|
1086
|
+
5: this.setPortamentoTime,
|
|
1087
|
+
6: this.dataEntryMSB,
|
|
1088
|
+
7: this.setVolume,
|
|
1089
|
+
10: this.setPan,
|
|
1090
|
+
11: this.setExpression,
|
|
1091
|
+
32: this.setBankLSB,
|
|
1092
|
+
38: this.dataEntryLSB,
|
|
1093
|
+
64: this.setSustainPedal,
|
|
1094
|
+
65: this.setPortamento,
|
|
1095
|
+
66: this.setSostenutoPedal,
|
|
1096
|
+
67: this.setSoftPedal,
|
|
1097
|
+
91: this.setReverbSendLevel,
|
|
1098
|
+
93: this.setChorusSendLevel,
|
|
1099
|
+
100: this.setRPNLSB,
|
|
1100
|
+
101: this.setRPNMSB,
|
|
1101
|
+
120: this.allSoundOff,
|
|
1102
|
+
121: this.resetAllControllers,
|
|
1103
|
+
123: this.allNotesOff,
|
|
1104
|
+
124: this.omniOff,
|
|
1105
|
+
125: this.omniOn,
|
|
1106
|
+
126: this.monoOn,
|
|
1107
|
+
127: this.polyOn,
|
|
1108
|
+
};
|
|
1109
|
+
}
|
|
1078
1110
|
handleControlChange(channelNumber, controller, value) {
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
return this.setPortamentoTime(channelNumber, value);
|
|
1086
|
-
case 6:
|
|
1087
|
-
return this.dataEntryMSB(channelNumber, value);
|
|
1088
|
-
case 7:
|
|
1089
|
-
return this.setVolume(channelNumber, value);
|
|
1090
|
-
case 10:
|
|
1091
|
-
return this.setPan(channelNumber, value);
|
|
1092
|
-
case 11:
|
|
1093
|
-
return this.setExpression(channelNumber, value);
|
|
1094
|
-
case 32:
|
|
1095
|
-
return this.setBankLSB(channelNumber, value);
|
|
1096
|
-
case 38:
|
|
1097
|
-
return this.dataEntryLSB(channelNumber, value);
|
|
1098
|
-
case 64:
|
|
1099
|
-
return this.setSustainPedal(channelNumber, value);
|
|
1100
|
-
case 65:
|
|
1101
|
-
return this.setPortamento(channelNumber, value);
|
|
1102
|
-
case 66:
|
|
1103
|
-
return this.setSostenutoPedal(channelNumber, value);
|
|
1104
|
-
case 67:
|
|
1105
|
-
return this.setSoftPedal(channelNumber, value);
|
|
1106
|
-
case 91:
|
|
1107
|
-
return this.setReverbSendLevel(channelNumber, value);
|
|
1108
|
-
case 93:
|
|
1109
|
-
return this.setChorusSendLevel(channelNumber, value);
|
|
1110
|
-
case 100:
|
|
1111
|
-
return this.setRPNLSB(channelNumber, value);
|
|
1112
|
-
case 101:
|
|
1113
|
-
return this.setRPNMSB(channelNumber, value);
|
|
1114
|
-
case 120:
|
|
1115
|
-
return this.allSoundOff(channelNumber);
|
|
1116
|
-
case 121:
|
|
1117
|
-
return this.resetAllControllers(channelNumber);
|
|
1118
|
-
case 123:
|
|
1119
|
-
return this.allNotesOff(channelNumber);
|
|
1120
|
-
case 124:
|
|
1121
|
-
return this.omniOff();
|
|
1122
|
-
case 125:
|
|
1123
|
-
return this.omniOn();
|
|
1124
|
-
case 126:
|
|
1125
|
-
return this.monoOn();
|
|
1126
|
-
case 127:
|
|
1127
|
-
return this.polyOn();
|
|
1128
|
-
default:
|
|
1129
|
-
console.warn(`Unsupported Control change: controller=${controller} value=${value}`);
|
|
1111
|
+
const handler = this.controlChangeHandlers[controller];
|
|
1112
|
+
if (handler) {
|
|
1113
|
+
handler.call(this, channelNumber, value);
|
|
1114
|
+
}
|
|
1115
|
+
else {
|
|
1116
|
+
console.warn(`Unsupported Control change: controller=${controller} value=${value}`);
|
|
1130
1117
|
}
|
|
1131
1118
|
}
|
|
1132
1119
|
setBankMSB(channelNumber, msb) {
|
|
@@ -1134,15 +1121,19 @@ export class MidyGM2 {
|
|
|
1134
1121
|
}
|
|
1135
1122
|
updateModulation(channel) {
|
|
1136
1123
|
const now = this.audioContext.currentTime;
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1124
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1125
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1126
|
+
const note = noteList[i];
|
|
1127
|
+
if (!note)
|
|
1128
|
+
continue;
|
|
1129
|
+
if (note.modulationDepth) {
|
|
1130
|
+
note.modulationDepth.gain.setValueAtTime(channel.modulationDepth, now);
|
|
1131
|
+
}
|
|
1132
|
+
else {
|
|
1133
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
1134
|
+
this.setPitch(note, semitoneOffset);
|
|
1135
|
+
this.startModulation(channel, note, now);
|
|
1136
|
+
}
|
|
1146
1137
|
}
|
|
1147
1138
|
});
|
|
1148
1139
|
}
|
|
@@ -1207,28 +1198,49 @@ export class MidyGM2 {
|
|
|
1207
1198
|
}
|
|
1208
1199
|
setReverbSendLevel(channelNumber, reverbSendLevel) {
|
|
1209
1200
|
const channel = this.channels[channelNumber];
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1201
|
+
if (0 < channel.reverbSendLevel) {
|
|
1202
|
+
if (0 < reverbSendLevel) {
|
|
1203
|
+
const now = this.audioContext.currentTime;
|
|
1204
|
+
channel.reverbSendLevel = reverbSendLevel / 127;
|
|
1205
|
+
reverbEffect.output.gain.cancelScheduledValues(now);
|
|
1206
|
+
reverbEffect.output.gain.setValueAtTime(channel.reverbSendLevel, now);
|
|
1207
|
+
}
|
|
1208
|
+
else {
|
|
1209
|
+
channel.merger.disconnect(reverbEffect.input);
|
|
1210
|
+
}
|
|
1216
1211
|
}
|
|
1217
|
-
else
|
|
1218
|
-
|
|
1212
|
+
else {
|
|
1213
|
+
if (0 < reverbSendLevel) {
|
|
1214
|
+
channel.merger.connect(reverbEffect.input);
|
|
1215
|
+
const now = this.audioContext.currentTime;
|
|
1216
|
+
channel.reverbSendLevel = reverbSendLevel / 127;
|
|
1217
|
+
reverbEffect.output.gain.cancelScheduledValues(now);
|
|
1218
|
+
reverbEffect.output.gain.setValueAtTime(channel.reverbSendLevel, now);
|
|
1219
|
+
}
|
|
1219
1220
|
}
|
|
1220
1221
|
}
|
|
1221
1222
|
setChorusSendLevel(channelNumber, chorusSendLevel) {
|
|
1222
1223
|
const channel = this.channels[channelNumber];
|
|
1223
1224
|
const chorusEffect = this.chorusEffect;
|
|
1224
|
-
if (0 < chorusSendLevel) {
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1225
|
+
if (0 < channel.chorusSendLevel) {
|
|
1226
|
+
if (0 < chorusSendLevel) {
|
|
1227
|
+
const now = this.audioContext.currentTime;
|
|
1228
|
+
channel.chorusSendLevel = chorusSendLevel / 127;
|
|
1229
|
+
chorusEffect.output.gain.cancelScheduledValues(now);
|
|
1230
|
+
chorusEffect.output.gain.setValueAtTime(channel.chorusSendLevel, now);
|
|
1231
|
+
}
|
|
1232
|
+
else {
|
|
1233
|
+
channel.merger.disconnect(chorusEffect.input);
|
|
1234
|
+
}
|
|
1229
1235
|
}
|
|
1230
|
-
else
|
|
1231
|
-
|
|
1236
|
+
else {
|
|
1237
|
+
if (0 < chorusSendLevel) {
|
|
1238
|
+
channel.merger.connect(chorusEffect.input);
|
|
1239
|
+
const now = this.audioContext.currentTime;
|
|
1240
|
+
channel.chorusSendLevel = chorusSendLevel / 127;
|
|
1241
|
+
chorusEffect.output.gain.cancelScheduledValues(now);
|
|
1242
|
+
chorusEffect.output.gain.setValueAtTime(channel.chorusSendLevel, now);
|
|
1243
|
+
}
|
|
1232
1244
|
}
|
|
1233
1245
|
}
|
|
1234
1246
|
setSostenutoPedal(channelNumber, value) {
|
|
@@ -1306,13 +1318,17 @@ export class MidyGM2 {
|
|
|
1306
1318
|
}
|
|
1307
1319
|
updateDetune(channel, detuneChange) {
|
|
1308
1320
|
const now = this.audioContext.currentTime;
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
.
|
|
1321
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1322
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1323
|
+
const note = noteList[i];
|
|
1324
|
+
if (!note)
|
|
1325
|
+
continue;
|
|
1326
|
+
const { bufferSource } = note;
|
|
1327
|
+
const detune = bufferSource.detune.value + detuneChange;
|
|
1328
|
+
bufferSource.detune
|
|
1329
|
+
.cancelScheduledValues(now)
|
|
1330
|
+
.setValueAtTime(detune, now);
|
|
1331
|
+
}
|
|
1316
1332
|
});
|
|
1317
1333
|
}
|
|
1318
1334
|
handlePitchBendRangeRPN(channelNumber) {
|
package/esm/midy-GMLite.d.ts
CHANGED
|
@@ -37,6 +37,20 @@ export class MidyGMLite {
|
|
|
37
37
|
notePromises: any[];
|
|
38
38
|
audioContext: any;
|
|
39
39
|
masterGain: any;
|
|
40
|
+
controlChangeHandlers: {
|
|
41
|
+
1: (channelNumber: any, modulation: any) => void;
|
|
42
|
+
6: (channelNumber: any, value: any) => void;
|
|
43
|
+
7: (channelNumber: any, volume: any) => void;
|
|
44
|
+
10: (channelNumber: any, pan: any) => void;
|
|
45
|
+
11: (channelNumber: any, expression: any) => void;
|
|
46
|
+
38: (channelNumber: any, value: any) => void;
|
|
47
|
+
64: (channelNumber: any, value: any) => void;
|
|
48
|
+
100: (channelNumber: any, value: any) => void;
|
|
49
|
+
101: (channelNumber: any, value: any) => void;
|
|
50
|
+
120: (channelNumber: any) => Promise<void>;
|
|
51
|
+
121: (channelNumber: any) => void;
|
|
52
|
+
123: (channelNumber: any) => Promise<void>;
|
|
53
|
+
};
|
|
40
54
|
channels: any[];
|
|
41
55
|
initSoundFontTable(): any[];
|
|
42
56
|
addSoundFont(soundFont: any): void;
|
|
@@ -77,19 +91,34 @@ export class MidyGMLite {
|
|
|
77
91
|
calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
|
|
78
92
|
setVolumeEnvelope(note: any): void;
|
|
79
93
|
setPitch(note: any, semitoneOffset: any): void;
|
|
80
|
-
|
|
94
|
+
clampCutoffFrequency(frequency: any): number;
|
|
95
|
+
setFilterEnvelope(note: any): void;
|
|
81
96
|
startModulation(channel: any, note: any, startTime: any): void;
|
|
82
97
|
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
83
98
|
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
84
99
|
noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
|
|
85
|
-
scheduleNoteRelease(channelNumber: any, noteNumber: any,
|
|
100
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, stopPedal?: boolean): Promise<any> | undefined;
|
|
86
101
|
releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
|
|
87
102
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
88
103
|
handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
|
|
89
104
|
handleProgramChange(channelNumber: any, program: any): void;
|
|
90
105
|
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
|
|
91
106
|
setPitchBend(channelNumber: any, pitchBend: any): void;
|
|
92
|
-
|
|
107
|
+
createControlChangeHandlers(): {
|
|
108
|
+
1: (channelNumber: any, modulation: any) => void;
|
|
109
|
+
6: (channelNumber: any, value: any) => void;
|
|
110
|
+
7: (channelNumber: any, volume: any) => void;
|
|
111
|
+
10: (channelNumber: any, pan: any) => void;
|
|
112
|
+
11: (channelNumber: any, expression: any) => void;
|
|
113
|
+
38: (channelNumber: any, value: any) => void;
|
|
114
|
+
64: (channelNumber: any, value: any) => void;
|
|
115
|
+
100: (channelNumber: any, value: any) => void;
|
|
116
|
+
101: (channelNumber: any, value: any) => void;
|
|
117
|
+
120: (channelNumber: any) => Promise<void>;
|
|
118
|
+
121: (channelNumber: any) => void;
|
|
119
|
+
123: (channelNumber: any) => Promise<void>;
|
|
120
|
+
};
|
|
121
|
+
handleControlChange(channelNumber: any, controller: any, value: any): void;
|
|
93
122
|
updateModulation(channel: any): void;
|
|
94
123
|
setModulationDepth(channelNumber: any, modulation: any): void;
|
|
95
124
|
setVolume(channelNumber: any, volume: 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":"AAsBA;IAmBE;;;;;;;;;MASE;IAEF;;;;;;;MAOE;IAEF,+
|
|
1
|
+
{"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAsBA;IAmBE;;;;;;;;;MASE;IAEF;;;;;;;MAOE;IAEF,+BAOC;IA7CD,qBAAmB;IACnB,kBAAc;IACd,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;IAuBhB,kBAAgC;IAChC,gBAA4C;IAC5C;;;;;;;;;;;;;MAA+D;IAC/D,gBAAiD;IAKnD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;MAeC;IAED,yCAUC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EA+CC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MA8DC;IAED,mFAmBC;IAED,yDAKC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED,2BAEC;IAED,4BAEC;IAED,yCAEC;IAED,mFAGC;IAED,mCAeC;IAED,+CAwBC;IAED,6CAIC;IAED,mCAsBC;IAED,+DA0BC;IAED,wHAmCC;IAED,kGA8BC;IAED,0EAGC;IAED,uIA2CC;IAED,0FAGC;IAED,kEAeC;IAED,gFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED;;;;;;;;;;;;;MAeC;IAED,2EASC;IAED,qCAkBC;IAED,8DAIC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,sCAUC;IAED,sDAMC;IAED,oCAYC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAaC;IAED,kDAKC;IAED,iEAOC;IAED,+CAEC;IAED,8CAEC;IAED,+CAEC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AAj/BD;IAQE,gFAKC;IAZD,kBAAa;IACb,gBAAW;IACX,gBAAW;IACX,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
|