@marmooo/midy 0.1.6 → 0.1.7
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 +5 -4
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +45 -16
- package/esm/midy-GM2.d.ts +5 -2
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +176 -66
- package/esm/midy-GMLite.d.ts +5 -4
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +45 -16
- package/esm/midy.d.ts +5 -2
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +177 -67
- package/package.json +5 -1
- package/script/midy-GM1.d.ts +5 -4
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +48 -19
- package/script/midy-GM2.d.ts +5 -2
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +179 -69
- package/script/midy-GMLite.d.ts +5 -4
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +48 -19
- package/script/midy.d.ts +5 -2
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +180 -70
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts +0 -149
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts.map +0 -1
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js +0 -180
- package/esm/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.d.ts +0 -84
- package/esm/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.d.ts.map +0 -1
- package/esm/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.js +0 -216
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts +0 -149
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.d.ts.map +0 -1
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js +0 -190
- package/script/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.d.ts +0 -84
- package/script/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.d.ts.map +0 -1
- package/script/deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.js +0 -221
package/script/midy.d.ts
CHANGED
|
@@ -83,6 +83,7 @@ export class Midy {
|
|
|
83
83
|
timeline: any[];
|
|
84
84
|
instruments: any[];
|
|
85
85
|
notePromises: any[];
|
|
86
|
+
exclusiveClassMap: Map<any, any>;
|
|
86
87
|
defaultOptions: {
|
|
87
88
|
reverbAlgorithm: (audioContext: any) => {
|
|
88
89
|
input: any;
|
|
@@ -218,8 +219,8 @@ export class Midy {
|
|
|
218
219
|
calcBank(channel: any, channelNumber: any): any;
|
|
219
220
|
scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any, portamento: any): Promise<void>;
|
|
220
221
|
noteOn(channelNumber: any, noteNumber: any, velocity: any, portamento: any): Promise<void>;
|
|
221
|
-
stopNote(
|
|
222
|
-
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any,
|
|
222
|
+
stopNote(endTime: any, stopTime: any, scheduledNotes: any, index: any): Promise<any>;
|
|
223
|
+
scheduleNoteRelease(channelNumber: any, noteNumber: any, _velocity: any, endTime: any, portamentoNoteNumber: any, force: any): Promise<any> | undefined;
|
|
223
224
|
releaseNote(channelNumber: any, noteNumber: any, velocity: any, portamentoNoteNumber: any): Promise<any> | undefined;
|
|
224
225
|
releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
|
|
225
226
|
releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
|
|
@@ -360,6 +361,8 @@ declare class Note {
|
|
|
360
361
|
modulationDepth: any;
|
|
361
362
|
vibratoLFO: any;
|
|
362
363
|
vibratoDepth: any;
|
|
364
|
+
reverbEffectsSend: any;
|
|
365
|
+
chorusEffectsSend: any;
|
|
363
366
|
noteNumber: any;
|
|
364
367
|
velocity: any;
|
|
365
368
|
startTime: any;
|
package/script/midy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"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"}
|
package/script/midy.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Midy = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const midi_file_1 = require("midi-file");
|
|
5
|
+
const soundfont_parser_1 = require("@marmooo/soundfont-parser");
|
|
6
6
|
class Note {
|
|
7
7
|
constructor(noteNumber, velocity, startTime, instrumentKey) {
|
|
8
8
|
Object.defineProperty(this, "bufferSource", {
|
|
@@ -53,6 +53,18 @@ class Note {
|
|
|
53
53
|
writable: true,
|
|
54
54
|
value: void 0
|
|
55
55
|
});
|
|
56
|
+
Object.defineProperty(this, "reverbEffectsSend", {
|
|
57
|
+
enumerable: true,
|
|
58
|
+
configurable: true,
|
|
59
|
+
writable: true,
|
|
60
|
+
value: void 0
|
|
61
|
+
});
|
|
62
|
+
Object.defineProperty(this, "chorusEffectsSend", {
|
|
63
|
+
enumerable: true,
|
|
64
|
+
configurable: true,
|
|
65
|
+
writable: true,
|
|
66
|
+
value: void 0
|
|
67
|
+
});
|
|
56
68
|
this.noteNumber = noteNumber;
|
|
57
69
|
this.velocity = velocity;
|
|
58
70
|
this.startTime = startTime;
|
|
@@ -208,6 +220,12 @@ class Midy {
|
|
|
208
220
|
writable: true,
|
|
209
221
|
value: []
|
|
210
222
|
});
|
|
223
|
+
Object.defineProperty(this, "exclusiveClassMap", {
|
|
224
|
+
enumerable: true,
|
|
225
|
+
configurable: true,
|
|
226
|
+
writable: true,
|
|
227
|
+
value: new Map()
|
|
228
|
+
});
|
|
211
229
|
Object.defineProperty(this, "defaultOptions", {
|
|
212
230
|
enumerable: true,
|
|
213
231
|
configurable: true,
|
|
@@ -264,14 +282,14 @@ class Midy {
|
|
|
264
282
|
async loadSoundFont(soundFontUrl) {
|
|
265
283
|
const response = await fetch(soundFontUrl);
|
|
266
284
|
const arrayBuffer = await response.arrayBuffer();
|
|
267
|
-
const parsed = (0,
|
|
268
|
-
const soundFont = new
|
|
285
|
+
const parsed = (0, soundfont_parser_1.parse)(new Uint8Array(arrayBuffer));
|
|
286
|
+
const soundFont = new soundfont_parser_1.SoundFont(parsed);
|
|
269
287
|
this.addSoundFont(soundFont);
|
|
270
288
|
}
|
|
271
289
|
async loadMIDI(midiUrl) {
|
|
272
290
|
const response = await fetch(midiUrl);
|
|
273
291
|
const arrayBuffer = await response.arrayBuffer();
|
|
274
|
-
const midi = (0,
|
|
292
|
+
const midi = (0, midi_file_1.parseMidi)(new Uint8Array(arrayBuffer));
|
|
275
293
|
this.ticksPerBeat = midi.header.ticksPerBeat;
|
|
276
294
|
const midiData = this.extractMidiData(midi);
|
|
277
295
|
this.instruments = midiData.instruments;
|
|
@@ -314,19 +332,25 @@ class Midy {
|
|
|
314
332
|
const sampleStart = instrumentKey.start;
|
|
315
333
|
const sampleEnd = instrumentKey.sample.length + instrumentKey.end;
|
|
316
334
|
if (isSF3) {
|
|
317
|
-
const sample = instrumentKey.sample
|
|
318
|
-
const
|
|
335
|
+
const sample = instrumentKey.sample;
|
|
336
|
+
const start = sample.byteOffset + sampleStart;
|
|
337
|
+
const end = sample.byteOffset + sampleEnd;
|
|
338
|
+
const buffer = sample.buffer.slice(start, end);
|
|
339
|
+
const audioBuffer = await this.audioContext.decodeAudioData(buffer);
|
|
319
340
|
return audioBuffer;
|
|
320
341
|
}
|
|
321
342
|
else {
|
|
322
|
-
const sample = instrumentKey.sample
|
|
343
|
+
const sample = instrumentKey.sample;
|
|
344
|
+
const start = sample.byteOffset + sampleStart;
|
|
345
|
+
const end = sample.byteOffset + sampleEnd;
|
|
346
|
+
const buffer = sample.buffer.slice(start, end);
|
|
323
347
|
const audioBuffer = new AudioBuffer({
|
|
324
348
|
numberOfChannels: 1,
|
|
325
349
|
length: sample.length,
|
|
326
350
|
sampleRate: instrumentKey.sampleRate,
|
|
327
351
|
});
|
|
328
352
|
const channelData = audioBuffer.getChannelData(0);
|
|
329
|
-
const int16Array = new Int16Array(
|
|
353
|
+
const int16Array = new Int16Array(buffer);
|
|
330
354
|
for (let i = 0; i < int16Array.length; i++) {
|
|
331
355
|
channelData[i] = int16Array[i] / 32768;
|
|
332
356
|
}
|
|
@@ -427,6 +451,7 @@ class Midy {
|
|
|
427
451
|
if (queueIndex >= this.timeline.length) {
|
|
428
452
|
await Promise.all(this.notePromises);
|
|
429
453
|
this.notePromises = [];
|
|
454
|
+
this.exclusiveClassMap.clear();
|
|
430
455
|
resolve();
|
|
431
456
|
return;
|
|
432
457
|
}
|
|
@@ -442,6 +467,7 @@ class Midy {
|
|
|
442
467
|
}
|
|
443
468
|
else if (this.isStopping) {
|
|
444
469
|
await this.stopNotes(0, true);
|
|
470
|
+
this.exclusiveClassMap.clear();
|
|
445
471
|
this.notePromises = [];
|
|
446
472
|
resolve();
|
|
447
473
|
this.isStopping = false;
|
|
@@ -450,6 +476,7 @@ class Midy {
|
|
|
450
476
|
}
|
|
451
477
|
else if (this.isSeeking) {
|
|
452
478
|
this.stopNotes(0, true);
|
|
479
|
+
this.exclusiveClassMap.clear();
|
|
453
480
|
this.startTime = this.audioContext.currentTime;
|
|
454
481
|
queueIndex = this.getQueueIndex(this.resumeTime);
|
|
455
482
|
offset = this.resumeTime - this.startTime;
|
|
@@ -678,14 +705,14 @@ class Midy {
|
|
|
678
705
|
return impulse;
|
|
679
706
|
}
|
|
680
707
|
createConvolutionReverb(audioContext, impulse) {
|
|
681
|
-
const
|
|
708
|
+
const input = new GainNode(audioContext);
|
|
682
709
|
const convolverNode = new ConvolverNode(audioContext, {
|
|
683
710
|
buffer: impulse,
|
|
684
711
|
});
|
|
685
|
-
|
|
712
|
+
input.connect(convolverNode);
|
|
686
713
|
return {
|
|
687
|
-
input
|
|
688
|
-
output,
|
|
714
|
+
input,
|
|
715
|
+
output: convolverNode,
|
|
689
716
|
convolverNode,
|
|
690
717
|
};
|
|
691
718
|
}
|
|
@@ -727,7 +754,6 @@ class Midy {
|
|
|
727
754
|
// M.R.Schroeder, "Natural Sounding Artificial Reverberation", J.Audio Eng. Soc., vol.10, p.219, 1962
|
|
728
755
|
createSchroederReverb(audioContext, combFeedbacks, combDelays, allpassFeedbacks, allpassDelays) {
|
|
729
756
|
const input = new GainNode(audioContext);
|
|
730
|
-
const output = new GainNode(audioContext);
|
|
731
757
|
const mergerGain = new GainNode(audioContext);
|
|
732
758
|
for (let i = 0; i < combDelays.length; i++) {
|
|
733
759
|
const comb = this.createCombFilter(audioContext, input, combDelays[i], combFeedbacks[i]);
|
|
@@ -738,7 +764,7 @@ class Midy {
|
|
|
738
764
|
const allpass = this.createAllpassFilter(audioContext, (i === 0) ? mergerGain : allpasses.at(-1), allpassDelays[i], allpassFeedbacks[i]);
|
|
739
765
|
allpasses.push(allpass);
|
|
740
766
|
}
|
|
741
|
-
allpasses.at(-1)
|
|
767
|
+
const output = allpasses.at(-1);
|
|
742
768
|
return { input, output };
|
|
743
769
|
}
|
|
744
770
|
createChorusEffect(audioContext) {
|
|
@@ -969,6 +995,20 @@ class Midy {
|
|
|
969
995
|
}
|
|
970
996
|
note.bufferSource.connect(note.filterNode);
|
|
971
997
|
note.filterNode.connect(note.volumeNode);
|
|
998
|
+
if (0 < channel.reverbSendLevel && 0 < instrumentKey.reverbEffectsSend) {
|
|
999
|
+
note.reverbEffectsSend = new GainNode(this.audioContext, {
|
|
1000
|
+
gain: instrumentKey.reverbEffectsSend,
|
|
1001
|
+
});
|
|
1002
|
+
note.volumeNode.connect(note.reverbEffectsSend);
|
|
1003
|
+
note.reverbEffectsSend.connect(this.reverbEffect.input);
|
|
1004
|
+
}
|
|
1005
|
+
if (0 < channel.chorusSendLevel && 0 < instrumentKey.chorusEffectsSend) {
|
|
1006
|
+
note.chorusEffectsSend = new GainNode(this.audioContext, {
|
|
1007
|
+
gain: instrumentKey.chorusEffectsSend,
|
|
1008
|
+
});
|
|
1009
|
+
note.volumeNode.connect(note.chorusEffectsSend);
|
|
1010
|
+
note.chorusEffectsSend.connect(this.chorusEffect.input);
|
|
1011
|
+
}
|
|
972
1012
|
note.bufferSource.start(startTime);
|
|
973
1013
|
return note;
|
|
974
1014
|
}
|
|
@@ -998,6 +1038,19 @@ class Midy {
|
|
|
998
1038
|
if (channel.sostenutoPedal) {
|
|
999
1039
|
channel.sostenutoNotes.set(noteNumber, note);
|
|
1000
1040
|
}
|
|
1041
|
+
const exclusiveClass = instrumentKey.exclusiveClass;
|
|
1042
|
+
if (exclusiveClass !== 0) {
|
|
1043
|
+
if (this.exclusiveClassMap.has(exclusiveClass)) {
|
|
1044
|
+
const prevEntry = this.exclusiveClassMap.get(exclusiveClass);
|
|
1045
|
+
const [prevNote, prevChannelNumber] = prevEntry;
|
|
1046
|
+
if (!prevNote.ending) {
|
|
1047
|
+
this.scheduleNoteRelease(prevChannelNumber, prevNote.noteNumber, 0, // velocity,
|
|
1048
|
+
startTime, undefined, // portamentoNoteNumber
|
|
1049
|
+
true);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
this.exclusiveClassMap.set(exclusiveClass, [note, channelNumber]);
|
|
1053
|
+
}
|
|
1001
1054
|
const scheduledNotes = channel.scheduledNotes;
|
|
1002
1055
|
if (scheduledNotes.has(noteNumber)) {
|
|
1003
1056
|
scheduledNotes.get(noteNumber).push(note);
|
|
@@ -1010,15 +1063,15 @@ class Midy {
|
|
|
1010
1063
|
const now = this.audioContext.currentTime;
|
|
1011
1064
|
return this.scheduleNoteOn(channelNumber, noteNumber, velocity, now, portamento);
|
|
1012
1065
|
}
|
|
1013
|
-
stopNote(
|
|
1066
|
+
stopNote(endTime, stopTime, scheduledNotes, index) {
|
|
1014
1067
|
const note = scheduledNotes[index];
|
|
1015
1068
|
note.volumeNode.gain
|
|
1016
|
-
.cancelScheduledValues(
|
|
1017
|
-
.linearRampToValueAtTime(0,
|
|
1069
|
+
.cancelScheduledValues(endTime)
|
|
1070
|
+
.linearRampToValueAtTime(0, stopTime);
|
|
1018
1071
|
note.ending = true;
|
|
1019
1072
|
this.scheduleTask(() => {
|
|
1020
1073
|
note.bufferSource.loop = false;
|
|
1021
|
-
},
|
|
1074
|
+
}, stopTime);
|
|
1022
1075
|
return new Promise((resolve) => {
|
|
1023
1076
|
note.bufferSource.onended = () => {
|
|
1024
1077
|
scheduledNotes[index] = null;
|
|
@@ -1034,12 +1087,18 @@ class Midy {
|
|
|
1034
1087
|
note.vibratoDepth.disconnect();
|
|
1035
1088
|
note.vibratoLFO.stop();
|
|
1036
1089
|
}
|
|
1090
|
+
if (note.reverbEffectsSend) {
|
|
1091
|
+
note.reverbEffectsSend.disconnect();
|
|
1092
|
+
}
|
|
1093
|
+
if (note.chorusEffectsSend) {
|
|
1094
|
+
note.chorusEffectsSend.disconnect();
|
|
1095
|
+
}
|
|
1037
1096
|
resolve();
|
|
1038
1097
|
};
|
|
1039
|
-
note.bufferSource.stop(
|
|
1098
|
+
note.bufferSource.stop(stopTime);
|
|
1040
1099
|
});
|
|
1041
1100
|
}
|
|
1042
|
-
scheduleNoteRelease(channelNumber, noteNumber, _velocity,
|
|
1101
|
+
scheduleNoteRelease(channelNumber, noteNumber, _velocity, endTime, portamentoNoteNumber, force) {
|
|
1043
1102
|
const channel = this.channels[channelNumber];
|
|
1044
1103
|
if (!force) {
|
|
1045
1104
|
if (channel.sustainPedal)
|
|
@@ -1057,22 +1116,23 @@ class Midy {
|
|
|
1057
1116
|
if (note.ending)
|
|
1058
1117
|
continue;
|
|
1059
1118
|
if (portamentoNoteNumber === undefined) {
|
|
1060
|
-
const
|
|
1119
|
+
const volRelease = endTime +
|
|
1061
1120
|
note.instrumentKey.volRelease * channel.releaseTime;
|
|
1062
|
-
const modRelease =
|
|
1121
|
+
const modRelease = endTime + note.instrumentKey.modRelease;
|
|
1063
1122
|
note.filterNode.frequency
|
|
1064
|
-
.cancelScheduledValues(
|
|
1123
|
+
.cancelScheduledValues(endTime)
|
|
1065
1124
|
.linearRampToValueAtTime(0, modRelease);
|
|
1066
|
-
|
|
1125
|
+
const stopTime = Math.min(volRelease, modRelease);
|
|
1126
|
+
return this.stopNote(endTime, stopTime, scheduledNotes, i);
|
|
1067
1127
|
}
|
|
1068
1128
|
else {
|
|
1069
|
-
const portamentoTime =
|
|
1129
|
+
const portamentoTime = endTime + channel.portamentoTime;
|
|
1070
1130
|
const detuneChange = (portamentoNoteNumber - noteNumber) * 100;
|
|
1071
1131
|
const detune = note.bufferSource.detune.value + detuneChange;
|
|
1072
1132
|
note.bufferSource.detune
|
|
1073
|
-
.cancelScheduledValues(
|
|
1133
|
+
.cancelScheduledValues(endTime)
|
|
1074
1134
|
.linearRampToValueAtTime(detune, portamentoTime);
|
|
1075
|
-
return this.stopNote(
|
|
1135
|
+
return this.stopNote(endTime, portamentoTime, scheduledNotes, i);
|
|
1076
1136
|
}
|
|
1077
1137
|
}
|
|
1078
1138
|
}
|
|
@@ -1119,7 +1179,7 @@ class Midy {
|
|
|
1119
1179
|
case 0x90:
|
|
1120
1180
|
return this.noteOn(channelNumber, data1, data2);
|
|
1121
1181
|
case 0xA0:
|
|
1122
|
-
return
|
|
1182
|
+
return this.handlePolyphonicKeyPressure(channelNumber, data1, data2);
|
|
1123
1183
|
case 0xB0:
|
|
1124
1184
|
return this.handleControlChange(channelNumber, data1, data2);
|
|
1125
1185
|
case 0xC0:
|
|
@@ -1314,20 +1374,44 @@ class Midy {
|
|
|
1314
1374
|
if (0 < reverbSendLevel) {
|
|
1315
1375
|
const now = this.audioContext.currentTime;
|
|
1316
1376
|
channel.reverbSendLevel = reverbSendLevel / 127;
|
|
1317
|
-
reverbEffect.
|
|
1318
|
-
reverbEffect.
|
|
1377
|
+
reverbEffect.input.gain.cancelScheduledValues(now);
|
|
1378
|
+
reverbEffect.input.gain.setValueAtTime(channel.reverbSendLevel, now);
|
|
1319
1379
|
}
|
|
1320
1380
|
else {
|
|
1321
|
-
channel.
|
|
1381
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1382
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1383
|
+
const note = noteList[i];
|
|
1384
|
+
if (!note)
|
|
1385
|
+
continue;
|
|
1386
|
+
if (note.instrumentKey.reverbEffectsSend <= 0)
|
|
1387
|
+
continue;
|
|
1388
|
+
note.reverbEffectsSend.disconnect();
|
|
1389
|
+
}
|
|
1390
|
+
});
|
|
1322
1391
|
}
|
|
1323
1392
|
}
|
|
1324
1393
|
else {
|
|
1325
1394
|
if (0 < reverbSendLevel) {
|
|
1326
|
-
channel.merger.connect(reverbEffect.input);
|
|
1327
1395
|
const now = this.audioContext.currentTime;
|
|
1396
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1397
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1398
|
+
const note = noteList[i];
|
|
1399
|
+
if (!note)
|
|
1400
|
+
continue;
|
|
1401
|
+
if (note.instrumentKey.reverbEffectsSend <= 0)
|
|
1402
|
+
continue;
|
|
1403
|
+
if (!note.reverbEffectsSend) {
|
|
1404
|
+
note.reverbEffectsSend = new GainNode(this.audioContext, {
|
|
1405
|
+
gain: note.instrumentKey.reverbEffectsSend,
|
|
1406
|
+
});
|
|
1407
|
+
note.volumeNode.connect(note.reverbEffectsSend);
|
|
1408
|
+
}
|
|
1409
|
+
note.reverbEffectsSend.connect(reverbEffect.input);
|
|
1410
|
+
}
|
|
1411
|
+
});
|
|
1328
1412
|
channel.reverbSendLevel = reverbSendLevel / 127;
|
|
1329
|
-
reverbEffect.
|
|
1330
|
-
reverbEffect.
|
|
1413
|
+
reverbEffect.input.gain.cancelScheduledValues(now);
|
|
1414
|
+
reverbEffect.input.gain.setValueAtTime(channel.reverbSendLevel, now);
|
|
1331
1415
|
}
|
|
1332
1416
|
}
|
|
1333
1417
|
}
|
|
@@ -1338,20 +1422,44 @@ class Midy {
|
|
|
1338
1422
|
if (0 < chorusSendLevel) {
|
|
1339
1423
|
const now = this.audioContext.currentTime;
|
|
1340
1424
|
channel.chorusSendLevel = chorusSendLevel / 127;
|
|
1341
|
-
chorusEffect.
|
|
1342
|
-
chorusEffect.
|
|
1425
|
+
chorusEffect.input.gain.cancelScheduledValues(now);
|
|
1426
|
+
chorusEffect.input.gain.setValueAtTime(channel.chorusSendLevel, now);
|
|
1343
1427
|
}
|
|
1344
1428
|
else {
|
|
1345
|
-
channel.
|
|
1429
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1430
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1431
|
+
const note = noteList[i];
|
|
1432
|
+
if (!note)
|
|
1433
|
+
continue;
|
|
1434
|
+
if (note.instrumentKey.chorusEffectsSend <= 0)
|
|
1435
|
+
continue;
|
|
1436
|
+
note.chorusEffectsSend.disconnect();
|
|
1437
|
+
}
|
|
1438
|
+
});
|
|
1346
1439
|
}
|
|
1347
1440
|
}
|
|
1348
1441
|
else {
|
|
1349
1442
|
if (0 < chorusSendLevel) {
|
|
1350
|
-
channel.merger.connect(chorusEffect.input);
|
|
1351
1443
|
const now = this.audioContext.currentTime;
|
|
1444
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1445
|
+
for (let i = 0; i < noteList.length; i++) {
|
|
1446
|
+
const note = noteList[i];
|
|
1447
|
+
if (!note)
|
|
1448
|
+
continue;
|
|
1449
|
+
if (note.instrumentKey.chorusEffectsSend <= 0)
|
|
1450
|
+
continue;
|
|
1451
|
+
if (!note.chorusEffectsSend) {
|
|
1452
|
+
note.chorusEffectsSend = new GainNode(this.audioContext, {
|
|
1453
|
+
gain: note.instrumentKey.chorusEffectsSend,
|
|
1454
|
+
});
|
|
1455
|
+
note.volumeNode.connect(note.chorusEffectsSend);
|
|
1456
|
+
}
|
|
1457
|
+
note.chorusEffectsSend.connect(chorusEffect.input);
|
|
1458
|
+
}
|
|
1459
|
+
});
|
|
1352
1460
|
channel.chorusSendLevel = chorusSendLevel / 127;
|
|
1353
|
-
chorusEffect.
|
|
1354
|
-
chorusEffect.
|
|
1461
|
+
chorusEffect.input.gain.cancelScheduledValues(now);
|
|
1462
|
+
chorusEffect.input.gain.setValueAtTime(channel.chorusSendLevel, now);
|
|
1355
1463
|
}
|
|
1356
1464
|
}
|
|
1357
1465
|
}
|
|
@@ -1784,10 +1892,8 @@ class Midy {
|
|
|
1784
1892
|
}
|
|
1785
1893
|
setReverbTime(value) {
|
|
1786
1894
|
this.reverb.time = this.getReverbTime(value);
|
|
1787
|
-
const { audioContext,
|
|
1788
|
-
|
|
1789
|
-
channels[i].reverbEffect = options.reverbAlgorithm(audioContext);
|
|
1790
|
-
}
|
|
1895
|
+
const { audioContext, options } = this;
|
|
1896
|
+
this.reverbEffect = options.reverbAlgorithm(audioContext);
|
|
1791
1897
|
}
|
|
1792
1898
|
getReverbTime(value) {
|
|
1793
1899
|
return Math.pow(Math.E, (value - 40) * 0.025);
|
|
@@ -1864,10 +1970,7 @@ class Midy {
|
|
|
1864
1970
|
const now = this.audioContext.currentTime;
|
|
1865
1971
|
const modRate = this.getChorusModRate(value);
|
|
1866
1972
|
this.chorus.modRate = modRate;
|
|
1867
|
-
|
|
1868
|
-
const lfo = this.channels[i].chorusEffect.lfo;
|
|
1869
|
-
lfo.frequency.setValueAtTime(modRate, now);
|
|
1870
|
-
}
|
|
1973
|
+
this.chorusEffect.lfo.frequency.setValueAtTime(modRate, now);
|
|
1871
1974
|
}
|
|
1872
1975
|
getChorusModRate(value) {
|
|
1873
1976
|
return value * 0.122; // Hz
|
|
@@ -1876,12 +1979,9 @@ class Midy {
|
|
|
1876
1979
|
const now = this.audioContext.currentTime;
|
|
1877
1980
|
const modDepth = this.getChorusModDepth(value);
|
|
1878
1981
|
this.chorus.modDepth = modDepth;
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
.cancelScheduledValues(now)
|
|
1883
|
-
.setValueAtTime(modDepth / 2, now);
|
|
1884
|
-
}
|
|
1982
|
+
this.chorusEffect.lfoGain.gain
|
|
1983
|
+
.cancelScheduledValues(now)
|
|
1984
|
+
.setValueAtTime(modDepth / 2, now);
|
|
1885
1985
|
}
|
|
1886
1986
|
getChorusModDepth(value) {
|
|
1887
1987
|
return (value + 1) / 3200; // second
|
|
@@ -1890,14 +1990,11 @@ class Midy {
|
|
|
1890
1990
|
const now = this.audioContext.currentTime;
|
|
1891
1991
|
const feedback = this.getChorusFeedback(value);
|
|
1892
1992
|
this.chorus.feedback = feedback;
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
.cancelScheduledValues(now)
|
|
1899
|
-
.setValueAtTime(feedback, now);
|
|
1900
|
-
}
|
|
1993
|
+
const chorusEffect = this.chorusEffect;
|
|
1994
|
+
for (let i = 0; i < chorusEffect.feedbackGains.length; i++) {
|
|
1995
|
+
chorusEffect.feedbackGains[i].gain
|
|
1996
|
+
.cancelScheduledValues(now)
|
|
1997
|
+
.setValueAtTime(feedback, now);
|
|
1901
1998
|
}
|
|
1902
1999
|
}
|
|
1903
2000
|
getChorusFeedback(value) {
|
|
@@ -1905,15 +2002,28 @@ class Midy {
|
|
|
1905
2002
|
}
|
|
1906
2003
|
setChorusSendToReverb(value) {
|
|
1907
2004
|
const sendToReverb = this.getChorusSendToReverb(value);
|
|
1908
|
-
|
|
1909
|
-
|
|
2005
|
+
const sendGain = this.chorusEffect.sendGain;
|
|
2006
|
+
if (0 < this.chorus.sendToReverb) {
|
|
1910
2007
|
this.chorus.sendToReverb = sendToReverb;
|
|
1911
|
-
|
|
1912
|
-
.
|
|
1913
|
-
.
|
|
2008
|
+
if (0 < sendToReverb) {
|
|
2009
|
+
const now = this.audioContext.currentTime;
|
|
2010
|
+
sendGain.gain
|
|
2011
|
+
.cancelScheduledValues(now)
|
|
2012
|
+
.setValueAtTime(sendToReverb, now);
|
|
2013
|
+
}
|
|
2014
|
+
else {
|
|
2015
|
+
sendGain.disconnect();
|
|
2016
|
+
}
|
|
1914
2017
|
}
|
|
1915
|
-
else
|
|
1916
|
-
this.
|
|
2018
|
+
else {
|
|
2019
|
+
this.chorus.sendToReverb = sendToReverb;
|
|
2020
|
+
if (0 < sendToReverb) {
|
|
2021
|
+
const now = this.audioContext.currentTime;
|
|
2022
|
+
sendGain.connect(this.reverbEffect.input);
|
|
2023
|
+
sendGain.gain
|
|
2024
|
+
.cancelScheduledValues(now)
|
|
2025
|
+
.setValueAtTime(sendToReverb, now);
|
|
2026
|
+
}
|
|
1917
2027
|
}
|
|
1918
2028
|
}
|
|
1919
2029
|
getChorusSendToReverb(value) {
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
declare const _default: null;
|
|
2
|
-
export default _default;
|
|
3
|
-
declare const M: string[];
|
|
4
|
-
declare class B {
|
|
5
|
-
constructor(e: any);
|
|
6
|
-
parsed: any;
|
|
7
|
-
getGenerators(e: any, t: any, n: any, r: any): any[];
|
|
8
|
-
getPresetGenerators(e: any): any[];
|
|
9
|
-
getInstrumentGenerators(e: any): any[];
|
|
10
|
-
findInstrumentZone(e: any, t: any, n: any): {} | undefined;
|
|
11
|
-
findInstrument(e: any, t: any, n: any): any;
|
|
12
|
-
getInstrument(e: any, t: any): any;
|
|
13
|
-
getInstrumentKey(e: any, t: any, n: any, r: any): {
|
|
14
|
-
start: any;
|
|
15
|
-
end: any;
|
|
16
|
-
loopStart: any;
|
|
17
|
-
loopEnd: any;
|
|
18
|
-
modLfoToPitch: any;
|
|
19
|
-
vibLfoToPitch: any;
|
|
20
|
-
modEnvToPitch: any;
|
|
21
|
-
initialFilterFc: any;
|
|
22
|
-
initialFilterQ: any;
|
|
23
|
-
modLfoToFilterFc: any;
|
|
24
|
-
modEnvToFilterFc: any;
|
|
25
|
-
modLfoToVolume: any;
|
|
26
|
-
chorusEffectsSend: number;
|
|
27
|
-
reverbEffectsSend: number;
|
|
28
|
-
pan: any;
|
|
29
|
-
delayModLFO: number;
|
|
30
|
-
freqModLFO: any;
|
|
31
|
-
delayVibLFO: number;
|
|
32
|
-
freqVibLFO: any;
|
|
33
|
-
modDelay: number;
|
|
34
|
-
modAttack: number;
|
|
35
|
-
modHold: number;
|
|
36
|
-
modDecay: number;
|
|
37
|
-
modSustain: number;
|
|
38
|
-
modRelease: number;
|
|
39
|
-
volDelay: number;
|
|
40
|
-
volAttack: number;
|
|
41
|
-
volHold: number;
|
|
42
|
-
volDecay: number;
|
|
43
|
-
volSustain: number;
|
|
44
|
-
volRelease: number;
|
|
45
|
-
initialAttenuation: any;
|
|
46
|
-
playbackRate: (e: any) => number;
|
|
47
|
-
sample: any;
|
|
48
|
-
sampleRate: any;
|
|
49
|
-
sampleName: any;
|
|
50
|
-
sampleModes: any;
|
|
51
|
-
exclusiveClass: any;
|
|
52
|
-
} | null;
|
|
53
|
-
getPresetNames(): {};
|
|
54
|
-
}
|
|
55
|
-
declare function S(e: any): {};
|
|
56
|
-
declare function V(e: any): {};
|
|
57
|
-
declare namespace W {
|
|
58
|
-
let startAddrsOffset: m;
|
|
59
|
-
let endAddrsOffset: m;
|
|
60
|
-
let startloopAddrsOffset: m;
|
|
61
|
-
let endloopAddrsOffset: m;
|
|
62
|
-
let startAddrsCoarseOffset: m;
|
|
63
|
-
let modLfoToPitch: m;
|
|
64
|
-
let vibLfoToPitch: m;
|
|
65
|
-
let modEnvToPitch: m;
|
|
66
|
-
let initialFilterFc: m;
|
|
67
|
-
let initialFilterQ: m;
|
|
68
|
-
let modLfoToFilterFc: m;
|
|
69
|
-
let modEnvToFilterFc: m;
|
|
70
|
-
let endAddrsCoarseOffset: m;
|
|
71
|
-
let modLfoToVolume: m;
|
|
72
|
-
let chorusEffectsSend: m;
|
|
73
|
-
let reverbEffectsSend: m;
|
|
74
|
-
let pan: m;
|
|
75
|
-
let delayModLFO: m;
|
|
76
|
-
let freqModLFO: m;
|
|
77
|
-
let delayVibLFO: m;
|
|
78
|
-
let freqVibLFO: m;
|
|
79
|
-
let delayModEnv: m;
|
|
80
|
-
let attackModEnv: m;
|
|
81
|
-
let holdModEnv: m;
|
|
82
|
-
let decayModEnv: m;
|
|
83
|
-
let sustainModEnv: m;
|
|
84
|
-
let releaseModEnv: m;
|
|
85
|
-
let keynumToModEnvHold: m;
|
|
86
|
-
let keynumToModEnvDecay: m;
|
|
87
|
-
let delayVolEnv: m;
|
|
88
|
-
let attackVolEnv: m;
|
|
89
|
-
let holdVolEnv: m;
|
|
90
|
-
let decayVolEnv: m;
|
|
91
|
-
let sustainVolEnv: m;
|
|
92
|
-
let releaseVolEnv: m;
|
|
93
|
-
let keynumToVolEnvHold: m;
|
|
94
|
-
let keynumToVolEnvDecay: m;
|
|
95
|
-
let instrument: m;
|
|
96
|
-
let keyRange: d;
|
|
97
|
-
let velRange: d;
|
|
98
|
-
let startloopAddrsCoarseOffset: m;
|
|
99
|
-
let keynum: m;
|
|
100
|
-
let velocity: m;
|
|
101
|
-
let initialAttenuation: m;
|
|
102
|
-
let endloopAddrsCoarseOffset: m;
|
|
103
|
-
let coarseTune: m;
|
|
104
|
-
let fineTune: m;
|
|
105
|
-
let sampleID: m;
|
|
106
|
-
let sampleModes: m;
|
|
107
|
-
let scaleTuning: m;
|
|
108
|
-
let exclusiveClass: m;
|
|
109
|
-
let overridingRootKey: m;
|
|
110
|
-
}
|
|
111
|
-
declare function L(e: any): boolean;
|
|
112
|
-
declare function p(e: any, r?: {}): {
|
|
113
|
-
samples: any;
|
|
114
|
-
presetHeaders: any[];
|
|
115
|
-
presetZone: any[];
|
|
116
|
-
presetModulators: any[];
|
|
117
|
-
presetGenerators: any[];
|
|
118
|
-
instruments: any[];
|
|
119
|
-
instrumentZone: any[];
|
|
120
|
-
instrumentModulators: any[];
|
|
121
|
-
instrumentGenerators: any[];
|
|
122
|
-
sampleHeaders: any[];
|
|
123
|
-
info: s;
|
|
124
|
-
samplingData: {
|
|
125
|
-
offsetMSB: any;
|
|
126
|
-
offsetLSB: any;
|
|
127
|
-
};
|
|
128
|
-
};
|
|
129
|
-
declare function H(e: any): number;
|
|
130
|
-
declare class m {
|
|
131
|
-
constructor(e: any, t: any, n: any);
|
|
132
|
-
min: any;
|
|
133
|
-
value: any;
|
|
134
|
-
max: any;
|
|
135
|
-
clamp(): number;
|
|
136
|
-
}
|
|
137
|
-
declare class d {
|
|
138
|
-
static parse(e: any): d;
|
|
139
|
-
constructor(e: any, t: any);
|
|
140
|
-
lo: any;
|
|
141
|
-
hi: any;
|
|
142
|
-
in(e: any): boolean;
|
|
143
|
-
}
|
|
144
|
-
declare class s {
|
|
145
|
-
static parse(t: any, n: any): s;
|
|
146
|
-
constructor(e: any, t: any, n: any, r: any, a: any, o: any, s: any, i: any, l: any, d: any, u: any);
|
|
147
|
-
}
|
|
148
|
-
export { M as RangeGeneratorNames, B as SoundFont, S as createInstrumentGeneratorObject, V as createPresetGeneratorObject, W as defaultInstrumentZone, L as isRangeGenerator, p as parse, H as timecentToSecond };
|
|
149
|
-
//# sourceMappingURL=+esm.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"+esm.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.6/+esm.js"],"names":[],"mappings":";;AAM0lV,0BAAyB;AAAugF;IAAQ,oBAA2H;IAAd,YAAa;IAAC,qDAAoJ;IAAA,mCAAoP;IAAA,uCAAwQ;IAAA,2DAAiP;IAAA,4CAAmX;IAAA,mCAAuL;IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAA49D;IAAA,qBAAqK;CAAC;AAApoL,+BAA2R;AAAzd,+BAA8L;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAjO,oCAAmC;AAA7yE;;;;;;;;;;;;;;;;EAA27B;AAAorO,mCAAwC;AAAziR;IAAQ,oCAAyU;IAAnC,SAAU;IAAC,WAAY;IAAC,SAAU;IAAC,gBAAgE;CAAC;AAA19G;IAAqQ,wBAAsE;IAAnU,4BAAyN;IAApB,QAAS;IAAC,QAAS;IAAC,oBAAoC;CAAuE;AAAv5F;IAAshC,gCAAqa;IAAn7C,oGAA8gC;CAAsa"}
|