@marmooo/midy 0.1.3 → 0.1.4
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 +3 -2
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +66 -55
- package/esm/midy-GM2.d.ts +3 -2
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +61 -47
- package/esm/midy-GMLite.d.ts +3 -2
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +64 -53
- package/esm/midy.d.ts +14 -3
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +140 -53
- package/package.json +1 -1
- package/script/midy-GM1.d.ts +3 -2
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +66 -55
- package/script/midy-GM2.d.ts +3 -2
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +61 -47
- package/script/midy-GMLite.d.ts +3 -2
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +64 -53
- package/script/midy.d.ts +14 -3
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +140 -53
package/script/midy.d.ts
CHANGED
|
@@ -4,6 +4,11 @@ export class Midy {
|
|
|
4
4
|
volume: number;
|
|
5
5
|
pan: number;
|
|
6
6
|
portamentoTime: number;
|
|
7
|
+
filterResonance: number;
|
|
8
|
+
releaseTime: number;
|
|
9
|
+
attackTime: number;
|
|
10
|
+
brightness: number;
|
|
11
|
+
decayTime: number;
|
|
7
12
|
reverbSendLevel: number;
|
|
8
13
|
chorusSendLevel: number;
|
|
9
14
|
vibratoRate: number;
|
|
@@ -165,16 +170,17 @@ export class Midy {
|
|
|
165
170
|
centToHz(cent: any): number;
|
|
166
171
|
calcSemitoneOffset(channel: any): any;
|
|
167
172
|
calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
|
|
168
|
-
setVolumeEnvelope(note: any): void;
|
|
173
|
+
setVolumeEnvelope(channel: any, note: any): void;
|
|
169
174
|
setPitch(note: any, semitoneOffset: any): void;
|
|
170
|
-
|
|
175
|
+
clampCutoffFrequency(frequency: any): number;
|
|
176
|
+
setFilterEnvelope(channel: any, note: any): void;
|
|
171
177
|
startModulation(channel: any, note: any, startTime: any): void;
|
|
172
178
|
startVibrato(channel: any, note: any, startTime: any): void;
|
|
173
179
|
createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
|
|
174
180
|
calcBank(channel: any, channelNumber: any): any;
|
|
175
181
|
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
|
|
176
182
|
noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
|
|
177
|
-
scheduleNoteRelease(channelNumber: any, noteNumber: any,
|
|
183
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, stopTime: any, stopPedal?: boolean): Promise<any> | undefined;
|
|
178
184
|
releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
|
|
179
185
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
180
186
|
releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
|
|
@@ -205,6 +211,11 @@ export class Midy {
|
|
|
205
211
|
setChorusSendLevel(channelNumber: any, chorusSendLevel: any): void;
|
|
206
212
|
setSostenutoPedal(channelNumber: any, value: any): void;
|
|
207
213
|
setSoftPedal(channelNumber: any, softPedal: any): void;
|
|
214
|
+
setFilterResonance(channelNumber: any, filterResonance: any): void;
|
|
215
|
+
setReleaseTime(channelNumber: any, releaseTime: any): void;
|
|
216
|
+
setAttackTime(channelNumber: any, attackTime: any): void;
|
|
217
|
+
setBrightness(channelNumber: any, brightness: any): void;
|
|
218
|
+
setDecayTime(channelNumber: any, dacayTime: any): void;
|
|
208
219
|
setVibratoRate(channelNumber: any, vibratoRate: any): void;
|
|
209
220
|
setVibratoDepth(channelNumber: any, vibratoDepth: any): void;
|
|
210
221
|
setVibratoDelay(channelNumber: any, vibratoDelay: any): void;
|
package/script/midy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAwBA;IAkCE
|
|
1
|
+
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}
|
package/script/midy.js
CHANGED
|
@@ -554,12 +554,13 @@ class Midy {
|
|
|
554
554
|
const now = this.audioContext.currentTime;
|
|
555
555
|
const channel = this.channels[channelNumber];
|
|
556
556
|
channel.scheduledNotes.forEach((noteList) => {
|
|
557
|
-
noteList.
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
557
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
558
|
+
const note = noteList[i];
|
|
559
|
+
if (!note)
|
|
560
|
+
continue;
|
|
561
|
+
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
|
|
562
|
+
this.notePromises.push(promise);
|
|
563
|
+
}
|
|
563
564
|
});
|
|
564
565
|
channel.scheduledNotes.clear();
|
|
565
566
|
await Promise.all(this.notePromises);
|
|
@@ -780,16 +781,17 @@ class Midy {
|
|
|
780
781
|
return instrumentKey.playbackRate(noteNumber) *
|
|
781
782
|
Math.pow(2, semitoneOffset / 12);
|
|
782
783
|
}
|
|
783
|
-
setVolumeEnvelope(note) {
|
|
784
|
+
setVolumeEnvelope(channel, note) {
|
|
784
785
|
const { instrumentKey, startTime } = note;
|
|
785
|
-
note.volumeNode = new GainNode(this.audioContext, { gain: 0 });
|
|
786
786
|
const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
|
|
787
787
|
const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
|
|
788
788
|
const volDelay = startTime + instrumentKey.volDelay;
|
|
789
|
-
const volAttack = volDelay + instrumentKey.volAttack;
|
|
789
|
+
const volAttack = volDelay + instrumentKey.volAttack * channel.attackTime;
|
|
790
790
|
const volHold = volAttack + instrumentKey.volHold;
|
|
791
|
-
const volDecay = volHold + instrumentKey.volDecay;
|
|
791
|
+
const volDecay = volHold + instrumentKey.volDecay * channel.decayTime;
|
|
792
792
|
note.volumeNode.gain
|
|
793
|
+
.cancelScheduledValues(startTime)
|
|
794
|
+
.setValueAtTime(0, startTime)
|
|
793
795
|
.setValueAtTime(1e-6, volDelay) // exponentialRampToValueAtTime() requires a non-zero value
|
|
794
796
|
.exponentialRampToValueAtTime(attackVolume, volAttack)
|
|
795
797
|
.setValueAtTime(attackVolume, volHold)
|
|
@@ -813,29 +815,30 @@ class Midy {
|
|
|
813
815
|
.setValueAtTime(peekPitch, modHold)
|
|
814
816
|
.linearRampToValueAtTime(basePitch, modDecay);
|
|
815
817
|
}
|
|
816
|
-
|
|
818
|
+
clampCutoffFrequency(frequency) {
|
|
819
|
+
const minFrequency = 20; // min Hz of initialFilterFc
|
|
820
|
+
const maxFrequency = 20000; // max Hz of initialFilterFc
|
|
821
|
+
return Math.max(minFrequency, Math.min(frequency, maxFrequency));
|
|
822
|
+
}
|
|
823
|
+
setFilterEnvelope(channel, note) {
|
|
817
824
|
const { instrumentKey, noteNumber, startTime } = note;
|
|
818
825
|
const softPedalFactor = 1 -
|
|
819
826
|
(0.1 + (noteNumber / 127) * 0.2) * channel.softPedal;
|
|
820
|
-
const maxFreq = this.audioContext.sampleRate / 2;
|
|
821
827
|
const baseFreq = this.centToHz(instrumentKey.initialFilterFc) *
|
|
822
|
-
softPedalFactor;
|
|
823
|
-
const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc) * softPedalFactor;
|
|
828
|
+
softPedalFactor * channel.brightness;
|
|
829
|
+
const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc) * softPedalFactor * channel.brightness;
|
|
824
830
|
const sustainFreq = baseFreq +
|
|
825
831
|
(peekFreq - baseFreq) * (1 - instrumentKey.modSustain);
|
|
826
|
-
const adjustedBaseFreq =
|
|
827
|
-
const adjustedPeekFreq =
|
|
828
|
-
const adjustedSustainFreq =
|
|
832
|
+
const adjustedBaseFreq = this.clampCutoffFrequency(baseFreq);
|
|
833
|
+
const adjustedPeekFreq = this.clampCutoffFrequency(peekFreq);
|
|
834
|
+
const adjustedSustainFreq = this.clampCutoffFrequency(sustainFreq);
|
|
829
835
|
const modDelay = startTime + instrumentKey.modDelay;
|
|
830
836
|
const modAttack = modDelay + instrumentKey.modAttack;
|
|
831
837
|
const modHold = modAttack + instrumentKey.modHold;
|
|
832
838
|
const modDecay = modHold + instrumentKey.modDecay;
|
|
833
|
-
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
834
|
-
type: "lowpass",
|
|
835
|
-
Q: instrumentKey.initialFilterQ / 10, // dB
|
|
836
|
-
frequency: adjustedBaseFreq,
|
|
837
|
-
});
|
|
838
839
|
note.filterNode.frequency
|
|
840
|
+
.cancelScheduledValues(startTime)
|
|
841
|
+
.setValueAtTime(adjustedBaseFreq, startTime)
|
|
839
842
|
.setValueAtTime(adjustedBaseFreq, modDelay)
|
|
840
843
|
.exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
|
|
841
844
|
.setValueAtTime(adjustedPeekFreq, modHold)
|
|
@@ -888,8 +891,13 @@ class Midy {
|
|
|
888
891
|
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
889
892
|
const note = new Note(noteNumber, velocity, startTime, instrumentKey);
|
|
890
893
|
note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
|
|
891
|
-
this.
|
|
892
|
-
this.
|
|
894
|
+
note.volumeNode = new GainNode(this.audioContext);
|
|
895
|
+
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
896
|
+
type: "lowpass",
|
|
897
|
+
Q: instrumentKey.initialFilterQ / 10 * channel.filterResonance, // dB
|
|
898
|
+
});
|
|
899
|
+
this.setVolumeEnvelope(channel, note);
|
|
900
|
+
this.setFilterEnvelope(channel, note);
|
|
893
901
|
if (0 < channel.vibratoDepth) {
|
|
894
902
|
this.startVibrato(channel, note, startTime);
|
|
895
903
|
}
|
|
@@ -947,7 +955,7 @@ class Midy {
|
|
|
947
955
|
const now = this.audioContext.currentTime;
|
|
948
956
|
return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now);
|
|
949
957
|
}
|
|
950
|
-
scheduleNoteRelease(channelNumber, noteNumber,
|
|
958
|
+
scheduleNoteRelease(channelNumber, noteNumber, _velocity, stopTime, stopPedal = false) {
|
|
951
959
|
const channel = this.channels[channelNumber];
|
|
952
960
|
if (stopPedal && channel.sustainPedal)
|
|
953
961
|
return;
|
|
@@ -962,14 +970,12 @@ class Midy {
|
|
|
962
970
|
continue;
|
|
963
971
|
if (note.ending)
|
|
964
972
|
continue;
|
|
965
|
-
const velocityRate = (velocity + 127) / 127;
|
|
966
973
|
const volEndTime = stopTime +
|
|
967
|
-
note.instrumentKey.volRelease *
|
|
974
|
+
note.instrumentKey.volRelease * channel.releaseTime;
|
|
968
975
|
note.volumeNode.gain
|
|
969
976
|
.cancelScheduledValues(stopTime)
|
|
970
977
|
.linearRampToValueAtTime(0, volEndTime);
|
|
971
|
-
const modRelease = stopTime +
|
|
972
|
-
note.instrumentKey.modRelease * velocityRate;
|
|
978
|
+
const modRelease = stopTime + note.instrumentKey.modRelease;
|
|
973
979
|
note.filterNode.frequency
|
|
974
980
|
.cancelScheduledValues(stopTime)
|
|
975
981
|
.linearRampToValueAtTime(0, modRelease);
|
|
@@ -1009,13 +1015,14 @@ class Midy {
|
|
|
1009
1015
|
const promises = [];
|
|
1010
1016
|
channel.sustainPedal = false;
|
|
1011
1017
|
channel.scheduledNotes.forEach((noteList) => {
|
|
1012
|
-
noteList.
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1018
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1019
|
+
const note = noteList[i];
|
|
1020
|
+
if (!note)
|
|
1021
|
+
continue;
|
|
1022
|
+
const { noteNumber } = note;
|
|
1023
|
+
const promise = this.releaseNote(channelNumber, noteNumber, velocity);
|
|
1024
|
+
promises.push(promise);
|
|
1025
|
+
}
|
|
1019
1026
|
});
|
|
1020
1027
|
return promises;
|
|
1021
1028
|
}
|
|
@@ -1129,7 +1136,16 @@ class Midy {
|
|
|
1129
1136
|
return this.setSostenutoPedal(channelNumber, value);
|
|
1130
1137
|
case 67:
|
|
1131
1138
|
return this.setSoftPedal(channelNumber, value);
|
|
1132
|
-
|
|
1139
|
+
case 71:
|
|
1140
|
+
return this.setFilterResonance(channelNumber, value);
|
|
1141
|
+
case 72:
|
|
1142
|
+
return this.setReleaseTime(channelNumber, value);
|
|
1143
|
+
case 73:
|
|
1144
|
+
return this.setAttackTime(channelNumber, value);
|
|
1145
|
+
case 74:
|
|
1146
|
+
return this.setBrightness(channelNumber, value);
|
|
1147
|
+
case 75:
|
|
1148
|
+
return this.setDecayTime(channelNumber, value);
|
|
1133
1149
|
case 76:
|
|
1134
1150
|
return this.setVibratoRate(channelNumber, value);
|
|
1135
1151
|
case 77:
|
|
@@ -1171,15 +1187,19 @@ class Midy {
|
|
|
1171
1187
|
}
|
|
1172
1188
|
updateModulation(channel) {
|
|
1173
1189
|
const now = this.audioContext.currentTime;
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1190
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1191
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1192
|
+
const note = noteList[i];
|
|
1193
|
+
if (!note)
|
|
1194
|
+
continue;
|
|
1195
|
+
if (note.modulationDepth) {
|
|
1196
|
+
note.modulationDepth.gain.setValueAtTime(channel.modulationDepth, now);
|
|
1197
|
+
}
|
|
1198
|
+
else {
|
|
1199
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
1200
|
+
this.setPitch(note, semitoneOffset);
|
|
1201
|
+
this.startModulation(channel, note, now);
|
|
1202
|
+
}
|
|
1183
1203
|
}
|
|
1184
1204
|
});
|
|
1185
1205
|
}
|
|
@@ -1285,6 +1305,64 @@ class Midy {
|
|
|
1285
1305
|
const channel = this.channels[channelNumber];
|
|
1286
1306
|
channel.softPedal = softPedal / 127;
|
|
1287
1307
|
}
|
|
1308
|
+
setFilterResonance(channelNumber, filterResonance) {
|
|
1309
|
+
const now = this.audioContext.currentTime;
|
|
1310
|
+
const channel = this.channels[channelNumber];
|
|
1311
|
+
channel.filterResonance = filterResonance / 64;
|
|
1312
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1313
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1314
|
+
const note = noteList[i];
|
|
1315
|
+
if (!note)
|
|
1316
|
+
continue;
|
|
1317
|
+
const Q = note.instrumentKey.initialFilterQ / 10 *
|
|
1318
|
+
channel.filterResonance;
|
|
1319
|
+
note.filterNode.Q.setValueAtTime(Q, now);
|
|
1320
|
+
}
|
|
1321
|
+
});
|
|
1322
|
+
}
|
|
1323
|
+
setReleaseTime(channelNumber, releaseTime) {
|
|
1324
|
+
const channel = this.channels[channelNumber];
|
|
1325
|
+
channel.releaseTime = releaseTime / 64;
|
|
1326
|
+
}
|
|
1327
|
+
setAttackTime(channelNumber, attackTime) {
|
|
1328
|
+
const now = this.audioContext.currentTime;
|
|
1329
|
+
const channel = this.channels[channelNumber];
|
|
1330
|
+
channel.attackTime = attackTime / 64;
|
|
1331
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1332
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1333
|
+
const note = noteList[i];
|
|
1334
|
+
if (!note)
|
|
1335
|
+
continue;
|
|
1336
|
+
if (note.startTime < now)
|
|
1337
|
+
continue;
|
|
1338
|
+
this.setVolumeEnvelope(channel, note);
|
|
1339
|
+
}
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
setBrightness(channelNumber, brightness) {
|
|
1343
|
+
const channel = this.channels[channelNumber];
|
|
1344
|
+
channel.brightness = brightness / 64;
|
|
1345
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1346
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1347
|
+
const note = noteList[i];
|
|
1348
|
+
if (!note)
|
|
1349
|
+
continue;
|
|
1350
|
+
this.setFilterEnvelope(channel, note);
|
|
1351
|
+
}
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
setDecayTime(channelNumber, dacayTime) {
|
|
1355
|
+
const channel = this.channels[channelNumber];
|
|
1356
|
+
channel.decayTime = dacayTime / 64;
|
|
1357
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1358
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1359
|
+
const note = noteList[i];
|
|
1360
|
+
if (!note)
|
|
1361
|
+
continue;
|
|
1362
|
+
this.setVolumeEnvelope(channel, note);
|
|
1363
|
+
}
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1288
1366
|
setVibratoRate(channelNumber, vibratoRate) {
|
|
1289
1367
|
const channel = this.channels[channelNumber];
|
|
1290
1368
|
channel.vibratoRate = vibratoRate / 64;
|
|
@@ -1365,13 +1443,17 @@ class Midy {
|
|
|
1365
1443
|
}
|
|
1366
1444
|
updateDetune(channel, detuneChange) {
|
|
1367
1445
|
const now = this.audioContext.currentTime;
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
.
|
|
1446
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1447
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1448
|
+
const note = noteList[i];
|
|
1449
|
+
if (!note)
|
|
1450
|
+
continue;
|
|
1451
|
+
const { bufferSource } = note;
|
|
1452
|
+
const detune = bufferSource.detune.value + detuneChange;
|
|
1453
|
+
bufferSource.detune
|
|
1454
|
+
.cancelScheduledValues(now)
|
|
1455
|
+
.setValueAtTime(detune, now);
|
|
1456
|
+
}
|
|
1375
1457
|
});
|
|
1376
1458
|
}
|
|
1377
1459
|
handlePitchBendRangeRPN(channelNumber) {
|
|
@@ -1792,6 +1874,11 @@ Object.defineProperty(Midy, "channelSettings", {
|
|
|
1792
1874
|
volume: 100 / 127,
|
|
1793
1875
|
pan: 64,
|
|
1794
1876
|
portamentoTime: 0,
|
|
1877
|
+
filterResonance: 1,
|
|
1878
|
+
releaseTime: 1,
|
|
1879
|
+
attackTime: 1,
|
|
1880
|
+
brightness: 1,
|
|
1881
|
+
decayTime: 1,
|
|
1795
1882
|
reverbSendLevel: 0,
|
|
1796
1883
|
chorusSendLevel: 0,
|
|
1797
1884
|
vibratoRate: 1,
|