@marmooo/midy 0.1.1 → 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 +18 -14
  5. package/esm/midy-GM1.d.ts.map +1 -1
  6. package/esm/midy-GM1.js +133 -110
  7. package/esm/midy-GM2.d.ts +36 -30
  8. package/esm/midy-GM2.d.ts.map +1 -1
  9. package/esm/midy-GM2.js +190 -158
  10. package/esm/midy-GMLite.d.ts +16 -14
  11. package/esm/midy-GMLite.d.ts.map +1 -1
  12. package/esm/midy-GMLite.js +123 -112
  13. package/esm/midy.d.ts +33 -31
  14. package/esm/midy.d.ts.map +1 -1
  15. package/esm/midy.js +191 -185
  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 +18 -14
  21. package/script/midy-GM1.d.ts.map +1 -1
  22. package/script/midy-GM1.js +133 -110
  23. package/script/midy-GM2.d.ts +36 -30
  24. package/script/midy-GM2.d.ts.map +1 -1
  25. package/script/midy-GM2.js +190 -158
  26. package/script/midy-GMLite.d.ts +16 -14
  27. package/script/midy-GMLite.d.ts.map +1 -1
  28. package/script/midy-GMLite.js +123 -112
  29. package/script/midy.d.ts +33 -31
  30. package/script/midy.d.ts.map +1 -1
  31. package/script/midy.js +191 -185
  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
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MidyGM1 = 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.2/+esm.js");
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,25 +11,43 @@ class Note {
11
11
  writable: true,
12
12
  value: void 0
13
13
  });
14
- Object.defineProperty(this, "gainNode", {
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, "filterNode", {
20
+ Object.defineProperty(this, "volumeNode", {
21
+ enumerable: true,
22
+ configurable: true,
23
+ writable: true,
24
+ value: void 0
25
+ });
26
+ Object.defineProperty(this, "volumeDepth", {
27
+ enumerable: true,
28
+ configurable: true,
29
+ writable: true,
30
+ value: void 0
31
+ });
32
+ Object.defineProperty(this, "modulationLFO", {
33
+ enumerable: true,
34
+ configurable: true,
35
+ writable: true,
36
+ value: void 0
37
+ });
38
+ Object.defineProperty(this, "modulationDepth", {
21
39
  enumerable: true,
22
40
  configurable: true,
23
41
  writable: true,
24
42
  value: void 0
25
43
  });
26
- Object.defineProperty(this, "modLFO", {
44
+ Object.defineProperty(this, "vibratoLFO", {
27
45
  enumerable: true,
28
46
  configurable: true,
29
47
  writable: true,
30
48
  value: void 0
31
49
  });
32
- Object.defineProperty(this, "modLFOGain", {
50
+ Object.defineProperty(this, "vibratoDepth", {
33
51
  enumerable: true,
34
52
  configurable: true,
35
53
  writable: true,
@@ -147,8 +165,8 @@ class MidyGM1 {
147
165
  });
148
166
  this.audioContext = audioContext;
149
167
  this.masterGain = new GainNode(audioContext);
150
- this.masterGain.connect(audioContext.destination);
151
168
  this.channels = this.createChannels(audioContext);
169
+ this.masterGain.connect(audioContext.destination);
152
170
  this.GM1SystemOn();
153
171
  }
154
172
  initSoundFontTable() {
@@ -192,6 +210,7 @@ class MidyGM1 {
192
210
  const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
193
211
  gainL.connect(merger, 0, 0);
194
212
  gainR.connect(merger, 0, 1);
213
+ merger.connect(this.masterGain);
195
214
  return {
196
215
  gainL,
197
216
  gainR,
@@ -315,7 +334,7 @@ class MidyGM1 {
315
334
  const t = this.audioContext.currentTime + offset;
316
335
  queueIndex = await this.scheduleTimelineEvents(t, offset, queueIndex);
317
336
  if (this.isPausing) {
318
- await this.stopNotes();
337
+ await this.stopNotes(0, true);
319
338
  this.notePromises = [];
320
339
  resolve();
321
340
  this.isPausing = false;
@@ -323,7 +342,7 @@ class MidyGM1 {
323
342
  return;
324
343
  }
325
344
  else if (this.isStopping) {
326
- await this.stopNotes();
345
+ await this.stopNotes(0, true);
327
346
  this.notePromises = [];
328
347
  resolve();
329
348
  this.isStopping = false;
@@ -331,7 +350,7 @@ class MidyGM1 {
331
350
  return;
332
351
  }
333
352
  else if (this.isSeeking) {
334
- this.stopNotes();
353
+ this.stopNotes(0, true);
335
354
  this.startTime = this.audioContext.currentTime;
336
355
  queueIndex = this.getQueueIndex(this.resumeTime);
337
356
  offset = this.resumeTime - this.startTime;
@@ -412,21 +431,24 @@ class MidyGM1 {
412
431
  }
413
432
  return { instruments, timeline };
414
433
  }
415
- stopNotes() {
434
+ async stopChannelNotes(channelNumber, velocity, stopPedal) {
416
435
  const now = this.audioContext.currentTime;
417
- const velocity = 0;
418
- const stopPedal = true;
419
- this.channels.forEach((channel, channelNumber) => {
420
- channel.scheduledNotes.forEach((scheduledNotes) => {
421
- scheduledNotes.forEach((scheduledNote) => {
422
- if (scheduledNote) {
423
- const promise = this.scheduleNoteRelease(channelNumber, scheduledNote.noteNumber, velocity, now, stopPedal);
424
- this.notePromises.push(promise);
425
- }
426
- });
436
+ const channel = this.channels[channelNumber];
437
+ channel.scheduledNotes.forEach((noteList) => {
438
+ noteList.forEach((note) => {
439
+ if (note) {
440
+ const promise = this.scheduleNoteRelease(channelNumber, note.noteNumber, velocity, now, stopPedal);
441
+ this.notePromises.push(promise);
442
+ }
427
443
  });
428
- channel.scheduledNotes.clear();
429
444
  });
445
+ channel.scheduledNotes.clear();
446
+ await Promise.all(this.notePromises);
447
+ }
448
+ stopNotes(velocity, stopPedal) {
449
+ for (let i = 0; i < this.channels.length; i++) {
450
+ this.stopChannelNotes(i, velocity, stopPedal);
451
+ }
430
452
  return Promise.all(this.notePromises);
431
453
  }
432
454
  async start() {
@@ -494,10 +516,6 @@ class MidyGM1 {
494
516
  }
495
517
  return noteList[0];
496
518
  }
497
- connectEffects(channel, gainNode) {
498
- gainNode.connect(channel.merger);
499
- merger.connect(this.masterGain);
500
- }
501
519
  cbToRatio(cb) {
502
520
  return Math.pow(10, cb / 200);
503
521
  }
@@ -512,27 +530,41 @@ class MidyGM1 {
512
530
  return instrumentKey.playbackRate(noteNumber) *
513
531
  Math.pow(2, semitoneOffset / 12);
514
532
  }
515
- setVolumeEnvelope(channel, note) {
516
- const { instrumentKey, startTime, velocity } = note;
517
- note.gainNode = new GainNode(this.audioContext, { gain: 0 });
518
- let volume = (velocity / 127) * channel.volume * channel.expression;
519
- if (volume === 0)
520
- volume = 1e-6; // exponentialRampToValueAtTime() requires a non-zero value
521
- const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation) *
522
- volume;
533
+ setVolumeEnvelope(note) {
534
+ const { instrumentKey, startTime } = note;
535
+ note.volumeNode = new GainNode(this.audioContext, { gain: 0 });
536
+ const attackVolume = this.cbToRatio(-instrumentKey.initialAttenuation);
523
537
  const sustainVolume = attackVolume * (1 - instrumentKey.volSustain);
524
538
  const volDelay = startTime + instrumentKey.volDelay;
525
539
  const volAttack = volDelay + instrumentKey.volAttack;
526
540
  const volHold = volAttack + instrumentKey.volHold;
527
541
  const volDecay = volHold + instrumentKey.volDecay;
528
- note.gainNode.gain
542
+ note.volumeNode.gain
529
543
  .setValueAtTime(1e-6, volDelay) // exponentialRampToValueAtTime() requires a non-zero value
530
544
  .exponentialRampToValueAtTime(attackVolume, volAttack)
531
545
  .setValueAtTime(attackVolume, volHold)
532
546
  .linearRampToValueAtTime(sustainVolume, volDecay);
533
547
  }
534
- setFilterEnvelope(channel, note) {
535
- const { instrumentKey, startTime, noteNumber } = note;
548
+ setPitch(note, semitoneOffset) {
549
+ const { instrumentKey, noteNumber, startTime } = note;
550
+ const modEnvToPitch = instrumentKey.modEnvToPitch / 100;
551
+ note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
552
+ if (modEnvToPitch === 0)
553
+ return;
554
+ const basePitch = note.bufferSource.playbackRate.value;
555
+ const peekPitch = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset + modEnvToPitch);
556
+ const modDelay = startTime + instrumentKey.modDelay;
557
+ const modAttack = modDelay + instrumentKey.modAttack;
558
+ const modHold = modAttack + instrumentKey.modHold;
559
+ const modDecay = modHold + instrumentKey.modDecay;
560
+ note.bufferSource.playbackRate.value
561
+ .setValueAtTime(basePitch, modDelay)
562
+ .exponentialRampToValueAtTime(peekPitch, modAttack)
563
+ .setValueAtTime(peekPitch, modHold)
564
+ .linearRampToValueAtTime(basePitch, modDecay);
565
+ }
566
+ setFilterNode(channel, note) {
567
+ const { instrumentKey, noteNumber, startTime } = note;
536
568
  const softPedalFactor = 1 -
537
569
  (0.1 + (noteNumber / 127) * 0.2) * channel.softPedal;
538
570
  const maxFreq = this.audioContext.sampleRate / 2;
@@ -541,13 +573,13 @@ class MidyGM1 {
541
573
  const peekFreq = this.centToHz(instrumentKey.initialFilterFc + instrumentKey.modEnvToFilterFc) * softPedalFactor;
542
574
  const sustainFreq = (baseFreq +
543
575
  (peekFreq - baseFreq) * (1 - instrumentKey.modSustain)) * softPedalFactor;
576
+ const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
577
+ const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
578
+ const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
544
579
  const modDelay = startTime + instrumentKey.modDelay;
545
580
  const modAttack = modDelay + instrumentKey.modAttack;
546
581
  const modHold = modAttack + instrumentKey.modHold;
547
582
  const modDecay = modHold + instrumentKey.modDecay;
548
- const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
549
- const adjustedPeekFreq = Math.min(maxFreq, peekFreq);
550
- const adjustedSustainFreq = Math.min(maxFreq, sustainFreq);
551
583
  note.filterNode = new BiquadFilterNode(this.audioContext, {
552
584
  type: "lowpass",
553
585
  Q: instrumentKey.initialFilterQ / 10, // dB
@@ -558,35 +590,49 @@ class MidyGM1 {
558
590
  .exponentialRampToValueAtTime(adjustedPeekFreq, modAttack)
559
591
  .setValueAtTime(adjustedPeekFreq, modHold)
560
592
  .linearRampToValueAtTime(adjustedSustainFreq, modDecay);
561
- note.bufferSource.detune.setValueAtTime(note.bufferSource.detune.value + instrumentKey.modEnvToPitch, modDelay);
562
593
  }
563
- startModulation(channel, note, time) {
594
+ startModulation(channel, note, startTime) {
564
595
  const { instrumentKey } = note;
565
- note.modLFOGain = new GainNode(this.audioContext, {
566
- gain: this.cbToRatio(instrumentKey.modLfoToVolume + channel.modulation),
567
- });
568
- note.modLFO = new OscillatorNode(this.audioContext, {
596
+ const { modLfoToPitch, modLfoToVolume } = instrumentKey;
597
+ note.modulationLFO = new OscillatorNode(this.audioContext, {
569
598
  frequency: this.centToHz(instrumentKey.freqModLFO),
570
599
  });
571
- note.modLFO.start(time);
572
- note.filterNode.frequency.setValueAtTime(note.filterNode.frequency.value + instrumentKey.modLfoToFilterFc, time);
573
- note.bufferSource.detune.setValueAtTime(note.bufferSource.detune.value + instrumentKey.modLfoToPitch, time);
574
- note.modLFO.connect(note.modLFOGain);
575
- note.modLFOGain.connect(note.bufferSource.detune);
600
+ note.filterDepth = new GainNode(this.audioContext, {
601
+ gain: instrumentKey.modLfoToFilterFc,
602
+ });
603
+ const modulationDepth = Math.abs(modLfoToPitch) + channel.modulationDepth;
604
+ const modulationDepthSign = (0 < modLfoToPitch) ? 1 : -1;
605
+ note.modulationDepth = new GainNode(this.audioContext, {
606
+ gain: modulationDepth * modulationDepthSign,
607
+ });
608
+ const volumeDepth = this.cbToRatio(Math.abs(modLfoToVolume)) - 1;
609
+ const volumeDepthSign = (0 < modLfoToVolume) ? 1 : -1;
610
+ note.volumeDepth = new GainNode(this.audioContext, {
611
+ gain: volumeDepth * volumeDepthSign,
612
+ });
613
+ note.modulationLFO.start(startTime + instrumentKey.delayModLFO);
614
+ note.modulationLFO.connect(note.filterDepth);
615
+ note.filterDepth.connect(note.filterNode.frequency);
616
+ note.modulationLFO.connect(note.modulationDepth);
617
+ note.modulationDepth.connect(note.bufferSource.detune);
618
+ note.modulationLFO.connect(note.volumeDepth);
619
+ note.volumeDepth.connect(note.volumeNode.gain);
576
620
  }
577
621
  async createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3) {
578
622
  const semitoneOffset = this.calcSemitoneOffset(channel);
579
623
  const note = new Note(noteNumber, velocity, startTime, instrumentKey);
580
624
  note.bufferSource = await this.createNoteBufferNode(instrumentKey, isSF3);
581
- note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
582
- this.setVolumeEnvelope(channel, note);
583
- this.setFilterEnvelope(channel, note);
584
- if (channel.modulation > 0) {
585
- const delayModLFO = startTime + instrumentKey.delayModLFO;
586
- this.startModulation(channel, note, delayModLFO);
625
+ this.setFilterNode(channel, note);
626
+ this.setVolumeEnvelope(note);
627
+ if (0 < channel.modulationDepth) {
628
+ this.setPitch(note, semitoneOffset);
629
+ this.startModulation(channel, note, startTime);
630
+ }
631
+ else {
632
+ note.bufferSource.playbackRate.value = this.calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
587
633
  }
588
634
  note.bufferSource.connect(note.filterNode);
589
- note.filterNode.connect(note.gainNode);
635
+ note.filterNode.connect(note.volumeNode);
590
636
  note.bufferSource.start(startTime, instrumentKey.start / instrumentKey.sampleRate);
591
637
  return note;
592
638
  }
@@ -602,7 +648,8 @@ class MidyGM1 {
602
648
  if (!instrumentKey)
603
649
  return;
604
650
  const note = await this.createNote(channel, instrumentKey, noteNumber, velocity, startTime, isSF3);
605
- this.connectEffects(channel, note.gainNode);
651
+ note.volumeNode.connect(channel.gainL);
652
+ note.volumeNode.connect(channel.gainR);
606
653
  const scheduledNotes = channel.scheduledNotes;
607
654
  if (scheduledNotes.has(noteNumber)) {
608
655
  scheduledNotes.get(noteNumber).push(note);
@@ -631,17 +678,14 @@ class MidyGM1 {
631
678
  const velocityRate = (velocity + 127) / 127;
632
679
  const volEndTime = stopTime +
633
680
  note.instrumentKey.volRelease * velocityRate;
634
- note.gainNode.gain
681
+ note.volumeNode.gain
635
682
  .cancelScheduledValues(stopTime)
636
683
  .linearRampToValueAtTime(0, volEndTime);
637
- const maxFreq = this.audioContext.sampleRate / 2;
638
- const baseFreq = this.centToHz(note.instrumentKey.initialFilterFc);
639
- const adjustedBaseFreq = Math.min(maxFreq, baseFreq);
640
- const modEndTime = stopTime +
684
+ const modRelease = stopTime +
641
685
  note.instrumentKey.modRelease * velocityRate;
642
686
  note.filterNode.frequency
643
687
  .cancelScheduledValues(stopTime)
644
- .linearRampToValueAtTime(adjustedBaseFreq, modEndTime);
688
+ .linearRampToValueAtTime(0, modRelease);
645
689
  note.ending = true;
646
690
  this.scheduleTask(() => {
647
691
  note.bufferSource.loop = false;
@@ -650,15 +694,17 @@ class MidyGM1 {
650
694
  note.bufferSource.onended = () => {
651
695
  scheduledNotes[i] = null;
652
696
  note.bufferSource.disconnect();
697
+ note.volumeNode.disconnect();
653
698
  note.filterNode.disconnect();
654
- note.gainNode.disconnect();
655
- if (note.modLFOGain)
656
- note.modLFOGain.disconnect();
657
- if (note.modLFO)
658
- note.modLFO.stop();
699
+ if (note.volumeDepth)
700
+ note.volumeDepth.disconnect();
701
+ if (note.modulationDepth)
702
+ note.modulationDepth.disconnect();
703
+ if (note.modulationLFO)
704
+ note.modulationLFO.stop();
659
705
  resolve();
660
706
  };
661
- bufferSource.stop(volEndTime);
707
+ note.bufferSource.stop(volEndTime);
662
708
  });
663
709
  }
664
710
  }
@@ -671,10 +717,10 @@ class MidyGM1 {
671
717
  const channel = this.channels[channelNumber];
672
718
  const promises = [];
673
719
  channel.sustainPedal = false;
674
- channel.scheduledNotes.forEach((scheduledNotes) => {
675
- scheduledNotes.forEach((scheduledNote) => {
676
- if (scheduledNote) {
677
- const { noteNumber } = scheduledNote;
720
+ channel.scheduledNotes.forEach((noteList) => {
721
+ noteList.forEach((note) => {
722
+ if (note) {
723
+ const { noteNumber } = note;
678
724
  const promise = this.releaseNote(channelNumber, noteNumber, velocity);
679
725
  promises.push(promise);
680
726
  }
@@ -705,13 +751,13 @@ class MidyGM1 {
705
751
  channel.program = program;
706
752
  }
707
753
  handlePitchBendMessage(channelNumber, lsb, msb) {
708
- const pitchBend = msb * 128 + lsb;
754
+ const pitchBend = msb * 128 + lsb - 8192;
709
755
  this.setPitchBend(channelNumber, pitchBend);
710
756
  }
711
757
  setPitchBend(channelNumber, pitchBend) {
712
758
  const channel = this.channels[channelNumber];
713
759
  const prevPitchBend = channel.pitchBend;
714
- channel.pitchBend = (pitchBend - 8192) / 8192;
760
+ channel.pitchBend = pitchBend / 8192;
715
761
  const detuneChange = (channel.pitchBend - prevPitchBend) *
716
762
  channel.pitchBendRange * 100;
717
763
  this.updateDetune(channel, detuneChange);
@@ -719,7 +765,7 @@ class MidyGM1 {
719
765
  handleControlChange(channelNumber, controller, value) {
720
766
  switch (controller) {
721
767
  case 1:
722
- return this.setModulation(channelNumber, value);
768
+ return this.setModulationDepth(channelNumber, value);
723
769
  case 6:
724
770
  return this.dataEntryMSB(channelNumber, value);
725
771
  case 7:
@@ -750,18 +796,19 @@ class MidyGM1 {
750
796
  const now = this.audioContext.currentTime;
751
797
  const activeNotes = this.getActiveNotes(channel, now);
752
798
  activeNotes.forEach((activeNote) => {
753
- if (activeNote.modLFO) {
754
- const { gainNode, instrumentKey } = activeNote;
755
- gainNode.gain.setValueAtTime(this.cbToRatio(instrumentKey.modLfoToVolume + channel.modulation), now);
799
+ if (activeNote.modulationDepth) {
800
+ activeNote.modulationDepth.gain.setValueAtTime(channel.modulationDepth, now);
756
801
  }
757
802
  else {
803
+ const semitoneOffset = this.calcSemitoneOffset(channel);
804
+ this.setPitch(activeNote, semitoneOffset);
758
805
  this.startModulation(channel, activeNote, now);
759
806
  }
760
807
  });
761
808
  }
762
- setModulation(channelNumber, modulation) {
809
+ setModulationDepth(channelNumber, modulation) {
763
810
  const channel = this.channels[channelNumber];
764
- channel.modulation = (modulation / 127) * channel.modulationDepthRange;
811
+ channel.modulationDepth = (modulation / 127) * channel.modulationDepthRange;
765
812
  this.updateModulation(channel);
766
813
  }
767
814
  setVolume(channelNumber, volume) {
@@ -913,37 +960,13 @@ class MidyGM1 {
913
960
  this.updateDetune(channel, detuneChange);
914
961
  }
915
962
  allSoundOff(channelNumber) {
916
- const now = this.audioContext.currentTime;
917
- const channel = this.channels[channelNumber];
918
- const velocity = 0;
919
- const stopPedal = true;
920
- const promises = [];
921
- channel.scheduledNotes.forEach((noteList) => {
922
- const activeNote = this.getActiveNote(noteList, now);
923
- if (activeNote) {
924
- const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
925
- promises.push(notePromise);
926
- }
927
- });
928
- return promises;
963
+ return this.stopChannelNotes(channelNumber, 0, true);
929
964
  }
930
965
  resetAllControllers(channelNumber) {
931
966
  Object.assign(this.channels[channelNumber], this.effectSettings);
932
967
  }
933
968
  allNotesOff(channelNumber) {
934
- const now = this.audioContext.currentTime;
935
- const channel = this.channels[channelNumber];
936
- const velocity = 0;
937
- const stopPedal = false;
938
- const promises = [];
939
- channel.scheduledNotes.forEach((noteList) => {
940
- const activeNote = this.getActiveNote(noteList, now);
941
- if (activeNote) {
942
- const notePromise = this.scheduleNoteRelease(channelNumber, noteNumber, velocity, now, stopPedal);
943
- promises.push(notePromise);
944
- }
945
- });
946
- return promises;
969
+ return this.stopChannelNotes(channelNumber, 0, false);
947
970
  }
948
971
  handleUniversalNonRealTimeExclusiveMessage(data) {
949
972
  switch (data[2]) {
@@ -1039,7 +1062,7 @@ Object.defineProperty(MidyGM1, "channelSettings", {
1039
1062
  pitchBend: 0,
1040
1063
  fineTuning: 0, // cb
1041
1064
  coarseTuning: 0, // cb
1042
- modulationDepthRange: 0.5, // cb
1065
+ modulationDepthRange: 50, // cent
1043
1066
  }
1044
1067
  });
1045
1068
  Object.defineProperty(MidyGM1, "effectSettings", {
@@ -1048,7 +1071,7 @@ Object.defineProperty(MidyGM1, "effectSettings", {
1048
1071
  writable: true,
1049
1072
  value: {
1050
1073
  expression: 1,
1051
- modulation: 0,
1074
+ modulationDepth: 0,
1052
1075
  sustainPedal: false,
1053
1076
  rpnMSB: 127,
1054
1077
  rpnLSB: 127,
@@ -6,6 +6,9 @@ export class MidyGM2 {
6
6
  portamentoTime: number;
7
7
  reverbSendLevel: number;
8
8
  chorusSendLevel: number;
9
+ vibratoRate: number;
10
+ vibratoDepth: number;
11
+ vibratoDelay: number;
9
12
  bank: number;
10
13
  bankMSB: number;
11
14
  bankLSB: number;
@@ -19,7 +22,7 @@ export class MidyGM2 {
19
22
  };
20
23
  static effectSettings: {
21
24
  expression: number;
22
- modulation: number;
25
+ modulationDepth: number;
23
26
  sustainPedal: boolean;
24
27
  portamento: boolean;
25
28
  sostenutoPedal: boolean;
@@ -90,6 +93,19 @@ export class MidyGM2 {
90
93
  };
91
94
  masterGain: any;
92
95
  channels: any[];
96
+ reverbEffect: {
97
+ input: any;
98
+ output: any;
99
+ };
100
+ chorusEffect: {
101
+ input: any;
102
+ output: any;
103
+ sendGain: any;
104
+ lfo: any;
105
+ lfoGain: any;
106
+ delayNodes: any[];
107
+ feedbackGains: any[];
108
+ };
93
109
  initSoundFontTable(): any[];
94
110
  addSoundFont(soundFont: any): void;
95
111
  loadSoundFont(soundFontUrl: any): Promise<void>;
@@ -98,19 +114,6 @@ export class MidyGM2 {
98
114
  gainL: any;
99
115
  gainR: any;
100
116
  merger: any;
101
- reverbEffect: {
102
- input: any;
103
- output: any;
104
- };
105
- chorusEffect: {
106
- input: any;
107
- output: any;
108
- sendGain: any;
109
- lfo: any;
110
- lfoGain: any;
111
- delayNodes: any[];
112
- feedbackGains: any[];
113
- };
114
117
  };
115
118
  createChannels(audioContext: any): any[];
116
119
  createNoteBuffer(instrumentKey: any, isSF3: any): Promise<any>;
@@ -125,7 +128,8 @@ export class MidyGM2 {
125
128
  instruments: Set<any>;
126
129
  timeline: any[];
127
130
  };
128
- stopNotes(): Promise<any[]>;
131
+ stopChannelNotes(channelNumber: any, velocity: any, stopPedal: any): Promise<void>;
132
+ stopNotes(velocity: any, stopPedal: any): Promise<any[]>;
129
133
  start(): Promise<void>;
130
134
  stop(): void;
131
135
  pause(): void;
@@ -144,7 +148,7 @@ export class MidyGM2 {
144
148
  createCombFilter(audioContext: any, input: any, delay: any, feedback: any): any;
145
149
  createAllpassFilter(audioContext: any, input: any, delay: any, feedback: any): any;
146
150
  generateDistributedArray(center: any, count: any, varianceRatio?: number, randomness?: number): any[];
147
- createSchroederReverb(audioContext: any, combDelays: any, combFeedbacks: any, allpassDelays: any, allpassFeedbacks: any): {
151
+ createSchroederReverb(audioContext: any, combFeedbacks: any, combDelays: any, allpassFeedbacks: any, allpassDelays: any): {
148
152
  input: any;
149
153
  output: any;
150
154
  };
@@ -157,14 +161,15 @@ export class MidyGM2 {
157
161
  delayNodes: any[];
158
162
  feedbackGains: any[];
159
163
  };
160
- connectEffects(channel: any, gainNode: any): void;
161
164
  cbToRatio(cb: any): number;
162
165
  centToHz(cent: any): number;
163
166
  calcSemitoneOffset(channel: any): any;
164
167
  calcPlaybackRate(instrumentKey: any, noteNumber: any, semitoneOffset: any): number;
165
- setVolumeEnvelope(channel: any, note: any): void;
166
- setFilterEnvelope(channel: any, note: any): void;
167
- startModulation(channel: any, note: any, time: any): void;
168
+ setVolumeEnvelope(note: any): void;
169
+ setPitch(note: any, semitoneOffset: any): void;
170
+ setFilterNode(channel: any, note: any): void;
171
+ startModulation(channel: any, note: any, startTime: any): void;
172
+ startVibrato(channel: any, note: any, startTime: any): void;
168
173
  createNote(channel: any, instrumentKey: any, noteNumber: any, velocity: any, startTime: any, isSF3: any): Promise<Note>;
169
174
  calcBank(channel: any, channelNumber: any): any;
170
175
  scheduleNoteOn(channelNumber: any, noteNumber: any, velocity: any, startTime: any): Promise<void>;
@@ -173,15 +178,15 @@ export class MidyGM2 {
173
178
  releaseNote(channelNumber: any, noteNumber: any, velocity: any): Promise<any> | undefined;
174
179
  releaseSustainPedal(channelNumber: any, halfVelocity: any): any[];
175
180
  releaseSostenutoPedal(channelNumber: any, halfVelocity: any): any[];
176
- handleMIDIMessage(statusByte: any, data1: any, data2: any): void | any[] | Promise<any>;
181
+ handleMIDIMessage(statusByte: any, data1: any, data2: any): void | Promise<any>;
177
182
  handleProgramChange(channelNumber: any, program: any): void;
178
183
  handleChannelPressure(channelNumber: any, pressure: any): void;
179
184
  handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
180
185
  setPitchBend(channelNumber: any, pitchBend: any): void;
181
- handleControlChange(channelNumber: any, controller: any, value: any): void | any[];
186
+ handleControlChange(channelNumber: any, controller: any, value: any): void | Promise<void>;
182
187
  setBankMSB(channelNumber: any, msb: any): void;
183
188
  updateModulation(channel: any): void;
184
- setModulation(channelNumber: any, modulation: any): void;
189
+ setModulationDepth(channelNumber: any, modulation: any): void;
185
190
  setPortamentoTime(channelNumber: any, portamentoTime: any): void;
186
191
  setVolume(channelNumber: any, volume: any): void;
187
192
  panToGain(pan: any): {
@@ -214,9 +219,9 @@ export class MidyGM2 {
214
219
  setCoarseTuning(channelNumber: any, coarseTuning: any): void;
215
220
  handleModulationDepthRangeRPN(channelNumber: any): void;
216
221
  setModulationDepthRange(channelNumber: any, modulationDepthRange: any): void;
217
- allSoundOff(channelNumber: any): any[];
222
+ allSoundOff(channelNumber: any): Promise<void>;
218
223
  resetAllControllers(channelNumber: any): void;
219
- allNotesOff(channelNumber: any): any[];
224
+ allNotesOff(channelNumber: any): Promise<void>;
220
225
  omniOff(): void;
221
226
  omniOn(): void;
222
227
  monoOn(): void;
@@ -256,12 +261,13 @@ export class MidyGM2 {
256
261
  declare class Note {
257
262
  constructor(noteNumber: any, velocity: any, startTime: any, instrumentKey: any);
258
263
  bufferSource: any;
259
- gainNode: any;
260
264
  filterNode: any;
261
- modLFO: any;
262
- modLFOGain: any;
263
- vibLFO: any;
264
- vibLFOGain: any;
265
+ volumeNode: any;
266
+ volumeDepth: any;
267
+ modulationLFO: any;
268
+ modulationDepth: any;
269
+ vibratoLFO: any;
270
+ vibratoDepth: any;
265
271
  noteNumber: any;
266
272
  velocity: any;
267
273
  startTime: any;
@@ -1 +1 @@
1
- {"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"midy-GM2.d.ts","sourceRoot":"","sources":["../src/midy-GM2.js"],"names":[],"mappings":"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"}