@marmooo/midy 0.1.2 → 0.1.3
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/+esm.d.ts +153 -0
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts.map +1 -0
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/{soundfont-parser@0.0.2 → soundfont-parser@0.0.4}/+esm.js +73 -66
- package/esm/midy-GM1.d.ts +17 -12
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +125 -96
- package/esm/midy-GM2.d.ts +21 -14
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +146 -107
- package/esm/midy-GMLite.d.ts +15 -12
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +115 -98
- package/esm/midy.d.ts +18 -15
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +147 -134
- package/package.json +1 -1
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts +153 -0
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts.map +1 -0
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/{soundfont-parser@0.0.2 → soundfont-parser@0.0.4}/+esm.js +75 -68
- package/script/midy-GM1.d.ts +17 -12
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +125 -96
- package/script/midy-GM2.d.ts +21 -14
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +146 -107
- package/script/midy-GMLite.d.ts +15 -12
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +115 -98
- package/script/midy.d.ts +18 -15
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +147 -134
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.2/+esm.d.ts +0 -135
- package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.2/+esm.d.ts.map +0 -1
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.2/+esm.d.ts +0 -135
- package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.2/+esm.d.ts.map +0 -1
package/script/midy.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Midy = void 0;
|
|
4
4
|
const _esm_js_1 = require("./deps/cdn.jsdelivr.net/npm/midi-file@1.2.4/+esm.js");
|
|
5
|
-
const _esm_js_2 = require("./deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.
|
|
5
|
+
const _esm_js_2 = require("./deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.js");
|
|
6
6
|
class Note {
|
|
7
7
|
constructor(noteNumber, velocity, startTime, instrumentKey) {
|
|
8
8
|
Object.defineProperty(this, "bufferSource", {
|
|
@@ -11,37 +11,43 @@ class Note {
|
|
|
11
11
|
writable: true,
|
|
12
12
|
value: void 0
|
|
13
13
|
});
|
|
14
|
-
Object.defineProperty(this, "
|
|
14
|
+
Object.defineProperty(this, "filterNode", {
|
|
15
15
|
enumerable: true,
|
|
16
16
|
configurable: true,
|
|
17
17
|
writable: true,
|
|
18
18
|
value: void 0
|
|
19
19
|
});
|
|
20
|
-
Object.defineProperty(this, "
|
|
20
|
+
Object.defineProperty(this, "volumeNode", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: void 0
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(this, "volumeDepth", {
|
|
21
27
|
enumerable: true,
|
|
22
28
|
configurable: true,
|
|
23
29
|
writable: true,
|
|
24
30
|
value: void 0
|
|
25
31
|
});
|
|
26
|
-
Object.defineProperty(this, "
|
|
32
|
+
Object.defineProperty(this, "modulationLFO", {
|
|
27
33
|
enumerable: true,
|
|
28
34
|
configurable: true,
|
|
29
35
|
writable: true,
|
|
30
36
|
value: void 0
|
|
31
37
|
});
|
|
32
|
-
Object.defineProperty(this, "
|
|
38
|
+
Object.defineProperty(this, "modulationDepth", {
|
|
33
39
|
enumerable: true,
|
|
34
40
|
configurable: true,
|
|
35
41
|
writable: true,
|
|
36
42
|
value: void 0
|
|
37
43
|
});
|
|
38
|
-
Object.defineProperty(this, "
|
|
44
|
+
Object.defineProperty(this, "vibratoLFO", {
|
|
39
45
|
enumerable: true,
|
|
40
46
|
configurable: true,
|
|
41
47
|
writable: true,
|
|
42
48
|
value: void 0
|
|
43
49
|
});
|
|
44
|
-
Object.defineProperty(this, "
|
|
50
|
+
Object.defineProperty(this, "vibratoDepth", {
|
|
45
51
|
enumerable: true,
|
|
46
52
|
configurable: true,
|
|
47
53
|
writable: true,
|
|
@@ -413,7 +419,7 @@ class Midy {
|
|
|
413
419
|
const t = this.audioContext.currentTime + offset;
|
|
414
420
|
queueIndex = await this.scheduleTimelineEvents(t, offset, queueIndex);
|
|
415
421
|
if (this.isPausing) {
|
|
416
|
-
await this.stopNotes();
|
|
422
|
+
await this.stopNotes(0, true);
|
|
417
423
|
this.notePromises = [];
|
|
418
424
|
resolve();
|
|
419
425
|
this.isPausing = false;
|
|
@@ -421,7 +427,7 @@ class Midy {
|
|
|
421
427
|
return;
|
|
422
428
|
}
|
|
423
429
|
else if (this.isStopping) {
|
|
424
|
-
await this.stopNotes();
|
|
430
|
+
await this.stopNotes(0, true);
|
|
425
431
|
this.notePromises = [];
|
|
426
432
|
resolve();
|
|
427
433
|
this.isStopping = false;
|
|
@@ -429,7 +435,7 @@ class Midy {
|
|
|
429
435
|
return;
|
|
430
436
|
}
|
|
431
437
|
else if (this.isSeeking) {
|
|
432
|
-
this.stopNotes();
|
|
438
|
+
this.stopNotes(0, true);
|
|
433
439
|
this.startTime = this.audioContext.currentTime;
|
|
434
440
|
queueIndex = this.getQueueIndex(this.resumeTime);
|
|
435
441
|
offset = this.resumeTime - this.startTime;
|
|
@@ -544,21 +550,24 @@ class Midy {
|
|
|
544
550
|
}
|
|
545
551
|
return { instruments, timeline };
|
|
546
552
|
}
|
|
547
|
-
|
|
553
|
+
async stopChannelNotes(channelNumber, velocity, stopPedal) {
|
|
548
554
|
const now = this.audioContext.currentTime;
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
this.notePromises.push(promise);
|
|
557
|
-
}
|
|
558
|
-
});
|
|
555
|
+
const channel = this.channels[channelNumber];
|
|
556
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
557
|
+
noteList.forEach((note) => {
|
|
558
|
+
if (note) {
|
|
559
|
+
const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
|
|
560
|
+
this.notePromises.push(promise);
|
|
561
|
+
}
|
|
559
562
|
});
|
|
560
|
-
channel.scheduledNotes.clear();
|
|
561
563
|
});
|
|
564
|
+
channel.scheduledNotes.clear();
|
|
565
|
+
await Promise.all(this.notePromises);
|
|
566
|
+
}
|
|
567
|
+
stopNotes(velocity, stopPedal) {
|
|
568
|
+
for (let i = 0; i < this.channels.length; i++) {
|
|
569
|
+
this.stopChannelNotes(i, velocity, stopPedal);
|
|
570
|
+
}
|
|
562
571
|
return Promise.all(this.notePromises);
|
|
563
572
|
}
|
|
564
573
|
async start() {
|
|
@@ -773,36 +782,54 @@ class Midy {
|
|
|
773
782
|
}
|
|
774
783
|
setVolumeEnvelope(note) {
|
|
775
784
|
const { instrumentKey, startTime } = note;
|
|
776
|
-
note.
|
|
785
|
+
note.volumeNode = new GainNode(this.audioContext, { gain: 0 });
|
|
777
786
|
const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
|
|
778
787
|
const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
|
|
779
788
|
const volDelay = startTime + instrumentKey.volDelay;
|
|
780
789
|
const volAttack = volDelay + instrumentKey.volAttack;
|
|
781
790
|
const volHold = volAttack + instrumentKey.volHold;
|
|
782
791
|
const volDecay = volHold + instrumentKey.volDecay;
|
|
783
|
-
note.
|
|
792
|
+
note.volumeNode.gain
|
|
784
793
|
.setValueAtTime(1e-6, volDelay) // exponentialRampToValueAtTime() requires a non-zero value
|
|
785
794
|
.exponentialRampToValueAtTime(attackVolume, volAttack)
|
|
786
795
|
.setValueAtTime(attackVolume, volHold)
|
|
787
796
|
.linearRampToValueAtTime(sustainVolume, volDecay);
|
|
788
797
|
}
|
|
789
|
-
|
|
790
|
-
const { instrumentKey,
|
|
798
|
+
setPitch(note, semitoneOffset) {
|
|
799
|
+
const { instrumentKey, noteNumber, startTime } = note;
|
|
800
|
+
const modEnvToPitch = instrumentKey.modEnvToPitch / 100;
|
|
801
|
+
note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
|
|
802
|
+
if (modEnvToPitch === 0)
|
|
803
|
+
return;
|
|
804
|
+
const basePitch = note.bufferSource.playbackRate.value;
|
|
805
|
+
const peekPitch = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset + modEnvToPitch);
|
|
806
|
+
const modDelay = startTime + instrumentKey.modDelay;
|
|
807
|
+
const modAttack = modDelay + instrumentKey.modAttack;
|
|
808
|
+
const modHold = modAttack + instrumentKey.modHold;
|
|
809
|
+
const modDecay = modHold + instrumentKey.modDecay;
|
|
810
|
+
note.bufferSource.playbackRate.value
|
|
811
|
+
.setValueAtTime(basePitch, modDelay)
|
|
812
|
+
.exponentialRampToValueAtTime(peekPitch, modAttack)
|
|
813
|
+
.setValueAtTime(peekPitch, modHold)
|
|
814
|
+
.linearRampToValueAtTime(basePitch, modDecay);
|
|
815
|
+
}
|
|
816
|
+
setFilterNode(channel, note) {
|
|
817
|
+
const { instrumentKey, noteNumber, startTime } = note;
|
|
791
818
|
const softPedalFactor = 1 -
|
|
792
819
|
(0.1 + (noteNumber / 127) * 0.2) * channel.softPedal;
|
|
793
820
|
const maxFreq = this.audioContext.sampleRate / 2;
|
|
794
821
|
const baseFreq = this.centToHz(instrumentKey.initialFilterFc) *
|
|
795
822
|
softPedalFactor;
|
|
796
823
|
const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc) * softPedalFactor;
|
|
797
|
-
const sustainFreq =
|
|
798
|
-
(peekFreq - baseFreq) * (1 - instrumentKey.modSustain)
|
|
824
|
+
const sustainFreq = baseFreq +
|
|
825
|
+
(peekFreq - baseFreq) * (1 - instrumentKey.modSustain);
|
|
826
|
+
const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
|
|
827
|
+
const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
|
|
828
|
+
const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
|
|
799
829
|
const modDelay = startTime + instrumentKey.modDelay;
|
|
800
830
|
const modAttack = modDelay + instrumentKey.modAttack;
|
|
801
831
|
const modHold = modAttack + instrumentKey.modHold;
|
|
802
832
|
const modDecay = modHold + instrumentKey.modDecay;
|
|
803
|
-
const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
|
|
804
|
-
const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
|
|
805
|
-
const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
|
|
806
833
|
note.filterNode = new BiquadFilterNode(this.audioContext, {
|
|
807
834
|
type: "lowpass",
|
|
808
835
|
Q: instrumentKey.initialFilterQ / 10, // dB
|
|
@@ -813,56 +840,72 @@ class Midy {
|
|
|
813
840
|
.exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
|
|
814
841
|
.setValueAtTime(adjustedPeekFreq, modHold)
|
|
815
842
|
.linearRampToValueAtTime(adjustedSustainFreq, modDecay);
|
|
816
|
-
note.bufferSource.detune.setValueAtTime(note.bufferSource.detune.value + instrumentKey.modEnvToPitch, modDelay);
|
|
817
843
|
}
|
|
818
|
-
startModulation(channel, note,
|
|
844
|
+
startModulation(channel, note, startTime) {
|
|
819
845
|
const { instrumentKey } = note;
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
});
|
|
823
|
-
note.modLFO = new OscillatorNode(this.audioContext, {
|
|
846
|
+
const { modLfoToPitch, modLfoToVolume } = instrumentKey;
|
|
847
|
+
note.modulationLFO = new OscillatorNode(this.audioContext, {
|
|
824
848
|
frequency: this.centToHz(instrumentKey.freqModLFO),
|
|
825
849
|
});
|
|
826
|
-
note.
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
850
|
+
note.filterDepth = new GainNode(this.audioContext, {
|
|
851
|
+
gain: instrumentKey.modLfoToFilterFc,
|
|
852
|
+
});
|
|
853
|
+
const modulationDepth = Math.abs(modLfoToPitch) + channel.modulationDepth;
|
|
854
|
+
const modulationDepthSign = (0 < modLfoToPitch) ? 1 : -1;
|
|
855
|
+
note.modulationDepth = new GainNode(this.audioContext, {
|
|
856
|
+
gain: modulationDepth * modulationDepthSign,
|
|
857
|
+
});
|
|
858
|
+
const volumeDepth = this.cbToRatio(Math.abs(modLfoToVolume)) - 1;
|
|
859
|
+
const volumeDepthSign = (0 < modLfoToVolume) ? 1 : -1;
|
|
860
|
+
note.volumeDepth = new GainNode(this.audioContext, {
|
|
861
|
+
gain: volumeDepth * volumeDepthSign,
|
|
836
862
|
});
|
|
837
|
-
note.
|
|
838
|
-
|
|
863
|
+
note.modulationLFO.start(startTime + instrumentKey.delayModLFO);
|
|
864
|
+
note.modulationLFO.connect(note.filterDepth);
|
|
865
|
+
note.filterDepth.connect(note.filterNode.frequency);
|
|
866
|
+
note.modulationLFO.connect(note.modulationDepth);
|
|
867
|
+
note.modulationDepth.connect(note.bufferSource.detune);
|
|
868
|
+
note.modulationLFO.connect(note.volumeDepth);
|
|
869
|
+
note.volumeDepth.connect(note.volumeNode.gain);
|
|
870
|
+
}
|
|
871
|
+
startVibrato(channel, note, startTime) {
|
|
872
|
+
const { instrumentKey } = note;
|
|
873
|
+
const { vibLfoToPitch } = instrumentKey;
|
|
874
|
+
note.vibratoLFO = new OscillatorNode(this.audioContext, {
|
|
875
|
+
frequency: this.centToHz(instrumentKey.freqVibLFO) *
|
|
839
876
|
channel.vibratoRate,
|
|
840
877
|
});
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
note.
|
|
878
|
+
const vibratoDepth = Math.abs(vibLfoToPitch) * channel.vibratoDepth;
|
|
879
|
+
const vibratoDepthSign = 0 < vibLfoToPitch;
|
|
880
|
+
note.vibratoDepth = new GainNode(this.audioContext, {
|
|
881
|
+
gain: vibratoDepth * vibratoDepthSign,
|
|
882
|
+
});
|
|
883
|
+
note.vibratoLFO.start(startTime + instrumentKey.delayVibLFO * channel.vibratoDelay);
|
|
884
|
+
note.vibratoLFO.connect(note.vibratoDepth);
|
|
885
|
+
note.vibratoDepth.connect(note.bufferSource.detune);
|
|
844
886
|
}
|
|
845
887
|
async createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3) {
|
|
846
888
|
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
847
889
|
const note = new Note(noteNumber, velocity, startTime, instrumentKey);
|
|
848
890
|
note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
|
|
849
|
-
|
|
891
|
+
this.setFilterNode(channel, note);
|
|
850
892
|
this.setVolumeEnvelope(note);
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
const delayModLFO = startTime + instrumentKey.delayModLFO;
|
|
854
|
-
this.startModulation(channel, note, delayModLFO);
|
|
893
|
+
if (0 < channel.vibratoDepth) {
|
|
894
|
+
this.startVibrato(channel, note, startTime);
|
|
855
895
|
}
|
|
856
|
-
if (channel.
|
|
857
|
-
|
|
858
|
-
this.
|
|
896
|
+
if (0 < channel.modulationDepth) {
|
|
897
|
+
this.setPitch(note, semitoneOffset);
|
|
898
|
+
this.startModulation(channel, note, startTime);
|
|
899
|
+
}
|
|
900
|
+
else {
|
|
901
|
+
note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
|
|
859
902
|
}
|
|
860
903
|
if (this.mono && channel.currentBufferSource) {
|
|
861
904
|
channel.currentBufferSource.stop(startTime);
|
|
862
905
|
channel.currentBufferSource = note.bufferSource;
|
|
863
906
|
}
|
|
864
907
|
note.bufferSource.connect(note.filterNode);
|
|
865
|
-
note.filterNode.connect(note.
|
|
908
|
+
note.filterNode.connect(note.volumeNode);
|
|
866
909
|
note.bufferSource.start(startTime, instrumentKey.start / instrumentKey.sampleRate);
|
|
867
910
|
return note;
|
|
868
911
|
}
|
|
@@ -887,8 +930,8 @@ class Midy {
|
|
|
887
930
|
if (!instrumentKey)
|
|
888
931
|
return;
|
|
889
932
|
const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
|
|
890
|
-
note.
|
|
891
|
-
note.
|
|
933
|
+
note.volumeNode.connect(channel.gainL);
|
|
934
|
+
note.volumeNode.connect(channel.gainR);
|
|
892
935
|
if (channel.sostenutoPedal) {
|
|
893
936
|
channel.sostenutoNotes.set(noteNumber, note);
|
|
894
937
|
}
|
|
@@ -922,17 +965,14 @@ class Midy {
|
|
|
922
965
|
const velocityRate = (velocity + 127) / 127;
|
|
923
966
|
const volEndTime = stopTime +
|
|
924
967
|
note.instrumentKey.volRelease * velocityRate;
|
|
925
|
-
note.
|
|
968
|
+
note.volumeNode.gain
|
|
926
969
|
.cancelScheduledValues(stopTime)
|
|
927
970
|
.linearRampToValueAtTime(0, volEndTime);
|
|
928
|
-
const
|
|
929
|
-
const baseFreq = this.centToHz(note.instrumentKey.initialFilterFc);
|
|
930
|
-
const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
|
|
931
|
-
const modEndTime = stopTime +
|
|
971
|
+
const modRelease = stopTime +
|
|
932
972
|
note.instrumentKey.modRelease * velocityRate;
|
|
933
973
|
note.filterNode.frequency
|
|
934
974
|
.cancelScheduledValues(stopTime)
|
|
935
|
-
.linearRampToValueAtTime(
|
|
975
|
+
.linearRampToValueAtTime(0, modRelease);
|
|
936
976
|
note.ending = true;
|
|
937
977
|
this.scheduleTask(() => {
|
|
938
978
|
note.bufferSource.loop = false;
|
|
@@ -941,16 +981,18 @@ class Midy {
|
|
|
941
981
|
note.bufferSource.onended = () => {
|
|
942
982
|
scheduledNotes[i] = null;
|
|
943
983
|
note.bufferSource.disconnect();
|
|
984
|
+
note.volumeNode.disconnect();
|
|
944
985
|
note.filterNode.disconnect();
|
|
945
|
-
note.
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
986
|
+
if (note.volumeDepth)
|
|
987
|
+
note.volumeDepth.disconnect();
|
|
988
|
+
if (note.modulationDepth)
|
|
989
|
+
note.modulationDepth.disconnect();
|
|
990
|
+
if (note.modulationLFO)
|
|
991
|
+
note.modulationLFO.stop();
|
|
992
|
+
if (note.vibratoDepth)
|
|
993
|
+
note.vibratoDepth.disconnect();
|
|
994
|
+
if (note.vibratoLFO)
|
|
995
|
+
note.vibratoLFO.stop();
|
|
954
996
|
resolve();
|
|
955
997
|
};
|
|
956
998
|
note.bufferSource.stop(volEndTime);
|
|
@@ -966,10 +1008,10 @@ class Midy {
|
|
|
966
1008
|
const channel = this.channels[channelNumber];
|
|
967
1009
|
const promises = [];
|
|
968
1010
|
channel.sustainPedal = false;
|
|
969
|
-
channel.scheduledNotes.forEach((
|
|
970
|
-
|
|
971
|
-
if (
|
|
972
|
-
const { noteNumber } =
|
|
1011
|
+
channel.scheduledNotes.forEach((noteList) => {
|
|
1012
|
+
noteList.forEach((note) => {
|
|
1013
|
+
if (note) {
|
|
1014
|
+
const { noteNumber } = note;
|
|
973
1015
|
const promise = this.releaseNote(channelNumber, noteNumber, velocity);
|
|
974
1016
|
promises.push(promise);
|
|
975
1017
|
}
|
|
@@ -1020,8 +1062,8 @@ class Midy {
|
|
|
1020
1062
|
if (channel.polyphonicKeyPressure.amplitudeControl !== 1) {
|
|
1021
1063
|
if (activeNotes.has(noteNumber)) {
|
|
1022
1064
|
const activeNote = activeNotes.get(noteNumber);
|
|
1023
|
-
const gain = activeNote.
|
|
1024
|
-
activeNote.
|
|
1065
|
+
const gain = activeNote.volumeNode.gain.value;
|
|
1066
|
+
activeNote.volumeNode.gain
|
|
1025
1067
|
.cancelScheduledValues(now)
|
|
1026
1068
|
.setValueAtTime(gain * pressure, now);
|
|
1027
1069
|
}
|
|
@@ -1040,8 +1082,8 @@ class Midy {
|
|
|
1040
1082
|
const activeNotes = this.getActiveNotes(channel, now);
|
|
1041
1083
|
if (channel.channelPressure.amplitudeControl !== 1) {
|
|
1042
1084
|
activeNotes.forEach((activeNote) => {
|
|
1043
|
-
const gain = activeNote.
|
|
1044
|
-
activeNote.
|
|
1085
|
+
const gain = activeNote.volumeNode.gain.value;
|
|
1086
|
+
activeNote.volumeNode.gain
|
|
1045
1087
|
.cancelScheduledValues(now)
|
|
1046
1088
|
.setValueAtTime(gain * pressure, now);
|
|
1047
1089
|
});
|
|
@@ -1064,7 +1106,7 @@ class Midy {
|
|
|
1064
1106
|
case 0:
|
|
1065
1107
|
return this.setBankMSB(channelNumber, value);
|
|
1066
1108
|
case 1:
|
|
1067
|
-
return this.
|
|
1109
|
+
return this.setModulationDepth(channelNumber, value);
|
|
1068
1110
|
case 5:
|
|
1069
1111
|
return this.setPortamentoTime(channelNumber, value);
|
|
1070
1112
|
case 6:
|
|
@@ -1131,18 +1173,19 @@ class Midy {
|
|
|
1131
1173
|
const now = this.audioContext.currentTime;
|
|
1132
1174
|
const activeNotes = this.getActiveNotes(channel, now);
|
|
1133
1175
|
activeNotes.forEach((activeNote) => {
|
|
1134
|
-
if (activeNote.
|
|
1135
|
-
|
|
1136
|
-
gainNode.gain.setValueAtTime(this.cbToRatio(instrumentKey.modLfoToVolume + channel.modulation), now);
|
|
1176
|
+
if (activeNote.modulationDepth) {
|
|
1177
|
+
activeNote.modulationDepth.gain.setValueAtTime(channel.modulationDepth, now);
|
|
1137
1178
|
}
|
|
1138
1179
|
else {
|
|
1180
|
+
const semitoneOffset = this.calcSemitoneOffset(channel);
|
|
1181
|
+
this.setPitch(activeNote, semitoneOffset);
|
|
1139
1182
|
this.startModulation(channel, activeNote, now);
|
|
1140
1183
|
}
|
|
1141
1184
|
});
|
|
1142
1185
|
}
|
|
1143
|
-
|
|
1186
|
+
setModulationDepth(channelNumber, modulation) {
|
|
1144
1187
|
const channel = this.channels[channelNumber];
|
|
1145
|
-
channel.
|
|
1188
|
+
channel.modulationDepth = (modulation / 127) * channel.modulationDepthRange;
|
|
1146
1189
|
this.updateModulation(channel);
|
|
1147
1190
|
}
|
|
1148
1191
|
setPortamentoTime(channelNumber, portamentoTime) {
|
|
@@ -1244,21 +1287,15 @@ class Midy {
|
|
|
1244
1287
|
}
|
|
1245
1288
|
setVibratoRate(channelNumber, vibratoRate) {
|
|
1246
1289
|
const channel = this.channels[channelNumber];
|
|
1247
|
-
channel.vibratoRate = vibratoRate /
|
|
1290
|
+
channel.vibratoRate = vibratoRate / 64;
|
|
1248
1291
|
}
|
|
1249
1292
|
setVibratoDepth(channelNumber, vibratoDepth) {
|
|
1250
1293
|
const channel = this.channels[channelNumber];
|
|
1251
|
-
channel.vibratoDepth = vibratoDepth /
|
|
1294
|
+
channel.vibratoDepth = vibratoDepth / 64;
|
|
1252
1295
|
}
|
|
1253
1296
|
setVibratoDelay(channelNumber, vibratoDelay) {
|
|
1254
|
-
// Access Virus: 0-10sec
|
|
1255
|
-
// Elektron: 0-5sec
|
|
1256
|
-
// Korg: 0-5sec
|
|
1257
|
-
// Nord: 0-5sec
|
|
1258
|
-
// Roland: 0-5sec
|
|
1259
|
-
// Yamaha: 0-8sec
|
|
1260
1297
|
const channel = this.channels[channelNumber];
|
|
1261
|
-
channel.vibratoDelay = vibratoDelay /
|
|
1298
|
+
channel.vibratoDelay = vibratoDelay / 64;
|
|
1262
1299
|
}
|
|
1263
1300
|
limitData(channel, minMSB, maxMSB, minLSB, maxLSB) {
|
|
1264
1301
|
if (maxLSB < channel.dataLSB) {
|
|
@@ -1380,47 +1417,23 @@ class Midy {
|
|
|
1380
1417
|
handleModulationDepthRangeRPN(channelNumber) {
|
|
1381
1418
|
const channel = this.channels[channelNumber];
|
|
1382
1419
|
this.limitData(channel, 0, 127, 0, 127);
|
|
1383
|
-
const modulationDepthRange = dataMSB + dataLSB / 128;
|
|
1420
|
+
const modulationDepthRange = (dataMSB + dataLSB / 128) * 100;
|
|
1384
1421
|
this.setModulationDepthRange(channelNumber, modulationDepthRange);
|
|
1385
1422
|
}
|
|
1386
1423
|
setModulationDepthRange(channelNumber, modulationDepthRange) {
|
|
1387
1424
|
const channel = this.channels[channelNumber];
|
|
1388
1425
|
channel.modulationDepthRange = modulationDepthRange;
|
|
1389
|
-
channel.
|
|
1426
|
+
channel.modulationDepth = (modulation / 127) * modulationDepthRange;
|
|
1390
1427
|
this.updateModulation(channel);
|
|
1391
1428
|
}
|
|
1392
1429
|
allSoundOff(channelNumber) {
|
|
1393
|
-
|
|
1394
|
-
const channel = this.channels[channelNumber];
|
|
1395
|
-
const velocity = 0;
|
|
1396
|
-
const stopPedal = true;
|
|
1397
|
-
const promises = [];
|
|
1398
|
-
channel.scheduledNotes.forEach((noteList) => {
|
|
1399
|
-
const activeNote = this.getActiveNote(noteList, now);
|
|
1400
|
-
if (activeNote) {
|
|
1401
|
-
const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
|
|
1402
|
-
promises.push(notePromise);
|
|
1403
|
-
}
|
|
1404
|
-
});
|
|
1405
|
-
return promises;
|
|
1430
|
+
return this.stopChannelNotes(channelNumber, 0, true);
|
|
1406
1431
|
}
|
|
1407
1432
|
resetAllControllers(channelNumber) {
|
|
1408
1433
|
Object.assign(this.channels[channelNumber], this.effectSettings);
|
|
1409
1434
|
}
|
|
1410
1435
|
allNotesOff(channelNumber) {
|
|
1411
|
-
|
|
1412
|
-
const channel = this.channels[channelNumber];
|
|
1413
|
-
const velocity = 0;
|
|
1414
|
-
const stopPedal = false;
|
|
1415
|
-
const promises = [];
|
|
1416
|
-
channel.scheduledNotes.forEach((noteList) => {
|
|
1417
|
-
const activeNote = this.getActiveNote(noteList, now);
|
|
1418
|
-
if (activeNote) {
|
|
1419
|
-
const notePromise = this.scheduleNoteRelease(channelNumber, activeNote.noteNumber, velocity, now, stopPedal);
|
|
1420
|
-
promises.push(notePromise);
|
|
1421
|
-
}
|
|
1422
|
-
});
|
|
1423
|
-
return promises;
|
|
1436
|
+
return this.stopChannelNotes(channelNumber, 0, false);
|
|
1424
1437
|
}
|
|
1425
1438
|
omniOff() {
|
|
1426
1439
|
this.omni = false;
|
|
@@ -1781,9 +1794,9 @@ Object.defineProperty(Midy, "channelSettings", {
|
|
|
1781
1794
|
portamentoTime: 0,
|
|
1782
1795
|
reverbSendLevel: 0,
|
|
1783
1796
|
chorusSendLevel: 0,
|
|
1784
|
-
vibratoRate:
|
|
1785
|
-
vibratoDepth:
|
|
1786
|
-
vibratoDelay:
|
|
1797
|
+
vibratoRate: 1,
|
|
1798
|
+
vibratoDepth: 1,
|
|
1799
|
+
vibratoDelay: 1,
|
|
1787
1800
|
bank: 121 * 128,
|
|
1788
1801
|
bankMSB: 121,
|
|
1789
1802
|
bankLSB: 0,
|
|
@@ -1793,7 +1806,7 @@ Object.defineProperty(Midy, "channelSettings", {
|
|
|
1793
1806
|
pitchBend: 0,
|
|
1794
1807
|
fineTuning: 0, // cb
|
|
1795
1808
|
coarseTuning: 0, // cb
|
|
1796
|
-
modulationDepthRange:
|
|
1809
|
+
modulationDepthRange: 50, // cent
|
|
1797
1810
|
}
|
|
1798
1811
|
});
|
|
1799
1812
|
Object.defineProperty(Midy, "effectSettings", {
|
|
@@ -1802,7 +1815,7 @@ Object.defineProperty(Midy, "effectSettings", {
|
|
|
1802
1815
|
writable: true,
|
|
1803
1816
|
value: {
|
|
1804
1817
|
expression: 1,
|
|
1805
|
-
|
|
1818
|
+
modulationDepth: 0,
|
|
1806
1819
|
sustainPedal: false,
|
|
1807
1820
|
portamento: false,
|
|
1808
1821
|
sostenutoPedal: false,
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
declare const _default: null;
|
|
2
|
-
export default _default;
|
|
3
|
-
declare class F {
|
|
4
|
-
constructor(e: any);
|
|
5
|
-
parsed: any;
|
|
6
|
-
getGenerators(e: any, t: any, r: any, n: any): any[];
|
|
7
|
-
getPresetGenerators(e: any): any[];
|
|
8
|
-
getInstrumentGenerators(e: any): any[];
|
|
9
|
-
getInstrumentKey(e: any, t: any, r: any, n?: number): {
|
|
10
|
-
sample: any;
|
|
11
|
-
sampleRate: any;
|
|
12
|
-
sampleName: any;
|
|
13
|
-
sampleModes: number;
|
|
14
|
-
playbackRate: (e: any) => number;
|
|
15
|
-
modLfoToPitch: number;
|
|
16
|
-
vibLfoToPitch: number;
|
|
17
|
-
modEnvToPitch: number;
|
|
18
|
-
initialFilterFc: number;
|
|
19
|
-
initialFilterQ: number;
|
|
20
|
-
modLfoToFilterFc: number;
|
|
21
|
-
modEnvToFilterFc: number;
|
|
22
|
-
modLfoToVolume: number;
|
|
23
|
-
scaleTuning: number;
|
|
24
|
-
start: number;
|
|
25
|
-
end: number;
|
|
26
|
-
loopStart: any;
|
|
27
|
-
loopEnd: any;
|
|
28
|
-
volDelay: number;
|
|
29
|
-
volAttack: number;
|
|
30
|
-
volHold: number;
|
|
31
|
-
volDecay: number;
|
|
32
|
-
volSustain: number;
|
|
33
|
-
volRelease: number;
|
|
34
|
-
modDelay: number;
|
|
35
|
-
modAttack: number;
|
|
36
|
-
modHold: number;
|
|
37
|
-
modDecay: number;
|
|
38
|
-
modSustain: number;
|
|
39
|
-
modRelease: number;
|
|
40
|
-
keyRange: d;
|
|
41
|
-
velRange: d;
|
|
42
|
-
delayModLFO: number;
|
|
43
|
-
freqModLFO: number;
|
|
44
|
-
delayVibLFO: number;
|
|
45
|
-
freqVibLFO: number;
|
|
46
|
-
initialAttenuation: number;
|
|
47
|
-
pan: number;
|
|
48
|
-
} | null;
|
|
49
|
-
getPresetNames(): {};
|
|
50
|
-
}
|
|
51
|
-
declare function M(e: any): number;
|
|
52
|
-
declare function I(e: any): {};
|
|
53
|
-
declare namespace T {
|
|
54
|
-
let keynum: undefined;
|
|
55
|
-
let instrument: undefined;
|
|
56
|
-
let velocity: undefined;
|
|
57
|
-
let exclusiveClass: undefined;
|
|
58
|
-
let keyRange: d;
|
|
59
|
-
let velRange: d;
|
|
60
|
-
let sampleID: undefined;
|
|
61
|
-
let delayVolEnv: number;
|
|
62
|
-
let attackVolEnv: number;
|
|
63
|
-
let decayVolEnv: number;
|
|
64
|
-
let holdVolEnv: number;
|
|
65
|
-
let sustainVolEnv: number;
|
|
66
|
-
let releaseVolEnv: number;
|
|
67
|
-
let delayModEnv: number;
|
|
68
|
-
let attackModEnv: number;
|
|
69
|
-
let decayModEnv: number;
|
|
70
|
-
let holdModEnv: number;
|
|
71
|
-
let sustainModEnv: number;
|
|
72
|
-
let releaseModEnv: number;
|
|
73
|
-
let modEnvToPitch: number;
|
|
74
|
-
let modEnvToFilterFc: number;
|
|
75
|
-
let modLfoToFilterFc: number;
|
|
76
|
-
let modLfoToPitch: number;
|
|
77
|
-
let modLfoToVolume: number;
|
|
78
|
-
let vibLfoToPitch: number;
|
|
79
|
-
let chorusEffectsSend: number;
|
|
80
|
-
let reverbEffectsSend: number;
|
|
81
|
-
let delayModLFO: number;
|
|
82
|
-
let freqModLFO: number;
|
|
83
|
-
let delayVibLFO: number;
|
|
84
|
-
let keynumToModEnvDecay: number;
|
|
85
|
-
let keynumToModEnvHold: number;
|
|
86
|
-
let keynumToVolEnvDecay: number;
|
|
87
|
-
let keynumToVolEnvHold: number;
|
|
88
|
-
let coarseTune: number;
|
|
89
|
-
let fineTune: number;
|
|
90
|
-
let scaleTuning: number;
|
|
91
|
-
let freqVibLFO: number;
|
|
92
|
-
let startAddrsOffset: number;
|
|
93
|
-
let startAddrsCoarseOffset: number;
|
|
94
|
-
let endAddrsOffset: number;
|
|
95
|
-
let endAddrsCoarseOffset: number;
|
|
96
|
-
let startloopAddrsOffset: number;
|
|
97
|
-
let startloopAddrsCoarseOffset: number;
|
|
98
|
-
let initialAttenuation: number;
|
|
99
|
-
let endloopAddrsOffset: number;
|
|
100
|
-
let endloopAddrsCoarseOffset: number;
|
|
101
|
-
let overridingRootKey: undefined;
|
|
102
|
-
let initialFilterQ: number;
|
|
103
|
-
let initialFilterFc: number;
|
|
104
|
-
let sampleModes: number;
|
|
105
|
-
let pan: number;
|
|
106
|
-
}
|
|
107
|
-
declare function b(e: any, n?: {}): {
|
|
108
|
-
samples: any;
|
|
109
|
-
presetHeaders: any[];
|
|
110
|
-
presetZone: any[];
|
|
111
|
-
presetModulators: any[];
|
|
112
|
-
presetGenerators: any[];
|
|
113
|
-
instruments: any[];
|
|
114
|
-
instrumentZone: any[];
|
|
115
|
-
instrumentModulators: any[];
|
|
116
|
-
instrumentGenerators: any[];
|
|
117
|
-
sampleHeaders: any[];
|
|
118
|
-
info: o;
|
|
119
|
-
samplingData: {
|
|
120
|
-
offsetMSB: any;
|
|
121
|
-
offsetLSB: any;
|
|
122
|
-
};
|
|
123
|
-
};
|
|
124
|
-
declare class d {
|
|
125
|
-
static parse(e: any): d;
|
|
126
|
-
constructor(e: any, t: any);
|
|
127
|
-
lo: any;
|
|
128
|
-
hi: any;
|
|
129
|
-
in(e: any): boolean;
|
|
130
|
-
}
|
|
131
|
-
declare class o {
|
|
132
|
-
static parse(t: any, r: any): o;
|
|
133
|
-
}
|
|
134
|
-
export { F as SoundFont, M as convertTime, I as createGeneratorObject, T as defaultInstrumentZone, b as parse };
|
|
135
|
-
//# 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.2/+esm.js"],"names":[],"mappings":";;AAMizX;IAAQ,oBAA2H;IAAd,YAAa;IAAC,qDAAoJ;IAAA,mCAAoP;IAAA,uCAAwQ;IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAAkqE;IAAA,qBAA0I;CAAC;AAAA,mCAAwC;AAA9oI,+BAA8F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAA98D;;;;;;;;;;;;;;;;EAA27B;AAAr4I;IAAqQ,wBAAwD;IAArT,4BAAyN;IAApB,QAAS;IAAC,QAAS;IAAC,oBAAoC;CAAyD;AAAllG;IAAwjC,gCAA8d;CAAC"}
|