@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.
Files changed (35) hide show
  1. package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts +153 -0
  2. package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts.map +1 -0
  3. package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/{soundfont-parser@0.0.2 → soundfont-parser@0.0.4}/+esm.js +73 -66
  4. package/esm/midy-GM1.d.ts +17 -12
  5. package/esm/midy-GM1.d.ts.map +1 -1
  6. package/esm/midy-GM1.js +125 -96
  7. package/esm/midy-GM2.d.ts +21 -14
  8. package/esm/midy-GM2.d.ts.map +1 -1
  9. package/esm/midy-GM2.js +146 -107
  10. package/esm/midy-GMLite.d.ts +15 -12
  11. package/esm/midy-GMLite.d.ts.map +1 -1
  12. package/esm/midy-GMLite.js +115 -98
  13. package/esm/midy.d.ts +18 -15
  14. package/esm/midy.d.ts.map +1 -1
  15. package/esm/midy.js +147 -134
  16. package/package.json +1 -1
  17. package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts +153 -0
  18. package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.d.ts.map +1 -0
  19. package/script/deps/cdn.jsdelivr.net/npm/@marmooo/{soundfont-parser@0.0.2 → soundfont-parser@0.0.4}/+esm.js +75 -68
  20. package/script/midy-GM1.d.ts +17 -12
  21. package/script/midy-GM1.d.ts.map +1 -1
  22. package/script/midy-GM1.js +125 -96
  23. package/script/midy-GM2.d.ts +21 -14
  24. package/script/midy-GM2.d.ts.map +1 -1
  25. package/script/midy-GM2.js +146 -107
  26. package/script/midy-GMLite.d.ts +15 -12
  27. package/script/midy-GMLite.d.ts.map +1 -1
  28. package/script/midy-GMLite.js +115 -98
  29. package/script/midy.d.ts +18 -15
  30. package/script/midy.d.ts.map +1 -1
  31. package/script/midy.js +147 -134
  32. package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.2/+esm.d.ts +0 -135
  33. package/esm/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.2/+esm.d.ts.map +0 -1
  34. package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.2/+esm.d.ts +0 -135
  35. package/script/deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.2/+esm.d.ts.map +0 -1
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/+esm.js";
2
+ import { parse, SoundFont, } from "./deps/cdn.jsdelivr.net/npm/@marmooo/soundfont-parser@0.0.4/+esm.js";
3
3
  class Note {
4
4
  constructor(noteNumber, velocity, startTime, instrumentKey) {
5
5
  Object.defineProperty(this, "bufferSource", {
@@ -8,37 +8,43 @@ class Note {
8
8
  writable: true,
9
9
  value: void 0
10
10
  });
11
- Object.defineProperty(this, "gainNode", {
11
+ Object.defineProperty(this, "filterNode", {
12
12
  enumerable: true,
13
13
  configurable: true,
14
14
  writable: true,
15
15
  value: void 0
16
16
  });
17
- Object.defineProperty(this, "filterNode", {
17
+ Object.defineProperty(this, "volumeNode", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: void 0
22
+ });
23
+ Object.defineProperty(this, "volumeDepth", {
18
24
  enumerable: true,
19
25
  configurable: true,
20
26
  writable: true,
21
27
  value: void 0
22
28
  });
23
- Object.defineProperty(this, "modLFO", {
29
+ Object.defineProperty(this, "modulationLFO", {
24
30
  enumerable: true,
25
31
  configurable: true,
26
32
  writable: true,
27
33
  value: void 0
28
34
  });
29
- Object.defineProperty(this, "modLFOGain", {
35
+ Object.defineProperty(this, "modulationDepth", {
30
36
  enumerable: true,
31
37
  configurable: true,
32
38
  writable: true,
33
39
  value: void 0
34
40
  });
35
- Object.defineProperty(this, "vibLFO", {
41
+ Object.defineProperty(this, "vibratoLFO", {
36
42
  enumerable: true,
37
43
  configurable: true,
38
44
  writable: true,
39
45
  value: void 0
40
46
  });
41
- Object.defineProperty(this, "vibLFOGain", {
47
+ Object.defineProperty(this, "vibratoDepth", {
42
48
  enumerable: true,
43
49
  configurable: true,
44
50
  writable: true,
@@ -404,7 +410,7 @@ export class MidyGM2 {
404
410
  const t = this.audioContext.currentTime + offset;
405
411
  queueIndex = await this.scheduleTimelineEvents(t, offset, queueIndex);
406
412
  if (this.isPausing) {
407
- await this.stopNotes();
413
+ await this.stopNotes(0, true);
408
414
  this.notePromises = [];
409
415
  resolve();
410
416
  this.isPausing = false;
@@ -412,7 +418,7 @@ export class MidyGM2 {
412
418
  return;
413
419
  }
414
420
  else if (this.isStopping) {
415
- await this.stopNotes();
421
+ await this.stopNotes(0, true);
416
422
  this.notePromises = [];
417
423
  resolve();
418
424
  this.isStopping = false;
@@ -420,7 +426,7 @@ export class MidyGM2 {
420
426
  return;
421
427
  }
422
428
  else if (this.isSeeking) {
423
- this.stopNotes();
429
+ this.stopNotes(0, true);
424
430
  this.startTime = this.audioContext.currentTime;
425
431
  queueIndex = this.getQueueIndex(this.resumeTime);
426
432
  offset = this.resumeTime - this.startTime;
@@ -535,21 +541,24 @@ export class MidyGM2 {
535
541
  }
536
542
  return { instruments, timeline };
537
543
  }
538
- stopNotes() {
544
+ async stopChannelNotes(channelNumber, velocity, stopPedal) {
539
545
  const now = this.audioContext.currentTime;
540
- const velocity = 0;
541
- const stopPedal = true;
542
- this.channels.forEach((channel, channelNumber) => {
543
- channel.scheduledNotes.forEach((scheduledNotes) => {
544
- scheduledNotes.forEach((scheduledNote) => {
545
- if (scheduledNote) {
546
- const promise = this.scheduleNoteRelease(channelNumber, scheduledNote.noteNumber, velocity, now, stopPedal);
547
- this.notePromises.push(promise);
548
- }
549
- });
546
+ const channel = this.channels[channelNumber];
547
+ channel.scheduledNotes.forEach((noteList) => {
548
+ noteList.forEach((note) => {
549
+ if (note) {
550
+ const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
551
+ this.notePromises.push(promise);
552
+ }
550
553
  });
551
- channel.scheduledNotes.clear();
552
554
  });
555
+ channel.scheduledNotes.clear();
556
+ await Promise.all(this.notePromises);
557
+ }
558
+ stopNotes(velocity, stopPedal) {
559
+ for (let i = 0; i < this.channels.length; i++) {
560
+ this.stopChannelNotes(i, velocity, stopPedal);
561
+ }
553
562
  return Promise.all(this.notePromises);
554
563
  }
555
564
  async start() {
@@ -764,36 +773,54 @@ export class MidyGM2 {
764
773
  }
765
774
  setVolumeEnvelope(note) {
766
775
  const { instrumentKey, startTime } = note;
767
- note.gainNode = new GainNode(this.audioContext, { gain: 0 });
776
+ note.volumeNode = new GainNode(this.audioContext, { gain: 0 });
768
777
  const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
769
778
  const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
770
779
  const volDelay = startTime + instrumentKey.volDelay;
771
780
  const volAttack = volDelay + instrumentKey.volAttack;
772
781
  const volHold = volAttack + instrumentKey.volHold;
773
782
  const volDecay = volHold + instrumentKey.volDecay;
774
- note.gainNode.gain
783
+ note.volumeNode.gain
775
784
  .setValueAtTime(1e-6, volDelay) // exponentialRampToValueAtTime() requires a non-zero value
776
785
  .exponentialRampToValueAtTime(attackVolume, volAttack)
777
786
  .setValueAtTime(attackVolume, volHold)
778
787
  .linearRampToValueAtTime(sustainVolume, volDecay);
779
788
  }
780
- setFilterEnvelope(channel, note) {
781
- const { instrumentKey, startTime, noteNumber } = note;
789
+ setPitch(note, semitoneOffset) {
790
+ const { instrumentKey, noteNumber, startTime } = note;
791
+ const modEnvToPitch = instrumentKey.modEnvToPitch / 100;
792
+ note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
793
+ if (modEnvToPitch === 0)
794
+ return;
795
+ const basePitch = note.bufferSource.playbackRate.value;
796
+ const peekPitch = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset + modEnvToPitch);
797
+ const modDelay = startTime + instrumentKey.modDelay;
798
+ const modAttack = modDelay + instrumentKey.modAttack;
799
+ const modHold = modAttack + instrumentKey.modHold;
800
+ const modDecay = modHold + instrumentKey.modDecay;
801
+ note.bufferSource.playbackRate.value
802
+ .setValueAtTime(basePitch, modDelay)
803
+ .exponentialRampToValueAtTime(peekPitch, modAttack)
804
+ .setValueAtTime(peekPitch, modHold)
805
+ .linearRampToValueAtTime(basePitch, modDecay);
806
+ }
807
+ setFilterNode(channel, note) {
808
+ const { instrumentKey, noteNumber, startTime } = note;
782
809
  const softPedalFactor = 1 -
783
810
  (0.1 + (noteNumber / 127) * 0.2) * channel.softPedal;
784
811
  const maxFreq = this.audioContext.sampleRate / 2;
785
812
  const baseFreq = this.centToHz(instrumentKey.initialFilterFc) *
786
813
  softPedalFactor;
787
814
  const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc) * softPedalFactor;
788
- const sustainFreq = (baseFreq +
789
- (peekFreq - baseFreq) * (1 - instrumentKey.modSustain)) * softPedalFactor;
815
+ const sustainFreq = baseFreq +
816
+ (peekFreq - baseFreq) * (1 - instrumentKey.modSustain);
817
+ const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
818
+ const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
819
+ const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
790
820
  const modDelay = startTime + instrumentKey.modDelay;
791
821
  const modAttack = modDelay + instrumentKey.modAttack;
792
822
  const modHold = modAttack + instrumentKey.modHold;
793
823
  const modDecay = modHold + instrumentKey.modDecay;
794
- const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
795
- const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
796
- const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
797
824
  note.filterNode = new BiquadFilterNode(this.audioContext, {
798
825
  type: "lowpass",
799
826
  Q: instrumentKey.initialFilterQ / 10, // dB
@@ -804,39 +831,72 @@ export class MidyGM2 {
804
831
  .exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
805
832
  .setValueAtTime(adjustedPeekFreq, modHold)
806
833
  .linearRampToValueAtTime(adjustedSustainFreq, modDecay);
807
- note.bufferSource.detune.setValueAtTime(note.bufferSource.detune.value + instrumentKey.modEnvToPitch, modDelay);
808
834
  }
809
- startModulation(channel, note, time) {
835
+ startModulation(channel, note, startTime) {
810
836
  const { instrumentKey } = note;
811
- note.modLFOGain = new GainNode(this.audioContext, {
812
- gain: this.cbToRatio(instrumentKey.modLfoToVolume + channel.modulation),
813
- });
814
- note.modLFO = new OscillatorNode(this.audioContext, {
837
+ const { modLfoToPitch, modLfoToVolume } = instrumentKey;
838
+ note.modulationLFO = new OscillatorNode(this.audioContext, {
815
839
  frequency: this.centToHz(instrumentKey.freqModLFO),
816
840
  });
817
- note.modLFO.start(time);
818
- note.filterNode.frequency.setValueAtTime(note.filterNode.frequency.value + instrumentKey.modLfoToFilterFc, time);
819
- note.bufferSource.detune.setValueAtTime(note.bufferSource.detune.value + instrumentKey.modLfoToPitch, time);
820
- note.modLFO.connect(note.modLFOGain);
821
- note.modLFOGain.connect(note.bufferSource.detune);
841
+ note.filterDepth = new GainNode(this.audioContext, {
842
+ gain: instrumentKey.modLfoToFilterFc,
843
+ });
844
+ const modulationDepth = Math.abs(modLfoToPitch) + channel.modulationDepth;
845
+ const modulationDepthSign = (0 < modLfoToPitch) ? 1 : -1;
846
+ note.modulationDepth = new GainNode(this.audioContext, {
847
+ gain: modulationDepth * modulationDepthSign,
848
+ });
849
+ const volumeDepth = this.cbToRatio(Math.abs(modLfoToVolume)) - 1;
850
+ const volumeDepthSign = (0 < modLfoToVolume) ? 1 : -1;
851
+ note.volumeDepth = new GainNode(this.audioContext, {
852
+ gain: volumeDepth * volumeDepthSign,
853
+ });
854
+ note.modulationLFO.start(startTime + instrumentKey.delayModLFO);
855
+ note.modulationLFO.connect(note.filterDepth);
856
+ note.filterDepth.connect(note.filterNode.frequency);
857
+ note.modulationLFO.connect(note.modulationDepth);
858
+ note.modulationDepth.connect(note.bufferSource.detune);
859
+ note.modulationLFO.connect(note.volumeDepth);
860
+ note.volumeDepth.connect(note.volumeNode.gain);
861
+ }
862
+ startVibrato(channel, note, startTime) {
863
+ const { instrumentKey } = note;
864
+ const { vibLfoToPitch } = instrumentKey;
865
+ note.vibratoLFO = new OscillatorNode(this.audioContext, {
866
+ frequency: this.centToHz(instrumentKey.freqVibLFO) *
867
+ channel.vibratoRate,
868
+ });
869
+ const vibratoDepth = Math.abs(vibLfoToPitch) * channel.vibratoDepth;
870
+ const vibratoDepthSign = 0 < vibLfoToPitch;
871
+ note.vibratoDepth = new GainNode(this.audioContext, {
872
+ gain: vibratoDepth * vibratoDepthSign,
873
+ });
874
+ note.vibratoLFO.start(startTime + instrumentKey.delayVibLFO * channel.vibratoDelay);
875
+ note.vibratoLFO.connect(note.vibratoDepth);
876
+ note.vibratoDepth.connect(note.bufferSource.detune);
822
877
  }
823
878
  async createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3) {
824
879
  const semitoneOffset = this.calcSemitoneOffset(channel);
825
880
  const note = new Note(noteNumber, velocity, startTime, instrumentKey);
826
881
  note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
827
- note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
882
+ this.setFilterNode(channel, note);
828
883
  this.setVolumeEnvelope(note);
829
- this.setFilterEnvelope(channel, note);
830
- if (channel.modulation > 0) {
831
- const delayModLFO = startTime + instrumentKey.delayModLFO;
832
- this.startModulation(channel, note, delayModLFO);
884
+ if (0 < channel.vibratoDepth) {
885
+ this.startVibrato(channel, note, startTime);
886
+ }
887
+ if (0 < channel.modulationDepth) {
888
+ this.setPitch(note, semitoneOffset);
889
+ this.startModulation(channel, note, startTime);
890
+ }
891
+ else {
892
+ note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
833
893
  }
834
894
  if (this.mono && channel.currentBufferSource) {
835
895
  channel.currentBufferSource.stop(startTime);
836
896
  channel.currentBufferSource = note.bufferSource;
837
897
  }
838
898
  note.bufferSource.connect(note.filterNode);
839
- note.filterNode.connect(note.gainNode);
899
+ note.filterNode.connect(note.volumeNode);
840
900
  note.bufferSource.start(startTime, instrumentKey.start / instrumentKey.sampleRate);
841
901
  return note;
842
902
  }
@@ -861,8 +921,8 @@ export class MidyGM2 {
861
921
  if (!instrumentKey)
862
922
  return;
863
923
  const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
864
- note.gainNode.connect(channel.gainL);
865
- note.gainNode.connect(channel.gainR);
924
+ note.volumeNode.connect(channel.gainL);
925
+ note.volumeNode.connect(channel.gainR);
866
926
  if (channel.sostenutoPedal) {
867
927
  channel.sostenutoNotes.set(noteNumber, note);
868
928
  }
@@ -896,17 +956,14 @@ export class MidyGM2 {
896
956
  const velocityRate = (velocity + 127) / 127;
897
957
  const volEndTime = stopTime +
898
958
  note.instrumentKey.volRelease * velocityRate;
899
- note.gainNode.gain
959
+ note.volumeNode.gain
900
960
  .cancelScheduledValues(stopTime)
901
961
  .linearRampToValueAtTime(0, volEndTime);
902
- const maxFreq = this.audioContext.sampleRate / 2;
903
- const baseFreq = this.centToHz(note.instrumentKey.initialFilterFc);
904
- const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
905
- const modEndTime = stopTime +
962
+ const modRelease = stopTime +
906
963
  note.instrumentKey.modRelease * velocityRate;
907
964
  note.filterNode.frequency
908
965
  .cancelScheduledValues(stopTime)
909
- .linearRampToValueAtTime(adjustedBaseFreq, modEndTime);
966
+ .linearRampToValueAtTime(0, modRelease);
910
967
  note.ending = true;
911
968
  this.scheduleTask(() => {
912
969
  note.bufferSource.loop = false;
@@ -915,16 +972,18 @@ export class MidyGM2 {
915
972
  note.bufferSource.onended = () => {
916
973
  scheduledNotes[i] = null;
917
974
  note.bufferSource.disconnect();
975
+ note.volumeNode.disconnect();
918
976
  note.filterNode.disconnect();
919
- note.gainNode.disconnect();
920
- if (note.modLFOGain)
921
- note.modLFOGain.disconnect();
922
- if (note.vibLFOGain)
923
- note.vibLFOGain.disconnect();
924
- if (note.modLFO)
925
- note.modLFO.stop();
926
- if (note.vibLFO)
927
- note.vibLFO.stop();
977
+ if (note.volumeDepth)
978
+ note.volumeDepth.disconnect();
979
+ if (note.modulationDepth)
980
+ note.modulationDepth.disconnect();
981
+ if (note.modulationLFO)
982
+ note.modulationLFO.stop();
983
+ if (note.vibratoDepth)
984
+ note.vibratoDepth.disconnect();
985
+ if (note.vibratoLFO)
986
+ note.vibratoLFO.stop();
928
987
  resolve();
929
988
  };
930
989
  note.bufferSource.stop(volEndTime);
@@ -940,10 +999,10 @@ export class MidyGM2 {
940
999
  const channel = this.channels[channelNumber];
941
1000
  const promises = [];
942
1001
  channel.sustainPedal = false;
943
- channel.scheduledNotes.forEach((scheduledNotes) => {
944
- scheduledNotes.forEach((scheduledNote) => {
945
- if (scheduledNote) {
946
- const { noteNumber } = scheduledNote;
1002
+ channel.scheduledNotes.forEach((noteList) => {
1003
+ noteList.forEach((note) => {
1004
+ if (note) {
1005
+ const { noteNumber } = note;
947
1006
  const promise = this.releaseNote(channelNumber, noteNumber, velocity);
948
1007
  promises.push(promise);
949
1008
  }
@@ -997,8 +1056,8 @@ export class MidyGM2 {
997
1056
  const activeNotes = this.getActiveNotes(channel, now);
998
1057
  if (channel.channelPressure.amplitudeControl !== 1) {
999
1058
  activeNotes.forEach((activeNote) => {
1000
- const gain = activeNote.gainNode.gain.value;
1001
- activeNote.gainNode.gain
1059
+ const gain = activeNote.volumeNode.gain.value;
1060
+ activeNote.volumeNode.gain
1002
1061
  .cancelScheduledValues(now)
1003
1062
  .setValueAtTime(gain * pressure, now);
1004
1063
  });
@@ -1021,7 +1080,7 @@ export class MidyGM2 {
1021
1080
  case 0:
1022
1081
  return this.setBankMSB(channelNumber, value);
1023
1082
  case 1:
1024
- return this.setModulation(channelNumber, value);
1083
+ return this.setModulationDepth(channelNumber, value);
1025
1084
  case 5:
1026
1085
  return this.setPortamentoTime(channelNumber, value);
1027
1086
  case 6:
@@ -1077,18 +1136,19 @@ export class MidyGM2 {
1077
1136
  const now = this.audioContext.currentTime;
1078
1137
  const activeNotes = this.getActiveNotes(channel, now);
1079
1138
  activeNotes.forEach((activeNote) => {
1080
- if (activeNote.modLFO) {
1081
- const { gainNode, instrumentKey } = activeNote;
1082
- gainNode.gain.setValueAtTime(this.cbToRatio(instrumentKey.modLfoToVolume + channel.modulation), now);
1139
+ if (activeNote.modulationDepth) {
1140
+ activeNote.modulationDepth.gain.setValueAtTime(channel.modulationDepth, now);
1083
1141
  }
1084
1142
  else {
1143
+ const semitoneOffset = this.calcSemitoneOffset(channel);
1144
+ this.setPitch(activeNote, semitoneOffset);
1085
1145
  this.startModulation(channel, activeNote, now);
1086
1146
  }
1087
1147
  });
1088
1148
  }
1089
- setModulation(channelNumber, modulation) {
1149
+ setModulationDepth(channelNumber, modulation) {
1090
1150
  const channel = this.channels[channelNumber];
1091
- channel.modulation = (modulation / 127) * channel.modulationDepthRange;
1151
+ channel.modulationDepth = (modulation / 127) * channel.modulationDepthRange;
1092
1152
  this.updateModulation(channel);
1093
1153
  }
1094
1154
  setPortamentoTime(channelNumber, portamentoTime) {
@@ -1298,47 +1358,23 @@ export class MidyGM2 {
1298
1358
  handleModulationDepthRangeRPN(channelNumber) {
1299
1359
  const channel = this.channels[channelNumber];
1300
1360
  this.limitData(channel, 0, 127, 0, 127);
1301
- const modulationDepthRange = dataMSB + dataLSB / 128;
1361
+ const modulationDepthRange = (dataMSB + dataLSB / 128) * 100;
1302
1362
  this.setModulationDepthRange(channelNumber, modulationDepthRange);
1303
1363
  }
1304
1364
  setModulationDepthRange(channelNumber, modulationDepthRange) {
1305
1365
  const channel = this.channels[channelNumber];
1306
1366
  channel.modulationDepthRange = modulationDepthRange;
1307
- channel.modulation = (modulation / 127) * channel.modulationDepthRange;
1367
+ channel.modulationDepth = (modulation / 127) * modulationDepthRange;
1308
1368
  this.updateModulation(channel);
1309
1369
  }
1310
1370
  allSoundOff(channelNumber) {
1311
- const now = this.audioContext.currentTime;
1312
- const channel = this.channels[channelNumber];
1313
- const velocity = 0;
1314
- const stopPedal = true;
1315
- const promises = [];
1316
- channel.scheduledNotes.forEach((noteList) => {
1317
- const activeNote = this.getActiveNote(noteList, now);
1318
- if (activeNote) {
1319
- const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
1320
- promises.push(notePromise);
1321
- }
1322
- });
1323
- return promises;
1371
+ return this.stopChannelNotes(channelNumber, 0, true);
1324
1372
  }
1325
1373
  resetAllControllers(channelNumber) {
1326
1374
  Object.assign(this.channels[channelNumber], this.effectSettings);
1327
1375
  }
1328
1376
  allNotesOff(channelNumber) {
1329
- const now = this.audioContext.currentTime;
1330
- const channel = this.channels[channelNumber];
1331
- const velocity = 0;
1332
- const stopPedal = false;
1333
- const promises = [];
1334
- channel.scheduledNotes.forEach((noteList) => {
1335
- const activeNote = this.getActiveNote(noteList, now);
1336
- if (activeNote) {
1337
- const notePromise = this.scheduleNoteRelease(channelNumber, activeNote.noteNumber, velocity, now, stopPedal);
1338
- promises.push(notePromise);
1339
- }
1340
- });
1341
- return promises;
1377
+ return this.stopChannelNotes(channelNumber, 0, false);
1342
1378
  }
1343
1379
  omniOff() {
1344
1380
  this.omni = false;
@@ -1698,6 +1734,9 @@ Object.defineProperty(MidyGM2, "channelSettings", {
1698
1734
  portamentoTime: 0,
1699
1735
  reverbSendLevel: 0,
1700
1736
  chorusSendLevel: 0,
1737
+ vibratoRate: 1,
1738
+ vibratoDepth: 1,
1739
+ vibratoDelay: 1,
1701
1740
  bank: 121 * 128,
1702
1741
  bankMSB: 121,
1703
1742
  bankLSB: 0,
@@ -1707,7 +1746,7 @@ Object.defineProperty(MidyGM2, "channelSettings", {
1707
1746
  pitchBend: 0,
1708
1747
  fineTuning: 0, // cb
1709
1748
  coarseTuning: 0, // cb
1710
- modulationDepthRange: 0.5, // cb
1749
+ modulationDepthRange: 50, // cent
1711
1750
  }
1712
1751
  });
1713
1752
  Object.defineProperty(MidyGM2, "effectSettings", {
@@ -1716,7 +1755,7 @@ Object.defineProperty(MidyGM2, "effectSettings", {
1716
1755
  writable: true,
1717
1756
  value: {
1718
1757
  expression: 1,
1719
- modulation: 0,
1758
+ modulationDepth: 0,
1720
1759
  sustainPedal: false,
1721
1760
  portamento: false,
1722
1761
  sostenutoPedal: false,
@@ -11,7 +11,7 @@ export class MidyGMLite {
11
11
  };
12
12
  static effectSettings: {
13
13
  expression: number;
14
- modulation: number;
14
+ modulationDepth: number;
15
15
  sustainPedal: boolean;
16
16
  rpnMSB: number;
17
17
  rpnLSB: number;
@@ -60,7 +60,8 @@ export class MidyGMLite {
60
60
  instruments: Set<any>;
61
61
  timeline: any[];
62
62
  };
63
- stopNotes(): Promise<any[]>;
63
+ stopChannelNotes(channelNumber: any, velocity: any, stopPedal: any): Promise<void>;
64
+ stopNotes(velocity: any, stopPedal: any): Promise<any[]>;
64
65
  start(): Promise<void>;
65
66
  stop(): void;
66
67
  pause(): void;
@@ -75,21 +76,22 @@ export class MidyGMLite {
75
76
  calcSemitoneOffset(channel: any): number;
76
77
  calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
77
78
  setVolumeEnvelope(note: any): void;
78
- setFilterEnvelope(channel: any, note: any): void;
79
- startModulation(channel: any, note: any, time: any): void;
79
+ setPitch(note: any, semitoneOffset: any): void;
80
+ setFilterNode(channel: any, note: any): void;
81
+ startModulation(channel: any, note: any, startTime: any): void;
80
82
  createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
81
83
  scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
82
84
  noteOn(channelNumber: any, noteNumber: any, velocity: any): Promise<void>;
83
85
  scheduleNoteRelease(channelNumber: any, noteNumber: any, velocity: any, stopTime: any, stopPedal?: boolean): Promise<any> | undefined;
84
86
  releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
85
87
  releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
86
- handleMIDIMessage(statusByte: any, data1: any, data2: any): void | any[] | Promise<any>;
88
+ handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
87
89
  handleProgramChange(channelNumber: any, program: any): void;
88
90
  handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
89
91
  setPitchBend(channelNumber: any, pitchBend: any): void;
90
- handleControlChange(channelNumber: any, controller: any, value: any): void | any[];
92
+ handleControlChange(channelNumber: any, controller: any, value: any): void | Promise<void>;
91
93
  updateModulation(channel: any): void;
92
- setModulation(channelNumber: any, modulation: any): void;
94
+ setModulationDepth(channelNumber: any, modulation: any): void;
93
95
  setVolume(channelNumber: any, volume: any): void;
94
96
  panToGain(pan: any): {
95
97
  gainLeft: number;
@@ -107,9 +109,9 @@ export class MidyGMLite {
107
109
  updateDetune(channel: any, detuneChange: any): void;
108
110
  handlePitchBendRangeRPN(channelNumber: any): void;
109
111
  setPitchBendRange(channelNumber: any, pitchBendRange: any): void;
110
- allSoundOff(channelNumber: any): any[];
112
+ allSoundOff(channelNumber: any): Promise<void>;
111
113
  resetAllControllers(channelNumber: any): void;
112
- allNotesOff(channelNumber: any): any[];
114
+ allNotesOff(channelNumber: any): Promise<void>;
113
115
  handleUniversalNonRealTimeExclusiveMessage(data: any): void;
114
116
  GM1SystemOn(): void;
115
117
  handleUniversalRealTimeExclusiveMessage(data: any): void;
@@ -122,10 +124,11 @@ export class MidyGMLite {
122
124
  declare class Note {
123
125
  constructor(noteNumber: any, velocity: any, startTime: any, instrumentKey: any);
124
126
  bufferSource: any;
125
- gainNode: any;
126
127
  filterNode: any;
127
- modLFO: any;
128
- modLFOGain: any;
128
+ volumeNode: any;
129
+ volumeDepth: any;
130
+ modulationLFO: any;
131
+ modulationDepth: any;
129
132
  noteNumber: any;
130
133
  velocity: any;
131
134
  startTime: any;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAqBA;IAmBE;;;;;;;;;MASE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA5CD,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,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,4BAsBC;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,mCAcC;IAED,iDAiCC;IAED,0DAmBC;IAED,wHA6BC;IAED,kGA6BC;IAED,0EAGC;IAED,sIA8CC;IAED,0FAGC;IAED,kEAeC;IAED,wFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED,mFA+BC;IAED,qCAcC;IAED,yDAIC;IACD,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,mDAGC;IAED,sCAUC;IAED,sDAMC;IAED,oCAYC;IAED,gDAEC;IAED,gDAEC;IAED,mDAGC;IAED,oDAUC;IAED,kDAKC;IAED,iEAOC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,4DAgBC;IAED,oBAQC;IAED,yDAaC;IAED,yCAGC;IAED,mCAQC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AA5+BD;IAOE,gFAKC;IAXD,kBAAa;IACb,cAAS;IACT,gBAAW;IACX,YAAO;IACP,gBAAW;IAGT,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
1
+ {"version":3,"file":"midy-GMLite.d.ts","sourceRoot":"","sources":["../src/midy-GMLite.js"],"names":[],"mappings":"AAsBA;IAmBE;;;;;;;;;MASE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IA5CD,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,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,mCAcC;IAED,+CAwBC;IAED,6CA6BC;IAED,+DA0BC;IAED,wHA8BC;IAED,kGA6BC;IAED,0EAGC;IAED,sIA4CC;IAED,0FAGC;IAED,kEAeC;IAED,gFAiBC;IAED,4DAGC;IAED,qEAGC;IAED,uDAOC;IAED,2FA+BC;IAED,qCAeC;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,oDAUC;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;AA1+BD;IAQE,gFAKC;IAZD,kBAAa;IACb,gBAAW;IACX,gBAAW;IACX,iBAAY;IACZ,mBAAc;IACd,qBAAgB;IAGd,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}